Convenient Signal Processing routines. More...

Go to the source code of this file.
Data Structures | |
| struct | ast_dsp_busy_pattern |
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_FAXMODE_DETECT_SQUELCH (1 << 2) |
| #define | DSP_FEATURE_BUSY_DETECT (1 << 1) |
| #define | DSP_FEATURE_CALL_PROGRESS (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION) |
| #define | DSP_FEATURE_DIGIT_DETECT (1 << 3) |
| #define | DSP_FEATURE_FAX_DETECT (1 << 4) |
| #define | DSP_FEATURE_SILENCE_SUPPRESS (1 << 0) |
| #define | DSP_FEATURE_WAITDIALTONE (1 << 20) |
| #define | DSP_PROGRESS_BUSY (1 << 18) |
| #define | DSP_PROGRESS_CONGESTION (1 << 19) |
| #define | DSP_PROGRESS_RINGING (1 << 17) |
| #define | DSP_PROGRESS_TALK (1 << 16) |
| #define | DSP_TONE_STATE_BUSY 4 |
| #define | DSP_TONE_STATE_DIALTONE 2 |
| #define | DSP_TONE_STATE_HUNGUP 8 |
| #define | DSP_TONE_STATE_RINGING 1 |
| #define | DSP_TONE_STATE_SILENCE 0 |
| #define | DSP_TONE_STATE_SPECIAL1 5 |
| #define | DSP_TONE_STATE_SPECIAL2 6 |
| #define | DSP_TONE_STATE_SPECIAL3 7 |
| #define | DSP_TONE_STATE_TALKING 3 |
Enumerations | |
| enum | threshold { THRESHOLD_SILENCE = 0, THRESHOLD_MAX = 1 } |
Functions | |
| int | ast_dsp_busydetect (struct ast_dsp *dsp) |
| Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called. | |
| int | ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf) |
| Scans for progress indication in audio. | |
| int | ast_dsp_digitdetect (struct ast_dsp *dsp, struct ast_frame *f) |
| Return non-zero if DTMF hit was found. | |
| void | ast_dsp_digitreset (struct ast_dsp *dsp) |
| Reset DTMF detector. | |
| void | ast_dsp_free (struct ast_dsp *dsp) |
| unsigned int | ast_dsp_get_sample_rate (const struct ast_dsp *dsp) |
| Retrieve the sample rate this DSP structure was created with. | |
| int | ast_dsp_get_tcount (struct ast_dsp *dsp) |
| Get tcount (Threshold counter) | |
| int | ast_dsp_get_threshold_from_settings (enum threshold which) |
| Get silence threshold from dsp.conf. | |
| int | ast_dsp_get_tstate (struct ast_dsp *dsp) |
| Get tstate (Tone State) | |
| int | ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max) |
| Get pending DTMF/MF digits. | |
| int | ast_dsp_init (void) |
| Load dsp settings from dsp.conf. | |
| struct ast_dsp * | ast_dsp_new (void) |
| Allocates a new dsp, assumes 8khz for internal sample rate. | |
| struct ast_dsp * | ast_dsp_new_with_rate (unsigned int sample_rate) |
| Allocates a new dsp with a specific internal sample rate used during processing. | |
| int | ast_dsp_noise (struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise) |
| Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise. | |
| struct ast_frame * | ast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf) |
| Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled. | |
| int | ast_dsp_reload (void) |
| Reloads dsp settings from dsp.conf. | |
| void | ast_dsp_reset (struct ast_dsp *dsp) |
| Reset total silence count. | |
| void | ast_dsp_set_busy_count (struct ast_dsp *dsp, int cadences) |
| Set number of required cadences for busy. | |
| void | ast_dsp_set_busy_pattern (struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence) |
| 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. | |
| 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_silence_with_energy (struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence, int *frames_energy) |
| Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence. Returns the average energy of the samples in the frame in frames_energy variable. | |
| int | ast_dsp_was_muted (struct ast_dsp *dsp) |
| Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio. | |
Convenient Signal Processing routines.
Definition in file dsp.h.
| #define DSP_DIGITMODE_DTMF 0 |
Detect DTMF digits
Definition at line 31 of file dsp.h.
Referenced by __ast_dsp_new(), analog_ss_thread(), ast_dsp_set_digitmode(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), enable_dsp_detect(), mkintf(), and my_dsp_set_digitmode().
| #define DSP_DIGITMODE_MF 1 |
Detect MF digits
Definition at line 32 of file dsp.h.
Referenced by __ast_dsp_new(), analog_ss_thread(), ast_dsp_digitreset(), ast_dsp_process(), ast_dsp_set_digitmode(), and my_dsp_set_digitmode().
| #define DSP_DIGITMODE_MUTECONF (1 << 9) |
Mute conference
Definition at line 35 of file dsp.h.
Referenced by ast_dsp_set_digitmode(), and dahdi_setoption().
| #define DSP_DIGITMODE_MUTEMAX (1 << 10) |
Delay audio by a frame to try to extra quelch
Definition at line 36 of file dsp.h.
Referenced by ast_dsp_set_digitmode(), and dahdi_setoption().
| #define DSP_DIGITMODE_NOQUELCH (1 << 8) |
Do not quelch DTMF from in-band
Definition at line 34 of file dsp.h.
Referenced by ast_dsp_process(), and mgcp_new().
| #define DSP_DIGITMODE_RELAXDTMF (1 << 11) |
"Radio" mode (relaxed DTMF)
Definition at line 37 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_setoption(), enable_dsp_detect(), and process_dahdi().
| #define DSP_FAXMODE_DETECT_CED (1 << 1) |
Definition at line 47 of file dsp.h.
Referenced by ast_dsp_process().
| #define DSP_FAXMODE_DETECT_CNG (1 << 0) |
Definition at line 46 of file dsp.h.
Referenced by __ast_dsp_new(), ast_dsp_process(), and fax_detect_new().
| #define DSP_FAXMODE_DETECT_SQUELCH (1 << 2) |
Definition at line 48 of file dsp.h.
Referenced by ast_fax_detect_init(), and fax_detect_new().
| #define DSP_FEATURE_BUSY_DETECT (1 << 1) |
Definition at line 27 of file dsp.h.
Referenced by ast_dsp_process(), and dahdi_new().
| #define DSP_FEATURE_CALL_PROGRESS (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION) |
Definition at line 43 of file dsp.h.
Referenced by __ast_dsp_call_progress(), ast_dsp_process(), and dahdi_new().
| #define DSP_FEATURE_DIGIT_DETECT (1 << 3) |
Definition at line 28 of file dsp.h.
Referenced by __oh323_new(), ast_dsp_process(), ast_dsp_set_features(), dahdi_new(), disable_dtmf_detect(), enable_dsp_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), and sip_rtp_read().
| #define DSP_FEATURE_FAX_DETECT (1 << 4) |
Definition at line 29 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_handle_dtmf(), dahdi_new(), dahdi_queryoption(), dahdi_setoption(), enable_dsp_detect(), fax_detect_new(), misdn_set_opt_exec(), my_handle_dtmf(), and read_config().
| #define DSP_FEATURE_SILENCE_SUPPRESS (1 << 0) |
Definition at line 26 of file dsp.h.
Referenced by __ast_dsp_new(), and ast_dsp_process().
| #define DSP_FEATURE_WAITDIALTONE (1 << 20) |
Enable dial tone detection
Definition at line 44 of file dsp.h.
Referenced by ast_dsp_process(), dahdi_new(), and dahdi_read().
| #define DSP_PROGRESS_BUSY (1 << 18) |
Enable busy tone detection
Definition at line 41 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_PROGRESS_CONGESTION (1 << 19) |
Enable congestion tone detection
Definition at line 42 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_PROGRESS_RINGING (1 << 17) |
Enable calling tone detection
Definition at line 40 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_PROGRESS_TALK (1 << 16) |
Enable talk detection
Definition at line 39 of file dsp.h.
Referenced by __ast_dsp_call_progress(), and dahdi_new().
| #define DSP_TONE_STATE_BUSY 4 |
Definition at line 55 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_DIALTONE 2 |
Definition at line 53 of file dsp.h.
Referenced by __ast_dsp_call_progress(), and dahdi_read().
| #define DSP_TONE_STATE_HUNGUP 8 |
Definition at line 59 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_RINGING 1 |
Definition at line 52 of file dsp.h.
Referenced by __ast_dsp_call_progress(), and dahdi_read().
| #define DSP_TONE_STATE_SILENCE 0 |
Definition at line 51 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL1 5 |
Definition at line 56 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL2 6 |
Definition at line 57 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_SPECIAL3 7 |
Definition at line 58 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| #define DSP_TONE_STATE_TALKING 3 |
Definition at line 54 of file dsp.h.
Referenced by __ast_dsp_call_progress().
| enum threshold |
Definition at line 70 of file dsp.h.
{
/* Array offsets */
THRESHOLD_SILENCE = 0,
/* Always the last */
THRESHOLD_MAX = 1,
};
| 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 1249 of file dsp.c.
References ast_debug, ast_dsp::busy_cadence, BUSY_MAX, BUSY_MIN, BUSY_PAT_PERCENT, BUSY_PERCENT, ast_dsp::busycount, ast_dsp::busymaybe, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp_busy_pattern::length, MAX, and ast_dsp_busy_pattern::pattern.
Referenced by ast_dsp_process().
{
int res = 0, x;
#ifndef BUSYDETECT_TONEONLY
int avgsilence = 0, hitsilence = 0;
#endif
int avgtone = 0, hittone = 0;
/* if we have a 4 length pattern, the way busymaybe is set doesn't help us. */
if (dsp->busy_cadence.length != 4) {
if (!dsp->busymaybe) {
return res;
}
}
for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
#ifndef BUSYDETECT_TONEONLY
avgsilence += dsp->historicsilence[x];
#endif
avgtone += dsp->historicnoise[x];
}
#ifndef BUSYDETECT_TONEONLY
avgsilence /= dsp->busycount;
#endif
avgtone /= dsp->busycount;
for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
#ifndef BUSYDETECT_TONEONLY
if (avgsilence > dsp->historicsilence[x]) {
if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
hitsilence++;
}
} else {
if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
hitsilence++;
}
}
#endif
if (avgtone > dsp->historicnoise[x]) {
if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
hittone++;
}
} else {
if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
hittone++;
}
}
}
#ifndef BUSYDETECT_TONEONLY
if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
(avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
(avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
#else
if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
#endif
#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
if (avgtone > avgsilence) {
if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
res = 1;
}
} else {
if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
res = 1;
}
}
#else
res = 1;
#endif
}
/* If we have a 4-length pattern, we can go ahead and just check it in a different way. */
if (dsp->busy_cadence.length == 4) {
int x;
int errors = 0;
int errors_max = ((4 * dsp->busycount) / 100.0) * BUSY_PAT_PERCENT;
for (x = DSP_HISTORY - (dsp->busycount); x < DSP_HISTORY; x += 2) {
int temp_error;
temp_error = abs(dsp->historicnoise[x] - dsp->busy_cadence.pattern[0]);
if ((temp_error * 100) / dsp->busy_cadence.pattern[0] > BUSY_PERCENT) {
errors++;
}
temp_error = abs(dsp->historicnoise[x + 1] - dsp->busy_cadence.pattern[2]);
if ((temp_error * 100) / dsp->busy_cadence.pattern[2] > BUSY_PERCENT) {
errors++;
}
temp_error = abs(dsp->historicsilence[x] - dsp->busy_cadence.pattern[1]);
if ((temp_error * 100) / dsp->busy_cadence.pattern[1] > BUSY_PERCENT) {
errors++;
}
temp_error = abs(dsp->historicsilence[x + 1] - dsp->busy_cadence.pattern[3]);
if ((temp_error * 100) / dsp->busy_cadence.pattern[3] > BUSY_PERCENT) {
errors++;
}
}
ast_debug(5, "errors = %d max = %d\n", errors, errors_max);
if (errors <= errors_max) {
return 1;
}
}
/* If we know the expected busy tone length, check we are in the range */
if (res && (dsp->busy_cadence.pattern[0] > 0)) {
if (abs(avgtone - dsp->busy_cadence.pattern[0]) > MAX(dsp->busy_cadence.pattern[0]*BUSY_PAT_PERCENT/100, 20)) {
#ifdef BUSYDETECT_DEBUG
ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
avgtone, dsp->busy_cadence.pattern[0]);
#endif
res = 0;
}
}
#ifndef BUSYDETECT_TONEONLY
/* If we know the expected busy tone silent-period length, check we are in the range */
if (res && (dsp->busy_cadence.pattern[1] > 0)) {
if (abs(avgsilence - dsp->busy_cadence.pattern[1]) > MAX(dsp->busy_cadence.pattern[1]*BUSY_PAT_PERCENT/100, 20)) {
#ifdef BUSYDETECT_DEBUG
ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
avgsilence, dsp->busy_cadence.pattern[1]);
#endif
res = 0;
}
}
#endif
#if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
if (res) {
ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
} else {
ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
}
#endif
return res;
}
| int ast_dsp_call_progress | ( | struct ast_dsp * | dsp, |
| struct ast_frame * | inf | ||
| ) |
Scans for progress indication in audio.
Definition at line 1170 of file dsp.c.
References __ast_dsp_call_progress(), ast_format_is_slinear(), AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.
{
if (inf->frametype != AST_FRAME_VOICE) {
ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
return 0;
}
if (!ast_format_is_slinear(&inf->subclass.format)) {
ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
return 0;
}
return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
}
| 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.
Definition at line 1737 of file dsp.c.
References dtmf_detect_state_t::col_out, digit_detect_state_t::current_digits, dtmf_detect_state_t::current_hit, mf_detect_state_t::current_hit, dtmf_detect_state_t::current_sample, mf_detect_state_t::current_sample, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, DSP_DIGITMODE_MF, digit_detect_state_t::dtmf, ast_dsp::dtmf_began, dtmf_detect_state_t::energy, goertzel_reset(), dtmf_detect_state_t::hits, mf_detect_state_t::hits, dtmf_detect_state_t::lasthit, digit_detect_state_t::mf, dtmf_detect_state_t::misses, dtmf_detect_state_t::row_out, digit_detect_state_t::td, and mf_detect_state_t::tone_out.
Referenced by analog_ss_thread(), and my_dsp_reset_and_flush_digits().
{
int i;
dsp->dtmf_began = 0;
if (dsp->digitmode & DSP_DIGITMODE_MF) {
mf_detect_state_t *s = &dsp->digit_state.td.mf;
/* Reinitialise the detector for the next block */
for (i = 0; i < 6; i++) {
goertzel_reset(&s->tone_out[i]);
}
s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
s->current_sample = 0;
} else {
dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
/* Reinitialise the detector for the next block */
for (i = 0; i < 4; i++) {
goertzel_reset(&s->row_out[i]);
goertzel_reset(&s->col_out[i]);
}
s->lasthit = s->current_hit = 0;
s->energy = 0.0;
s->current_sample = 0;
s->hits = 0;
s->misses = 0;
}
dsp->digit_state.digits[0] = '\0';
dsp->digit_state.current_digits = 0;
}
| void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |
Definition at line 1710 of file dsp.c.
References ast_free.
Referenced by __ast_play_and_record(), __oh323_destroy(), analog_ss_thread(), background_detect_exec(), chan_list_destructor(), cleanup_connection(), conf_run(), dahdi_hangup(), destroy_endpoint(), destroy_faxdetect(), destroy_session(), disable_dsp_detect(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), my_all_subchannels_hungup(), my_dsp_set_digitmode(), record_exec(), set_softmix_bridge_data(), sip_rtp_read(), and softmix_bridge_leave().
{
ast_free(dsp);
}
| unsigned int ast_dsp_get_sample_rate | ( | const struct ast_dsp * | dsp | ) |
Retrieve the sample rate this DSP structure was created with.
Definition at line 1665 of file dsp.c.
References ast_dsp::sample_rate.
{
return dsp->sample_rate;
}
| int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |
Get tcount (Threshold counter)
Definition at line 1830 of file dsp.c.
References ast_dsp::tcount.
Referenced by dahdi_read().
{
return dsp->tcount;
}
| int ast_dsp_get_threshold_from_settings | ( | enum threshold | which | ) |
Get silence threshold from dsp.conf.
Definition at line 1923 of file dsp.c.
Referenced by actual_load_config(), app_exec(), ast_record_review(), conf_rec_name(), conf_run(), do_waiting(), handle_recordfile(), load_config(), record_exec(), and setup_privacy_args().
{
return thresholds[which];
}
| int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |
Get tstate (Tone State)
Definition at line 1825 of file dsp.c.
References ast_dsp::tstate.
Referenced by dahdi_read().
{
return dsp->tstate;
}
| 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 1928 of file dsp.c.
References _dsp_init().
Referenced by main().
{
return _dsp_init(0);
}
| struct ast_dsp* ast_dsp_new | ( | void | ) | [read] |
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition at line 1692 of file dsp.c.
References __ast_dsp_new(), and DEFAULT_SAMPLE_RATE.
Referenced by __ast_play_and_record(), __oh323_new(), background_detect_exec(), conf_run(), dahdi_new(), do_waiting(), enable_dsp_detect(), fax_detect_new(), fax_session_new(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), my_dsp_set_digitmode(), read_config(), and record_exec().
{
return __ast_dsp_new(DEFAULT_SAMPLE_RATE);
}
| struct ast_dsp* ast_dsp_new_with_rate | ( | unsigned int | sample_rate | ) | [read] |
Allocates a new dsp with a specific internal sample rate used during processing.
Definition at line 1697 of file dsp.c.
References __ast_dsp_new().
Referenced by set_softmix_bridge_data().
{
return __ast_dsp_new(sample_rate);
}
| 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.
Definition at line 1442 of file dsp.c.
References ast_dsp_silence_noise_with_energy().
Referenced by do_waiting().
{
return ast_dsp_silence_noise_with_energy(dsp, f, totalnoise, NULL, 1);
}
| struct ast_frame* ast_dsp_process | ( | struct ast_channel * | chan, |
| struct ast_dsp * | dsp, | ||
| struct ast_frame * | inf | ||
| ) | [read] |
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled.
Definition at line 1448 of file dsp.c.
References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), AST_ALAW, ast_alloca, ast_channel_name(), ast_channel_softhangup_internal_flag_add(), 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_is_slinear(), AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), ast_getformatname(), AST_LIN2A, AST_LIN2MU, ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_dsp::ced_tone_state, ast_dsp::cng_tone_state, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, digit_detect_state_t::digitlen, ast_dsp::digitmode, digit_detect_state_t::digits, ast_dsp::display_inband_dtmf_warning, DSP_DIGITMODE_MF, DSP_DIGITMODE_NOQUELCH, DSP_DIGITMODE_RELAXDTMF, DSP_FAXMODE_DETECT_CED, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, DSP_FEATURE_WAITDIALTONE, ast_dsp::dtmf_began, dtmf_detect(), fragment_t::end, ast_dsp::f, ast_dsp::faxmode, ast_dsp::features, ast_frame_subclass::format, ast_frame::frametype, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_format::id, ast_frame_subclass::integer, ast_frame::len, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, ast_frame::ptr, ast_dsp::sample_rate, ast_frame::src, fragment_t::start, ast_frame::subclass, and tone_detect().
Referenced by dahdi_read(), fax_detect_framehook(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), and sip_rtp_read().
{
int silence;
int res;
int digit = 0, fax_digit = 0;
int x;
short *shortdata;
unsigned char *odata;
int len;
struct ast_frame *outf = NULL;
if (!af) {
return NULL;
}
if (af->frametype != AST_FRAME_VOICE) {
return af;
}
odata = af->data.ptr;
len = af->datalen;
/* Make sure we have short data */
if (ast_format_is_slinear(&af->subclass.format)) {
shortdata = af->data.ptr;
len = af->datalen / 2;
} else {
switch (af->subclass.format.id) {
case AST_FORMAT_ULAW:
case AST_FORMAT_TESTLAW:
shortdata = ast_alloca(af->datalen * 2);
for (x = 0;x < len; x++) {
shortdata[x] = AST_MULAW(odata[x]);
}
break;
case AST_FORMAT_ALAW:
shortdata = ast_alloca(af->datalen * 2);
for (x = 0; x < len; x++) {
shortdata[x] = AST_ALAW(odata[x]);
}
break;
default:
/*Display warning only once. Otherwise you would get hundreds of warnings every second */
if (dsp->display_inband_dtmf_warning)
ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(&af->subclass.format));
dsp->display_inband_dtmf_warning = 0;
return af;
}
}
/* Initially we do not want to mute anything */
dsp->mute_fragments = 0;
/* Need to run the silence detection stuff for silence suppression and busy detection */
if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL, NULL);
}
if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = AST_FRAME_NULL;
ast_frfree(af);
return ast_frisolate(&dsp->f);
}
if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = AST_FRAME_CONTROL;
dsp->f.subclass.integer = AST_CONTROL_BUSY;
ast_frfree(af);
ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", ast_channel_name(chan));
return ast_frisolate(&dsp->f);
}
if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
fax_digit = 'f';
}
if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
fax_digit = 'e';
}
}
if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
if (dsp->digitmode & DSP_DIGITMODE_MF) {
digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
} else {
digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
}
if (dsp->digit_state.current_digits) {
int event = 0, event_len = 0;
char event_digit = 0;
if (!dsp->dtmf_began) {
/* We have not reported DTMF_BEGIN for anything yet */
if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
event = AST_FRAME_DTMF_BEGIN;
event_digit = dsp->digit_state.digits[0];
}
dsp->dtmf_began = 1;
} else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
/* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
event = AST_FRAME_DTMF_END;
event_digit = dsp->digit_state.digits[0];
event_len = dsp->digit_state.digitlen[0] * 1000 / dsp->sample_rate;
}
memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
dsp->digit_state.current_digits--;
dsp->dtmf_began = 0;
if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
/* Reset Busy Detector as we have some confirmed activity */
memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
ast_debug(1, "DTMF Detected - Reset busydetector\n");
}
}
if (event) {
memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = event;
dsp->f.subclass.integer = event_digit;
dsp->f.len = event_len;
outf = &dsp->f;
goto done;
}
}
}
if (fax_digit) {
/* Fax was detected - digit is either 'f' or 'e' */
memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = AST_FRAME_DTMF;
dsp->f.subclass.integer = fax_digit;
outf = &dsp->f;
goto done;
}
if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
res = __ast_dsp_call_progress(dsp, shortdata, len);
if (res) {
switch (res) {
case AST_CONTROL_ANSWER:
case AST_CONTROL_BUSY:
case AST_CONTROL_RINGING:
case AST_CONTROL_CONGESTION:
case AST_CONTROL_HANGUP:
memset(&dsp->f, 0, sizeof(dsp->f));
dsp->f.frametype = AST_FRAME_CONTROL;
dsp->f.subclass.integer = res;
dsp->f.src = "dsp_progress";
if (chan) {
ast_queue_frame(chan, &dsp->f);
}
break;
default:
ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
}
}
} else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
res = __ast_dsp_call_progress(dsp, shortdata, len);
}
done:
/* Mute fragment of the frame */
for (x = 0; x < dsp->mute_fragments; x++) {
memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
}
switch (af->subclass.format.id) {
case AST_FORMAT_ULAW:
for (x = 0; x < len; x++) {
odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
}
break;
case AST_FORMAT_ALAW:
for (x = 0; x < len; x++) {
odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
}
/* fall through */
default:
break;
}
if (outf) {
if (chan) {
ast_queue_frame(chan, af);
}
ast_frfree(af);
return ast_frisolate(outf);
} else {
return af;
}
}
| int ast_dsp_reload | ( | void | ) |
Reloads dsp settings from dsp.conf.
Definition at line 1933 of file dsp.c.
References _dsp_init().
{
return _dsp_init(1);
}
| void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |
Reset total silence count.
Definition at line 1768 of file dsp.c.
References ast_dsp::freqs, ast_dsp::gsamps, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp::ringtimeout, ast_dsp::totalsilence, goertzel_state_t::v2, and goertzel_state_t::v3.
Referenced by debug_check_frame_for_silence().
{
int x;
dsp->totalsilence = 0;
dsp->gsamps = 0;
for (x = 0; x < 4; x++) {
dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
}
memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
dsp->ringtimeout= 0;
}
| void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp, |
| int | cadences | ||
| ) |
Set number of required cadences for busy.
Definition at line 1720 of file dsp.c.
References ast_dsp::busycount, cadences, and DSP_HISTORY.
Referenced by dahdi_new().
{
if (cadences < 4) {
cadences = 4;
}
if (cadences > DSP_HISTORY) {
cadences = DSP_HISTORY;
}
dsp->busycount = cadences;
}
| void ast_dsp_set_busy_pattern | ( | struct ast_dsp * | dsp, |
| const struct ast_dsp_busy_pattern * | cadence | ||
| ) |
Set expected lengths of the busy tone.
Definition at line 1731 of file dsp.c.
References ast_debug, ast_dsp::busy_cadence, ast_dsp_busy_pattern::length, and ast_dsp_busy_pattern::pattern.
Referenced by dahdi_new().
| int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp, |
| char * | zone | ||
| ) |
Set zone for doing progress detection.
Definition at line 1806 of file dsp.c.
References aliases, ARRAY_LEN, ast_dsp_prog_reset(), progalias::mode, name, and ast_dsp::progmode.
Referenced by dahdi_new().
| int ast_dsp_set_digitmode | ( | struct ast_dsp * | dsp, |
| int | digitmode | ||
| ) |
Set digit mode.
Definition at line 1782 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, DSP_DIGITMODE_MUTEMAX, and ast_dsp::sample_rate.
Referenced by analog_ss_thread(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), enable_dsp_detect(), mgcp_new(), mkintf(), and my_dsp_set_digitmode().
{
int new;
int old;
old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
if (old != new) {
/* Must initialize structures if switching from MF to DTMF or vice-versa */
ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF, dsp->sample_rate);
}
dsp->digitmode = digitmode;
return 0;
}
| int ast_dsp_set_faxmode | ( | struct ast_dsp * | dsp, |
| int | faxmode | ||
| ) |
Set fax mode.
Definition at line 1797 of file dsp.c.
References ast_fax_detect_init(), and ast_dsp::faxmode.
Referenced by fax_detect_new().
{
if (dsp->faxmode != faxmode) {
dsp->faxmode = faxmode;
ast_fax_detect_init(dsp);
}
return 0;
}
| void ast_dsp_set_features | ( | struct ast_dsp * | dsp, |
| int | features | ||
| ) |
Select feature set.
Definition at line 1702 of file dsp.c.
References ast_dsp::display_inband_dtmf_warning, DSP_FEATURE_DIGIT_DETECT, and ast_dsp::features.
Referenced by __oh323_new(), dahdi_handle_dtmf(), dahdi_new(), dahdi_read(), dahdi_setoption(), disable_dtmf_detect(), enable_dsp_detect(), enable_dtmf_detect(), fax_detect_new(), mgcp_new(), misdn_set_opt_exec(), my_handle_dtmf(), my_pri_ss7_open_media(), read_config(), and sip_rtp_read().
{
dsp->features = features;
if (!(features & DSP_FEATURE_DIGIT_DETECT)) {
dsp->display_inband_dtmf_warning = 0;
}
}
| void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp, |
| int | threshold | ||
| ) |
Set threshold value for silence.
Definition at line 1715 of file dsp.c.
References ast_dsp::threshold.
Referenced by __ast_play_and_record(), do_waiting(), fax_session_new(), handle_recordfile(), isAnsweringMachine(), record_exec(), and set_softmix_bridge_data().
| 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 at line 1437 of file dsp.c.
References ast_dsp_silence_noise_with_energy().
Referenced by __ast_play_and_record(), background_detect_exec(), conf_run(), debug_check_frame_for_silence(), do_waiting(), handle_recordfile(), isAnsweringMachine(), and record_exec().
{
return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, NULL, 0);
}
| int ast_dsp_silence_with_energy | ( | struct ast_dsp * | dsp, |
| struct ast_frame * | f, | ||
| int * | totalsilence, | ||
| int * | frames_energy | ||
| ) |
Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence. Returns the average energy of the samples in the frame in frames_energy variable.
Definition at line 1432 of file dsp.c.
References ast_dsp_silence_noise_with_energy().
Referenced by softmix_bridge_write().
{
return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, frames_energy, 0);
}
| 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 1820 of file dsp.c.
References ast_dsp::mute_fragments.
Referenced by dahdi_read().
{
return (dsp->mute_fragments > 0);
}