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_FEATURE_WAITDIALTONE (1 << 20) |
| #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_frame_freed (struct ast_frame *fr) |
| Hint that a frame from a dsp was freed. | |
| 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 47 of file dsp.h.
Referenced by ast_dsp_process().
| #define DSP_FAXMODE_DETECT_CNG (1 << 0) |
Definition at line 46 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_FEATURE_WAITDIALTONE (1 << 20) |
Enable dial tone detection
Definition at line 44 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_new(), and dahdi_read().
| #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 54 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_DIALTONE 2 |
Definition at line 52 of file dsp.h.
Referenced by __ast_dsp_call_progress(), and dahdi_read().
| #define DSP_TONE_STATE_HUNGUP 8 |
Definition at line 58 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_RINGING 1 |
Definition at line 51 of file dsp.h.
Referenced by __ast_dsp_call_progress(), and dahdi_read().
| #define DSP_TONE_STATE_SILENCE 0 |
Definition at line 50 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL1 5 |
Definition at line 55 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL2 6 |
Definition at line 56 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL3 7 |
Definition at line 57 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_TALKING 3 |
Definition at line 53 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| enum threshold |
Definition at line 62 of file dsp.h.
00062 { 00063 /* Array offsets */ 00064 THRESHOLD_SILENCE = 0, 00065 /* Always the last */ 00066 THRESHOLD_MAX = 1, 00067 };
| 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 1174 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().
01175 { 01176 int res = 0, x; 01177 #ifndef BUSYDETECT_TONEONLY 01178 int avgsilence = 0, hitsilence = 0; 01179 #endif 01180 int avgtone = 0, hittone = 0; 01181 if (!dsp->busymaybe) { 01182 return res; 01183 } 01184 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) { 01185 #ifndef BUSYDETECT_TONEONLY 01186 avgsilence += dsp->historicsilence[x]; 01187 #endif 01188 avgtone += dsp->historicnoise[x]; 01189 } 01190 #ifndef BUSYDETECT_TONEONLY 01191 avgsilence /= dsp->busycount; 01192 #endif 01193 avgtone /= dsp->busycount; 01194 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) { 01195 #ifndef BUSYDETECT_TONEONLY 01196 if (avgsilence > dsp->historicsilence[x]) { 01197 if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) { 01198 hitsilence++; 01199 } 01200 } else { 01201 if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) { 01202 hitsilence++; 01203 } 01204 } 01205 #endif 01206 if (avgtone > dsp->historicnoise[x]) { 01207 if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) { 01208 hittone++; 01209 } 01210 } else { 01211 if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) { 01212 hittone++; 01213 } 01214 } 01215 } 01216 #ifndef BUSYDETECT_TONEONLY 01217 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 01218 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 01219 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) { 01220 #else 01221 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { 01222 #endif 01223 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01224 if (avgtone > avgsilence) { 01225 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) { 01226 res = 1; 01227 } 01228 } else { 01229 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) { 01230 res = 1; 01231 } 01232 } 01233 #else 01234 res = 1; 01235 #endif 01236 } 01237 /* If we know the expected busy tone length, check we are in the range */ 01238 if (res && (dsp->busy_tonelength > 0)) { 01239 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) { 01240 #ifdef BUSYDETECT_DEBUG 01241 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n", 01242 avgtone, dsp->busy_tonelength); 01243 #endif 01244 res = 0; 01245 } 01246 } 01247 #ifndef BUSYDETECT_TONEONLY 01248 /* If we know the expected busy tone silent-period length, check we are in the range */ 01249 if (res && (dsp->busy_quietlength > 0)) { 01250 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) { 01251 #ifdef BUSYDETECT_DEBUG 01252 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n", 01253 avgsilence, dsp->busy_quietlength); 01254 #endif 01255 res = 0; 01256 } 01257 } 01258 #endif 01259 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG) 01260 if (res) { 01261 ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01262 } else { 01263 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01264 } 01265 #endif 01266 return res; 01267 }
Scans for progress indication in audio.
Definition at line 1098 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.
01099 { 01100 if (inf->frametype != AST_FRAME_VOICE) { 01101 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01102 return 0; 01103 } 01104 if (inf->subclass != AST_FORMAT_SLINEAR) { 01105 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01106 return 0; 01107 } 01108 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2); 01109 }
Return non-zero if DTMF hit was found.
| void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |
Reset DTMF detector.
Definition at line 1583 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().
01584 { 01585 int i; 01586 01587 dsp->dtmf_began = 0; 01588 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01589 mf_detect_state_t *s = &dsp->digit_state.td.mf; 01590 /* Reinitialise the detector for the next block */ 01591 for (i = 0; i < 6; i++) { 01592 goertzel_reset(&s->tone_out[i]); 01593 } 01594 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0; 01595 s->current_sample = 0; 01596 } else { 01597 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf; 01598 /* Reinitialise the detector for the next block */ 01599 for (i = 0; i < 4; i++) { 01600 goertzel_reset(&s->row_out[i]); 01601 goertzel_reset(&s->col_out[i]); 01602 } 01603 s->lasthit = s->current_hit = 0; 01604 s->energy = 0.0; 01605 s->current_sample = 0; 01606 s->hits = 0; 01607 s->misses = 0; 01608 } 01609 01610 dsp->digit_state.digits[0] = '\0'; 01611 dsp->digit_state.current_digits = 0; 01612 }
| void ast_dsp_frame_freed | ( | struct ast_frame * | fr | ) |
Hint that a frame from a dsp was freed.
This is called from ast_frame_free if AST_FRFLAG_FROM_DSP is set. This occurs because it is possible for the dsp to be freed while someone still holds a reference to the frame that is in that dsp. This has been known to happen when the dsp on a DAHDI channel detects a busy signal. The channel is hung up, and the application that read the frame to begin with still has a reference to the frame.
Definition at line 1722 of file dsp.c.
References ast_clear_flag, ast_dsp_free(), AST_FRFLAG_FROM_DSP, ast_dsp::destroy, and f.
Referenced by __frame_free().
01723 { 01724 struct ast_dsp *dsp; 01725 01726 ast_clear_flag(fr, AST_FRFLAG_FROM_DSP); 01727 01728 dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f)); 01729 01730 if (!dsp->destroy) 01731 return; 01732 01733 ast_dsp_free(dsp); 01734 }
| void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1545 of file dsp.c.
References ast_free, AST_FRFLAG_FROM_DSP, ast_test_flag, ast_dsp::destroy, and ast_dsp::f.
Referenced by __ast_play_and_record(), __oh323_destroy(), ast_dsp_frame_freed(), 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().
01546 { 01547 if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) { 01548 /* If this flag is still set, that means that the dsp's destruction 01549 * been torn down, while we still have a frame out there being used. 01550 * When ast_frfree() gets called on that frame, this ast_trans_pvt 01551 * will get destroyed, too. */ 01552 01553 dsp->destroy = 1; 01554 01555 return; 01556 } 01557 ast_free(dsp); 01558 }
| int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter).
Definition at line 1676 of file dsp.c.
References ast_dsp::tcount.
Referenced by dahdi_read().
01677 { 01678 return dsp->tcount; 01679 }
| int ast_dsp_get_threshold_from_settings | ( | enum threshold | which | ) |
Get silence threshold from dsp.conf.
Definition at line 1707 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().
01708 { 01709 return thresholds[which]; 01710 }
| int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State).
Definition at line 1671 of file dsp.c.
References ast_dsp::tstate.
Referenced by dahdi_read().
01672 { 01673 return dsp->tstate; 01674 }
| 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 1712 of file dsp.c.
References _dsp_init().
Referenced by main().
01713 { 01714 return _dsp_init(0); 01715 }
| struct ast_dsp* ast_dsp_new | ( | void | ) | [read] |
Definition at line 1519 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().
01520 { 01521 struct ast_dsp *dsp; 01522 01523 if ((dsp = ast_calloc(1, sizeof(*dsp)))) { 01524 dsp->threshold = DEFAULT_THRESHOLD; 01525 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS; 01526 dsp->busycount = DSP_HISTORY; 01527 dsp->digitmode = DSP_DIGITMODE_DTMF; 01528 dsp->faxmode = DSP_FAXMODE_DETECT_CNG; 01529 /* Initialize digit detector */ 01530 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF); 01531 dsp->display_inband_dtmf_warning = 1; 01532 /* Initialize initial DSP progress detect parameters */ 01533 ast_dsp_prog_reset(dsp); 01534 /* Initialize fax detector */ 01535 ast_fax_detect_init(dsp); 01536 } 01537 return dsp; 01538 }
Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise.
Definition at line 1287 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().
01288 { 01289 short *s; 01290 int len; 01291 01292 if (f->frametype != AST_FRAME_VOICE) { 01293 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n"); 01294 return 0; 01295 } 01296 if (f->subclass != AST_FORMAT_SLINEAR) { 01297 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n"); 01298 return 0; 01299 } 01300 s = f->data.ptr; 01301 len = f->datalen/2; 01302 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise); 01303 }
| 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 1306 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_FRFLAG_FROM_DSP, ast_frfree, ast_getformatname(), AST_LIN2A, AST_LIN2MU, ast_log(), AST_MULAW, ast_queue_frame(), ast_set_flag, 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, DSP_FEATURE_WAITDIALTONE, 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_channel::name, 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().
01307 { 01308 int silence; 01309 int res; 01310 int digit = 0, fax_digit = 0; 01311 int x; 01312 short *shortdata; 01313 unsigned char *odata; 01314 int len; 01315 struct ast_frame *outf = NULL; 01316 01317 if (!af) { 01318 return NULL; 01319 } 01320 if (af->frametype != AST_FRAME_VOICE) { 01321 return af; 01322 } 01323 01324 odata = af->data.ptr; 01325 len = af->datalen; 01326 /* Make sure we have short data */ 01327 switch (af->subclass) { 01328 case AST_FORMAT_SLINEAR: 01329 shortdata = af->data.ptr; 01330 len = af->datalen / 2; 01331 break; 01332 case AST_FORMAT_ULAW: 01333 shortdata = alloca(af->datalen * 2); 01334 for (x = 0;x < len; x++) { 01335 shortdata[x] = AST_MULAW(odata[x]); 01336 } 01337 break; 01338 case AST_FORMAT_ALAW: 01339 shortdata = alloca(af->datalen * 2); 01340 for (x = 0; x < len; x++) { 01341 shortdata[x] = AST_ALAW(odata[x]); 01342 } 01343 break; 01344 default: 01345 /*Display warning only once. Otherwise you would get hundreds of warnings every second */ 01346 if (dsp->display_inband_dtmf_warning) 01347 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); 01348 dsp->display_inband_dtmf_warning = 0; 01349 return af; 01350 } 01351 01352 /* Initially we do not want to mute anything */ 01353 dsp->mute_fragments = 0; 01354 01355 /* Need to run the silence detection stuff for silence suppression and busy detection */ 01356 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) { 01357 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL); 01358 } 01359 01360 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { 01361 memset(&dsp->f, 0, sizeof(dsp->f)); 01362 dsp->f.frametype = AST_FRAME_NULL; 01363 ast_frfree(af); 01364 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01365 return &dsp->f; 01366 } 01367 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) { 01368 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01369 memset(&dsp->f, 0, sizeof(dsp->f)); 01370 dsp->f.frametype = AST_FRAME_CONTROL; 01371 dsp->f.subclass = AST_CONTROL_BUSY; 01372 ast_frfree(af); 01373 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name); 01374 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01375 return &dsp->f; 01376 } 01377 01378 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) { 01379 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) { 01380 fax_digit = 'f'; 01381 } 01382 01383 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) { 01384 fax_digit = 'e'; 01385 } 01386 } 01387 01388 if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) { 01389 if (dsp->digitmode & DSP_DIGITMODE_MF) 01390 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01391 else 01392 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01393 01394 if (dsp->digit_state.current_digits) { 01395 int event = 0; 01396 char event_digit = 0; 01397 01398 if (!dsp->dtmf_began) { 01399 /* We have not reported DTMF_BEGIN for anything yet */ 01400 01401 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { 01402 event = AST_FRAME_DTMF_BEGIN; 01403 event_digit = dsp->digit_state.digits[0]; 01404 } 01405 dsp->dtmf_began = 1; 01406 01407 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) { 01408 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */ 01409 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { 01410 event = AST_FRAME_DTMF_END; 01411 event_digit = dsp->digit_state.digits[0]; 01412 } 01413 memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits); 01414 dsp->digit_state.current_digits--; 01415 dsp->dtmf_began = 0; 01416 01417 if (dsp->features & DSP_FEATURE_BUSY_DETECT) { 01418 /* Reset Busy Detector as we have some confirmed activity */ 01419 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01420 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01421 ast_debug(1, "DTMF Detected - Reset busydetector\n"); 01422 } 01423 } 01424 01425 if (event) { 01426 memset(&dsp->f, 0, sizeof(dsp->f)); 01427 dsp->f.frametype = event; 01428 dsp->f.subclass = event_digit; 01429 outf = &dsp->f; 01430 goto done; 01431 } 01432 } 01433 } 01434 01435 if (fax_digit) { 01436 /* Fax was detected - digit is either 'f' or 'e' */ 01437 01438 memset(&dsp->f, 0, sizeof(dsp->f)); 01439 dsp->f.frametype = AST_FRAME_DTMF; 01440 dsp->f.subclass = fax_digit; 01441 outf = &dsp->f; 01442 goto done; 01443 } 01444 01445 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) { 01446 res = __ast_dsp_call_progress(dsp, shortdata, len); 01447 if (res) { 01448 switch (res) { 01449 case AST_CONTROL_ANSWER: 01450 case AST_CONTROL_BUSY: 01451 case AST_CONTROL_RINGING: 01452 case AST_CONTROL_CONGESTION: 01453 case AST_CONTROL_HANGUP: 01454 memset(&dsp->f, 0, sizeof(dsp->f)); 01455 dsp->f.frametype = AST_FRAME_CONTROL; 01456 dsp->f.subclass = res; 01457 dsp->f.src = "dsp_progress"; 01458 if (chan) 01459 ast_queue_frame(chan, &dsp->f); 01460 break; 01461 default: 01462 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res); 01463 } 01464 } 01465 } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) { 01466 res = __ast_dsp_call_progress(dsp, shortdata, len); 01467 } 01468 01469 done: 01470 /* Mute fragment of the frame */ 01471 for (x = 0; x < dsp->mute_fragments; x++) { 01472 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start)); 01473 } 01474 01475 switch (af->subclass) { 01476 case AST_FORMAT_SLINEAR: 01477 break; 01478 case AST_FORMAT_ULAW: 01479 for (x = 0; x < len; x++) { 01480 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]); 01481 } 01482 break; 01483 case AST_FORMAT_ALAW: 01484 for (x = 0; x < len; x++) { 01485 odata[x] = AST_LIN2A((unsigned short) shortdata[x]); 01486 } 01487 break; 01488 } 01489 01490 if (outf) { 01491 if (chan) { 01492 ast_queue_frame(chan, af); 01493 } 01494 ast_frfree(af); 01495 ast_set_flag(outf, AST_FRFLAG_FROM_DSP); 01496 return outf; 01497 } else { 01498 return af; 01499 } 01500 }
| int ast_dsp_reload | ( | void | ) |
Reloads dsp settings from dsp.conf.
Definition at line 1717 of file dsp.c.
References _dsp_init().
01718 { 01719 return _dsp_init(1); 01720 }
| void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1614 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.
01615 { 01616 int x; 01617 01618 dsp->totalsilence = 0; 01619 dsp->gsamps = 0; 01620 for (x = 0; x < 4; x++) { 01621 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01622 } 01623 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01624 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01625 dsp->ringtimeout= 0; 01626 }
| void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, | |
| int | cadences | |||
| ) |
Set number of required cadences for busy.
Definition at line 1565 of file dsp.c.
References ast_dsp::busycount, and DSP_HISTORY.
Referenced by dahdi_new().
01566 { 01567 if (cadences < 4) { 01568 cadences = 4; 01569 } 01570 if (cadences > DSP_HISTORY) { 01571 cadences = DSP_HISTORY; 01572 } 01573 dsp->busycount = cadences; 01574 }
| void ast_dsp_set_busy_pattern | ( | struct ast_dsp * | dsp, | |
| int | tonelength, | |||
| int | quietlength | |||
| ) |
Set expected lengths of the busy tone.
Definition at line 1576 of file dsp.c.
References ast_debug, ast_dsp::busy_quietlength, and ast_dsp::busy_tonelength.
Referenced by dahdi_new().
01577 { 01578 dsp->busy_tonelength = tonelength; 01579 dsp->busy_quietlength = quietlength; 01580 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength); 01581 }
| int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, | |
| char * | zone | |||
| ) |
Set zone for doing progress detection.
Definition at line 1652 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 1628 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().
01629 { 01630 int new; 01631 int old; 01632 01633 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01634 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01635 if (old != new) { 01636 /* Must initialize structures if switching from MF to DTMF or vice-versa */ 01637 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF); 01638 } 01639 dsp->digitmode = digitmode; 01640 return 0; 01641 }
| int ast_dsp_set_faxmode | ( | struct ast_dsp * | dsp, | |
| int | faxmode | |||
| ) |
Set fax mode.
Definition at line 1643 of file dsp.c.
References ast_fax_detect_init(), and ast_dsp::faxmode.
01644 { 01645 if (dsp->faxmode != faxmode) { 01646 ast_fax_detect_init(dsp); 01647 } 01648 dsp->faxmode = faxmode; 01649 return 0; 01650 }
| void ast_dsp_set_features | ( | struct ast_dsp * | dsp, | |
| int | features | |||
| ) |
Select feature set.
Definition at line 1540 of file dsp.c.
References ast_dsp::features.
Referenced by __oh323_new(), dahdi_new(), dahdi_read(), 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().
01541 { 01542 dsp->features = features; 01543 }
| void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, | |
| int | threshold | |||
| ) |
Set threshold value for silence.
Definition at line 1560 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 1269 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().
01270 { 01271 short *s; 01272 int len; 01273 01274 if (f->frametype != AST_FRAME_VOICE) { 01275 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n"); 01276 return 0; 01277 } 01278 if (f->subclass != AST_FORMAT_SLINEAR) { 01279 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n"); 01280 return 0; 01281 } 01282 s = f->data.ptr; 01283 len = f->datalen/2; 01284 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL); 01285 }
| 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 1666 of file dsp.c.
References ast_dsp::mute_fragments.
Referenced by dahdi_read().
01667 { 01668 return (dsp->mute_fragments > 0); 01669 }
1.6.2