dsp.h File Reference

Convenient Signal Processing routines. More...

This graph shows which files directly or indirectly include this file:

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)
int ast_dsp_get_features (struct ast_dsp *dsp)
 Get features.
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_dspast_dsp_new (void)
 Allocates a new dsp, assumes 8khz for internal sample rate.
struct ast_dspast_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_frameast_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.


Detailed Description

Convenient Signal Processing routines.

Definition in file dsp.h.


Define Documentation

#define DSP_DIGITMODE_DTMF   0

#define DSP_DIGITMODE_MF   1

#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(), mbl_load_device(), ooh323_new(), and process_dahdi().

#define DSP_FAXMODE_DETECT_ALL   (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED)

Definition at line 49 of file dsp.h.

#define DSP_FAXMODE_DETECT_CED   (1 << 1)

Definition at line 47 of file dsp.h.

Referenced by ast_dsp_process(), and ooh323_new().

#define DSP_FAXMODE_DETECT_CNG   (1 << 0)

Definition at line 46 of file dsp.h.

Referenced by __ast_dsp_new(), ast_dsp_process(), fax_detect_new(), and ooh323_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)

#define DSP_FEATURE_FAX_DETECT   (1 << 4)

#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().


Enumeration Type Documentation

enum threshold

Enumerator:
THRESHOLD_SILENCE 
THRESHOLD_MAX 

Definition at line 70 of file dsp.h.

00070                {
00071    /* Array offsets */
00072    THRESHOLD_SILENCE = 0,
00073    /* Always the last */
00074    THRESHOLD_MAX = 1,
00075 };


Function Documentation

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 1254 of file dsp.c.

References abs, 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().

01255 {
01256    int res = 0, x;
01257 #ifndef BUSYDETECT_TONEONLY
01258    int avgsilence = 0, hitsilence = 0;
01259 #endif
01260    int avgtone = 0, hittone = 0;
01261 
01262    /* if we have a 4 length pattern, the way busymaybe is set doesn't help us. */
01263    if (dsp->busy_cadence.length != 4) {
01264       if (!dsp->busymaybe) {
01265          return res;
01266       }
01267    }
01268 
01269    for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01270 #ifndef BUSYDETECT_TONEONLY
01271       avgsilence += dsp->historicsilence[x];
01272 #endif
01273       avgtone += dsp->historicnoise[x];
01274    }
01275 #ifndef BUSYDETECT_TONEONLY
01276    avgsilence /= dsp->busycount;
01277 #endif
01278    avgtone /= dsp->busycount;
01279    for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01280 #ifndef BUSYDETECT_TONEONLY
01281       if (avgsilence > dsp->historicsilence[x]) {
01282          if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
01283             hitsilence++;
01284          }
01285       } else {
01286          if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
01287             hitsilence++;
01288          }
01289       }
01290 #endif
01291       if (avgtone > dsp->historicnoise[x]) {
01292          if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
01293             hittone++;
01294          }
01295       } else {
01296          if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
01297             hittone++;
01298          }
01299       }
01300    }
01301 #ifndef BUSYDETECT_TONEONLY
01302    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
01303        (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
01304        (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01305 #else
01306    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01307 #endif
01308 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01309       if (avgtone > avgsilence) {
01310          if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
01311             res = 1;
01312          }
01313       } else {
01314          if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
01315             res = 1;
01316          }
01317       }
01318 #else
01319       res = 1;
01320 #endif
01321    }
01322 
01323    /* If we have a 4-length pattern, we can go ahead and just check it in a different way. */
01324    if (dsp->busy_cadence.length == 4) {
01325       int x;
01326       int errors = 0;
01327       int errors_max = ((4 * dsp->busycount) / 100.0) * BUSY_PAT_PERCENT;
01328 
01329       for (x = DSP_HISTORY - (dsp->busycount); x < DSP_HISTORY; x += 2) {
01330          int temp_error;
01331          temp_error = abs(dsp->historicnoise[x] - dsp->busy_cadence.pattern[0]);
01332          if ((temp_error * 100) / dsp->busy_cadence.pattern[0] > BUSY_PERCENT) {
01333             errors++;
01334          }
01335 
01336          temp_error = abs(dsp->historicnoise[x + 1] - dsp->busy_cadence.pattern[2]);
01337          if ((temp_error * 100) / dsp->busy_cadence.pattern[2] > BUSY_PERCENT) {
01338             errors++;
01339          }
01340 
01341          temp_error = abs(dsp->historicsilence[x] - dsp->busy_cadence.pattern[1]);
01342          if ((temp_error * 100) / dsp->busy_cadence.pattern[1] > BUSY_PERCENT) {
01343             errors++;
01344          }
01345 
01346          temp_error = abs(dsp->historicsilence[x + 1] - dsp->busy_cadence.pattern[3]);
01347          if ((temp_error * 100) / dsp->busy_cadence.pattern[3] > BUSY_PERCENT) {
01348             errors++;
01349          }
01350       }
01351 
01352       ast_debug(5, "errors = %d  max = %d\n", errors, errors_max);
01353 
01354       if (errors <= errors_max) {
01355          return 1;
01356       }
01357    }
01358 
01359    /* If we know the expected busy tone length, check we are in the range */
01360    if (res && (dsp->busy_cadence.pattern[0] > 0)) {
01361       if (abs(avgtone - dsp->busy_cadence.pattern[0]) > MAX(dsp->busy_cadence.pattern[0]*BUSY_PAT_PERCENT/100, 20)) {
01362 #ifdef BUSYDETECT_DEBUG
01363          ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01364             avgtone, dsp->busy_cadence.pattern[0]);
01365 #endif
01366          res = 0;
01367       }
01368    }
01369 #ifndef BUSYDETECT_TONEONLY
01370    /* If we know the expected busy tone silent-period length, check we are in the range */
01371    if (res && (dsp->busy_cadence.pattern[1] > 0)) {
01372       if (abs(avgsilence - dsp->busy_cadence.pattern[1]) > MAX(dsp->busy_cadence.pattern[1]*BUSY_PAT_PERCENT/100, 20)) {
01373 #ifdef BUSYDETECT_DEBUG
01374       ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01375          avgsilence, dsp->busy_cadence.pattern[1]);
01376 #endif
01377          res = 0;
01378       }
01379    }
01380 #endif
01381 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
01382    if (res) {
01383       ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01384    } else {
01385       ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01386    }
01387 #endif
01388    return res;
01389 }

int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Scans for progress indication in audio.

Definition at line 1175 of file dsp.c.

References __ast_dsp_call_progress(), ast_format_cache_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.

01176 {
01177    if (inf->frametype != AST_FRAME_VOICE) {
01178       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01179       return 0;
01180    }
01181    if (!ast_format_cache_is_slinear(inf->subclass.format)) {
01182       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01183       return 0;
01184    }
01185    return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
01186 }

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 1739 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(), mbl_new(), and my_dsp_reset_and_flush_digits().

01740 {
01741    int i;
01742 
01743    dsp->dtmf_began = 0;
01744    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01745       mf_detect_state_t *s = &dsp->digit_state.td.mf;
01746       /* Reinitialise the detector for the next block */
01747       for (i = 0; i < 6; i++) {
01748          goertzel_reset(&s->tone_out[i]);
01749       }
01750       s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = 0;
01751       s->current_hit = 0;
01752       s->current_sample = 0;
01753    } else {
01754       dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01755       /* Reinitialise the detector for the next block */
01756       for (i = 0; i < 4; i++) {
01757          goertzel_reset(&s->row_out[i]);
01758          goertzel_reset(&s->col_out[i]);
01759       }
01760       s->lasthit = 0;
01761       s->current_hit = 0;
01762       s->energy = 0.0;
01763       s->current_sample = 0;
01764       s->hits = 0;
01765       s->misses = 0;
01766    }
01767 
01768    dsp->digit_state.digits[0] = '\0';
01769    dsp->digit_state.current_digits = 0;
01770 }

void ast_dsp_free ( struct ast_dsp dsp  ) 

int ast_dsp_get_features ( struct ast_dsp dsp  ) 

Get features.

Definition at line 1706 of file dsp.c.

References ast_dsp::features.

Referenced by set_caps().

01707 {
01708         return (dsp->features);
01709 }

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 1659 of file dsp.c.

References ast_dsp::sample_rate.

01660 {
01661    return dsp->sample_rate;
01662 }

int ast_dsp_get_tcount ( struct ast_dsp dsp  ) 

Get tcount (Threshold counter).

Definition at line 1834 of file dsp.c.

References ast_dsp::tcount.

Referenced by dahdi_read().

01835 {
01836    return dsp->tcount;
01837 }

int ast_dsp_get_threshold_from_settings ( enum threshold  which  ) 

Get silence threshold from dsp.conf.

Since:
1.6.1
Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 1927 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(), setup_privacy_args(), and talk_detect_fn_write().

01928 {
01929    return thresholds[which];
01930 }

int ast_dsp_get_tstate ( struct ast_dsp dsp  ) 

Get tstate (Tone State).

Definition at line 1829 of file dsp.c.

References ast_dsp::tstate.

Referenced by dahdi_read().

01830 {
01831    return dsp->tstate;
01832 }

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.

Since:
1.6.1

Definition at line 1932 of file dsp.c.

References _dsp_init().

Referenced by main().

01933 {
01934    return _dsp_init(0);
01935 }

struct ast_dsp* ast_dsp_new ( void   )  [read]

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 1692 of file dsp.c.

References __ast_dsp_new().

Referenced by set_softmix_bridge_data(), and set_talk_detect().

01693 {
01694    return __ast_dsp_new(sample_rate);
01695 }

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.

Since:
1.6.1

Definition at line 1446 of file dsp.c.

References ast_dsp_silence_noise_with_energy(), and NULL.

Referenced by do_waiting().

01447 {
01448    return ast_dsp_silence_noise_with_energy(dsp, f, totalnoise, NULL, 1);
01449 }

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 1452 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_cache_is_slinear(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_get_name(), 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_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, digit, 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_frame_subclass::integer, ast_frame::len, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, NULL, ast_frame::ptr, ast_dsp::sample_rate, ast_frame::src, fragment_t::start, ast_frame::subclass, and tone_detect().

Referenced by chan_pjsip_read(), dahdi_read(), fax_detect_framehook(), mbl_read(), mgcp_rtp_read(), ooh323_rtp_read(), process_ast_dsp(), and sip_rtp_read().

01453 {
01454    int silence;
01455    int res;
01456    int digit = 0, fax_digit = 0;
01457    int x;
01458    short *shortdata;
01459    unsigned char *odata;
01460    int len;
01461    struct ast_frame *outf = NULL;
01462 
01463    if (!af) {
01464       return NULL;
01465    }
01466    if (af->frametype != AST_FRAME_VOICE) {
01467       return af;
01468    }
01469 
01470    odata = af->data.ptr;
01471    len = af->datalen;
01472    /* Make sure we have short data */
01473    if (ast_format_cache_is_slinear(af->subclass.format)) {
01474       shortdata = af->data.ptr;
01475       len = af->datalen / 2;
01476    } else if (ast_format_cmp(af->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
01477       shortdata = ast_alloca(af->datalen * 2);
01478       for (x = 0; x < len; x++) {
01479          shortdata[x] = AST_MULAW(odata[x]);
01480       }
01481    } else if (ast_format_cmp(af->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
01482       shortdata = ast_alloca(af->datalen * 2);
01483       for (x = 0; x < len; x++) {
01484          shortdata[x] = AST_ALAW(odata[x]);
01485       }
01486    } else {
01487       /*Display warning only once. Otherwise you would get hundreds of warnings every second */
01488       if (dsp->display_inband_dtmf_warning) {
01489          ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_format_get_name(af->subclass.format));
01490       }
01491       dsp->display_inband_dtmf_warning = 0;
01492       return af;
01493    }
01494 
01495    /* Initially we do not want to mute anything */
01496    dsp->mute_fragments = 0;
01497 
01498    /* Need to run the silence detection stuff for silence suppression and busy detection */
01499    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01500       res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL, NULL);
01501    }
01502 
01503    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01504       memset(&dsp->f, 0, sizeof(dsp->f));
01505       dsp->f.frametype = AST_FRAME_NULL;
01506       ast_frfree(af);
01507       return ast_frisolate(&dsp->f);
01508    }
01509    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01510       ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
01511       memset(&dsp->f, 0, sizeof(dsp->f));
01512       dsp->f.frametype = AST_FRAME_CONTROL;
01513       dsp->f.subclass.integer = AST_CONTROL_BUSY;
01514       ast_frfree(af);
01515       ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", ast_channel_name(chan));
01516       return ast_frisolate(&dsp->f);
01517    }
01518 
01519    if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01520       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01521          fax_digit = 'f';
01522       }
01523 
01524       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01525          fax_digit = 'e';
01526       }
01527    }
01528 
01529    if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
01530       if (dsp->digitmode & DSP_DIGITMODE_MF) {
01531          digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01532       } else {
01533          digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01534       }
01535 
01536       if (dsp->digit_state.current_digits) {
01537          int event = 0, event_len = 0;
01538          char event_digit = 0;
01539 
01540          if (!dsp->dtmf_began) {
01541             /* We have not reported DTMF_BEGIN for anything yet */
01542 
01543             if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01544                event = AST_FRAME_DTMF_BEGIN;
01545                event_digit = dsp->digit_state.digits[0];
01546             }
01547             dsp->dtmf_began = 1;
01548 
01549          } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01550             /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
01551             if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01552                event = AST_FRAME_DTMF_END;
01553                event_digit = dsp->digit_state.digits[0];
01554                event_len = dsp->digit_state.digitlen[0] * 1000 / dsp->sample_rate;
01555             }
01556             memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
01557             memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
01558             dsp->digit_state.current_digits--;
01559             dsp->dtmf_began = 0;
01560 
01561             if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
01562                /* Reset Busy Detector as we have some confirmed activity */
01563                memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01564                memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01565                ast_debug(1, "DTMF Detected - Reset busydetector\n");
01566             }
01567          }
01568 
01569          if (event) {
01570             memset(&dsp->f, 0, sizeof(dsp->f));
01571             dsp->f.frametype = event;
01572             dsp->f.subclass.integer = event_digit;
01573             dsp->f.len = event_len;
01574             outf = &dsp->f;
01575             goto done;
01576          }
01577       }
01578    }
01579 
01580    if (fax_digit) {
01581       /* Fax was detected - digit is either 'f' or 'e' */
01582 
01583       memset(&dsp->f, 0, sizeof(dsp->f));
01584       dsp->f.frametype = AST_FRAME_DTMF;
01585       dsp->f.subclass.integer = fax_digit;
01586       outf = &dsp->f;
01587       goto done;
01588    }
01589 
01590    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01591       res = __ast_dsp_call_progress(dsp, shortdata, len);
01592       if (res) {
01593          switch (res) {
01594          case AST_CONTROL_ANSWER:
01595          case AST_CONTROL_BUSY:
01596          case AST_CONTROL_RINGING:
01597          case AST_CONTROL_CONGESTION:
01598          case AST_CONTROL_HANGUP:
01599             memset(&dsp->f, 0, sizeof(dsp->f));
01600             dsp->f.frametype = AST_FRAME_CONTROL;
01601             dsp->f.subclass.integer = res;
01602             dsp->f.src = "dsp_progress";
01603             if (chan) {
01604                ast_queue_frame(chan, &dsp->f);
01605             }
01606             break;
01607          default:
01608             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01609          }
01610       }
01611    } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
01612       res = __ast_dsp_call_progress(dsp, shortdata, len);
01613    }
01614 
01615 done:
01616    /* Mute fragment of the frame */
01617    for (x = 0; x < dsp->mute_fragments; x++) {
01618       memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01619    }
01620 
01621    if (ast_format_cmp(af->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
01622       for (x = 0; x < len; x++) {
01623          odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01624       }
01625    } else if (ast_format_cmp(af->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
01626       for (x = 0; x < len; x++) {
01627          odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01628       }
01629    }
01630 
01631    if (outf) {
01632       if (chan) {
01633          ast_queue_frame(chan, af);
01634       }
01635       ast_frfree(af);
01636       return ast_frisolate(outf);
01637    } else {
01638       return af;
01639    }
01640 }

int ast_dsp_reload ( void   ) 

Reloads dsp settings from dsp.conf.

Since:
1.6.1

Definition at line 1937 of file dsp.c.

References _dsp_init().

01938 {
01939    return _dsp_init(1);
01940 }

void ast_dsp_reset ( struct ast_dsp dsp  ) 

Reset total silence count.

Definition at line 1772 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().

01773 {
01774    int x;
01775 
01776    dsp->totalsilence = 0;
01777    dsp->gsamps = 0;
01778    for (x = 0; x < 4; x++) {
01779       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01780    }
01781    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01782    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01783    dsp->ringtimeout = 0;
01784 }

void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Set number of required cadences for busy.

Definition at line 1722 of file dsp.c.

References ast_dsp::busycount, and DSP_HISTORY.

Referenced by dahdi_new().

01723 {
01724    if (cadences < 4) {
01725       cadences = 4;
01726    }
01727    if (cadences > DSP_HISTORY) {
01728       cadences = DSP_HISTORY;
01729    }
01730    dsp->busycount = cadences;
01731 }

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 1733 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().

01734 {
01735    dsp->busy_cadence = *cadence;
01736    ast_debug(1, "dsp busy pattern set to %d,%d,%d,%d\n", cadence->pattern[0], cadence->pattern[1], (cadence->length == 4) ? cadence->pattern[2] : 0, (cadence->length == 4) ? cadence->pattern[3] : 0);
01737 }

int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Set zone for doing progress detection.

Definition at line 1810 of file dsp.c.

References aliases, ARRAY_LEN, ast_dsp_prog_reset(), name, and ast_dsp::progmode.

Referenced by dahdi_new().

01811 {
01812    int x;
01813 
01814    for (x = 0; x < ARRAY_LEN(aliases); x++) {
01815       if (!strcasecmp(aliases[x].name, zone)) {
01816          dsp->progmode = aliases[x].mode;
01817          ast_dsp_prog_reset(dsp);
01818          return 0;
01819       }
01820    }
01821    return -1;
01822 }

int ast_dsp_set_digitmode ( struct ast_dsp dsp,
int  digitmode 
)

Set digit mode.

Version:
1.6.1 renamed from ast_dsp_digitmode to ast_dsp_set_digitmode

Definition at line 1786 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(), mbl_load_device(), mgcp_new(), mkintf(), my_dsp_set_digitmode(), and ooh323_new().

01787 {
01788    int new;
01789    int old;
01790 
01791    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01792    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01793    if (old != new) {
01794       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01795       ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF, dsp->sample_rate);
01796    }
01797    dsp->digitmode = digitmode;
01798    return 0;
01799 }

int ast_dsp_set_faxmode ( struct ast_dsp dsp,
int  faxmode 
)

Set fax mode.

Definition at line 1801 of file dsp.c.

References ast_fax_detect_init(), and ast_dsp::faxmode.

Referenced by fax_detect_new(), and ooh323_new().

01802 {
01803    if (dsp->faxmode != faxmode) {
01804       dsp->faxmode = faxmode;
01805       ast_fax_detect_init(dsp);
01806    }
01807    return 0;
01808 }

void ast_dsp_set_features ( struct ast_dsp dsp,
int  features 
)

void ast_dsp_set_threshold ( struct ast_dsp dsp,
int  threshold 
)

Set threshold value for silence.

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 1717 of file dsp.c.

References ast_dsp::threshold.

Referenced by __ast_play_and_record(), do_waiting(), fax_session_new(), handle_recordfile(), isAnsweringMachine(), record_exec(), set_softmix_bridge_data(), and set_talk_detect().

01718 {
01719    dsp->threshold = threshold;
01720 }

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.

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 1441 of file dsp.c.

References ast_dsp_silence_noise_with_energy(), and NULL.

Referenced by __ast_play_and_record(), background_detect_exec(), conf_run(), debug_check_frame_for_silence(), do_waiting(), handle_recordfile(), isAnsweringMachine(), record_exec(), and talk_detect_audiohook_cb().

01442 {
01443    return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, NULL, 0);
01444 }

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 1436 of file dsp.c.

References ast_dsp_silence_noise_with_energy().

Referenced by softmix_bridge_write_voice().

01437 {
01438    return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, frames_energy, 0);
01439 }

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.

Since:
1.6.1

Definition at line 1824 of file dsp.c.

References ast_dsp::mute_fragments.

Referenced by dahdi_read().

01825 {
01826    return (dsp->mute_fragments > 0);
01827 }


Generated on Thu Apr 16 06:30:47 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6