static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) { switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data; switch_frame_t *frame = NULL; switch (type) { case SWITCH_ABC_TYPE_INIT: { pvt->dtmf_detect = dtmf_rx_init(NULL, NULL, NULL); dtmf_rx_parms(pvt->dtmf_detect, pvt->filter_dialtone, pvt->twist, pvt->reverse_twist, pvt->threshold); dtmf_rx_set_realtime_callback(pvt->dtmf_detect, spandsp_dtmf_rx_realtime_callback, pvt); break; } case SWITCH_ABC_TYPE_CLOSE: if (pvt->dtmf_detect) { dtmf_rx_free(pvt->dtmf_detect); } break; case SWITCH_ABC_TYPE_READ_REPLACE: if ((frame = switch_core_media_bug_get_read_replace_frame(bug))) { dtmf_rx(pvt->dtmf_detect, frame->data, frame->samples); switch_core_media_bug_set_read_replace_frame(bug, frame); } break; case SWITCH_ABC_TYPE_WRITE: default: break; } return SWITCH_TRUE; }
void SpanDtmfProbe() { std::string dtmfCode = "*1234567890#ABCD"; iDSP::DtmfGeneratorProfile prof; prof.Level = 0; prof.DurationMs = 80; // 70 мало prof.PauseMs = 40; // 50 20-мало iDSP::DtmfGenerator gen; gen.Add(dtmfCode); // Init: digits_rx_callback_t callback = 0;//EvDigitDetected; void* pUserData = 0; dtmf_rx_state_t state; dtmf_rx_state_t* pState = &state; dtmf_rx_init(pState, callback, pUserData); // Adjust detector: bool rej350_440 = false; int fwTwist = 8; //8 Db максимальная разница уровней частот в комбинации int revTwist = 8; //-4 Db ? int threshold = -26; //Db минимальный уровень сигнала dtmf_rx_parms(pState, rej350_440, fwTwist, revTwist, threshold); while (gen.RestSampleCount() != 0) { int16_t sample = gen.NextSample(); dtmf_rx(pState, &sample, 1); } const int CMaxSymbols = 100; char dtmfCodeRx[CMaxSymbols]; int size = dtmf_rx_get(pState, dtmfCodeRx, CMaxSymbols); TUT_ASSERT(size == dtmfCode.size()); dtmfCodeRx[size] = '\0'; TUT_ASSERT(dtmfCode == dtmfCodeRx); // delete pState; //dtmf_rx_free(pState); //pState = 0; }