/** * Process a buffer of audio data for call progress tones * * @param bug the session's media bug * @param user_data the detector * @param type the type of data available from the bug * @return SWITCH_TRUE */ static switch_bool_t callprogress_detector_process_buffer(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; switch_frame_t frame = { 0 }; tone_detector_t *detector = (tone_detector_t *)user_data; switch_core_session_t *session = switch_core_media_bug_get_session(bug); switch_channel_t *channel = switch_core_session_get_channel(session); frame.data = data; frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; switch(type) { case SWITCH_ABC_TYPE_INIT: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "(%s) initializing tone detector\n", switch_channel_get_name(channel)); tone_detector_init(detector); break; case SWITCH_ABC_TYPE_READ: { const char *detected_tone = NULL; if (!detector->spandsp_detector) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "(%s) detector is destroyed\n", switch_channel_get_name(channel)); return SWITCH_FALSE; } if (switch_core_media_bug_read(bug, &frame, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "(%s) error reading frame\n", switch_channel_get_name(channel)); return SWITCH_FALSE; } tone_detector_process_buffer(detector, frame.data, frame.samples, &detected_tone); if (detected_tone) { switch_event_t *event = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "(%s) DETECTED TONE: %s\n", switch_channel_get_name(channel), detected_tone); if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", detected_tone); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session)); switch_event_fire(&event); } } break; } case SWITCH_ABC_TYPE_WRITE: break; case SWITCH_ABC_TYPE_WRITE_REPLACE: break; case SWITCH_ABC_TYPE_READ_REPLACE: break; case SWITCH_ABC_TYPE_READ_PING: break; case SWITCH_ABC_TYPE_CLOSE: if (detector->spandsp_detector) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "(%s) destroying tone detector\n", switch_channel_get_name(channel)); tone_detector_destroy(detector); } break; } return SWITCH_TRUE; }
/** * Process a buffer of audio data for call progress tones * * @param bug the session's media bug * @param user_data the detector * @param type the type of data available from the bug * @return SWITCH_TRUE */ static switch_bool_t callprogress_detector_process_buffer(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { tone_detector_t *detector = (tone_detector_t *)user_data; switch_core_session_t *session = detector->session; switch(type) { case SWITCH_ABC_TYPE_INIT: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "initializing tone detector\n"); tone_detector_init(detector); break; case SWITCH_ABC_TYPE_READ_REPLACE: { switch_frame_t *frame; const char *detected_tone = NULL; if (!detector->spandsp_detector) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "detector is destroyed\n"); return SWITCH_FALSE; } if (!(frame = switch_core_media_bug_get_read_replace_frame(bug))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "error reading frame\n"); return SWITCH_FALSE; } tone_detector_process_buffer(detector, frame->data, frame->samples, &detected_tone); if (detected_tone) { switch_event_t *event = NULL; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "DETECTED TONE: %s\n", detected_tone); if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", detected_tone); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session)); switch_event_fire(&event); } } break; } case SWITCH_ABC_TYPE_CLOSE: if (detector->spandsp_detector) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "destroying tone detector\n"); tone_detector_destroy(detector); } break; default: break; } return SWITCH_TRUE; }