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_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_frame_freed (struct ast_frame *fr) |
Hint that a frame from a dsp was freed. | |
void | ast_dsp_free (struct ast_dsp *dsp) |
int | ast_dsp_get_tcount (struct ast_dsp *dsp) |
Get tcount (Threshold counter). | |
int | ast_dsp_get_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. | |
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. |
Definition in file dsp.h.
#define DSP_DIGITMODE_DTMF 0 |
Detect DTMF digits
Definition at line 31 of file dsp.h.
Referenced by ast_dsp_digitmode(), ast_dsp_new(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), sip_new(), ss_thread(), and store_config().
#define DSP_DIGITMODE_MF 1 |
Detect MF digits
Definition at line 32 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_new(), and ss_thread().
#define DSP_DIGITMODE_MUTECONF (1 << 9) |
Mute conference
Definition at line 35 of file dsp.h.
Referenced by ast_dsp_digitmode(), ast_dsp_process(), dahdi_setoption(), and store_config().
#define DSP_DIGITMODE_MUTEMAX (1 << 10) |
Delay audio by a frame to try to extra quelch
Definition at line 36 of file dsp.h.
Referenced by ast_dsp_digitmode(), ast_dsp_process(), 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 dtmf_detect(), mf_detect(), 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_digitdetect(), dahdi_setoption(), process_dahdi(), sip_new(), and store_config().
#define DSP_FAXMODE_DETECT_ALL (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED) |
#define DSP_FAXMODE_DETECT_CED (1 << 1) |
#define DSP_FAXMODE_DETECT_CNG (1 << 0) |
Definition at line 45 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), ast_dsp_new(), and transmit_audio().
#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) |
Definition at line 28 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), __oh323_new(), ast_dsp_process(), dahdi_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), sip_new(), and store_config().
#define DSP_FEATURE_FAX_DETECT (1 << 4) |
Definition at line 29 of file dsp.h.
Referenced by __ast_dsp_digitdetect(), ast_dsp_process(), dahdi_new(), misdn_set_opt_exec(), read_config(), and transmit_audio().
#define DSP_FEATURE_SILENCE_SUPPRESS (1 << 0) |
#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_RINGING 1 |
#define DSP_TONE_STATE_SILENCE 0 |
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 1084 of file dsp.c.
References ast_log(), buf, 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().
01085 { 01086 int res = 0, x; 01087 int avgsilence = 0, hitsilence = 0; 01088 int avgtone = 0, hittone = 0; 01089 #ifdef DEBUG_DSP_BUSYDETECT 01090 char buf[16]; 01091 char silence_list[64]="", tone_list[64]=""; 01092 #endif 01093 01094 if (!dsp->busymaybe) 01095 return res; 01096 dsp->busymaybe = 0; 01097 01098 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) { 01099 avgsilence += dsp->historicsilence[x]; 01100 avgtone += dsp->historicnoise[x]; 01101 } 01102 avgsilence /= dsp->busycount; 01103 avgtone /= dsp->busycount; 01104 #ifdef DEBUG_DSP_BUSYDETECT 01105 sprintf(silence_list,"Silences: "); 01106 sprintf(tone_list,"Tones: "); 01107 #endif 01108 for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) { 01109 #ifdef DEBUG_DSP_BUSYDETECT 01110 snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]); 01111 strcat(silence_list, buf); 01112 snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]); 01113 strcat(tone_list, buf); 01114 #endif 01115 if (!dsp->busytoneonly) { 01116 if (avgsilence > dsp->historicsilence[x]) { 01117 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x]) 01118 hitsilence++; 01119 } else { 01120 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x]) 01121 hitsilence++; 01122 } 01123 } 01124 if (avgtone > dsp->historicnoise[x]) { 01125 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x]) 01126 hittone++; 01127 } else { 01128 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x]) 01129 hittone++; 01130 } 01131 } 01132 #ifdef DEBUG_DSP_BUSYDETECT 01133 fprintf(stderr, "BUSY DETECTOR\n"); 01134 fprintf(stderr, "%s\n", tone_list); 01135 fprintf(stderr, "%s\n", silence_list) 01136 #endif 01137 if ((dsp->busytoneonly || 01138 (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) && 01139 (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { 01140 if (dsp->busycompare) { 01141 if (dsp->busytoneonly) { 01142 res = 1; 01143 ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare"); 01144 } else { 01145 if (avgtone > avgsilence) { 01146 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) 01147 res = 1; 01148 } else { 01149 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) 01150 res = 1; 01151 } 01152 } 01153 } else { 01154 res = 1; 01155 } 01156 } 01157 /* If we know the expected busy tone length, check we are in the range */ 01158 if (res && (dsp->busy_tonelength > 0)) { 01159 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100)) { 01160 #ifdef BUSYDETECT_DEBUG 01161 if(option_debug) { 01162 ast_log(LOG_DEBUG, "busy detector: avgtone of %d not close enough to desired %d\n", avgtone, dsp->busy_tonelength); 01163 } 01164 #endif 01165 res = 0; 01166 } 01167 } 01168 /* If we know the expected busy tone silent-period length, check we are in the range */ 01169 if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) { 01170 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100)) { 01171 #ifdef BUSYDETECT_DEBUG 01172 if(option_debug) { 01173 ast_log(LOG_DEBUG, "busy detector: avgsilence of %d not close enough to desired %d\n", avgsilence, dsp->busy_quietlength); 01174 } 01175 #endif 01176 res = 0; 01177 } 01178 } 01179 if (res) { 01180 if (option_debug) 01181 ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01182 } else { 01183 if (option_debug) 01184 ast_log(LOG_NOTICE, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01185 } 01186 return res; 01187 }
Scans for progress indication in audio.
Definition at line 1014 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.
01015 { 01016 if (inf->frametype != AST_FRAME_VOICE) { 01017 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01018 return 0; 01019 } 01020 if (inf->subclass != AST_FORMAT_SLINEAR) { 01021 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01022 return 0; 01023 } 01024 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2); 01025 }
Return non-zero if DTMF hit was found.
Definition at line 837 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.
00838 { 00839 short *s; 00840 int len; 00841 int ign=0; 00842 00843 if (inf->frametype != AST_FRAME_VOICE) { 00844 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 00845 return 0; 00846 } 00847 if (inf->subclass != AST_FORMAT_SLINEAR) { 00848 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 00849 return 0; 00850 } 00851 s = inf->data; 00852 len = inf->datalen / 2; 00853 return __ast_dsp_digitdetect(dsp, s, len, &ign); 00854 }
int ast_dsp_digitmode | ( | struct ast_dsp * | dsp, | |
int | digitmode | |||
) |
Set digit mode.
Definition at line 1541 of file dsp.c.
References ast_digit_detect_init(), ast_dsp::digit_state, ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, and DSP_DIGITMODE_MUTEMAX.
Referenced by dahdi_hangup(), dahdi_new(), dahdi_setoption(), mgcp_new(), sip_new(), ss_thread(), and store_config().
01542 { 01543 int new; 01544 int old; 01545 01546 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01547 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01548 if (old != new) { 01549 /* Must initialize structures if switching from MF to DTMF or vice-versa */ 01550 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF); 01551 } 01552 dsp->digitmode = digitmode; 01553 return 0; 01554 }
void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |
Reset DTMF detector.
Definition at line 1499 of file dsp.c.
References digit_detect_state_t::current_digits, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, DSP_DIGITMODE_MF, digit_detect_state_t::dtmf, goertzel_reset(), digit_detect_state_t::mf, s, digit_detect_state_t::td, and ast_dsp::thinkdigit.
Referenced by ss_thread().
01500 { 01501 int i; 01502 01503 dsp->thinkdigit = 0; 01504 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01505 mf_detect_state_t *s = &dsp->digit_state.td.mf; 01506 /* Reinitialise the detector for the next block */ 01507 for (i = 0; i < 6; i++) { 01508 goertzel_reset(&s->tone_out[i]); 01509 } 01510 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0; 01511 s->current_sample = 0; 01512 } else { 01513 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf; 01514 /* Reinitialise the detector for the next block */ 01515 for (i = 0; i < 4; i++) { 01516 goertzel_reset(&s->row_out[i]); 01517 goertzel_reset(&s->col_out[i]); 01518 } 01519 s->lasthit = s->current_hit = 0; 01520 s->energy = 0.0; 01521 s->current_sample = 0; 01522 } 01523 01524 dsp->digit_state.digits[0] = '\0'; 01525 dsp->digit_state.current_digits = 0; 01526 }
void ast_dsp_frame_freed | ( | struct ast_frame * | fr | ) |
Hint that a frame from a dsp was freed.
This is called from ast_frame_free if AST_FRFLAG_FROM_DSP is set. This occurs because it is possible for the dsp to be freed while someone still holds a reference to the frame that is in that dsp. This has been known to happen when the dsp on a DAHDI channel detects a busy signal. The channel is hung up, and the application that read the frame to begin with still has a reference to the frame.
Definition at line 1589 of file dsp.c.
References ast_clear_flag, ast_dsp_free(), AST_FRFLAG_FROM_DSP, f, and ast_dsp::freqcount.
Referenced by __frame_free().
01590 { 01591 struct ast_dsp *dsp; 01592 01593 ast_clear_flag(fr, AST_FRFLAG_FROM_DSP); 01594 01595 dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f)); 01596 01597 if (dsp->freqcount != -1) 01598 return; 01599 01600 ast_dsp_free(dsp); 01601 }
void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1446 of file dsp.c.
References ast_free, AST_FRFLAG_FROM_DSP, ast_test_flag, ast_dsp::f, and ast_dsp::freqcount.
Referenced by __ast_play_and_record(), __oh323_destroy(), ast_dsp_frame_freed(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), conf_run(), dahdi_hangup(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), sip_dtmfmode(), sip_hangup(), ss_thread(), transmit_audio(), and unload_module().
01447 { 01448 if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) { 01449 /* If this flag is still set, that means that the dsp's destruction 01450 * been torn down, while we still have a frame out there being used. 01451 * When ast_frfree() gets called on that frame, this ast_trans_pvt 01452 * will get destroyed, too. */ 01453 01454 /* Set the magic flag to destroy the dsp when the frame is freed */ 01455 dsp->freqcount = -1; 01456 01457 return; 01458 } 01459 ast_free(dsp); 01460 }
int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter).
Definition at line 1584 of file dsp.c.
References ast_dsp::tcount.
01585 { 01586 return dsp->tcount; 01587 }
int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State).
Definition at line 1579 of file dsp.c.
References ast_dsp::tstate.
01580 { 01581 return dsp->tstate; 01582 }
int ast_dsp_getdigits | ( | struct ast_dsp * | dsp, | |
char * | buf, | |||
int | max | |||
) |
Get pending DTMF/MF digits.
Definition at line 876 of file dsp.c.
References digit_detect_state_t::current_digits, ast_dsp::digit_state, and digit_detect_state_t::digits.
00877 { 00878 if (max > dsp->digit_state.current_digits) 00879 max = dsp->digit_state.current_digits; 00880 if (max > 0) { 00881 memcpy(buf, dsp->digit_state.digits, max); 00882 memmove(dsp->digit_state.digits, dsp->digit_state.digits + max, dsp->digit_state.current_digits - max); 00883 dsp->digit_state.current_digits -= max; 00884 } 00885 buf[max] = '\0'; 00886 return max; 00887 }
struct ast_dsp* ast_dsp_new | ( | void | ) |
Definition at line 1407 of file dsp.c.
References ast_calloc, ast_digit_detect_init(), ast_dsp_prog_reset(), ast_fax_detect_init(), BUSY_PAT_PERCENT, DEFAULT_THRESHOLD, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_FAXMODE_DETECT_CNG, 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(), sip_new(), store_config(), and transmit_audio().
01408 { 01409 struct ast_dsp *dsp; 01410 01411 if ((dsp = ast_calloc(1, sizeof(*dsp)))) { 01412 dsp->threshold = DEFAULT_THRESHOLD; 01413 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS; 01414 dsp->busycount = DSP_HISTORY; 01415 dsp->digitmode = DSP_DIGITMODE_DTMF; 01416 dsp->faxmode = DSP_FAXMODE_DETECT_CNG; 01417 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT; 01418 #ifdef BUSYDETECT_TONEONLY 01419 dsp->busytoneonly = 1; 01420 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01421 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE"); 01422 #endif 01423 #else 01424 dsp->busytoneonly = 0; 01425 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01426 dsp->busycompare = 1; 01427 #else 01428 dsp->busycompare = 0; 01429 #endif 01430 #endif 01431 /* Initialize digit detector */ 01432 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF); 01433 /* Initialize initial DSP progress detect parameters */ 01434 ast_dsp_prog_reset(dsp); 01435 /* Initialize fax detector */ 01436 ast_fax_detect_init(dsp); 01437 } 01438 return dsp; 01439 }
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 1207 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_debug, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRFLAG_FROM_DSP, ast_frfree, ast_getformatname(), ast_log(), AST_MULAW, ast_queue_frame(), ast_set_flag, AST_SOFTHANGUP_DEV, chan, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::f, ast_dsp::features, FIX_INF, ast_frame::frametype, len(), LOG_WARNING, ast_channel::name, ast_frame::src, ast_frame::subclass, and ast_dsp::thinkdigit.
Referenced by dahdi_read(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), sip_rtp_read(), transmit_audio(), and usbradio_read().
01208 { 01209 int silence; 01210 int res; 01211 int digit; 01212 int x; 01213 short *shortdata; 01214 unsigned char *odata; 01215 int len; 01216 int writeback = 0; 01217 01218 #define FIX_INF(inf) do { \ 01219 if (writeback) { \ 01220 switch (inf->subclass) { \ 01221 case AST_FORMAT_SLINEAR: \ 01222 break; \ 01223 case AST_FORMAT_ULAW: \ 01224 for (x=0;x<len;x++) \ 01225 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \ 01226 break; \ 01227 case AST_FORMAT_ALAW: \ 01228 for (x=0;x<len;x++) \ 01229 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \ 01230 break; \ 01231 } \ 01232 } \ 01233 } while(0) 01234 01235 if (!af) 01236 return NULL; 01237 if (af->frametype != AST_FRAME_VOICE) 01238 return af; 01239 odata = af->data; 01240 len = af->datalen; 01241 /* Make sure we have short data */ 01242 switch (af->subclass) { 01243 case AST_FORMAT_SLINEAR: 01244 shortdata = af->data; 01245 len = af->datalen / 2; 01246 break; 01247 case AST_FORMAT_ULAW: 01248 shortdata = alloca(af->datalen * 2); 01249 for (x = 0;x < len; x++) 01250 shortdata[x] = AST_MULAW(odata[x]); 01251 break; 01252 case AST_FORMAT_ALAW: 01253 shortdata = alloca(af->datalen * 2); 01254 for (x = 0; x < len; x++) 01255 shortdata[x] = AST_ALAW(odata[x]); 01256 break; 01257 default: 01258 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); 01259 return af; 01260 } 01261 silence = __ast_dsp_silence(dsp, shortdata, len, NULL); 01262 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { 01263 memset(&dsp->f, 0, sizeof(dsp->f)); 01264 dsp->f.frametype = AST_FRAME_NULL; 01265 ast_frfree(af); 01266 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01267 return &dsp->f; 01268 } 01269 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) { 01270 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01271 memset(&dsp->f, 0, sizeof(dsp->f)); 01272 dsp->f.frametype = AST_FRAME_CONTROL; 01273 dsp->f.subclass = AST_CONTROL_BUSY; 01274 ast_frfree(af); 01275 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name); 01276 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01277 return &dsp->f; 01278 } 01279 if (((dsp->features & DSP_FEATURE_DTMF_DETECT) || (dsp->features & DSP_FEATURE_FAX_DETECT))) { 01280 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback); 01281 #if 0 01282 if (digit) 01283 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode); 01284 #endif 01285 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) { 01286 if (!dsp->thinkdigit) { 01287 if (digit) { 01288 /* Looks like we might have something. 01289 * Request a conference mute for the moment */ 01290 memset(&dsp->f, 0, sizeof(dsp->f)); 01291 dsp->f.frametype = AST_FRAME_DTMF; 01292 dsp->f.subclass = 'm'; 01293 dsp->thinkdigit = 'x'; 01294 FIX_INF(af); 01295 if (chan) 01296 ast_queue_frame(chan, af); 01297 ast_frfree(af); 01298 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01299 return &dsp->f; 01300 } 01301 } else { 01302 if (digit) { 01303 /* Thought we saw one last time. Pretty sure we really have now */ 01304 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) { 01305 /* If we found a digit, and we're changing digits, go 01306 ahead and send this one, but DON'T stop confmute because 01307 we're detecting something else, too... */ 01308 memset(&dsp->f, 0, sizeof(dsp->f)); 01309 dsp->f.frametype = AST_FRAME_DTMF_END; 01310 dsp->f.subclass = dsp->thinkdigit; 01311 FIX_INF(af); 01312 if (chan) 01313 ast_queue_frame(chan, af); 01314 ast_frfree(af); 01315 } else { 01316 dsp->thinkdigit = digit; 01317 memset(&dsp->f, 0, sizeof(dsp->f)); 01318 dsp->f.frametype = AST_FRAME_DTMF_BEGIN; 01319 dsp->f.subclass = dsp->thinkdigit; 01320 FIX_INF(af); 01321 if (chan) 01322 ast_queue_frame(chan, af); 01323 ast_frfree(af); 01324 } 01325 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01326 return &dsp->f; 01327 } else { 01328 memset(&dsp->f, 0, sizeof(dsp->f)); 01329 if (dsp->thinkdigit != 'x') { 01330 /* If we found a digit, send it now */ 01331 dsp->f.frametype = AST_FRAME_DTMF_END; 01332 dsp->f.subclass = dsp->thinkdigit; 01333 dsp->thinkdigit = 0; 01334 } else { 01335 dsp->f.frametype = AST_FRAME_DTMF; 01336 dsp->f.subclass = 'u'; 01337 dsp->thinkdigit = 0; 01338 } 01339 FIX_INF(af); 01340 if (chan) 01341 ast_queue_frame(chan, af); 01342 ast_frfree(af); 01343 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01344 return &dsp->f; 01345 } 01346 } 01347 } else if (dsp->digit_state.current_digits > 1 || 01348 (dsp->digit_state.current_digits == 1 && digit != dsp->digit_state.digits[0])) { 01349 /* Since we basically generate DTMF_END frames we do it only when a digit 01350 has finished. */ 01351 01352 memset(&dsp->f, 0, sizeof(dsp->f)); 01353 dsp->f.frametype = AST_FRAME_DTMF; 01354 dsp->f.subclass = dsp->digit_state.digits[0]; 01355 memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits); 01356 dsp->digit_state.current_digits--; 01357 FIX_INF(af); 01358 if (chan) 01359 ast_queue_frame(chan, af); 01360 ast_frfree(af); 01361 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01362 return &dsp->f; 01363 } 01364 } 01365 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) { 01366 res = __ast_dsp_call_progress(dsp, shortdata, len); 01367 if (res) { 01368 switch (res) { 01369 case AST_CONTROL_ANSWER: 01370 case AST_CONTROL_BUSY: 01371 case AST_CONTROL_RINGING: 01372 case AST_CONTROL_CONGESTION: 01373 case AST_CONTROL_HANGUP: 01374 memset(&dsp->f, 0, sizeof(dsp->f)); 01375 dsp->f.frametype = AST_FRAME_CONTROL; 01376 dsp->f.subclass = res; 01377 dsp->f.src = "dsp_progress"; 01378 if (chan) 01379 ast_queue_frame(chan, &dsp->f); 01380 break; 01381 default: 01382 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res); 01383 } 01384 } 01385 } 01386 FIX_INF(af); 01387 return af; 01388 }
void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1528 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.
01529 { 01530 int x; 01531 01532 dsp->totalsilence = 0; 01533 dsp->gsamps = 0; 01534 for (x=0;x<4;x++) 01535 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01536 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01537 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01538 dsp->ringtimeout= 0; 01539 }
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 1479 of file dsp.c.
References ast_dsp::busycompare.
Referenced by dahdi_new().
01480 { 01481 if (compare > 0) 01482 dsp->busycompare = 1; 01483 else 01484 dsp->busycompare = 0; 01485 }
void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, | |
int | cadences | |||
) |
Set number of required cadences for busy.
Definition at line 1470 of file dsp.c.
References ast_dsp::busycount, and DSP_HISTORY.
Referenced by dahdi_new().
01471 { 01472 if (cadences < 4) 01473 cadences = 4; 01474 if (cadences > DSP_HISTORY) 01475 cadences = DSP_HISTORY; 01476 dsp->busycount = cadences; 01477 }
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 1487 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().
01488 { 01489 dsp->busy_tonelength = tonelength; 01490 if (quietlength > 0) 01491 dsp->busy_quietlength = quietlength; 01492 else 01493 dsp->busytoneonly = 1; 01494 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength); 01495 if( fuzzy > 0 && fuzzy < 50 ) 01496 dsp->busy_pattern_fuzzy = fuzzy; 01497 }
int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, | |
char * | zone | |||
) |
Set zone for doing progress detection.
Definition at line 1565 of file dsp.c.
References aliases, ARRAY_LEN, ast_dsp_prog_reset(), progalias::mode, name, and ast_dsp::progmode.
Referenced by dahdi_new().
01566 { 01567 int x; 01568 01569 for (x = 0; x < ARRAY_LEN(aliases); x++) { 01570 if (!strcasecmp(aliases[x].name, zone)) { 01571 dsp->progmode = aliases[x].mode; 01572 ast_dsp_prog_reset(dsp); 01573 return 0; 01574 } 01575 } 01576 return -1; 01577 }
int ast_dsp_set_faxmode | ( | struct ast_dsp * | dsp, | |
int | faxmode | |||
) |
Set fax mode.
Definition at line 1556 of file dsp.c.
References ast_fax_detect_init(), and ast_dsp::faxmode.
Referenced by transmit_audio().
01557 { 01558 if (dsp->faxmode != faxmode) { 01559 ast_fax_detect_init(dsp); 01560 } 01561 dsp->faxmode = faxmode; 01562 return 0; 01563 }
void ast_dsp_set_features | ( | struct ast_dsp * | dsp, | |
int | features | |||
) |
Select feature set.
Definition at line 1441 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(), sip_new(), store_config(), and transmit_audio().
void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, | |
int | threshold | |||
) |
Set threshold value for silence.
Definition at line 1462 of file dsp.c.
References ast_dsp::threshold.
Referenced by __ast_play_and_record(), dahdi_new(), do_waiting(), handle_recordfile(), and isAnsweringMachine().
01463 { 01464 if (threshold < 256) 01465 dsp->threshold = 256; 01466 else 01467 dsp->threshold = threshold; 01468 }
Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.
Definition at line 1189 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().
01190 { 01191 short *s; 01192 int len; 01193 01194 if (f->frametype != AST_FRAME_VOICE) { 01195 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n"); 01196 return 0; 01197 } 01198 if (f->subclass != AST_FORMAT_SLINEAR) { 01199 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n"); 01200 return 0; 01201 } 01202 s = f->data; 01203 len = f->datalen/2; 01204 return __ast_dsp_silence(dsp, s, len, totalsilence); 01205 }