static switch_bool_t tdd_encode_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_tdd_t *pvt = (switch_tdd_t *) user_data; switch_frame_t *frame = NULL; switch_bool_t r = SWITCH_TRUE; switch (type) { case SWITCH_ABC_TYPE_INIT: { break; } case SWITCH_ABC_TYPE_CLOSE: if (pvt->tdd_state) { v18_free(pvt->tdd_state); } break; case SWITCH_ABC_TYPE_WRITE_REPLACE: if ((frame = switch_core_media_bug_get_write_replace_frame(bug))) { int len; if (pvt->tail_lead) { if (!--pvt->tail_lead) { r = SWITCH_FALSE; } memset(frame->data, 0, frame->datalen); } else if (pvt->head_lead) { pvt->head_lead--; memset(frame->data, 0, frame->datalen); } else { len = v18_tx(pvt->tdd_state, frame->data, frame->samples); if (!len) { pvt->tail_lead = TDD_LEAD; } } switch_core_media_bug_set_write_replace_frame(bug, frame); } break; case SWITCH_ABC_TYPE_WRITE: default: break; } return r; }
static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_fsk_detect_t *pvt = (switch_fsk_detect_t *) user_data; //switch_frame_t *frame = NULL; switch_channel_t *channel = switch_core_session_get_channel(pvt->session); switch (type) { case SWITCH_ABC_TYPE_INIT: { switch_codec_implementation_t read_impl = { 0 }; switch_core_session_get_read_impl(pvt->session, &read_impl); if (fsk_demod_init(&pvt->fsk_data, read_impl.actual_samples_per_second, pvt->fbuf, sizeof(pvt->fbuf))) { return SWITCH_FALSE; } break; } case SWITCH_ABC_TYPE_CLOSE: { fsk_demod_destroy(&pvt->fsk_data); } break; case SWITCH_ABC_TYPE_WRITE_REPLACE: case SWITCH_ABC_TYPE_READ_REPLACE: { switch_frame_t *rframe; if (type == SWITCH_ABC_TYPE_READ_REPLACE) { rframe = switch_core_media_bug_get_read_replace_frame(bug); } else { rframe = switch_core_media_bug_get_write_replace_frame(bug); } if (!pvt->skip && fsk_demod_feed(&pvt->fsk_data, rframe->data, rframe->datalen / 2) != SWITCH_STATUS_SUCCESS) { char str[1024] = ""; size_t type, mlen; char *sp; switch_event_t *event; const char *app_var; int total = 0; switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA); while(fsk_data_parse(&pvt->fsk_data, &type, &sp, &mlen) == SWITCH_STATUS_SUCCESS) { char *varname = NULL, *val, *p; switch_copy_string(str, sp, mlen+1); *(str+mlen) = '\0'; switch_clean_string(str); //printf("TYPE %u LEN %u VAL [%s]\n", (unsigned)type, (unsigned)mlen, str); val = str; switch(type) { case MDMF_DATETIME: varname = "fsk_datetime"; break; case MDMF_PHONE_NAME: varname = "fsk_phone_name"; break; case MDMF_PHONE_NUM: varname = "fsk_phone_num"; break; case MDMF_NAME_VALUE: varname = switch_core_session_sprintf(pvt->session, "fsk_%s", val); if ((p = strchr(varname, ':'))) { *p++ = '\0'; val = p; } break; default: break; } if (varname && val) { total++; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n", switch_channel_get_name(channel), varname, val); switch_channel_set_variable(channel, varname, val); if (event) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, varname, val); } } } if (event) { if (switch_core_session_queue_event(pvt->session, &event) != SWITCH_STATUS_SUCCESS) { switch_event_destroy(&event); } } if (total && (app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) { char *app_arg; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n", switch_channel_get_name(channel), app_var); if ((app_arg = strchr(app_var, ' '))) { *app_arg++ = '\0'; } switch_core_session_execute_application(pvt->session, app_var, app_arg); } pvt->skip = 10; } memset(rframe->data, 255, rframe->datalen); if (type == SWITCH_ABC_TYPE_READ_REPLACE) { switch_core_media_bug_set_read_replace_frame(bug, rframe); } else { switch_core_media_bug_set_write_replace_frame(bug, rframe); } if (pvt->skip && !--pvt->skip) { return SWITCH_FALSE; } } break; case SWITCH_ABC_TYPE_WRITE: default: break; } return SWITCH_TRUE; }
static switch_bool_t oreka_audio_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { oreka_session_t *oreka = user_data; switch_core_session_t *session = oreka->session; switch_frame_t pcmu_frame = { 0 }; switch_frame_t *linear_frame, raw_frame = { 0 }; uint8_t pcmu_data[SWITCH_RECOMMENDED_BUFFER_SIZE]; uint8_t raw_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; uint8_t resample_data[SWITCH_RECOMMENDED_BUFFER_SIZE]; uint32_t linear_len = 0; uint32_t i = 0; int16_t *linear_samples = NULL; if (type == SWITCH_ABC_TYPE_READ_REPLACE || type == SWITCH_ABC_TYPE_WRITE_REPLACE || type == SWITCH_ABC_TYPE_READ_PING) { int16_t *data; if (type == SWITCH_ABC_TYPE_READ_REPLACE || type == SWITCH_ABC_TYPE_READ_PING) { if (type == SWITCH_ABC_TYPE_READ_REPLACE) { linear_frame = switch_core_media_bug_get_read_replace_frame(bug); } else { switch_status_t status; raw_frame.data = raw_data; raw_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; linear_frame = &raw_frame; status = switch_core_media_bug_read(bug, &raw_frame, SWITCH_FALSE); if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { return SWITCH_TRUE; } } if (oreka->read_resampler) { data = (int16_t *) linear_frame->data; switch_resample_process(oreka->read_resampler, data, (int) linear_frame->datalen / 2); linear_len = oreka->read_resampler->to_len * 2; memcpy(resample_data, oreka->read_resampler->to, linear_len); linear_samples = (int16_t *)resample_data; } else { linear_samples = linear_frame->data; linear_len = linear_frame->datalen; } } if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) { linear_frame = switch_core_media_bug_get_write_replace_frame(bug); if (oreka->write_resampler) { data = (int16_t *) linear_frame->data; switch_resample_process(oreka->write_resampler, data, (int) linear_frame->datalen / 2); linear_len = oreka->write_resampler->to_len * 2; memcpy(resample_data, oreka->write_resampler->to, linear_len); linear_samples = (int16_t *)resample_data; } else { linear_samples = linear_frame->data; linear_len = linear_frame->datalen; } } /* convert the L16 frame into PCMU */ memset(&pcmu_frame, 0, sizeof(pcmu_frame)); for (i = 0; i < linear_len / sizeof(int16_t); i++) { pcmu_data[i] = linear_to_ulaw(linear_samples[i]); } pcmu_frame.source = __FUNCTION__; pcmu_frame.data = pcmu_data; pcmu_frame.datalen = i; pcmu_frame.payload = 0; } switch (type) { case SWITCH_ABC_TYPE_INIT: { switch_codec_implementation_t read_impl; switch_core_session_get_read_impl(session, &read_impl); if (read_impl.actual_samples_per_second != 8000) { switch_resample_create(&oreka->read_resampler, read_impl.actual_samples_per_second, 8000, 320, SWITCH_RESAMPLE_QUALITY, 1); switch_resample_create(&oreka->write_resampler, read_impl.actual_samples_per_second, 8000, 320, SWITCH_RESAMPLE_QUALITY, 1); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Starting Oreka recording for audio stream\n"); oreka_send_sip_message(oreka, FS_OREKA_START, FS_OREKA_READ); if (!oreka->mux_streams) { oreka_send_sip_message(oreka, FS_OREKA_START, FS_OREKA_WRITE); } } break; case SWITCH_ABC_TYPE_CLOSE: { if (oreka->mux_streams) { int16_t *data; raw_frame.data = raw_data; raw_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; linear_frame = &raw_frame; while (switch_core_media_bug_read(bug, &raw_frame, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { linear_frame = &raw_frame; if (oreka->read_resampler) { data = (int16_t *) linear_frame->data; switch_resample_process(oreka->read_resampler, data, (int) linear_frame->datalen / 2); linear_len = oreka->read_resampler->to_len * 2; memcpy(resample_data, oreka->read_resampler->to, linear_len); linear_samples = (int16_t *)resample_data; } else { linear_samples = linear_frame->data; linear_len = linear_frame->datalen; } memset(&pcmu_frame, 0, sizeof(pcmu_frame)); for (i = 0; i < linear_len / sizeof(int16_t); i++) { pcmu_data[i] = linear_to_ulaw(linear_samples[i]); } pcmu_frame.source = __FUNCTION__; pcmu_frame.data = pcmu_data; pcmu_frame.datalen = i; pcmu_frame.payload = 0; switch_rtp_write_frame(oreka->read_rtp_stream, &pcmu_frame); } } if (oreka->read_resampler) { switch_resample_destroy(&oreka->read_resampler); } if (oreka->write_resampler) { switch_resample_destroy(&oreka->write_resampler); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Stopping Oreka recording for audio stream\n"); oreka_send_sip_message(oreka, FS_OREKA_STOP, FS_OREKA_READ); if (!oreka->mux_streams) { oreka_send_sip_message(oreka, FS_OREKA_STOP, FS_OREKA_WRITE); } } break; case SWITCH_ABC_TYPE_READ_REPLACE: case SWITCH_ABC_TYPE_READ_PING: { if (pcmu_frame.datalen) { if (switch_rtp_write_frame(oreka->read_rtp_stream, &pcmu_frame) > 0) { oreka->read_cnt++; if (oreka->read_cnt < 10) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Oreka wrote %u bytes! (read)\n", pcmu_frame.datalen); } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to write %u bytes! (read)\n", pcmu_frame.datalen); } } } break; case SWITCH_ABC_TYPE_WRITE_REPLACE: { if (pcmu_frame.datalen) { if (switch_rtp_write_frame(oreka->write_rtp_stream, &pcmu_frame) > 0) { oreka->write_cnt++; if (oreka->write_cnt < 10) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Oreka wrote %u bytes! (write)\n", pcmu_frame.datalen); } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to write %u bytes! (write)\n", pcmu_frame.datalen); } } } break; default: break; } return SWITCH_TRUE; }
static switch_bool_t ladspa_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_ladspa_t *pvt = (switch_ladspa_t *) user_data; //switch_frame_t *frame = NULL; switch_channel_t *channel = switch_core_session_get_channel(pvt->session); switch (type) { case SWITCH_ABC_TYPE_INIT: { switch_codec_implementation_t read_impl = { 0 }; LADSPA_PortDescriptor port_desc; int i = 0, j = 0, k = 0, str_idx = 0; switch_core_session_get_read_impl(pvt->session, &read_impl); if (!(pvt->library_handle = loadLADSPAPluginLibrary(pvt->plugin_name))) { return SWITCH_FALSE; } if (!(pvt->ldesc = findLADSPAPluginDescriptor(pvt->library_handle, pvt->plugin_name, pvt->label_name))) { return SWITCH_FALSE; } pvt->handle = pvt->ldesc->instantiate(pvt->ldesc, read_impl.actual_samples_per_second); dump_info(pvt->ldesc); for (i = 0; i < pvt->ldesc->PortCount; i++) { port_desc = pvt->ldesc->PortDescriptors[i]; if (LADSPA_IS_PORT_CONTROL(port_desc) && LADSPA_IS_PORT_INPUT(port_desc)) { LADSPA_Data dft = 0.0f; int found = find_default(pvt->ldesc, i, &dft); if (found && !pvt->has_config[j]) { pvt->config[j] = dft; pvt->has_config[j] = 1; } if (pvt->has_config[j]) { if (!check_range(pvt->ldesc, i, pvt->config[j])) { pvt->config[j] = dft; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_WARNING, "FALLING TO DEFAULT PARAM %d [%s] (%f)\n", j+1, pvt->ldesc->PortNames[i], pvt->config[j]); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "ADDING PARAM %d [%s] (%f)\n", j+1, pvt->ldesc->PortNames[i], pvt->config[j]); pvt->ldesc->connect_port(pvt->handle, i, &pvt->config[j++]); usleep(10000); } } if (LADSPA_IS_PORT_INPUT(port_desc) && LADSPA_IS_PORT_AUDIO(port_desc)) { int mapped = 0; if (pvt->str_idx && !zstr(pvt->str_config[str_idx])) { if (!strcasecmp(pvt->str_config[str_idx], "none")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT NOTHING to port: %s\n", pvt->ldesc->PortNames[i] ); mapped = 1; } else if (!strncasecmp(pvt->str_config[str_idx], "file:", 5)) { char *file = pvt->str_config[str_idx] + 5; if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "CAN'T CONNECT FILE [%s] File already mapped\n", file); } else { if (switch_core_file_open(&pvt->fh, file, read_impl.number_of_channels, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot open file: %s\n", file); return SWITCH_FALSE; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT FILE [%s] to port: %s\n", file, pvt->ldesc->PortNames[i] ); pvt->ldesc->connect_port(pvt->handle, i, pvt->file_buf); mapped = 1; } } str_idx++; } if (!mapped) { pvt->ldesc->connect_port(pvt->handle, i, pvt->in_buf); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "CONNECT CHANNEL AUDIO to port: %s\n", pvt->ldesc->PortNames[i] ); } } if (LADSPA_IS_PORT_OUTPUT(port_desc)) { if (LADSPA_IS_PORT_AUDIO(port_desc)) { pvt->ldesc->connect_port(pvt->handle, i, pvt->out_buf); } else if (k < MAX_INDEX) { pvt->ldesc->connect_port(pvt->handle, i, &pvt->out_ports[k++]); } } } } break; case SWITCH_ABC_TYPE_CLOSE: { if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&pvt->fh); } if (pvt->handle && pvt->ldesc) { pvt->ldesc->cleanup(pvt->handle); } if (pvt->library_handle) { unloadLADSPAPluginLibrary(pvt->library_handle); } } break; case SWITCH_ABC_TYPE_WRITE_REPLACE: case SWITCH_ABC_TYPE_READ_REPLACE: { switch_frame_t *rframe; int16_t *slin, abuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; switch_size_t olen = 0; if (type == SWITCH_ABC_TYPE_READ_REPLACE) { rframe = switch_core_media_bug_get_read_replace_frame(bug); } else { rframe = switch_core_media_bug_get_write_replace_frame(bug); } slin = rframe->data; if (switch_channel_media_ready(channel)) { switch_short_to_float(slin, pvt->in_buf, rframe->samples); if (switch_test_flag((&pvt->fh), SWITCH_FILE_OPEN)) { olen = rframe->samples; if (switch_core_file_read(&pvt->fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { switch_codec_implementation_t read_impl = { 0 }; char *file = switch_core_session_strdup(pvt->session, pvt->fh.file_path); switch_core_session_get_read_impl(pvt->session, &read_impl); switch_core_file_close(&pvt->fh); if (switch_core_file_open(&pvt->fh, file, read_impl.number_of_channels, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot open file: %s\n", file); return SWITCH_FALSE; } olen = rframe->samples; if (switch_core_file_read(&pvt->fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_ERROR, "Cannot READ file: %s\n", file); return SWITCH_FALSE; } } switch_short_to_float(abuf, pvt->file_buf, olen); } pvt->ldesc->run(pvt->handle, rframe->samples); switch_float_to_short(pvt->out_buf, slin, rframe->samples); } if (type == SWITCH_ABC_TYPE_READ_REPLACE) { switch_core_media_bug_set_read_replace_frame(bug, rframe); } else { switch_core_media_bug_set_write_replace_frame(bug, rframe); } if (pvt->skip && !--pvt->skip) { return SWITCH_FALSE; } } break; case SWITCH_ABC_TYPE_WRITE: default: break; } return SWITCH_TRUE; }