This graph shows which files directly or indirectly include this file:
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_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_DTMF_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 |
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. | |
int | ast_dsp_digitmode (struct ast_dsp *dsp, int digitmode) |
Set digit mode. | |
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_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. | |
ast_dsp * | ast_dsp_new (void) |
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. | |
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. | |
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. |
Definition in file dsp.h.
#define DSP_DIGITMODE_DTMF 0 |
Definition at line 31 of file dsp.h.
Referenced by ast_dsp_digitmode(), nv_background_detect_exec(), nv_detectfax_exec(), sip_new(), ss_thread(), zt_hangup(), zt_new(), and zt_setoption().
#define DSP_DIGITMODE_MF 1 |
Definition at line 32 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_getdigits(), ast_dsp_process(), and ss_thread().
#define DSP_DIGITMODE_MUTECONF (1 << 9) |
Definition at line 35 of file dsp.h.
Referenced by ast_dsp_digitmode(), ast_dsp_process(), and zt_setoption().
#define DSP_DIGITMODE_MUTEMAX (1 << 10) |
Definition at line 36 of file dsp.h.
Referenced by ast_dsp_digitmode(), ast_dsp_process(), and zt_setoption().
#define DSP_DIGITMODE_NOQUELCH (1 << 8) |
#define DSP_DIGITMODE_RELAXDTMF (1 << 11) |
Definition at line 37 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), nv_background_detect_exec(), nv_detectfax_exec(), process_zap(), sip_new(), and zt_setoption().
#define DSP_FEATURE_BUSY_DETECT (1 << 1) |
#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 zt_new().
#define DSP_FEATURE_DTMF_DETECT (1 << 3) |
Definition at line 28 of file dsp.h.
Referenced by __oh323_new(), ast_dsp_process(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), nv_background_detect_exec(), nv_detectfax_exec(), read_config(), sip_dtmfmode(), sip_new(), and zt_new().
#define DSP_FEATURE_FAX_DETECT (1 << 4) |
Definition at line 29 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), misdn_set_opt_exec(), nv_background_detect_exec(), nv_detectfax_exec(), read_config(), and zt_new().
#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 |
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 1256 of file dsp.c.
References ast_dsp_busydetect(), ast_log(), BUSY_MAX, BUSY_MIN, BUSY_PAT_PERCENT, BUSY_PERCENT, ast_dsp::busy_quietlength, BUSY_THRESHOLD, ast_dsp::busy_tonelength, ast_dsp::busycount, ast_dsp::busymaybe, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::historicsilence, LOG_DEBUG, and LOG_NOTICE.
Referenced by ast_dsp_busydetect(), and ast_dsp_process().
01257 { 01258 int res = 0, x; 01259 #ifndef BUSYDETECT_TONEONLY 01260 int avgsilence = 0, hitsilence = 0; 01261 #endif 01262 int avgtone = 0, hittone = 0; 01263 if (!dsp->busymaybe) 01264 return res; 01265 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) { 01266 #ifndef BUSYDETECT_TONEONLY 01267 avgsilence += dsp->historicsilence[x]; 01268 #endif 01269 avgtone += dsp->historicnoise[x]; 01270 } 01271 #ifndef BUSYDETECT_TONEONLY 01272 avgsilence /= dsp->busycount; 01273 #endif 01274 avgtone /= dsp->busycount; 01275 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) { 01276 #ifndef BUSYDETECT_TONEONLY 01277 if (avgsilence > dsp->historicsilence[x]) { 01278 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x]) 01279 hitsilence++; 01280 } else { 01281 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x]) 01282 hitsilence++; 01283 } 01284 #endif 01285 if (avgtone > dsp->historicnoise[x]) { 01286 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x]) 01287 hittone++; 01288 } else { 01289 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x]) 01290 hittone++; 01291 } 01292 } 01293 #ifndef BUSYDETECT_TONEONLY 01294 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 01295 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 01296 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) { 01297 #else 01298 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { 01299 #endif 01300 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01301 #ifdef BUSYDETECT_TONEONLY 01302 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE 01303 #endif 01304 if (avgtone > avgsilence) { 01305 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) 01306 res = 1; 01307 } else { 01308 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) 01309 res = 1; 01310 } 01311 #else 01312 res = 1; 01313 #endif 01314 } 01315 /* If we know the expected busy tone length, check we are in the range */ 01316 if (res && (dsp->busy_tonelength > 0)) { 01317 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) { 01318 #if 0 01319 ast_log(LOG_NOTICE, "busy detector: avgtone of %d not close enough to desired %d\n", 01320 avgtone, dsp->busy_tonelength); 01321 #endif 01322 res = 0; 01323 } 01324 } 01325 #ifndef BUSYDETECT_TONEONLY 01326 /* If we know the expected busy tone silent-period length, check we are in the range */ 01327 if (res && (dsp->busy_quietlength > 0)) { 01328 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) { 01329 #if 0 01330 ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n", 01331 avgsilence, dsp->busy_quietlength); 01332 #endif 01333 res = 0; 01334 } 01335 } 01336 #endif 01337 #ifndef BUSYDETECT_TONEONLY 01338 #if 1 01339 if (res) 01340 ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01341 #endif 01342 #endif 01343 return res; 01344 }
Scans for progress indication in audio.
Definition at line 1187 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, and ast_frame::subclass.
01188 { 01189 if (inf->frametype != AST_FRAME_VOICE) { 01190 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01191 return 0; 01192 } 01193 if (inf->subclass != AST_FORMAT_SLINEAR) { 01194 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01195 return 0; 01196 } 01197 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2); 01198 }
Return non-zero if DTMF hit was found.
Definition at line 986 of file dsp.c.
References __ast_dsp_digitdetect(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, len, LOG_WARNING, s, and ast_frame::subclass.
00987 { 00988 short *s; 00989 int len; 00990 int ign=0; 00991 00992 if (inf->frametype != AST_FRAME_VOICE) { 00993 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 00994 return 0; 00995 } 00996 if (inf->subclass != AST_FORMAT_SLINEAR) { 00997 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 00998 return 0; 00999 } 01000 s = inf->data; 01001 len = inf->datalen / 2; 01002 return __ast_dsp_digitdetect(dsp, s, len, &ign); 01003 }
int ast_dsp_digitmode | ( | struct ast_dsp * | dsp, | |
int | digitmode | |||
) |
Set digit mode.
Definition at line 1726 of file dsp.c.
References ast_dtmf_detect_init(), ast_mf_detect_init(), ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, ast_dsp::dtmf, ast_dsp::mf, and ast_dsp::td.
Referenced by mgcp_new(), nv_background_detect_exec(), nv_detectfax_exec(), sip_new(), ss_thread(), zt_hangup(), zt_new(), and zt_setoption().
01727 { 01728 int new; 01729 int old; 01730 01731 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01732 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01733 if (old != new) { 01734 /* Must initialize structures if switching from MF to DTMF or vice-versa */ 01735 if (new & DSP_DIGITMODE_MF) 01736 ast_mf_detect_init(&dsp->td.mf); 01737 else 01738 ast_dtmf_detect_init(&dsp->td.dtmf); 01739 } 01740 dsp->digitmode = digitmode; 01741 return 0; 01742 }
void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |
Reset DTMF detector.
Definition at line 1663 of file dsp.c.
References dtmf_detect_state_t::col_out, dtmf_detect_state_t::current_digits, mf_detect_state_t::current_digits, dtmf_detect_state_t::current_sample, mf_detect_state_t::current_sample, ast_dsp::digitmode, dtmf_detect_state_t::digits, mf_detect_state_t::digits, DSP_DIGITMODE_MF, ast_dsp::dtmf, dtmf_detect_state_t::energy, dtmf_detect_state_t::fax_tone, goertzel_reset(), dtmf_detect_state_t::hits, mf_detect_state_t::hits, ast_dsp::mf, dtmf_detect_state_t::mhit, mf_detect_state_t::mhit, dtmf_detect_state_t::row_out, ast_dsp::td, ast_dsp::thinkdigit, and mf_detect_state_t::tone_out.
Referenced by ss_thread().
01664 { 01665 int i; 01666 01667 dsp->thinkdigit = 0; 01668 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01669 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits)); 01670 dsp->td.mf.current_digits = 0; 01671 /* Reinitialise the detector for the next block */ 01672 for (i = 0; i < 6; i++) { 01673 goertzel_reset(&dsp->td.mf.tone_out[i]); 01674 #ifdef OLD_DSP_ROUTINES 01675 goertzel_reset(&dsp->td.mf.tone_out2nd[i]); 01676 #endif 01677 } 01678 #ifdef OLD_DSP_ROUTINES 01679 dsp->td.mf.energy = 0.0; 01680 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0; 01681 #else 01682 dsp->td.mf.hits[4] = dsp->td.mf.hits[3] = dsp->td.mf.hits[2] = dsp->td.mf.hits[1] = dsp->td.mf.hits[0] = dsp->td.mf.mhit = 0; 01683 #endif 01684 dsp->td.mf.current_sample = 0; 01685 } else { 01686 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits)); 01687 dsp->td.dtmf.current_digits = 0; 01688 /* Reinitialise the detector for the next block */ 01689 for (i = 0; i < 4; i++) { 01690 goertzel_reset(&dsp->td.dtmf.row_out[i]); 01691 goertzel_reset(&dsp->td.dtmf.col_out[i]); 01692 #ifdef OLD_DSP_ROUTINES 01693 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]); 01694 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]); 01695 #endif 01696 } 01697 #ifdef FAX_DETECT 01698 goertzel_reset (&dsp->td.dtmf.fax_tone); 01699 #endif 01700 #ifdef OLD_DSP_ROUTINES 01701 #ifdef FAX_DETECT 01702 goertzel_reset (&dsp->td.dtmf.fax_tone2nd); 01703 #endif 01704 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0; 01705 #else 01706 dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0; 01707 #endif 01708 dsp->td.dtmf.energy = 0.0; 01709 dsp->td.dtmf.current_sample = 0; 01710 } 01711 }
void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1637 of file dsp.c.
References free.
Referenced by __ast_play_and_record(), __oh323_destroy(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), nv_background_detect_exec(), nv_detectfax_exec(), sip_dtmfmode(), sip_hangup(), ss_thread(), and zt_hangup().
01638 { 01639 free(dsp); 01640 }
int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter).
Definition at line 1763 of file dsp.c.
References ast_dsp::tcount.
01764 { 01765 return dsp->tcount; 01766 }
int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State).
Definition at line 1758 of file dsp.c.
References ast_dsp::tstate.
01759 { 01760 return dsp->tstate; 01761 }
int ast_dsp_getdigits | ( | struct ast_dsp * | dsp, | |
char * | buf, | |||
int | max | |||
) |
Get pending DTMF/MF digits.
Definition at line 1025 of file dsp.c.
References dtmf_detect_state_t::current_digits, mf_detect_state_t::current_digits, ast_dsp::digitmode, dtmf_detect_state_t::digits, mf_detect_state_t::digits, DSP_DIGITMODE_MF, ast_dsp::dtmf, ast_dsp::mf, and ast_dsp::td.
01026 { 01027 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01028 if (max > dsp->td.mf.current_digits) 01029 max = dsp->td.mf.current_digits; 01030 if (max > 0) { 01031 memcpy(buf, dsp->td.mf.digits, max); 01032 memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max); 01033 dsp->td.mf.current_digits -= max; 01034 } 01035 buf[max] = '\0'; 01036 return max; 01037 } else { 01038 if (max > dsp->td.dtmf.current_digits) 01039 max = dsp->td.dtmf.current_digits; 01040 if (max > 0) { 01041 memcpy (buf, dsp->td.dtmf.digits, max); 01042 memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max); 01043 dsp->td.dtmf.current_digits -= max; 01044 } 01045 buf[max] = '\0'; 01046 return max; 01047 } 01048 }
struct ast_dsp* ast_dsp_new | ( | void | ) |
Definition at line 1616 of file dsp.c.
References ast_calloc, ast_dsp_prog_reset(), ast_dtmf_detect_init(), DEFAULT_THRESHOLD, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, and ast_dsp::threshold.
Referenced by __ast_play_and_record(), __oh323_new(), background_detect_exec(), conf_run(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), nv_background_detect_exec(), nv_detectfax_exec(), read_config(), sip_dtmfmode(), sip_new(), and zt_new().
01617 { 01618 struct ast_dsp *dsp; 01619 01620 if ((dsp = ast_calloc(1, sizeof(*dsp)))) { 01621 dsp->threshold = DEFAULT_THRESHOLD; 01622 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS; 01623 dsp->busycount = DSP_HISTORY; 01624 /* Initialize DTMF detector */ 01625 ast_dtmf_detect_init(&dsp->td.dtmf); 01626 /* Initialize initial DSP progress detect parameters */ 01627 ast_dsp_prog_reset(dsp); 01628 } 01629 return dsp; 01630 }
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.
Definition at line 1410 of file dsp.c.
References __ast_dsp_call_progress(), __ast_dsp_digitdetect(), __ast_dsp_silence(), ast_channel::_softhangup, AST_ALAW, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, 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_getformatname(), ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, dtmf_detect_state_t::current_digits, mf_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digitmode, dtmf_detect_state_t::digits, mf_detect_state_t::digits, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::dtmf, ast_dsp::f, ast_dsp::features, FIX_INF, ast_frame::frametype, len, LOG_DEBUG, LOG_WARNING, ast_dsp::mf, silence, ast_frame::src, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit.
Referenced by mgcp_rtp_read(), nv_background_detect_exec(), nv_detectfax_exec(), oh323_rtp_read(), process_ast_dsp(), sip_rtp_read(), and zt_read().
01411 { 01412 int silence; 01413 int res; 01414 int digit; 01415 int x; 01416 short *shortdata; 01417 unsigned char *odata; 01418 int len; 01419 int writeback = 0; 01420 01421 #define FIX_INF(inf) do { \ 01422 if (writeback) { \ 01423 switch(inf->subclass) { \ 01424 case AST_FORMAT_SLINEAR: \ 01425 break; \ 01426 case AST_FORMAT_ULAW: \ 01427 for (x=0;x<len;x++) \ 01428 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \ 01429 break; \ 01430 case AST_FORMAT_ALAW: \ 01431 for (x=0;x<len;x++) \ 01432 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \ 01433 break; \ 01434 } \ 01435 } \ 01436 } while(0) 01437 01438 if (!af) 01439 return NULL; 01440 if (af->frametype != AST_FRAME_VOICE) 01441 return af; 01442 odata = af->data; 01443 len = af->datalen; 01444 /* Make sure we have short data */ 01445 switch(af->subclass) { 01446 case AST_FORMAT_SLINEAR: 01447 shortdata = af->data; 01448 len = af->datalen / 2; 01449 break; 01450 case AST_FORMAT_ULAW: 01451 shortdata = alloca(af->datalen * 2); 01452 for (x = 0;x < len; x++) 01453 shortdata[x] = AST_MULAW(odata[x]); 01454 break; 01455 case AST_FORMAT_ALAW: 01456 shortdata = alloca(af->datalen * 2); 01457 for (x = 0; x < len; x++) 01458 shortdata[x] = AST_ALAW(odata[x]); 01459 break; 01460 default: 01461 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); 01462 return af; 01463 } 01464 silence = __ast_dsp_silence(dsp, shortdata, len, NULL); 01465 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { 01466 memset(&dsp->f, 0, sizeof(dsp->f)); 01467 dsp->f.frametype = AST_FRAME_NULL; 01468 return &dsp->f; 01469 } 01470 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) { 01471 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01472 memset(&dsp->f, 0, sizeof(dsp->f)); 01473 dsp->f.frametype = AST_FRAME_CONTROL; 01474 dsp->f.subclass = AST_CONTROL_BUSY; 01475 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name); 01476 return &dsp->f; 01477 } 01478 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) { 01479 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback); 01480 #if 0 01481 if (digit) 01482 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode); 01483 #endif 01484 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) { 01485 if (!dsp->thinkdigit) { 01486 if (digit) { 01487 /* Looks like we might have something. 01488 * Request a conference mute for the moment */ 01489 memset(&dsp->f, 0, sizeof(dsp->f)); 01490 dsp->f.frametype = AST_FRAME_DTMF; 01491 dsp->f.subclass = 'm'; 01492 dsp->thinkdigit = 'x'; 01493 FIX_INF(af); 01494 if (chan) 01495 ast_queue_frame(chan, af); 01496 ast_frfree(af); 01497 return &dsp->f; 01498 } 01499 } else { 01500 if (digit) { 01501 /* Thought we saw one last time. Pretty sure we really have now */ 01502 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) { 01503 /* If we found a digit, and we're changing digits, go 01504 ahead and send this one, but DON'T stop confmute because 01505 we're detecting something else, too... */ 01506 memset(&dsp->f, 0, sizeof(dsp->f)); 01507 dsp->f.frametype = AST_FRAME_DTMF_END; 01508 dsp->f.subclass = dsp->thinkdigit; 01509 FIX_INF(af); 01510 if (chan) 01511 ast_queue_frame(chan, af); 01512 ast_frfree(af); 01513 } else { 01514 dsp->thinkdigit = digit; 01515 memset(&dsp->f, 0, sizeof(dsp->f)); 01516 dsp->f.frametype = AST_FRAME_DTMF_BEGIN; 01517 dsp->f.subclass = dsp->thinkdigit; 01518 FIX_INF(af); 01519 if (chan) 01520 ast_queue_frame(chan, af); 01521 ast_frfree(af); 01522 } 01523 return &dsp->f; 01524 } else { 01525 memset(&dsp->f, 0, sizeof(dsp->f)); 01526 if (dsp->thinkdigit != 'x') { 01527 /* If we found a digit, send it now */ 01528 dsp->f.frametype = AST_FRAME_DTMF_END; 01529 dsp->f.subclass = dsp->thinkdigit; 01530 dsp->thinkdigit = 0; 01531 } else { 01532 dsp->f.frametype = AST_FRAME_DTMF; 01533 dsp->f.subclass = 'u'; 01534 dsp->thinkdigit = 0; 01535 } 01536 FIX_INF(af); 01537 if (chan) 01538 ast_queue_frame(chan, af); 01539 ast_frfree(af); 01540 return &dsp->f; 01541 } 01542 } 01543 } else if (!digit) { 01544 /* Only check when there is *not* a hit... */ 01545 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01546 if (dsp->td.mf.current_digits) { 01547 memset(&dsp->f, 0, sizeof(dsp->f)); 01548 dsp->f.frametype = AST_FRAME_DTMF; 01549 dsp->f.subclass = dsp->td.mf.digits[0]; 01550 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits); 01551 dsp->td.mf.current_digits--; 01552 FIX_INF(af); 01553 if (chan) 01554 ast_queue_frame(chan, af); 01555 ast_frfree(af); 01556 return &dsp->f; 01557 } 01558 } else { 01559 if (dsp->td.dtmf.current_digits) { 01560 memset(&dsp->f, 0, sizeof(dsp->f)); 01561 dsp->f.frametype = AST_FRAME_DTMF_END; 01562 dsp->f.subclass = dsp->td.dtmf.digits[0]; 01563 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits); 01564 dsp->td.dtmf.current_digits--; 01565 FIX_INF(af); 01566 if (chan) 01567 ast_queue_frame(chan, af); 01568 ast_frfree(af); 01569 return &dsp->f; 01570 } 01571 } 01572 } 01573 } 01574 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) { 01575 res = __ast_dsp_call_progress(dsp, shortdata, len); 01576 if (res) { 01577 switch(res) { 01578 case AST_CONTROL_ANSWER: 01579 case AST_CONTROL_BUSY: 01580 case AST_CONTROL_RINGING: 01581 case AST_CONTROL_CONGESTION: 01582 case AST_CONTROL_HANGUP: 01583 memset(&dsp->f, 0, sizeof(dsp->f)); 01584 dsp->f.frametype = AST_FRAME_CONTROL; 01585 dsp->f.subclass = res; 01586 dsp->f.src = "dsp_progress"; 01587 if (chan) 01588 ast_queue_frame(chan, &dsp->f); 01589 break; 01590 default: 01591 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res); 01592 } 01593 } 01594 } 01595 FIX_INF(af); 01596 return af; 01597 }
void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1713 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.
01714 { 01715 int x; 01716 01717 dsp->totalsilence = 0; 01718 dsp->gsamps = 0; 01719 for (x=0;x<4;x++) 01720 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01721 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01722 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01723 dsp->ringtimeout= 0; 01724 }
void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, | |
int | cadences | |||
) |
Set number of required cadences for busy.
Definition at line 1647 of file dsp.c.
References ast_dsp::busycount, and DSP_HISTORY.
Referenced by zt_new().
01648 { 01649 if (cadences < 4) 01650 cadences = 4; 01651 if (cadences > DSP_HISTORY) 01652 cadences = DSP_HISTORY; 01653 dsp->busycount = cadences; 01654 }
void ast_dsp_set_busy_pattern | ( | struct ast_dsp * | dsp, | |
int | tonelength, | |||
int | quietlength | |||
) |
Set expected lengths of the busy tone.
Definition at line 1656 of file dsp.c.
References ast_log(), ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, and LOG_DEBUG.
Referenced by zt_new().
01657 { 01658 dsp->busy_tonelength = tonelength; 01659 dsp->busy_quietlength = quietlength; 01660 ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength); 01661 }
int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, | |
char * | zone | |||
) |
Set zone for doing progress detection.
Definition at line 1744 of file dsp.c.
References aliases, ast_dsp_prog_reset(), name, and ast_dsp::progmode.
Referenced by zt_new().
01745 { 01746 int x; 01747 01748 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) { 01749 if (!strcasecmp(aliases[x].name, zone)) { 01750 dsp->progmode = aliases[x].mode; 01751 ast_dsp_prog_reset(dsp); 01752 return 0; 01753 } 01754 } 01755 return -1; 01756 }
void ast_dsp_set_features | ( | struct ast_dsp * | dsp, | |
int | features | |||
) |
Select feature set.
Definition at line 1632 of file dsp.c.
References ast_dsp::features.
Referenced by __oh323_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), nv_background_detect_exec(), nv_detectfax_exec(), read_config(), sip_dtmfmode(), sip_new(), and zt_new().
void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, | |
int | threshold | |||
) |
Set threshold value for silence.
Definition at line 1642 of file dsp.c.
References ast_dsp::threshold.
Referenced by __ast_play_and_record(), do_waiting(), handle_recordfile(), isAnsweringMachine(), nv_background_detect_exec(), and nv_detectfax_exec().
Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.
Definition at line 1392 of file dsp.c.
References __ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), f, len, LOG_WARNING, and s.
Referenced by __ast_play_and_record(), background_detect_exec(), conf_run(), do_waiting(), handle_recordfile(), isAnsweringMachine(), nv_background_detect_exec(), and nv_detectfax_exec().
01393 { 01394 short *s; 01395 int len; 01396 01397 if (f->frametype != AST_FRAME_VOICE) { 01398 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n"); 01399 return 0; 01400 } 01401 if (f->subclass != AST_FORMAT_SLINEAR) { 01402 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n"); 01403 return 0; 01404 } 01405 s = f->data; 01406 len = f->datalen/2; 01407 return __ast_dsp_silence(dsp, s, len, totalsilence); 01408 }