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_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_compare (struct ast_dsp *dsp, int compare) |
Set if silence and noice lengths must be compared for busy. | |
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, int fuzzy) |
Set expected lengths of the busy tones. | |
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 analog_ss_thread(), ast_dsp_new(), ast_dsp_set_digitmode(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), enable_dsp_detect(), mkintf(), and my_dsp_set_digitmode().
#define DSP_DIGITMODE_MF 1 |
Detect MF digits
Definition at line 32 of file dsp.h.
Referenced by analog_ss_thread(), ast_dsp_digitreset(), ast_dsp_new(), ast_dsp_process(), ast_dsp_set_digitmode(), and my_dsp_set_digitmode().
#define DSP_DIGITMODE_MUTECONF (1 << 9) |
Mute conference
Definition at line 35 of file dsp.h.
Referenced by ast_dsp_set_digitmode(), and dahdi_setoption().
#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(), enable_dsp_detect(), and process_dahdi().
#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(), ast_dsp_set_features(), dahdi_new(), disable_dtmf_detect(), enable_dsp_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), and sip_rtp_read().
#define DSP_FEATURE_FAX_DETECT (1 << 4) |
Definition at line 29 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_handle_dtmf(), dahdi_new(), dahdi_queryoption(), dahdi_setoption(), enable_dsp_detect(), misdn_set_opt_exec(), my_handle_dtmf(), and read_config().
#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().
#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 1250 of file dsp.c.
References ast_debug, ast_log(), BUSY_MAX, BUSY_MIN, ast_dsp::busy_pattern_fuzzy, BUSY_PERCENT, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busycompare, ast_dsp::busycount, ast_dsp::busymaybe, ast_dsp::busytoneonly, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::historicsilence, LOG_ERROR, LOG_NOTICE, MAX, and option_debug.
Referenced by ast_dsp_process().
01251 { 01252 int res = 0, x; 01253 int avgsilence = 0, hitsilence = 0; 01254 int avgtone = 0, hittone = 0; 01255 #ifdef DEBUG_DSP_BUSYDETECT 01256 char buf[16]; 01257 char silence_list[64]="", tone_list[64]=""; 01258 #endif 01259 01260 if (!dsp->busymaybe) { 01261 return res; 01262 } 01263 dsp->busymaybe = 0; 01264 01265 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) { 01266 avgsilence += dsp->historicsilence[x]; 01267 avgtone += dsp->historicnoise[x]; 01268 } 01269 avgsilence /= dsp->busycount; 01270 avgtone /= dsp->busycount; 01271 #ifdef DEBUG_DSP_BUSYDETECT 01272 sprintf(silence_list,"Silences: "); 01273 sprintf(tone_list,"Tones: "); 01274 #endif 01275 for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) { 01276 #ifdef DEBUG_DSP_BUSYDETECT 01277 snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]); 01278 strcat(silence_list, buf); 01279 snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]); 01280 strcat(tone_list, buf); 01281 #endif 01282 if (!dsp->busytoneonly) { 01283 if (avgsilence > dsp->historicsilence[x]) { 01284 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x]) 01285 hitsilence++; 01286 } else { 01287 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x]) 01288 hitsilence++; 01289 } 01290 } 01291 if (avgtone > dsp->historicnoise[x]) { 01292 if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) { 01293 hittone++; 01294 } 01295 } else { 01296 if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) { 01297 hittone++; 01298 } 01299 } 01300 } 01301 #ifdef DEBUG_DSP_BUSYDETECT 01302 fprintf(stderr, "BUSY DETECTOR\n"); 01303 fprintf(stderr, "%s\n", tone_list); 01304 fprintf(stderr, "%s\n", silence_list) 01305 #endif 01306 if ((dsp->busytoneonly || 01307 (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) && 01308 (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { 01309 if (dsp->busycompare) { 01310 if (dsp->busytoneonly) { 01311 res = 1; 01312 ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare"); 01313 } else { 01314 if (avgtone > avgsilence) { 01315 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) 01316 res = 1; 01317 } else { 01318 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) 01319 res = 1; 01320 } 01321 } 01322 } else { 01323 res = 1; 01324 } 01325 } 01326 /* If we know the expected busy tone length, check we are in the range */ 01327 if (res && (dsp->busy_tonelength > 0)) { 01328 if (abs(avgtone - dsp->busy_tonelength) > MAX(dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100, 20)) { 01329 #ifdef BUSYDETECT_DEBUG 01330 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n", 01331 avgtone, dsp->busy_tonelength); 01332 #endif 01333 res = 0; 01334 } 01335 } 01336 /* If we know the expected busy tone silent-period length, check we are in the range */ 01337 if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) { 01338 if (abs(avgsilence - dsp->busy_quietlength) > MAX(dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100, 20)) { 01339 #ifdef BUSYDETECT_DEBUG 01340 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n", 01341 avgsilence, dsp->busy_quietlength); 01342 #endif 01343 res = 0; 01344 } 01345 } 01346 if (res) { 01347 if (option_debug) 01348 ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01349 } else { 01350 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01351 } 01352 return res; 01353 }
Scans for progress indication in audio.
Definition at line 1174 of file dsp.c.
References __ast_dsp_call_progress(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
01175 { 01176 if (inf->frametype != AST_FRAME_VOICE) { 01177 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01178 return 0; 01179 } 01180 if (inf->subclass.codec != AST_FORMAT_SLINEAR) { 01181 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01182 return 0; 01183 } 01184 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2); 01185 }
Return non-zero if DTMF hit was found.
void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |
Reset DTMF detector.
Definition at line 1694 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, digit_detect_state_t::td, and mf_detect_state_t::tone_out.
Referenced by analog_ss_thread(), and my_dsp_reset_and_flush_digits().
01695 { 01696 int i; 01697 01698 dsp->dtmf_began = 0; 01699 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01700 mf_detect_state_t *s = &dsp->digit_state.td.mf; 01701 /* Reinitialise the detector for the next block */ 01702 for (i = 0; i < 6; i++) { 01703 goertzel_reset(&s->tone_out[i]); 01704 } 01705 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0; 01706 s->current_sample = 0; 01707 } else { 01708 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf; 01709 /* Reinitialise the detector for the next block */ 01710 for (i = 0; i < 4; i++) { 01711 goertzel_reset(&s->row_out[i]); 01712 goertzel_reset(&s->col_out[i]); 01713 } 01714 s->lasthit = s->current_hit = 0; 01715 s->energy = 0.0; 01716 s->current_sample = 0; 01717 s->hits = 0; 01718 s->misses = 0; 01719 } 01720 01721 dsp->digit_state.digits[0] = '\0'; 01722 dsp->digit_state.current_digits = 0; 01723 }
void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1650 of file dsp.c.
References ast_free.
Referenced by __ast_play_and_record(), __oh323_destroy(), analog_ss_thread(), background_detect_exec(), chan_list_destructor(), cleanup_connection(), conf_run(), dahdi_hangup(), destroy_endpoint(), destroy_session(), disable_dsp_detect(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), my_all_subchannels_hungup(), my_dsp_set_digitmode(), record_exec(), and sip_rtp_read().
01651 { 01652 ast_free(dsp); 01653 }
int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter).
Definition at line 1787 of file dsp.c.
References ast_dsp::tcount.
Referenced by dahdi_read().
01788 { 01789 return dsp->tcount; 01790 }
int ast_dsp_get_threshold_from_settings | ( | enum threshold | which | ) |
Get silence threshold from dsp.conf.
Definition at line 1880 of file dsp.c.
Referenced by actual_load_config(), app_exec(), ast_record_review(), conf_run(), do_waiting(), handle_recordfile(), load_config(), record_exec(), and setup_privacy_args().
01881 { 01882 return thresholds[which]; 01883 }
int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State).
Definition at line 1782 of file dsp.c.
References ast_dsp::tstate.
Referenced by dahdi_read().
01783 { 01784 return dsp->tstate; 01785 }
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 1885 of file dsp.c.
References _dsp_init().
Referenced by main().
01886 { 01887 return _dsp_init(0); 01888 }
struct ast_dsp* ast_dsp_new | ( | void | ) | [read] |
Definition at line 1607 of file dsp.c.
References ast_calloc, ast_digit_detect_init(), ast_dsp_prog_reset(), ast_fax_detect_init(), BUSY_PAT_PERCENT, ast_dsp::busy_pattern_fuzzy, ast_dsp::busycompare, ast_dsp::busycount, ast_dsp::busytoneonly, 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(), enable_dsp_detect(), fax_session_new(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), my_dsp_set_digitmode(), read_config(), and record_exec().
01608 { 01609 struct ast_dsp *dsp; 01610 01611 if ((dsp = ast_calloc(1, sizeof(*dsp)))) { 01612 dsp->threshold = DEFAULT_THRESHOLD; 01613 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS; 01614 dsp->busycount = DSP_HISTORY; 01615 dsp->digitmode = DSP_DIGITMODE_DTMF; 01616 dsp->faxmode = DSP_FAXMODE_DETECT_CNG; 01617 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT; 01618 #ifdef BUSYDETECT_TONEONLY 01619 dsp->busytoneonly = 1; 01620 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01621 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE"); 01622 #endif 01623 #else 01624 dsp->busytoneonly = 0; 01625 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01626 dsp->busycompare = 1; 01627 #else 01628 dsp->busycompare = 0; 01629 #endif 01630 #endif 01631 /* Initialize digit detector */ 01632 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF); 01633 dsp->display_inband_dtmf_warning = 1; 01634 /* Initialize initial DSP progress detect parameters */ 01635 ast_dsp_prog_reset(dsp); 01636 /* Initialize fax detector */ 01637 ast_fax_detect_init(dsp); 01638 } 01639 return dsp; 01640 }
Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise.
Definition at line 1373 of file dsp.c.
References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
Referenced by do_waiting().
01374 { 01375 short *s; 01376 int len; 01377 01378 if (f->frametype != AST_FRAME_VOICE) { 01379 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n"); 01380 return 0; 01381 } 01382 if (f->subclass.codec != AST_FORMAT_SLINEAR) { 01383 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n"); 01384 return 0; 01385 } 01386 s = f->data.ptr; 01387 len = f->datalen/2; 01388 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise); 01389 }
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 1392 of file dsp.c.
References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), ast_channel::_softhangup, AST_ALAW, ast_alloca, 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_TESTLAW, 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, ast_frame_subclass::codec, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, digit_detect_state_t::digitlen, 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, ast_frame_subclass::integer, ast_frame::len, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, ast_frame::ptr, SAMPLE_RATE, 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(), and sip_rtp_read().
01393 { 01394 int silence; 01395 int res; 01396 int digit = 0, fax_digit = 0; 01397 int x; 01398 short *shortdata; 01399 unsigned char *odata; 01400 int len; 01401 struct ast_frame *outf = NULL; 01402 01403 if (!af) { 01404 return NULL; 01405 } 01406 if (af->frametype != AST_FRAME_VOICE) { 01407 return af; 01408 } 01409 01410 odata = af->data.ptr; 01411 len = af->datalen; 01412 /* Make sure we have short data */ 01413 switch (af->subclass.codec) { 01414 case AST_FORMAT_SLINEAR: 01415 shortdata = af->data.ptr; 01416 len = af->datalen / 2; 01417 break; 01418 case AST_FORMAT_ULAW: 01419 case AST_FORMAT_TESTLAW: 01420 shortdata = ast_alloca(af->datalen * 2); 01421 for (x = 0;x < len; x++) { 01422 shortdata[x] = AST_MULAW(odata[x]); 01423 } 01424 break; 01425 case AST_FORMAT_ALAW: 01426 shortdata = ast_alloca(af->datalen * 2); 01427 for (x = 0; x < len; x++) { 01428 shortdata[x] = AST_ALAW(odata[x]); 01429 } 01430 break; 01431 default: 01432 /*Display warning only once. Otherwise you would get hundreds of warnings every second */ 01433 if (dsp->display_inband_dtmf_warning) 01434 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec)); 01435 dsp->display_inband_dtmf_warning = 0; 01436 return af; 01437 } 01438 01439 /* Initially we do not want to mute anything */ 01440 dsp->mute_fragments = 0; 01441 01442 /* Need to run the silence detection stuff for silence suppression and busy detection */ 01443 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) { 01444 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL); 01445 } 01446 01447 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { 01448 memset(&dsp->f, 0, sizeof(dsp->f)); 01449 dsp->f.frametype = AST_FRAME_NULL; 01450 ast_frfree(af); 01451 return ast_frisolate(&dsp->f); 01452 } 01453 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) { 01454 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01455 memset(&dsp->f, 0, sizeof(dsp->f)); 01456 dsp->f.frametype = AST_FRAME_CONTROL; 01457 /* Signal this as it was a channel hangup, to avoid msg "channel.c:3473 ast_waitfordigit_full: Unexpected control subclass '5'" */ 01458 dsp->f.subclass.integer = AST_CONTROL_HANGUP; 01459 ast_frfree(af); 01460 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name); 01461 return ast_frisolate(&dsp->f); 01462 } 01463 01464 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) { 01465 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) { 01466 fax_digit = 'f'; 01467 } 01468 01469 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) { 01470 fax_digit = 'e'; 01471 } 01472 } 01473 01474 if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) { 01475 if (dsp->digitmode & DSP_DIGITMODE_MF) 01476 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01477 else 01478 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01479 01480 if (dsp->digit_state.current_digits) { 01481 int event = 0, event_len = 0; 01482 char event_digit = 0; 01483 01484 if (!dsp->dtmf_began) { 01485 /* We have not reported DTMF_BEGIN for anything yet */ 01486 01487 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { 01488 event = AST_FRAME_DTMF_BEGIN; 01489 event_digit = dsp->digit_state.digits[0]; 01490 } 01491 dsp->dtmf_began = 1; 01492 01493 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) { 01494 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */ 01495 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { 01496 event = AST_FRAME_DTMF_END; 01497 event_digit = dsp->digit_state.digits[0]; 01498 event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE; 01499 } 01500 memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits); 01501 memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0])); 01502 dsp->digit_state.current_digits--; 01503 dsp->dtmf_began = 0; 01504 01505 if (dsp->features & DSP_FEATURE_BUSY_DETECT) { 01506 /* Reset Busy Detector as we have some confirmed activity */ 01507 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01508 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01509 ast_debug(1, "DTMF Detected - Reset busydetector\n"); 01510 } 01511 } 01512 01513 if (event) { 01514 memset(&dsp->f, 0, sizeof(dsp->f)); 01515 dsp->f.frametype = event; 01516 dsp->f.subclass.integer = event_digit; 01517 dsp->f.len = event_len; 01518 outf = &dsp->f; 01519 goto done; 01520 } 01521 } 01522 } 01523 01524 if (fax_digit) { 01525 /* Fax was detected - digit is either 'f' or 'e' */ 01526 01527 memset(&dsp->f, 0, sizeof(dsp->f)); 01528 dsp->f.frametype = AST_FRAME_DTMF; 01529 dsp->f.subclass.integer = fax_digit; 01530 outf = &dsp->f; 01531 goto done; 01532 } 01533 01534 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) { 01535 res = __ast_dsp_call_progress(dsp, shortdata, len); 01536 if (res) { 01537 switch (res) { 01538 case AST_CONTROL_ANSWER: 01539 case AST_CONTROL_BUSY: 01540 case AST_CONTROL_RINGING: 01541 case AST_CONTROL_CONGESTION: 01542 case AST_CONTROL_HANGUP: 01543 memset(&dsp->f, 0, sizeof(dsp->f)); 01544 dsp->f.frametype = AST_FRAME_CONTROL; 01545 dsp->f.subclass.integer = res; 01546 dsp->f.src = "dsp_progress"; 01547 if (chan) 01548 ast_queue_frame(chan, &dsp->f); 01549 break; 01550 default: 01551 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res); 01552 } 01553 } 01554 } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) { 01555 res = __ast_dsp_call_progress(dsp, shortdata, len); 01556 } 01557 01558 done: 01559 /* Mute fragment of the frame */ 01560 for (x = 0; x < dsp->mute_fragments; x++) { 01561 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start)); 01562 } 01563 01564 switch (af->subclass.codec) { 01565 case AST_FORMAT_SLINEAR: 01566 break; 01567 case AST_FORMAT_ULAW: 01568 for (x = 0; x < len; x++) { 01569 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]); 01570 } 01571 break; 01572 case AST_FORMAT_ALAW: 01573 for (x = 0; x < len; x++) { 01574 odata[x] = AST_LIN2A((unsigned short) shortdata[x]); 01575 } 01576 break; 01577 } 01578 01579 if (outf) { 01580 if (chan) { 01581 ast_queue_frame(chan, af); 01582 } 01583 ast_frfree(af); 01584 return ast_frisolate(outf); 01585 } else { 01586 return af; 01587 } 01588 }
int ast_dsp_reload | ( | void | ) |
Reloads dsp settings from dsp.conf.
Definition at line 1890 of file dsp.c.
References _dsp_init().
01891 { 01892 return _dsp_init(1); 01893 }
void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1725 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.
Referenced by debug_check_frame_for_silence().
01726 { 01727 int x; 01728 01729 dsp->totalsilence = 0; 01730 dsp->gsamps = 0; 01731 for (x = 0; x < 4; x++) { 01732 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01733 } 01734 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01735 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01736 dsp->ringtimeout= 0; 01737 }
void ast_dsp_set_busy_compare | ( | struct ast_dsp * | dsp, | |
int | compare | |||
) |
Set if silence and noice lengths must be compared for busy.
Definition at line 1674 of file dsp.c.
References ast_dsp::busycompare.
Referenced by dahdi_new().
01675 { 01676 if (compare > 0) 01677 dsp->busycompare = 1; 01678 else 01679 dsp->busycompare = 0; 01680 }
void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, | |
int | cadences | |||
) |
Set number of required cadences for busy.
Definition at line 1663 of file dsp.c.
References ast_dsp::busycount, and DSP_HISTORY.
Referenced by dahdi_new().
01664 { 01665 if (cadences < 4) { 01666 cadences = 4; 01667 } 01668 if (cadences > DSP_HISTORY) { 01669 cadences = DSP_HISTORY; 01670 } 01671 dsp->busycount = cadences; 01672 }
void ast_dsp_set_busy_pattern | ( | struct ast_dsp * | dsp, | |
int | tonelength, | |||
int | quietlength, | |||
int | fuzzy | |||
) |
Set expected lengths of the busy tones.
Definition at line 1682 of file dsp.c.
References ast_debug, ast_dsp::busy_pattern_fuzzy, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, and ast_dsp::busytoneonly.
Referenced by dahdi_new().
01683 { 01684 dsp->busy_tonelength = tonelength; 01685 if (quietlength > 0) 01686 dsp->busy_quietlength = quietlength; 01687 else 01688 dsp->busytoneonly = 1; 01689 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength); 01690 if( fuzzy > 0 && fuzzy < 50 ) 01691 dsp->busy_pattern_fuzzy = fuzzy; 01692 }
int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, | |
char * | zone | |||
) |
Set zone for doing progress detection.
Definition at line 1763 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 1739 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 analog_ss_thread(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), enable_dsp_detect(), mgcp_new(), mkintf(), and my_dsp_set_digitmode().
01740 { 01741 int new; 01742 int old; 01743 01744 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01745 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01746 if (old != new) { 01747 /* Must initialize structures if switching from MF to DTMF or vice-versa */ 01748 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF); 01749 } 01750 dsp->digitmode = digitmode; 01751 return 0; 01752 }
int ast_dsp_set_faxmode | ( | struct ast_dsp * | dsp, | |
int | faxmode | |||
) |
Set fax mode.
Definition at line 1754 of file dsp.c.
References ast_fax_detect_init(), and ast_dsp::faxmode.
01755 { 01756 if (dsp->faxmode != faxmode) { 01757 ast_fax_detect_init(dsp); 01758 } 01759 dsp->faxmode = faxmode; 01760 return 0; 01761 }
void ast_dsp_set_features | ( | struct ast_dsp * | dsp, | |
int | features | |||
) |
Select feature set.
Definition at line 1642 of file dsp.c.
References ast_dsp::display_inband_dtmf_warning, DSP_FEATURE_DIGIT_DETECT, and ast_dsp::features.
Referenced by __oh323_new(), dahdi_handle_dtmf(), dahdi_new(), dahdi_read(), dahdi_setoption(), disable_dtmf_detect(), enable_dsp_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), my_handle_dtmf(), read_config(), and sip_rtp_read().
01643 { 01644 dsp->features = features; 01645 if (!(features & DSP_FEATURE_DIGIT_DETECT)) { 01646 dsp->display_inband_dtmf_warning = 0; 01647 } 01648 }
void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, | |
int | threshold | |||
) |
Set threshold value for silence.
Definition at line 1655 of file dsp.c.
References ast_dsp::threshold.
Referenced by __ast_play_and_record(), dahdi_new(), do_waiting(), fax_session_new(), 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 1355 of file dsp.c.
References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
Referenced by __ast_play_and_record(), background_detect_exec(), conf_run(), debug_check_frame_for_silence(), do_waiting(), handle_recordfile(), isAnsweringMachine(), and record_exec().
01356 { 01357 short *s; 01358 int len; 01359 01360 if (f->frametype != AST_FRAME_VOICE) { 01361 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n"); 01362 return 0; 01363 } 01364 if (f->subclass.codec != AST_FORMAT_SLINEAR) { 01365 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n"); 01366 return 0; 01367 } 01368 s = f->data.ptr; 01369 len = f->datalen/2; 01370 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL); 01371 }
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 1777 of file dsp.c.
References ast_dsp::mute_fragments.
Referenced by dahdi_read().
01778 { 01779 return (dsp->mute_fragments > 0); 01780 }