Convenient Signal Processing routines. More...

Go to the source code of this file.
Defines | |
| #define | DSP_DIGITMODE_DTMF 0 |
| #define | DSP_DIGITMODE_MF 1 |
| #define | DSP_DIGITMODE_MUTECONF (1 << 9) |
| #define | DSP_DIGITMODE_MUTEMAX (1 << 10) |
| #define | DSP_DIGITMODE_NOQUELCH (1 << 8) |
| #define | DSP_DIGITMODE_RELAXDTMF (1 << 11) |
| #define | DSP_FAXMODE_DETECT_ALL (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED) |
| #define | DSP_FAXMODE_DETECT_CED (1 << 1) |
| #define | DSP_FAXMODE_DETECT_CNG (1 << 0) |
| #define | DSP_FEATURE_BUSY_DETECT (1 << 1) |
| #define | DSP_FEATURE_CALL_PROGRESS (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION) |
| #define | DSP_FEATURE_DIGIT_DETECT (1 << 3) |
| #define | DSP_FEATURE_FAX_DETECT (1 << 4) |
| #define | DSP_FEATURE_SILENCE_SUPPRESS (1 << 0) |
| #define | DSP_PROGRESS_BUSY (1 << 18) |
| #define | DSP_PROGRESS_CONGESTION (1 << 19) |
| #define | DSP_PROGRESS_RINGING (1 << 17) |
| #define | DSP_PROGRESS_TALK (1 << 16) |
| #define | DSP_TONE_STATE_BUSY 4 |
| #define | DSP_TONE_STATE_DIALTONE 2 |
| #define | DSP_TONE_STATE_HUNGUP 8 |
| #define | DSP_TONE_STATE_RINGING 1 |
| #define | DSP_TONE_STATE_SILENCE 0 |
| #define | DSP_TONE_STATE_SPECIAL1 5 |
| #define | DSP_TONE_STATE_SPECIAL2 6 |
| #define | DSP_TONE_STATE_SPECIAL3 7 |
| #define | DSP_TONE_STATE_TALKING 3 |
Enumerations | |
| enum | threshold { THRESHOLD_SILENCE = 0, THRESHOLD_MAX = 1 } |
Functions | |
| int | ast_dsp_busydetect (struct ast_dsp *dsp) |
| Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called. | |
| int | ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf) |
| Scans for progress indication in audio. | |
| int | ast_dsp_digitdetect (struct ast_dsp *dsp, struct ast_frame *f) |
| Return non-zero if DTMF hit was found. | |
| void | ast_dsp_digitreset (struct ast_dsp *dsp) |
| Reset DTMF detector. | |
| void | ast_dsp_free (struct ast_dsp *dsp) |
| int | ast_dsp_get_tcount (struct ast_dsp *dsp) |
| Get tcount (Threshold counter). | |
| int | ast_dsp_get_threshold_from_settings (enum threshold which) |
| Get silence threshold from dsp.conf. | |
| int | ast_dsp_get_tstate (struct ast_dsp *dsp) |
| Get tstate (Tone State). | |
| int | ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max) |
| Get pending DTMF/MF digits. | |
| int | ast_dsp_init (void) |
| Load dsp settings from dsp.conf. | |
| struct ast_dsp * | ast_dsp_new (void) |
| int | ast_dsp_noise (struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise) |
| Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise. | |
| struct ast_frame * | ast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf) |
| Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled. | |
| int | ast_dsp_reload (void) |
| Reloads dsp settings from dsp.conf. | |
| void | ast_dsp_reset (struct ast_dsp *dsp) |
| Reset total silence count. | |
| void | ast_dsp_set_busy_count (struct ast_dsp *dsp, int cadences) |
| Set number of required cadences for busy. | |
| void | ast_dsp_set_busy_pattern (struct ast_dsp *dsp, int tonelength, int quietlength) |
| Set expected lengths of the busy tone. | |
| int | ast_dsp_set_call_progress_zone (struct ast_dsp *dsp, char *zone) |
| Set zone for doing progress detection. | |
| int | ast_dsp_set_digitmode (struct ast_dsp *dsp, int digitmode) |
| Set digit mode. | |
| int | ast_dsp_set_faxmode (struct ast_dsp *dsp, int faxmode) |
| Set fax mode. | |
| void | ast_dsp_set_features (struct ast_dsp *dsp, int features) |
| Select feature set. | |
| void | ast_dsp_set_threshold (struct ast_dsp *dsp, int threshold) |
| Set threshold value for silence. | |
| int | ast_dsp_silence (struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence) |
| Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence. | |
| int | ast_dsp_was_muted (struct ast_dsp *dsp) |
| Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio. | |
Convenient Signal Processing routines.
Definition in file dsp.h.
| #define DSP_DIGITMODE_DTMF 0 |
Detect DTMF digits
Definition at line 31 of file dsp.h.
Referenced by ast_dsp_new(), ast_dsp_set_digitmode(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), mkintf(), sip_new(), ss_thread(), and store_config().
| #define DSP_DIGITMODE_MF 1 |
Detect MF digits
Definition at line 32 of file dsp.h.
Referenced by ast_dsp_digitreset(), ast_dsp_new(), ast_dsp_process(), ast_dsp_set_digitmode(), and ss_thread().
| #define DSP_DIGITMODE_MUTECONF (1 << 9) |
Mute conference
Definition at line 35 of file dsp.h.
Referenced by ast_dsp_set_digitmode(), dahdi_setoption(), and store_config().
| #define DSP_DIGITMODE_MUTEMAX (1 << 10) |
Delay audio by a frame to try to extra quelch
Definition at line 36 of file dsp.h.
Referenced by ast_dsp_set_digitmode(), and dahdi_setoption().
| #define DSP_DIGITMODE_NOQUELCH (1 << 8) |
Do not quelch DTMF from in-band
Definition at line 34 of file dsp.h.
Referenced by ast_dsp_process(), and mgcp_new().
| #define DSP_DIGITMODE_RELAXDTMF (1 << 11) |
"Radio" mode (relaxed DTMF)
Definition at line 37 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_setoption(), process_dahdi(), sip_new(), and store_config().
| #define DSP_FAXMODE_DETECT_ALL (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED) |
| #define DSP_FAXMODE_DETECT_CED (1 << 1) |
Definition at line 46 of file dsp.h.
Referenced by ast_dsp_process().
| #define DSP_FAXMODE_DETECT_CNG (1 << 0) |
Definition at line 45 of file dsp.h.
Referenced by ast_dsp_new(), and ast_dsp_process().
| #define DSP_FEATURE_BUSY_DETECT (1 << 1) |
Definition at line 27 of file dsp.h.
Referenced by ast_dsp_process(), and dahdi_new().
| #define DSP_FEATURE_CALL_PROGRESS (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION) |
Definition at line 43 of file dsp.h.
Referenced by __ast_dsp_call_progress(), ast_dsp_process(), and dahdi_new().
| #define DSP_FEATURE_DIGIT_DETECT (1 << 3) |
Definition at line 28 of file dsp.h.
Referenced by __oh323_new(), ast_dsp_process(), dahdi_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), sip_new(), sip_rtp_read(), and store_config().
| #define DSP_FEATURE_FAX_DETECT (1 << 4) |
Definition at line 29 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_new(), misdn_set_opt_exec(), read_config(), and sip_new().
| #define DSP_FEATURE_SILENCE_SUPPRESS (1 << 0) |
Definition at line 26 of file dsp.h.
Referenced by ast_dsp_new(), and ast_dsp_process().
| #define DSP_PROGRESS_BUSY (1 << 18) |
Enable busy tone detection
Definition at line 41 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_PROGRESS_CONGESTION (1 << 19) |
Enable congestion tone detection
Definition at line 42 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_PROGRESS_RINGING (1 << 17) |
Enable calling tone detection
Definition at line 40 of file dsp.h.
Referenced by __ast_dsp_call_progress(), and pri_dchannel().
| #define DSP_PROGRESS_TALK (1 << 16) |
Enable talk detection
Definition at line 39 of file dsp.h.
Referenced by __ast_dsp_call_progress(), and dahdi_new().
| #define DSP_TONE_STATE_BUSY 4 |
Definition at line 53 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_DIALTONE 2 |
Definition at line 51 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_HUNGUP 8 |
Definition at line 57 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_RINGING 1 |
Definition at line 50 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SILENCE 0 |
Definition at line 49 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL1 5 |
Definition at line 54 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL2 6 |
Definition at line 55 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL3 7 |
Definition at line 56 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_TALKING 3 |
Definition at line 52 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| enum threshold |
Definition at line 61 of file dsp.h.
00061 { 00062 /* Array offsets */ 00063 THRESHOLD_SILENCE = 0, 00064 /* Always the last */ 00065 THRESHOLD_MAX = 1, 00066 };
| int ast_dsp_busydetect | ( | struct ast_dsp * | dsp | ) |
Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called.
Definition at line 1144 of file dsp.c.
References ast_debug, BUSY_MAX, BUSY_MIN, BUSY_PAT_PERCENT, BUSY_PERCENT, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busycount, ast_dsp::busymaybe, DSP_HISTORY, ast_dsp::historicnoise, and ast_dsp::historicsilence.
Referenced by ast_dsp_process().
01145 { 01146 int res = 0, x; 01147 #ifndef BUSYDETECT_TONEONLY 01148 int avgsilence = 0, hitsilence = 0; 01149 #endif 01150 int avgtone = 0, hittone = 0; 01151 if (!dsp->busymaybe) 01152 return res; 01153 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) { 01154 #ifndef BUSYDETECT_TONEONLY 01155 avgsilence += dsp->historicsilence[x]; 01156 #endif 01157 avgtone += dsp->historicnoise[x]; 01158 } 01159 #ifndef BUSYDETECT_TONEONLY 01160 avgsilence /= dsp->busycount; 01161 #endif 01162 avgtone /= dsp->busycount; 01163 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) { 01164 #ifndef BUSYDETECT_TONEONLY 01165 if (avgsilence > dsp->historicsilence[x]) { 01166 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x]) 01167 hitsilence++; 01168 } else { 01169 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x]) 01170 hitsilence++; 01171 } 01172 #endif 01173 if (avgtone > dsp->historicnoise[x]) { 01174 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x]) 01175 hittone++; 01176 } else { 01177 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x]) 01178 hittone++; 01179 } 01180 } 01181 #ifndef BUSYDETECT_TONEONLY 01182 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 01183 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 01184 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) { 01185 #else 01186 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { 01187 #endif 01188 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01189 if (avgtone > avgsilence) { 01190 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) 01191 res = 1; 01192 } else { 01193 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) 01194 res = 1; 01195 } 01196 #else 01197 res = 1; 01198 #endif 01199 } 01200 /* If we know the expected busy tone length, check we are in the range */ 01201 if (res && (dsp->busy_tonelength > 0)) { 01202 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) { 01203 #ifdef BUSYDETECT_DEBUG 01204 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n", 01205 avgtone, dsp->busy_tonelength); 01206 #endif 01207 res = 0; 01208 } 01209 } 01210 #ifndef BUSYDETECT_TONEONLY 01211 /* If we know the expected busy tone silent-period length, check we are in the range */ 01212 if (res && (dsp->busy_quietlength > 0)) { 01213 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) { 01214 #ifdef BUSYDETECT_DEBUG 01215 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n", 01216 avgsilence, dsp->busy_quietlength); 01217 #endif 01218 res = 0; 01219 } 01220 } 01221 #endif 01222 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG) 01223 if (res) { 01224 ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01225 } else { 01226 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01227 } 01228 #endif 01229 return res; 01230 }
Scans for progress indication in audio.
Definition at line 1074 of file dsp.c.
References __ast_dsp_call_progress(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
01075 { 01076 if (inf->frametype != AST_FRAME_VOICE) { 01077 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01078 return 0; 01079 } 01080 if (inf->subclass != AST_FORMAT_SLINEAR) { 01081 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01082 return 0; 01083 } 01084 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2); 01085 }
Return non-zero if DTMF hit was found.
| void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |
Reset DTMF detector.
Definition at line 1522 of file dsp.c.
References dtmf_detect_state_t::col_out, digit_detect_state_t::current_digits, dtmf_detect_state_t::current_hit, mf_detect_state_t::current_hit, dtmf_detect_state_t::current_sample, mf_detect_state_t::current_sample, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, DSP_DIGITMODE_MF, digit_detect_state_t::dtmf, ast_dsp::dtmf_began, dtmf_detect_state_t::energy, goertzel_reset(), dtmf_detect_state_t::hits, mf_detect_state_t::hits, dtmf_detect_state_t::lasthit, digit_detect_state_t::mf, dtmf_detect_state_t::misses, dtmf_detect_state_t::row_out, s, digit_detect_state_t::td, and mf_detect_state_t::tone_out.
Referenced by ss_thread().
01523 { 01524 int i; 01525 01526 dsp->dtmf_began = 0; 01527 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01528 mf_detect_state_t *s = &dsp->digit_state.td.mf; 01529 /* Reinitialise the detector for the next block */ 01530 for (i = 0; i < 6; i++) { 01531 goertzel_reset(&s->tone_out[i]); 01532 } 01533 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0; 01534 s->current_sample = 0; 01535 } else { 01536 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf; 01537 /* Reinitialise the detector for the next block */ 01538 for (i = 0; i < 4; i++) { 01539 goertzel_reset(&s->row_out[i]); 01540 goertzel_reset(&s->col_out[i]); 01541 } 01542 s->lasthit = s->current_hit = 0; 01543 s->energy = 0.0; 01544 s->current_sample = 0; 01545 s->hits = 0; 01546 s->misses = 0; 01547 } 01548 01549 dsp->digit_state.digits[0] = '\0'; 01550 dsp->digit_state.current_digits = 0; 01551 }
| void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1496 of file dsp.c.
References ast_free.
Referenced by __ast_play_and_record(), __oh323_destroy(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), conf_run(), dahdi_hangup(), destroy_endpoint(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), record_exec(), sip_dtmfmode(), sip_hangup(), sip_rtp_read(), ss_thread(), and unload_module().
01497 { 01498 ast_free(dsp); 01499 }
| int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter).
Definition at line 1614 of file dsp.c.
References ast_dsp::tcount.
01615 { 01616 return dsp->tcount; 01617 }
| int ast_dsp_get_threshold_from_settings | ( | enum threshold | which | ) |
Get silence threshold from dsp.conf.
Definition at line 1641 of file dsp.c.
Referenced by app_exec(), ast_record_review(), conf_run(), do_waiting(), handle_recordfile(), load_config(), record_exec(), and setup_privacy_args().
01642 { 01643 return thresholds[which]; 01644 }
| int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State).
Definition at line 1609 of file dsp.c.
References ast_dsp::tstate.
01610 { 01611 return dsp->tstate; 01612 }
| int ast_dsp_getdigits | ( | struct ast_dsp * | dsp, | |
| char * | buf, | |||
| int | max | |||
| ) |
Get pending DTMF/MF digits.
| int ast_dsp_init | ( | void | ) |
Load dsp settings from dsp.conf.
Definition at line 1646 of file dsp.c.
References _dsp_init().
Referenced by main().
01647 { 01648 return _dsp_init(0); 01649 }
| struct ast_dsp* ast_dsp_new | ( | void | ) | [read] |
Definition at line 1470 of file dsp.c.
References ast_calloc, ast_digit_detect_init(), ast_dsp_prog_reset(), ast_fax_detect_init(), ast_dsp::busycount, DEFAULT_THRESHOLD, ast_dsp::digit_state, ast_dsp::digitmode, ast_dsp::display_inband_dtmf_warning, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, ast_dsp::faxmode, ast_dsp::features, and ast_dsp::threshold.
Referenced by __ast_play_and_record(), __oh323_new(), background_detect_exec(), conf_run(), dahdi_new(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), read_config(), record_exec(), sip_dtmfmode(), sip_new(), and store_config().
01471 { 01472 struct ast_dsp *dsp; 01473 01474 if ((dsp = ast_calloc(1, sizeof(*dsp)))) { 01475 dsp->threshold = DEFAULT_THRESHOLD; 01476 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS; 01477 dsp->busycount = DSP_HISTORY; 01478 dsp->digitmode = DSP_DIGITMODE_DTMF; 01479 dsp->faxmode = DSP_FAXMODE_DETECT_CNG; 01480 /* Initialize digit detector */ 01481 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF); 01482 dsp->display_inband_dtmf_warning = 1; 01483 /* Initialize initial DSP progress detect parameters */ 01484 ast_dsp_prog_reset(dsp); 01485 /* Initialize fax detector */ 01486 ast_fax_detect_init(dsp); 01487 } 01488 return dsp; 01489 }
Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise.
Definition at line 1250 of file dsp.c.
References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, s, and ast_frame::subclass.
Referenced by do_waiting().
01251 { 01252 short *s; 01253 int len; 01254 01255 if (f->frametype != AST_FRAME_VOICE) { 01256 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n"); 01257 return 0; 01258 } 01259 if (f->subclass != AST_FORMAT_SLINEAR) { 01260 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n"); 01261 return 0; 01262 } 01263 s = f->data.ptr; 01264 len = f->datalen/2; 01265 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise); 01266 }
| struct ast_frame* ast_dsp_process | ( | struct ast_channel * | chan, | |
| struct ast_dsp * | dsp, | |||
| struct ast_frame * | inf | |||
| ) | [read] |
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled.
Definition at line 1269 of file dsp.c.
References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), ast_channel::_softhangup, AST_ALAW, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_debug, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), ast_getformatname(), AST_LIN2A, AST_LIN2MU, ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_dsp::ced_tone_state, ast_dsp::cng_tone_state, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, ast_dsp::display_inband_dtmf_warning, DSP_DIGITMODE_MF, DSP_DIGITMODE_NOQUELCH, DSP_DIGITMODE_RELAXDTMF, DSP_FAXMODE_DETECT_CED, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::dtmf_began, dtmf_detect(), fragment_t::end, ast_dsp::f, ast_dsp::faxmode, ast_dsp::features, ast_frame::frametype, ast_dsp::historicnoise, ast_dsp::historicsilence, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, ast_frame::ptr, ast_frame::src, fragment_t::start, ast_frame::subclass, and tone_detect().
Referenced by dahdi_read(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), sip_rtp_read(), and usbradio_read().
01270 { 01271 int silence; 01272 int res; 01273 int digit = 0, fax_digit = 0; 01274 int x; 01275 short *shortdata; 01276 unsigned char *odata; 01277 int len; 01278 struct ast_frame *outf = NULL; 01279 01280 if (!af) 01281 return NULL; 01282 if (af->frametype != AST_FRAME_VOICE) 01283 return af; 01284 01285 odata = af->data.ptr; 01286 len = af->datalen; 01287 /* Make sure we have short data */ 01288 switch (af->subclass) { 01289 case AST_FORMAT_SLINEAR: 01290 shortdata = af->data.ptr; 01291 len = af->datalen / 2; 01292 break; 01293 case AST_FORMAT_ULAW: 01294 shortdata = alloca(af->datalen * 2); 01295 for (x = 0;x < len; x++) 01296 shortdata[x] = AST_MULAW(odata[x]); 01297 break; 01298 case AST_FORMAT_ALAW: 01299 shortdata = alloca(af->datalen * 2); 01300 for (x = 0; x < len; x++) 01301 shortdata[x] = AST_ALAW(odata[x]); 01302 break; 01303 default: 01304 /*Display warning only once. Otherwise you would get hundreds of warnings every second */ 01305 if (dsp->display_inband_dtmf_warning) 01306 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); 01307 dsp->display_inband_dtmf_warning = 0; 01308 return af; 01309 } 01310 01311 /* Initially we do not want to mute anything */ 01312 dsp->mute_fragments = 0; 01313 01314 /* Need to run the silence detection stuff for silence suppression and busy detection */ 01315 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) { 01316 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL); 01317 } 01318 01319 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { 01320 memset(&dsp->f, 0, sizeof(dsp->f)); 01321 dsp->f.frametype = AST_FRAME_NULL; 01322 ast_frfree(af); 01323 return ast_frisolate(&dsp->f); 01324 } 01325 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) { 01326 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01327 memset(&dsp->f, 0, sizeof(dsp->f)); 01328 dsp->f.frametype = AST_FRAME_CONTROL; 01329 dsp->f.subclass = AST_CONTROL_BUSY; 01330 ast_frfree(af); 01331 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name); 01332 return ast_frisolate(&dsp->f); 01333 } 01334 01335 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) { 01336 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) { 01337 fax_digit = 'f'; 01338 } 01339 01340 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) { 01341 fax_digit = 'e'; 01342 } 01343 } 01344 01345 if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) { 01346 if (dsp->digitmode & DSP_DIGITMODE_MF) 01347 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01348 else 01349 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01350 01351 if (dsp->digit_state.current_digits) { 01352 int event = 0; 01353 char event_digit = 0; 01354 01355 if (!dsp->dtmf_began) { 01356 /* We have not reported DTMF_BEGIN for anything yet */ 01357 01358 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { 01359 event = AST_FRAME_DTMF_BEGIN; 01360 event_digit = dsp->digit_state.digits[0]; 01361 } 01362 dsp->dtmf_began = 1; 01363 01364 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) { 01365 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */ 01366 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { 01367 event = AST_FRAME_DTMF_END; 01368 event_digit = dsp->digit_state.digits[0]; 01369 } 01370 memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits); 01371 dsp->digit_state.current_digits--; 01372 dsp->dtmf_began = 0; 01373 01374 if (dsp->features & DSP_FEATURE_BUSY_DETECT) { 01375 /* Reset Busy Detector as we have some confirmed activity */ 01376 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01377 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01378 ast_debug(1, "DTMF Detected - Reset busydetector\n"); 01379 } 01380 } 01381 01382 if (event) { 01383 memset(&dsp->f, 0, sizeof(dsp->f)); 01384 dsp->f.frametype = event; 01385 dsp->f.subclass = event_digit; 01386 outf = &dsp->f; 01387 goto done; 01388 } 01389 } 01390 } 01391 01392 if (fax_digit) { 01393 /* Fax was detected - digit is either 'f' or 'e' */ 01394 01395 memset(&dsp->f, 0, sizeof(dsp->f)); 01396 dsp->f.frametype = AST_FRAME_DTMF; 01397 dsp->f.subclass = fax_digit; 01398 outf = &dsp->f; 01399 goto done; 01400 } 01401 01402 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) { 01403 res = __ast_dsp_call_progress(dsp, shortdata, len); 01404 if (res) { 01405 switch (res) { 01406 case AST_CONTROL_ANSWER: 01407 case AST_CONTROL_BUSY: 01408 case AST_CONTROL_RINGING: 01409 case AST_CONTROL_CONGESTION: 01410 case AST_CONTROL_HANGUP: 01411 memset(&dsp->f, 0, sizeof(dsp->f)); 01412 dsp->f.frametype = AST_FRAME_CONTROL; 01413 dsp->f.subclass = res; 01414 dsp->f.src = "dsp_progress"; 01415 if (chan) 01416 ast_queue_frame(chan, &dsp->f); 01417 break; 01418 default: 01419 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res); 01420 } 01421 } 01422 } 01423 01424 done: 01425 /* Mute fragment of the frame */ 01426 for (x = 0; x < dsp->mute_fragments; x++) { 01427 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start)); 01428 } 01429 01430 switch (af->subclass) { 01431 case AST_FORMAT_SLINEAR: 01432 break; 01433 case AST_FORMAT_ULAW: 01434 for (x = 0; x < len; x++) 01435 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]); 01436 break; 01437 case AST_FORMAT_ALAW: 01438 for (x = 0; x < len; x++) 01439 odata[x] = AST_LIN2A((unsigned short) shortdata[x]); 01440 break; 01441 } 01442 01443 if (outf) { 01444 if (chan) 01445 ast_queue_frame(chan, af); 01446 ast_frfree(af); 01447 return ast_frisolate(outf); 01448 } else { 01449 return af; 01450 } 01451 }
| int ast_dsp_reload | ( | void | ) |
Reloads dsp settings from dsp.conf.
Definition at line 1651 of file dsp.c.
References _dsp_init().
01652 { 01653 return _dsp_init(1); 01654 }
| void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1553 of file dsp.c.
References ast_dsp::freqs, ast_dsp::gsamps, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp::ringtimeout, ast_dsp::totalsilence, goertzel_state_t::v2, and goertzel_state_t::v3.
01554 { 01555 int x; 01556 01557 dsp->totalsilence = 0; 01558 dsp->gsamps = 0; 01559 for (x=0;x<4;x++) 01560 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01561 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01562 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01563 dsp->ringtimeout= 0; 01564 }
| void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, | |
| int | cadences | |||
| ) |
Set number of required cadences for busy.
Definition at line 1506 of file dsp.c.
References ast_dsp::busycount, and DSP_HISTORY.
Referenced by dahdi_new().
01507 { 01508 if (cadences < 4) 01509 cadences = 4; 01510 if (cadences > DSP_HISTORY) 01511 cadences = DSP_HISTORY; 01512 dsp->busycount = cadences; 01513 }
| void ast_dsp_set_busy_pattern | ( | struct ast_dsp * | dsp, | |
| int | tonelength, | |||
| int | quietlength | |||
| ) |
Set expected lengths of the busy tone.
Definition at line 1515 of file dsp.c.
References ast_debug, ast_dsp::busy_quietlength, and ast_dsp::busy_tonelength.
Referenced by dahdi_new().
01516 { 01517 dsp->busy_tonelength = tonelength; 01518 dsp->busy_quietlength = quietlength; 01519 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength); 01520 }
| int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, | |
| char * | zone | |||
| ) |
Set zone for doing progress detection.
Definition at line 1590 of file dsp.c.
References aliases, ARRAY_LEN, ast_dsp_prog_reset(), progalias::mode, name, and ast_dsp::progmode.
Referenced by dahdi_new().
| int ast_dsp_set_digitmode | ( | struct ast_dsp * | dsp, | |
| int | digitmode | |||
| ) |
Set digit mode.
Definition at line 1566 of file dsp.c.
References ast_digit_detect_init(), ast_dsp::digit_state, ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, and DSP_DIGITMODE_MUTEMAX.
Referenced by dahdi_hangup(), dahdi_new(), dahdi_setoption(), mgcp_new(), mkintf(), sip_new(), ss_thread(), and store_config().
01567 { 01568 int new; 01569 int old; 01570 01571 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01572 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01573 if (old != new) { 01574 /* Must initialize structures if switching from MF to DTMF or vice-versa */ 01575 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF); 01576 } 01577 dsp->digitmode = digitmode; 01578 return 0; 01579 }
| int ast_dsp_set_faxmode | ( | struct ast_dsp * | dsp, | |
| int | faxmode | |||
| ) |
Set fax mode.
Definition at line 1581 of file dsp.c.
References ast_fax_detect_init(), and ast_dsp::faxmode.
01582 { 01583 if (dsp->faxmode != faxmode) { 01584 ast_fax_detect_init(dsp); 01585 } 01586 dsp->faxmode = faxmode; 01587 return 0; 01588 }
| void ast_dsp_set_features | ( | struct ast_dsp * | dsp, | |
| int | features | |||
| ) |
Select feature set.
Definition at line 1491 of file dsp.c.
References ast_dsp::features.
Referenced by __oh323_new(), dahdi_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), pri_dchannel(), read_config(), sip_dtmfmode(), sip_new(), sip_rtp_read(), ss7_linkset(), and store_config().
01492 { 01493 dsp->features = features; 01494 }
| void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, | |
| int | threshold | |||
| ) |
Set threshold value for silence.
Definition at line 1501 of file dsp.c.
References ast_dsp::threshold.
Referenced by __ast_play_and_record(), do_waiting(), handle_recordfile(), isAnsweringMachine(), and record_exec().
Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.
Definition at line 1232 of file dsp.c.
References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, s, and ast_frame::subclass.
Referenced by __ast_play_and_record(), background_detect_exec(), conf_run(), do_waiting(), handle_recordfile(), isAnsweringMachine(), and record_exec().
01233 { 01234 short *s; 01235 int len; 01236 01237 if (f->frametype != AST_FRAME_VOICE) { 01238 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n"); 01239 return 0; 01240 } 01241 if (f->subclass != AST_FORMAT_SLINEAR) { 01242 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n"); 01243 return 0; 01244 } 01245 s = f->data.ptr; 01246 len = f->datalen/2; 01247 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL); 01248 }
| int ast_dsp_was_muted | ( | struct ast_dsp * | dsp | ) |
Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio.
Definition at line 1604 of file dsp.c.
References ast_dsp::mute_fragments.
Referenced by dahdi_read().
01605 { 01606 return (dsp->mute_fragments > 0); 01607 }
1.6.1