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_PROGRESS_BUSY (1 << 18) |
#define | DSP_PROGRESS_CONGESTION (1 << 19) |
#define | DSP_PROGRESS_RINGING (1 << 17) |
#define | DSP_PROGRESS_TALK (1 << 16) |
#define | DSP_TONE_STATE_BUSY 4 |
#define | DSP_TONE_STATE_DIALTONE 2 |
#define | DSP_TONE_STATE_HUNGUP 8 |
#define | DSP_TONE_STATE_RINGING 1 |
#define | DSP_TONE_STATE_SILENCE 0 |
#define | DSP_TONE_STATE_SPECIAL1 5 |
#define | DSP_TONE_STATE_SPECIAL2 6 |
#define | DSP_TONE_STATE_SPECIAL3 7 |
#define | DSP_TONE_STATE_TALKING 3 |
Enumerations | |
enum | threshold { THRESHOLD_SILENCE = 0, THRESHOLD_MAX = 1 } |
Functions | |
int | ast_dsp_busydetect (struct ast_dsp *dsp) |
Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called. | |
int | ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf) |
Scans for progress indication in audio. | |
int | ast_dsp_digitdetect (struct ast_dsp *dsp, struct ast_frame *f) |
Return non-zero if DTMF hit was found. | |
void | ast_dsp_digitreset (struct ast_dsp *dsp) |
Reset DTMF detector. | |
void | ast_dsp_frame_freed (struct ast_frame *fr) |
Hint that a frame from a dsp was freed. | |
void | ast_dsp_free (struct ast_dsp *dsp) |
int | ast_dsp_get_tcount (struct ast_dsp *dsp) |
Get tcount (Threshold counter). | |
int | ast_dsp_get_threshold_from_settings (enum threshold which) |
Get silence threshold from dsp.conf. | |
int | ast_dsp_get_tstate (struct ast_dsp *dsp) |
Get tstate (Tone State). | |
int | ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max) |
Get pending DTMF/MF digits. | |
int | ast_dsp_init (void) |
Load dsp settings from dsp.conf. | |
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. | |
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. |
Definition in file dsp.h.
#define DSP_DIGITMODE_DTMF 0 |
Detect DTMF digits
Definition at line 31 of file dsp.h.
Referenced by ast_dsp_new(), ast_dsp_set_digitmode(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), sip_new(), ss_thread(), and store_config().
#define DSP_DIGITMODE_MF 1 |
Detect MF digits
Definition at line 32 of file dsp.h.
Referenced by ast_dsp_digitreset(), ast_dsp_new(), ast_dsp_process(), ast_dsp_set_digitmode(), and ss_thread().
#define DSP_DIGITMODE_MUTECONF (1 << 9) |
Mute conference
Definition at line 35 of file dsp.h.
Referenced by ast_dsp_set_digitmode(), dahdi_setoption(), and store_config().
#define DSP_DIGITMODE_MUTEMAX (1 << 10) |
Delay audio by a frame to try to extra quelch
Definition at line 36 of file dsp.h.
Referenced by ast_dsp_set_digitmode(), and dahdi_setoption().
#define DSP_DIGITMODE_NOQUELCH (1 << 8) |
Do not quelch DTMF from in-band
Definition at line 34 of file dsp.h.
Referenced by ast_dsp_process(), and mgcp_new().
#define DSP_DIGITMODE_RELAXDTMF (1 << 11) |
"Radio" mode (relaxed DTMF)
Definition at line 37 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_setoption(), 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_new(), ast_dsp_process(), 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_DIGIT_DETECT (1 << 3) |
Definition at line 28 of file dsp.h.
Referenced by __oh323_new(), ast_dsp_process(), dahdi_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), sip_new(), and store_config().
#define DSP_FEATURE_FAX_DETECT (1 << 4) |
Definition at line 29 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_new(), misdn_set_opt_exec(), read_config(), and 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 |
enum threshold |
Definition at line 61 of file dsp.h.
00061 { 00062 /* Array offsets */ 00063 THRESHOLD_SILENCE = 0, 00064 /* Always the last */ 00065 THRESHOLD_MAX = 1, 00066 };
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 1149 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().
01150 { 01151 int res = 0, x; 01152 int avgsilence = 0, hitsilence = 0; 01153 int avgtone = 0, hittone = 0; 01154 #ifdef DEBUG_DSP_BUSYDETECT 01155 char buf[16]; 01156 char silence_list[64]="", tone_list[64]=""; 01157 #endif 01158 01159 if (!dsp->busymaybe) 01160 return res; 01161 dsp->busymaybe = 0; 01162 01163 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) { 01164 avgsilence += dsp->historicsilence[x]; 01165 avgtone += dsp->historicnoise[x]; 01166 } 01167 avgsilence /= dsp->busycount; 01168 avgtone /= dsp->busycount; 01169 #ifdef DEBUG_DSP_BUSYDETECT 01170 sprintf(silence_list,"Silences: "); 01171 sprintf(tone_list,"Tones: "); 01172 #endif 01173 for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) { 01174 #ifdef DEBUG_DSP_BUSYDETECT 01175 snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]); 01176 strcat(silence_list, buf); 01177 snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]); 01178 strcat(tone_list, buf); 01179 #endif 01180 if (!dsp->busytoneonly) { 01181 if (avgsilence > dsp->historicsilence[x]) { 01182 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x]) 01183 hitsilence++; 01184 } else { 01185 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x]) 01186 hitsilence++; 01187 } 01188 } 01189 if (avgtone > dsp->historicnoise[x]) { 01190 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x]) 01191 hittone++; 01192 } else { 01193 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x]) 01194 hittone++; 01195 } 01196 } 01197 #ifdef DEBUG_DSP_BUSYDETECT 01198 fprintf(stderr, "BUSY DETECTOR\n"); 01199 fprintf(stderr, "%s\n", tone_list); 01200 fprintf(stderr, "%s\n", silence_list) 01201 #endif 01202 if ((dsp->busytoneonly || 01203 (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) && 01204 (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { 01205 if (dsp->busycompare) { 01206 if (dsp->busytoneonly) { 01207 res = 1; 01208 ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare"); 01209 } else { 01210 if (avgtone > avgsilence) { 01211 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) 01212 res = 1; 01213 } else { 01214 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) 01215 res = 1; 01216 } 01217 } 01218 } else { 01219 res = 1; 01220 } 01221 } 01222 /* If we know the expected busy tone length, check we are in the range */ 01223 if (res && (dsp->busy_tonelength > 0)) { 01224 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100)) { 01225 #ifdef BUSYDETECT_DEBUG 01226 if(option_debug) { 01227 ast_log(LOG_DEBUG, "busy detector: avgtone of %d not close enough to desired %d\n", avgtone, dsp->busy_tonelength); 01228 } 01229 #endif 01230 res = 0; 01231 } 01232 } 01233 /* If we know the expected busy tone silent-period length, check we are in the range */ 01234 if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) { 01235 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100)) { 01236 #ifdef BUSYDETECT_DEBUG 01237 if(option_debug) { 01238 ast_log(LOG_DEBUG, "busy detector: avgsilence of %d not close enough to desired %d\n", avgsilence, dsp->busy_quietlength); 01239 } 01240 #endif 01241 res = 0; 01242 } 01243 } 01244 if (res) { 01245 if (option_debug) 01246 ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01247 } else { 01248 if (option_debug) 01249 ast_log(LOG_NOTICE, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence); 01250 } 01251 return res; 01252 }
Scans for progress indication in audio.
Definition at line 1077 of file dsp.c.
References __ast_dsp_call_progress(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
01078 { 01079 if (inf->frametype != AST_FRAME_VOICE) { 01080 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); 01081 return 0; 01082 } 01083 if (inf->subclass != AST_FORMAT_SLINEAR) { 01084 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n"); 01085 return 0; 01086 } 01087 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2); 01088 }
Return non-zero if DTMF hit was found.
void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |
Reset DTMF detector.
Definition at line 1573 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, ast_dsp::dtmf_began, goertzel_reset(), digit_detect_state_t::mf, s, and digit_detect_state_t::td.
Referenced by ss_thread().
01574 { 01575 int i; 01576 01577 dsp->dtmf_began = 0; 01578 if (dsp->digitmode & DSP_DIGITMODE_MF) { 01579 mf_detect_state_t *s = &dsp->digit_state.td.mf; 01580 /* Reinitialise the detector for the next block */ 01581 for (i = 0; i < 6; i++) { 01582 goertzel_reset(&s->tone_out[i]); 01583 } 01584 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0; 01585 s->current_sample = 0; 01586 } else { 01587 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf; 01588 /* Reinitialise the detector for the next block */ 01589 for (i = 0; i < 4; i++) { 01590 goertzel_reset(&s->row_out[i]); 01591 goertzel_reset(&s->col_out[i]); 01592 } 01593 s->lasthit = s->current_hit = 0; 01594 s->energy = 0.0; 01595 s->current_sample = 0; 01596 s->hits = 0; 01597 s->misses = 0; 01598 } 01599 01600 dsp->digit_state.digits[0] = '\0'; 01601 dsp->digit_state.current_digits = 0; 01602 }
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 1707 of file dsp.c.
References ast_clear_flag, ast_dsp_free(), AST_FRFLAG_FROM_DSP, ast_dsp::destroy, and f.
Referenced by ast_frame_free().
01708 { 01709 struct ast_dsp *dsp; 01710 01711 ast_clear_flag(fr, AST_FRFLAG_FROM_DSP); 01712 01713 dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f)); 01714 01715 if (!dsp->destroy) 01716 return; 01717 01718 ast_dsp_free(dsp); 01719 }
void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1521 of file dsp.c.
References ast_free, AST_FRFLAG_FROM_DSP, ast_test_flag, ast_dsp::destroy, and ast_dsp::f.
Referenced by __ast_play_and_record(), __oh323_destroy(), ast_dsp_frame_freed(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), conf_run(), dahdi_hangup(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), sip_dtmfmode(), sip_hangup(), ss_thread(), transmit_audio(), and unload_module().
01522 { 01523 if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) { 01524 /* If this flag is still set, that means that the dsp's destruction 01525 * been torn down, while we still have a frame out there being used. 01526 * When ast_frfree() gets called on that frame, this ast_trans_pvt 01527 * will get destroyed, too. */ 01528 01529 dsp->destroy = 1; 01530 01531 return; 01532 } 01533 ast_free(dsp); 01534 }
int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter).
Definition at line 1665 of file dsp.c.
References ast_dsp::tcount.
01666 { 01667 return dsp->tcount; 01668 }
int ast_dsp_get_threshold_from_settings | ( | enum threshold | which | ) |
Get silence threshold from dsp.conf.
Definition at line 1692 of file dsp.c.
References thresholds.
Referenced by app_exec(), ast_record_review(), conf_run(), do_waiting(), handle_recordfile(), load_config(), and setup_privacy_args().
01693 { 01694 return thresholds[which]; 01695 }
int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State).
Definition at line 1660 of file dsp.c.
References ast_dsp::tstate.
01661 { 01662 return dsp->tstate; 01663 }
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 1697 of file dsp.c.
References _dsp_init().
Referenced by main().
01698 { 01699 return _dsp_init(0); 01700 }
struct ast_dsp* ast_dsp_new | ( | void | ) |
Definition at line 1482 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().
01483 { 01484 struct ast_dsp *dsp; 01485 01486 if ((dsp = ast_calloc(1, sizeof(*dsp)))) { 01487 dsp->threshold = DEFAULT_THRESHOLD; 01488 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS; 01489 dsp->busycount = DSP_HISTORY; 01490 dsp->digitmode = DSP_DIGITMODE_DTMF; 01491 dsp->faxmode = DSP_FAXMODE_DETECT_CNG; 01492 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT; 01493 #ifdef BUSYDETECT_TONEONLY 01494 dsp->busytoneonly = 1; 01495 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01496 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE"); 01497 #endif 01498 #else 01499 dsp->busytoneonly = 0; 01500 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE 01501 dsp->busycompare = 1; 01502 #else 01503 dsp->busycompare = 0; 01504 #endif 01505 #endif 01506 /* Initialize digit detector */ 01507 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF); 01508 /* Initialize initial DSP progress detect parameters */ 01509 ast_dsp_prog_reset(dsp); 01510 /* Initialize fax detector */ 01511 ast_fax_detect_init(dsp); 01512 } 01513 return dsp; 01514 }
Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise.
Definition at line 1272 of file dsp.c.
References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), f, len(), LOG_WARNING, and s.
Referenced by do_waiting().
01273 { 01274 short *s; 01275 int len; 01276 01277 if (f->frametype != AST_FRAME_VOICE) { 01278 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n"); 01279 return 0; 01280 } 01281 if (f->subclass != AST_FORMAT_SLINEAR) { 01282 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n"); 01283 return 0; 01284 } 01285 s = f->data.ptr; 01286 len = f->datalen/2; 01287 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise); 01288 }
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 1291 of file dsp.c.
References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), ast_channel::_softhangup, AST_ALAW, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_debug, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRFLAG_FROM_DSP, ast_frfree, ast_getformatname(), AST_LIN2A, AST_LIN2MU, ast_log(), AST_MULAW, ast_queue_frame(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_dsp::ced_tone_state, chan, ast_dsp::cng_tone_state, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, 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, ast_dsp::dtmf_began, dtmf_detect(), fragment_t::end, ast_dsp::f, ast_dsp::faxmode, ast_dsp::features, ast_frame::frametype, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, ast_channel::name, ast_frame::ptr, ast_frame::src, fragment_t::start, ast_frame::subclass, and tone_detect().
Referenced by dahdi_read(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), sip_rtp_read(), transmit_audio(), and usbradio_read().
01292 { 01293 int silence; 01294 int res; 01295 int digit = 0, fax_digit = 0; 01296 int x; 01297 short *shortdata; 01298 unsigned char *odata; 01299 int len; 01300 struct ast_frame *outf = NULL; 01301 01302 if (!af) 01303 return NULL; 01304 if (af->frametype != AST_FRAME_VOICE) 01305 return af; 01306 01307 odata = af->data.ptr; 01308 len = af->datalen; 01309 /* Make sure we have short data */ 01310 switch (af->subclass) { 01311 case AST_FORMAT_SLINEAR: 01312 shortdata = af->data.ptr; 01313 len = af->datalen / 2; 01314 break; 01315 case AST_FORMAT_ULAW: 01316 shortdata = alloca(af->datalen * 2); 01317 for (x = 0;x < len; x++) 01318 shortdata[x] = AST_MULAW(odata[x]); 01319 break; 01320 case AST_FORMAT_ALAW: 01321 shortdata = alloca(af->datalen * 2); 01322 for (x = 0; x < len; x++) 01323 shortdata[x] = AST_ALAW(odata[x]); 01324 break; 01325 default: 01326 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass)); 01327 return af; 01328 } 01329 01330 /* Initially we do not want to mute anything */ 01331 dsp->mute_fragments = 0; 01332 01333 /* Need to run the silence detection stuff for silence suppression and busy detection */ 01334 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) { 01335 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL); 01336 } 01337 01338 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) { 01339 memset(&dsp->f, 0, sizeof(dsp->f)); 01340 dsp->f.frametype = AST_FRAME_NULL; 01341 ast_frfree(af); 01342 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01343 return &dsp->f; 01344 } 01345 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) { 01346 chan->_softhangup |= AST_SOFTHANGUP_DEV; 01347 memset(&dsp->f, 0, sizeof(dsp->f)); 01348 dsp->f.frametype = AST_FRAME_CONTROL; 01349 dsp->f.subclass = AST_CONTROL_BUSY; 01350 ast_frfree(af); 01351 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name); 01352 ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP); 01353 return &dsp->f; 01354 } 01355 01356 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) { 01357 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) { 01358 fax_digit = 'f'; 01359 } 01360 01361 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) { 01362 fax_digit = 'e'; 01363 } 01364 } 01365 01366 if ((dsp->features & DSP_FEATURE_DIGIT_DETECT)) { 01367 if ((dsp->digitmode & DSP_DIGITMODE_MF)) 01368 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01369 else 01370 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF)); 01371 01372 if (dsp->digit_state.current_digits) { 01373 int event = 0; 01374 char event_digit = 0; 01375 01376 if (!dsp->dtmf_began) { 01377 /* We have not reported DTMF_BEGIN for anything yet */ 01378 01379 event = AST_FRAME_DTMF_BEGIN; 01380 event_digit = dsp->digit_state.digits[0]; 01381 dsp->dtmf_began = 1; 01382 01383 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) { 01384 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */ 01385 01386 event = AST_FRAME_DTMF_END; 01387 event_digit = dsp->digit_state.digits[0]; 01388 memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits); 01389 dsp->digit_state.current_digits--; 01390 dsp->dtmf_began = 0; 01391 } 01392 01393 if (event) { 01394 memset(&dsp->f, 0, sizeof(dsp->f)); 01395 dsp->f.frametype = event; 01396 dsp->f.subclass = event_digit; 01397 outf = &dsp->f; 01398 goto done; 01399 } 01400 } 01401 } 01402 01403 if (fax_digit) { 01404 /* Fax was detected - digit is either 'f' or 'e' */ 01405 01406 memset(&dsp->f, 0, sizeof(dsp->f)); 01407 dsp->f.frametype = AST_FRAME_DTMF; 01408 dsp->f.subclass = fax_digit; 01409 outf = &dsp->f; 01410 goto done; 01411 } 01412 01413 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) { 01414 res = __ast_dsp_call_progress(dsp, shortdata, len); 01415 if (res) { 01416 switch (res) { 01417 case AST_CONTROL_ANSWER: 01418 case AST_CONTROL_BUSY: 01419 case AST_CONTROL_RINGING: 01420 case AST_CONTROL_CONGESTION: 01421 case AST_CONTROL_HANGUP: 01422 memset(&dsp->f, 0, sizeof(dsp->f)); 01423 dsp->f.frametype = AST_FRAME_CONTROL; 01424 dsp->f.subclass = res; 01425 dsp->f.src = "dsp_progress"; 01426 if (chan) 01427 ast_queue_frame(chan, &dsp->f); 01428 break; 01429 default: 01430 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res); 01431 } 01432 } 01433 } 01434 01435 done: 01436 /* Mute fragment of the frame */ 01437 for (x = 0; x < dsp->mute_fragments; x++) { 01438 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start)); 01439 } 01440 01441 switch (af->subclass) { 01442 case AST_FORMAT_SLINEAR: 01443 break; 01444 case AST_FORMAT_ULAW: 01445 for (x = 0; x < len; x++) 01446 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]); 01447 break; 01448 case AST_FORMAT_ALAW: 01449 for (x = 0; x < len; x++) 01450 odata[x] = AST_LIN2A((unsigned short) shortdata[x]); 01451 break; 01452 } 01453 01454 if (outf) { 01455 if (chan) 01456 ast_queue_frame(chan, af); 01457 ast_frfree(af); 01458 ast_set_flag(outf, AST_FRFLAG_FROM_DSP); 01459 return outf; 01460 } else { 01461 return af; 01462 } 01463 }
int ast_dsp_reload | ( | void | ) |
Reloads dsp settings from dsp.conf.
Definition at line 1702 of file dsp.c.
References _dsp_init().
01703 { 01704 return _dsp_init(1); 01705 }
void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1604 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.
01605 { 01606 int x; 01607 01608 dsp->totalsilence = 0; 01609 dsp->gsamps = 0; 01610 for (x=0;x<4;x++) 01611 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01612 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence)); 01613 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise)); 01614 dsp->ringtimeout= 0; 01615 }
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 1553 of file dsp.c.
References ast_dsp::busycompare.
Referenced by dahdi_new().
01554 { 01555 if (compare > 0) 01556 dsp->busycompare = 1; 01557 else 01558 dsp->busycompare = 0; 01559 }
void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, | |
int | cadences | |||
) |
Set number of required cadences for busy.
Definition at line 1544 of file dsp.c.
References ast_dsp::busycount, and DSP_HISTORY.
Referenced by dahdi_new().
01545 { 01546 if (cadences < 4) 01547 cadences = 4; 01548 if (cadences > DSP_HISTORY) 01549 cadences = DSP_HISTORY; 01550 dsp->busycount = cadences; 01551 }
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 1561 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().
01562 { 01563 dsp->busy_tonelength = tonelength; 01564 if (quietlength > 0) 01565 dsp->busy_quietlength = quietlength; 01566 else 01567 dsp->busytoneonly = 1; 01568 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength); 01569 if( fuzzy > 0 && fuzzy < 50 ) 01570 dsp->busy_pattern_fuzzy = fuzzy; 01571 }
int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, | |
char * | zone | |||
) |
Set zone for doing progress detection.
Definition at line 1641 of file dsp.c.
References aliases, ARRAY_LEN, ast_dsp_prog_reset(), progalias::mode, name, and ast_dsp::progmode.
Referenced by dahdi_new().
01642 { 01643 int x; 01644 01645 for (x = 0; x < ARRAY_LEN(aliases); x++) { 01646 if (!strcasecmp(aliases[x].name, zone)) { 01647 dsp->progmode = aliases[x].mode; 01648 ast_dsp_prog_reset(dsp); 01649 return 0; 01650 } 01651 } 01652 return -1; 01653 }
int ast_dsp_set_digitmode | ( | struct ast_dsp * | dsp, | |
int | digitmode | |||
) |
Set digit mode.
Definition at line 1617 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().
01618 { 01619 int new; 01620 int old; 01621 01622 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01623 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX); 01624 if (old != new) { 01625 /* Must initialize structures if switching from MF to DTMF or vice-versa */ 01626 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF); 01627 } 01628 dsp->digitmode = digitmode; 01629 return 0; 01630 }
int ast_dsp_set_faxmode | ( | struct ast_dsp * | dsp, | |
int | faxmode | |||
) |
Set fax mode.
Definition at line 1632 of file dsp.c.
References ast_fax_detect_init(), and ast_dsp::faxmode.
Referenced by transmit_audio().
01633 { 01634 if (dsp->faxmode != faxmode) { 01635 ast_fax_detect_init(dsp); 01636 } 01637 dsp->faxmode = faxmode; 01638 return 0; 01639 }
void ast_dsp_set_features | ( | struct ast_dsp * | dsp, | |
int | features | |||
) |
Select feature set.
Definition at line 1516 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().
01517 { 01518 dsp->features = features; 01519 }
void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, | |
int | threshold | |||
) |
Set threshold value for silence.
Definition at line 1536 of file dsp.c.
References ast_dsp::threshold.
Referenced by __ast_play_and_record(), dahdi_new(), do_waiting(), handle_recordfile(), and isAnsweringMachine().
01537 { 01538 if (threshold < 256) 01539 dsp->threshold = 256; 01540 else 01541 dsp->threshold = threshold; 01542 }
Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.
Definition at line 1254 of file dsp.c.
References __ast_dsp_silence_noise(), 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().
01255 { 01256 short *s; 01257 int len; 01258 01259 if (f->frametype != AST_FRAME_VOICE) { 01260 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n"); 01261 return 0; 01262 } 01263 if (f->subclass != AST_FORMAT_SLINEAR) { 01264 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n"); 01265 return 0; 01266 } 01267 s = f->data.ptr; 01268 len = f->datalen/2; 01269 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL); 01270 }
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 1655 of file dsp.c.
References ast_dsp::mute_fragments.
Referenced by dahdi_read().
01656 { 01657 return (dsp->mute_fragments > 0); 01658 }