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_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. | |
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(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), sip_new(), and ss_thread().
#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 dahdi_setoption().
#define DSP_DIGITMODE_MUTEMAX (1 << 10) |
Definition at line 36 of file dsp.h.
Referenced by ast_dsp_digitmode(), ast_dsp_process(), and dahdi_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(), dahdi_setoption(), process_dahdi(), and sip_new().
#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 dahdi_new().
#define DSP_FEATURE_DTMF_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(), and sip_new().
#define DSP_FEATURE_FAX_DETECT (1 << 4) |
Definition at line 29 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), dahdi_new(), misdn_set_opt_exec(), and read_config().
#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 1283 of file dsp.c.
References 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_DEBUG, LOG_ERROR, LOG_NOTICE, and option_debug.
Referenced by ast_dsp_process().
01284 { 01285 int res = 0, x; 01286 int avgsilence = 0, hitsilence = 0; 01287 int avgtone = 0, hittone = 0; 01288 #ifdef DEBUG_DSP_BUSYDETECT 01289 char buf[16]; 01290 char silence_list[64]="", tone_list[64]=""; 01291 #endif 01292 01293 if (!dsp->busymaybe) 01294 return res; 01295 dsp->busymaybe = 0; 01296 01297 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) { 01298 avgsilence += dsp->historicsilence[x]; 01299 avgtone += dsp->historicnoise[x]; 01300 } 01301 avgsilence /= dsp->busycount; 01302 avgtone /= dsp->busycount; 01303 #ifdef DEBUG_DSP_BUSYDETECT 01304 sprintf(silence_list,"Silences: "); 01305 sprintf(tone_list,"Tones: "); 01306 #endif 01307 for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) { 01308 #ifdef DEBUG_DSP_BUSYDETECT 01309 snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]); 01310 strcat(silence_list, buf); 01311 snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]); 01312 strcat(tone_list, buf); 01313 #endif 01314 if (!dsp->busytoneonly) { 01315 if (avgsilence > dsp->historicsilence[x]) { 01316 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x]) 01317 hitsilence++; 01318 } else { 01319 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x]) 01320 hitsilence++; 01321 } 01322 } 01323 if (avgtone > dsp->historicnoise[x]) { 01324 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x]) 01325 hittone++; 01326 } else { 01327 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x]) 01328 hittone++; 01329 } 01330 } 01331 #ifdef DEBUG_DSP_BUSYDETECT 01332 fprintf(stderr, "BUSY DETECTOR\n"); 01333 fprintf(stderr, "%s\n", tone_list); 01334 fprintf(stderr, "%s\n", silence_list) 01335 #endif 01336 if ((dsp->busytoneonly || 01337 (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) && 01338 (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { 01339 if (dsp->busycompare) { 01340 if (dsp->busytoneonly) { 01341 res = 1; 01342 ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare"); 01343 } else { 01344 if (avgtone > avgsilence) { 01345 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) 01346 res = 1; 01347 } else { 01348 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) 01349 res = 1; 01350 } 01351 } 01352 } else { 01353 res = 1; 01354 } 01355 } 01356 /* If we know the expected busy tone length, check we are in the range */ 01357 if (res && (dsp->busy_tonelength > 0)) { 01358 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100)) { 01359 if(option_debug) { 01360 ast_log(LOG_DEBUG, "busy detector: avgtone of %d not close enough to desired %d\n", avgtone, dsp->busy_tonelength); 01361 } 01362 res = 0; 01363 } 01364 } 01365 /* If we know the expected busy tone silent-period length, check we are in the range */ 01366 if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) { 01367 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100)) { 01368 if(option_debug) { 01369 ast_log(LOG_DEBUG, "busy detector: avgsilence of %d not close enough to desired %d\n", avgsilence, dsp->busy_quietlength); 01370 } 01371 res = 0; 01372 } 01373 } 01374 if (res && option_debug) 01375 ast_log(LOG_NOTICE, "Detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01376 return res; 01377 }
Scans for progress indication in audio.
Definition at line 1212 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.
01213 { 01214 if (inf->frametype != AST_FRAME_VOICE) { 01215 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01216 return 0; 01217 } 01218 if (inf->subclass != AST_FORMAT_SLINEAR) { 01219 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01220 return 0; 01221 } 01222 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2); 01223 }
Return non-zero if DTMF hit was found.
Definition at line 1011 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.
01012 { 01013 short *s; 01014 int len; 01015 int ign=0; 01016 01017 if (inf->frametype != AST_FRAME_VOICE) { 01018 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01019 return 0; 01020 } 01021 if (inf->subclass != AST_FORMAT_SLINEAR) { 01022 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01023 return 0; 01024 } 01025 s = inf->data; 01026 len = inf->datalen / 2; 01027 return __ast_dsp_digitdetect(dsp, s, len, &ign); 01028 }
int ast_dsp_digitmode | ( | struct ast_dsp * | dsp, | |
int | digitmode | |||
) |
Set digit mode.
Definition at line 1794 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 dahdi_hangup(), dahdi_new(), dahdi_setoption(), mgcp_new(), sip_new(), and ss_thread().
01795 { 01796 int new; 01797 int old; 01798 01799 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01800 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01801 if (old != new) { 01802 /* Must initialize structures if switching from MF to DTMF or vice-versa */ 01803 if (new & DSP_DIGITMODE_MF) 01804 ast_mf_detect_init(&dsp->td.mf); 01805 else 01806 ast_dtmf_detect_init(&dsp->td.dtmf); 01807 } 01808 dsp->digitmode = digitmode; 01809 return 0; 01810 }
void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |
Reset DTMF detector.
Definition at line 1731 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(), mf_detect_state_t::hits, dtmf_detect_state_t::lasthit, 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().
01732 { 01733 int i; 01734 01735 dsp->thinkdigit = 0; 01736 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01737 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits)); 01738 dsp->td.mf.current_digits = 0; 01739 /* Reinitialise the detector for the next block */ 01740 for (i = 0; i < 6; i++) { 01741 goertzel_reset(&dsp->td.mf.tone_out[i]); 01742 #ifdef OLD_DSP_ROUTINES 01743 goertzel_reset(&dsp->td.mf.tone_out2nd[i]); 01744 #endif 01745 } 01746 #ifdef OLD_DSP_ROUTINES 01747 dsp->td.mf.energy = 0.0; 01748 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0; 01749 #else 01750 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; 01751 #endif 01752 dsp->td.mf.current_sample = 0; 01753 } else { 01754 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits)); 01755 dsp->td.dtmf.current_digits = 0; 01756 /* Reinitialise the detector for the next block */ 01757 for (i = 0; i < 4; i++) { 01758 goertzel_reset(&dsp->td.dtmf.row_out[i]); 01759 goertzel_reset(&dsp->td.dtmf.col_out[i]); 01760 #ifdef OLD_DSP_ROUTINES 01761 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]); 01762 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]); 01763 #endif 01764 } 01765 #ifdef FAX_DETECT 01766 goertzel_reset (&dsp->td.dtmf.fax_tone); 01767 #endif 01768 #ifdef OLD_DSP_ROUTINES 01769 #ifdef FAX_DETECT 01770 goertzel_reset (&dsp->td.dtmf.fax_tone2nd); 01771 #endif 01772 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0; 01773 #else 01774 dsp->td.dtmf.lasthit = dsp->td.dtmf.mhit = 0; 01775 #endif 01776 dsp->td.dtmf.energy = 0.0; 01777 dsp->td.dtmf.current_sample = 0; 01778 } 01779 }
void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1689 of file dsp.c.
References free.
Referenced by __ast_play_and_record(), __oh323_destroy(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), dahdi_hangup(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), sip_dtmfmode(), sip_hangup(), and ss_thread().
01690 { 01691 free(dsp); 01692 }
int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter).
Definition at line 1831 of file dsp.c.
References ast_dsp::tcount.
01832 { 01833 return dsp->tcount; 01834 }
int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State).
Definition at line 1826 of file dsp.c.
References ast_dsp::tstate.
01827 { 01828 return dsp->tstate; 01829 }
int ast_dsp_getdigits | ( | struct ast_dsp * | dsp, | |
char * | buf, | |||
int | max | |||
) |
Get pending DTMF/MF digits.
Definition at line 1050 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.
01051 { 01052 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01053 if (max > dsp->td.mf.current_digits) 01054 max = dsp->td.mf.current_digits; 01055 if (max > 0) { 01056 memcpy(buf, dsp->td.mf.digits, max); 01057 memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max); 01058 dsp->td.mf.current_digits -= max; 01059 } 01060 buf[max] = '\0'; 01061 return max; 01062 } else { 01063 if (max > dsp->td.dtmf.current_digits) 01064 max = dsp->td.dtmf.current_digits; 01065 if (max > 0) { 01066 memcpy (buf, dsp->td.dtmf.digits, max); 01067 memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max); 01068 dsp->td.dtmf.current_digits -= max; 01069 } 01070 buf[max] = '\0'; 01071 return max; 01072 } 01073 }
struct ast_dsp* ast_dsp_new | ( | void | ) |
Definition at line 1653 of file dsp.c.
References ast_calloc, ast_dsp_prog_reset(), ast_dtmf_detect_init(), BUSY_PAT_PERCENT, 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(), dahdi_new(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), and sip_new().
01654 { 01655 struct ast_dsp *dsp; 01656 01657 if ((dsp = ast_calloc(1, sizeof(*dsp)))) { 01658 dsp->threshold = DEFAULT_THRESHOLD; 01659 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS; 01660 dsp->busycount = DSP_HISTORY; 01661 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT; 01662 #ifdef BUSYDETECT_TONEONLY 01663 dsp->busytoneonly = 1; 01664 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01665 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE"); 01666 #endif 01667 #else 01668 dsp->busytoneonly = 0; 01669 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01670 dsp->busycompare = 1; 01671 #else 01672 dsp->busycompare = 0; 01673 #endif 01674 #endif 01675 dsp->display_inband_dtmf_warning = 1; 01676 /* Initialize DTMF detector */ 01677 ast_dtmf_detect_init(&dsp->td.dtmf); 01678 /* Initialize initial DSP progress detect parameters */ 01679 ast_dsp_prog_reset(dsp); 01680 } 01681 return dsp; 01682 }
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 1443 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_frisolate(), 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, ast_dsp::display_inband_dtmf_warning, 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_WARNING, ast_dsp::mf, silence, ast_frame::src, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit.
Referenced by dahdi_read(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), and sip_rtp_read().
01444 { 01445 int silence; 01446 int res; 01447 int digit; 01448 int x; 01449 short *shortdata; 01450 unsigned char *odata; 01451 int len; 01452 int writeback = 0; 01453 01454 #define FIX_INF(inf) do { \ 01455 if (writeback) { \ 01456 switch(inf->subclass) { \ 01457 case AST_FORMAT_SLINEAR: \ 01458 break; \ 01459 case AST_FORMAT_ULAW: \ 01460 for (x=0;x<len;x++) \ 01461 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \ 01462 break; \ 01463 case AST_FORMAT_ALAW: \ 01464 for (x=0;x<len;x++) \ 01465 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \ 01466 break; \ 01467 } \ 01468 } \ 01469 } while(0) 01470 01471 if (!af) 01472 return NULL; 01473 if (af->frametype != AST_FRAME_VOICE) 01474 return af; 01475 odata = af->data; 01476 len = af->datalen; 01477 /* Make sure we have short data */ 01478 switch(af->subclass) { 01479 case AST_FORMAT_SLINEAR: 01480 shortdata = af->data; 01481 len = af->datalen / 2; 01482 break; 01483 case AST_FORMAT_ULAW: 01484 shortdata = alloca(af->datalen * 2); 01485 for (x = 0;x < len; x++) 01486 shortdata[x] = AST_MULAW(odata[x]); 01487 break; 01488 case AST_FORMAT_ALAW: 01489 shortdata = alloca(af->datalen * 2); 01490 for (x = 0; x < len; x++) 01491 shortdata[x] = AST_ALAW(odata[x]); 01492 break; 01493 default: 01494 /*Display warning only once. Otherwise you would get hundreds of warnings every second */ 01495 if (dsp->display_inband_dtmf_warning) 01496 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); 01497 dsp->display_inband_dtmf_warning = 0; 01498 return af; 01499 } 01500 silence = __ast_dsp_silence(dsp, shortdata, len, NULL); 01501 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { 01502 memset(&dsp->f, 0, sizeof(dsp->f)); 01503 dsp->f.frametype = AST_FRAME_NULL; 01504 ast_frfree(af); 01505 return ast_frisolate(&dsp->f); 01506 } 01507 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) { 01508 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01509 memset(&dsp->f, 0, sizeof(dsp->f)); 01510 dsp->f.frametype = AST_FRAME_CONTROL; 01511 dsp->f.subclass = AST_CONTROL_BUSY; 01512 ast_frfree(af); 01513 return ast_frisolate(&dsp->f); 01514 } 01515 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) { 01516 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback); 01517 #if 0 01518 if (digit) 01519 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode); 01520 #endif 01521 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) { 01522 if (!dsp->thinkdigit) { 01523 if (digit) { 01524 /* Looks like we might have something. 01525 * Request a conference mute for the moment */ 01526 memset(&dsp->f, 0, sizeof(dsp->f)); 01527 dsp->f.frametype = AST_FRAME_DTMF; 01528 dsp->f.subclass = 'm'; 01529 dsp->thinkdigit = 'x'; 01530 FIX_INF(af); 01531 if (chan) 01532 ast_queue_frame(chan, af); 01533 ast_frfree(af); 01534 return ast_frisolate(&dsp->f); 01535 } 01536 } else { 01537 if (digit) { 01538 /* Thought we saw one last time. Pretty sure we really have now */ 01539 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) { 01540 /* If we found a digit, and we're changing digits, go 01541 ahead and send this one, but DON'T stop confmute because 01542 we're detecting something else, too... */ 01543 memset(&dsp->f, 0, sizeof(dsp->f)); 01544 dsp->f.frametype = AST_FRAME_DTMF_END; 01545 dsp->f.subclass = dsp->thinkdigit; 01546 FIX_INF(af); 01547 if (chan) 01548 ast_queue_frame(chan, af); 01549 ast_frfree(af); 01550 } else { 01551 dsp->thinkdigit = digit; 01552 memset(&dsp->f, 0, sizeof(dsp->f)); 01553 dsp->f.frametype = AST_FRAME_DTMF_BEGIN; 01554 dsp->f.subclass = dsp->thinkdigit; 01555 FIX_INF(af); 01556 if (chan) 01557 ast_queue_frame(chan, af); 01558 ast_frfree(af); 01559 } 01560 return ast_frisolate(&dsp->f); 01561 } else { 01562 memset(&dsp->f, 0, sizeof(dsp->f)); 01563 if (dsp->thinkdigit != 'x') { 01564 /* If we found a digit, send it now */ 01565 dsp->f.frametype = AST_FRAME_DTMF_END; 01566 dsp->f.subclass = dsp->thinkdigit; 01567 dsp->thinkdigit = 0; 01568 } else { 01569 dsp->f.frametype = AST_FRAME_DTMF; 01570 dsp->f.subclass = 'u'; 01571 dsp->thinkdigit = 0; 01572 } 01573 FIX_INF(af); 01574 if (chan) 01575 ast_queue_frame(chan, af); 01576 ast_frfree(af); 01577 return ast_frisolate(&dsp->f); 01578 } 01579 } 01580 } else if (!digit) { 01581 /* Only check when there is *not* a hit... */ 01582 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01583 if (dsp->td.mf.current_digits) { 01584 memset(&dsp->f, 0, sizeof(dsp->f)); 01585 dsp->f.frametype = AST_FRAME_DTMF; 01586 dsp->f.subclass = dsp->td.mf.digits[0]; 01587 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits); 01588 dsp->td.mf.current_digits--; 01589 FIX_INF(af); 01590 if (chan) 01591 ast_queue_frame(chan, af); 01592 ast_frfree(af); 01593 return ast_frisolate(&dsp->f); 01594 } 01595 } else { 01596 if (dsp->td.dtmf.current_digits) { 01597 memset(&dsp->f, 0, sizeof(dsp->f)); 01598 dsp->f.frametype = AST_FRAME_DTMF_END; 01599 dsp->f.subclass = dsp->td.dtmf.digits[0]; 01600 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits); 01601 dsp->td.dtmf.current_digits--; 01602 FIX_INF(af); 01603 if (chan) 01604 ast_queue_frame(chan, af); 01605 ast_frfree(af); 01606 return ast_frisolate(&dsp->f); 01607 } 01608 } 01609 } 01610 } 01611 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) { 01612 res = __ast_dsp_call_progress(dsp, shortdata, len); 01613 if (res) { 01614 switch(res) { 01615 case AST_CONTROL_ANSWER: 01616 case AST_CONTROL_BUSY: 01617 case AST_CONTROL_RINGING: 01618 case AST_CONTROL_CONGESTION: 01619 case AST_CONTROL_HANGUP: 01620 memset(&dsp->f, 0, sizeof(dsp->f)); 01621 dsp->f.frametype = AST_FRAME_CONTROL; 01622 dsp->f.subclass = res; 01623 dsp->f.src = "dsp_progress"; 01624 if (chan) 01625 ast_queue_frame(chan, &dsp->f); 01626 break; 01627 default: 01628 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res); 01629 } 01630 } 01631 } 01632 FIX_INF(af); 01633 return af; 01634 }
void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1781 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.
01782 { 01783 int x; 01784 01785 dsp->totalsilence = 0; 01786 dsp->gsamps = 0; 01787 for (x=0;x<4;x++) 01788 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01789 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01790 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01791 dsp->ringtimeout= 0; 01792 }
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 1711 of file dsp.c.
References ast_dsp::busycompare.
Referenced by dahdi_new().
01712 { 01713 if (compare > 0) 01714 dsp->busycompare = 1; 01715 else 01716 dsp->busycompare = 0; 01717 }
void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, | |
int | cadences | |||
) |
Set number of required cadences for busy.
Definition at line 1702 of file dsp.c.
References ast_dsp::busycount, and DSP_HISTORY.
Referenced by dahdi_new().
01703 { 01704 if (cadences < 4) 01705 cadences = 4; 01706 if (cadences > DSP_HISTORY) 01707 cadences = DSP_HISTORY; 01708 dsp->busycount = cadences; 01709 }
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 1719 of file dsp.c.
References ast_log(), ast_dsp::busy_pattern_fuzzy, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busytoneonly, and LOG_DEBUG.
Referenced by dahdi_new().
01720 { 01721 dsp->busy_tonelength = tonelength; 01722 if (quietlength > 0) 01723 dsp->busy_quietlength = quietlength; 01724 else 01725 dsp->busytoneonly = 1; 01726 ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength); 01727 if( fuzzy > 0 && fuzzy < 50 ) 01728 dsp->busy_pattern_fuzzy = fuzzy; 01729 }
int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, | |
char * | zone | |||
) |
Set zone for doing progress detection.
Definition at line 1812 of file dsp.c.
References aliases, ast_dsp_prog_reset(), name, and ast_dsp::progmode.
Referenced by dahdi_new().
01813 { 01814 int x; 01815 01816 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) { 01817 if (!strcasecmp(aliases[x].name, zone)) { 01818 dsp->progmode = aliases[x].mode; 01819 ast_dsp_prog_reset(dsp); 01820 return 0; 01821 } 01822 } 01823 return -1; 01824 }
void ast_dsp_set_features | ( | struct ast_dsp * | dsp, | |
int | features | |||
) |
Select feature set.
Definition at line 1684 of file dsp.c.
References ast_dsp::features.
Referenced by __oh323_new(), dahdi_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), and sip_new().
void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, | |
int | threshold | |||
) |
Set threshold value for silence.
Definition at line 1694 of file dsp.c.
References ast_dsp::threshold.
Referenced by __ast_play_and_record(), dahdi_new(), do_waiting(), handle_recordfile(), and isAnsweringMachine().
01695 { 01696 if (threshold < 256) 01697 dsp->threshold = 256; 01698 else 01699 dsp->threshold = threshold; 01700 }
Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.
Definition at line 1425 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(), and isAnsweringMachine().
01426 { 01427 short *s; 01428 int len; 01429 01430 if (f->frametype != AST_FRAME_VOICE) { 01431 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n"); 01432 return 0; 01433 } 01434 if (f->subclass != AST_FORMAT_SLINEAR) { 01435 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n"); 01436 return 0; 01437 } 01438 s = f->data; 01439 len = f->datalen/2; 01440 return __ast_dsp_silence(dsp, s, len, totalsilence); 01441 }