Tue Aug 20 16:35:02 2013

Asterisk developer's documentation


dsp.h File Reference

Convenient Signal Processing routines. More...

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_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_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)
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_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.

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

#define DSP_FAXMODE_DETECT_ALL   (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED)

Definition at line 48 of file dsp.h.

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

#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 54 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_DIALTONE   2

Definition at line 52 of file dsp.h.

Referenced by __ast_dsp_call_progress(), and dahdi_read().

#define DSP_TONE_STATE_HUNGUP   8

Definition at line 58 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_RINGING   1

Definition at line 51 of file dsp.h.

Referenced by __ast_dsp_call_progress(), and dahdi_read().

#define DSP_TONE_STATE_SILENCE   0

Definition at line 50 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL1   5

Definition at line 55 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL2   6

Definition at line 56 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL3   7

Definition at line 57 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_TALKING   3

Definition at line 53 of file dsp.h.

Referenced by __ast_dsp_call_progress().


Enumeration Type Documentation

enum threshold
Enumerator:
THRESHOLD_SILENCE 
THRESHOLD_MAX 

Definition at line 62 of file dsp.h.

00062                {
00063    /* Array offsets */
00064    THRESHOLD_SILENCE = 0,
00065    /* Always the last */
00066    THRESHOLD_MAX = 1,
00067 };


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

References ast_debug, ast_log(), BUSY_MAX, BUSY_MIN, ast_dsp::busy_pattern_fuzzy, BUSY_PERCENT, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busycompare, ast_dsp::busycount, ast_dsp::busymaybe, ast_dsp::busytoneonly, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::historicsilence, LOG_ERROR, LOG_NOTICE, MAX, and option_debug.

Referenced by ast_dsp_process().

01251 {
01252    int res = 0, x;
01253    int avgsilence = 0, hitsilence = 0;
01254    int avgtone = 0, hittone = 0;
01255 #ifdef DEBUG_DSP_BUSYDETECT
01256    char buf[16];
01257    char silence_list[64]="", tone_list[64]="";
01258 #endif
01259    
01260    if (!dsp->busymaybe) {
01261       return res;
01262    }
01263    dsp->busymaybe = 0;
01264 
01265    for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01266       avgsilence += dsp->historicsilence[x];
01267       avgtone += dsp->historicnoise[x];
01268    }
01269    avgsilence /= dsp->busycount;
01270    avgtone /= dsp->busycount;
01271 #ifdef DEBUG_DSP_BUSYDETECT
01272    sprintf(silence_list,"Silences: ");
01273    sprintf(tone_list,"Tones:    ");
01274 #endif
01275    for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) {
01276 #ifdef DEBUG_DSP_BUSYDETECT
01277       snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]);
01278       strcat(silence_list, buf);
01279       snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]);
01280       strcat(tone_list, buf); 
01281 #endif
01282       if (!dsp->busytoneonly) {
01283          if (avgsilence > dsp->historicsilence[x]) {
01284             if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01285                hitsilence++;
01286          } else {
01287             if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01288                hitsilence++;
01289          }
01290       }
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 #ifdef DEBUG_DSP_BUSYDETECT
01302    fprintf(stderr, "BUSY DETECTOR\n");   
01303    fprintf(stderr, "%s\n", tone_list);
01304    fprintf(stderr, "%s\n", silence_list)
01305 #endif
01306    if ((dsp->busytoneonly || 
01307        (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) &&
01308       (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01309       if (dsp->busycompare) {
01310            if (dsp->busytoneonly) {
01311              res = 1;
01312             ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare");
01313          } else {
01314               if (avgtone > avgsilence) {
01315                  if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01316                     res = 1;
01317             } else {
01318                  if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01319                    res = 1;
01320             }
01321          }
01322       } else {
01323          res = 1;
01324       }
01325    }
01326    /* If we know the expected busy tone length, check we are in the range */
01327    if (res && (dsp->busy_tonelength > 0)) {
01328       if (abs(avgtone - dsp->busy_tonelength) > MAX(dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100, 20)) {
01329 #ifdef BUSYDETECT_DEBUG
01330          ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01331             avgtone, dsp->busy_tonelength);
01332 #endif
01333          res = 0;
01334       }
01335    }
01336    /* If we know the expected busy tone silent-period length, check we are in the range */
01337    if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) {
01338       if (abs(avgsilence - dsp->busy_quietlength) > MAX(dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100, 20)) {
01339 #ifdef BUSYDETECT_DEBUG
01340       ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01341          avgsilence, dsp->busy_quietlength);
01342 #endif
01343          res = 0;
01344       }
01345    }
01346    if (res) {
01347       if (option_debug)
01348          ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01349    } else {
01350       ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01351    }
01352    return res;
01353 }

int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Scans for progress indication in audio.

Definition at line 1174 of file dsp.c.

References __ast_dsp_call_progress(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

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

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

01695 {
01696    int i;
01697    
01698    dsp->dtmf_began = 0;
01699    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01700       mf_detect_state_t *s = &dsp->digit_state.td.mf;
01701       /* Reinitialise the detector for the next block */
01702       for (i = 0;  i < 6;  i++) {
01703          goertzel_reset(&s->tone_out[i]);
01704       }
01705       s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01706       s->current_sample = 0;
01707    } else {
01708       dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01709       /* Reinitialise the detector for the next block */
01710       for (i = 0;  i < 4;  i++) {
01711          goertzel_reset(&s->row_out[i]);
01712          goertzel_reset(&s->col_out[i]);
01713       }
01714       s->lasthit = s->current_hit = 0;
01715       s->energy = 0.0;
01716       s->current_sample = 0;
01717       s->hits = 0;
01718       s->misses = 0;
01719    }
01720 
01721    dsp->digit_state.digits[0] = '\0';
01722    dsp->digit_state.current_digits = 0;
01723 }

void ast_dsp_free ( struct ast_dsp dsp  ) 
int ast_dsp_get_tcount ( struct ast_dsp dsp  ) 

Get tcount (Threshold counter).

Definition at line 1787 of file dsp.c.

References ast_dsp::tcount.

Referenced by dahdi_read().

01788 {
01789    return dsp->tcount;
01790 }

int ast_dsp_get_threshold_from_settings ( enum threshold  which  ) 

Get silence threshold from dsp.conf.

Since:
1.6.1

Definition at line 1880 of file dsp.c.

Referenced by actual_load_config(), app_exec(), ast_record_review(), conf_run(), do_waiting(), handle_recordfile(), load_config(), record_exec(), and setup_privacy_args().

01881 {
01882    return thresholds[which];
01883 }

int ast_dsp_get_tstate ( struct ast_dsp dsp  ) 

Get tstate (Tone State).

Definition at line 1782 of file dsp.c.

References ast_dsp::tstate.

Referenced by dahdi_read().

01783 {
01784    return dsp->tstate;
01785 }

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

References _dsp_init().

Referenced by main().

01886 {
01887    return _dsp_init(0);
01888 }

struct ast_dsp* ast_dsp_new ( void   )  [read]

Definition at line 1607 of file dsp.c.

References ast_calloc, ast_digit_detect_init(), ast_dsp_prog_reset(), ast_fax_detect_init(), BUSY_PAT_PERCENT, ast_dsp::busy_pattern_fuzzy, ast_dsp::busycompare, ast_dsp::busycount, ast_dsp::busytoneonly, DEFAULT_THRESHOLD, ast_dsp::digit_state, ast_dsp::digitmode, ast_dsp::display_inband_dtmf_warning, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, ast_dsp::faxmode, ast_dsp::features, and ast_dsp::threshold.

Referenced by __ast_play_and_record(), __oh323_new(), background_detect_exec(), conf_run(), dahdi_new(), do_waiting(), enable_dsp_detect(), fax_session_new(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), my_dsp_set_digitmode(), read_config(), and record_exec().

01608 {
01609    struct ast_dsp *dsp;
01610    
01611    if ((dsp = ast_calloc(1, sizeof(*dsp)))) {      
01612       dsp->threshold = DEFAULT_THRESHOLD;
01613       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01614       dsp->busycount = DSP_HISTORY;
01615       dsp->digitmode = DSP_DIGITMODE_DTMF;
01616       dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01617       dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT;
01618 #ifdef BUSYDETECT_TONEONLY
01619       dsp->busytoneonly = 1;
01620 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01621 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
01622 #endif
01623 #else
01624    dsp->busytoneonly = 0;
01625 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01626    dsp->busycompare = 1;
01627 #else
01628    dsp->busycompare = 0;
01629 #endif
01630 #endif
01631       /* Initialize digit detector */
01632       ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01633       dsp->display_inband_dtmf_warning = 1;
01634       /* Initialize initial DSP progress detect parameters */
01635       ast_dsp_prog_reset(dsp);
01636       /* Initialize fax detector */
01637       ast_fax_detect_init(dsp);
01638    }
01639    return dsp;
01640 }

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

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

Referenced by do_waiting().

01374 {
01375        short *s;
01376        int len;
01377 
01378        if (f->frametype != AST_FRAME_VOICE) {
01379                ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
01380                return 0;
01381        }
01382        if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01383                ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
01384                return 0;
01385        }
01386        s = f->data.ptr;
01387        len = f->datalen/2;
01388        return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
01389 }

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

References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), ast_channel::_softhangup, AST_ALAW, ast_alloca, 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_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, ast_frame_subclass::codec, 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::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, ast_frame::ptr, SAMPLE_RATE, 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(), and sip_rtp_read().

01393 {
01394    int silence;
01395    int res;
01396    int digit = 0, fax_digit = 0;
01397    int x;
01398    short *shortdata;
01399    unsigned char *odata;
01400    int len;
01401    struct ast_frame *outf = NULL;
01402 
01403    if (!af) {
01404       return NULL;
01405    }
01406    if (af->frametype != AST_FRAME_VOICE) {
01407       return af;
01408    }
01409 
01410    odata = af->data.ptr;
01411    len = af->datalen;
01412    /* Make sure we have short data */
01413    switch (af->subclass.codec) {
01414    case AST_FORMAT_SLINEAR:
01415       shortdata = af->data.ptr;
01416       len = af->datalen / 2;
01417       break;
01418    case AST_FORMAT_ULAW:
01419    case AST_FORMAT_TESTLAW:
01420       shortdata = ast_alloca(af->datalen * 2);
01421       for (x = 0;x < len; x++) {
01422          shortdata[x] = AST_MULAW(odata[x]);
01423       }
01424       break;
01425    case AST_FORMAT_ALAW:
01426       shortdata = ast_alloca(af->datalen * 2);
01427       for (x = 0; x < len; x++) {
01428          shortdata[x] = AST_ALAW(odata[x]);
01429       }
01430       break;
01431    default:
01432       /*Display warning only once. Otherwise you would get hundreds of warnings every second */
01433       if (dsp->display_inband_dtmf_warning)
01434          ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
01435       dsp->display_inband_dtmf_warning = 0;
01436       return af;
01437    }
01438 
01439    /* Initially we do not want to mute anything */
01440    dsp->mute_fragments = 0;
01441 
01442    /* Need to run the silence detection stuff for silence suppression and busy detection */
01443    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01444       res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
01445    }
01446 
01447    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01448       memset(&dsp->f, 0, sizeof(dsp->f));
01449       dsp->f.frametype = AST_FRAME_NULL;
01450       ast_frfree(af);
01451       return ast_frisolate(&dsp->f);
01452    }
01453    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01454       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01455       memset(&dsp->f, 0, sizeof(dsp->f));
01456       dsp->f.frametype = AST_FRAME_CONTROL;
01457       /* Signal this as it was a channel hangup, to avoid msg "channel.c:3473 ast_waitfordigit_full: Unexpected control subclass '5'" */
01458       dsp->f.subclass.integer = AST_CONTROL_HANGUP;
01459       ast_frfree(af);
01460       ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01461       return ast_frisolate(&dsp->f);
01462    }
01463 
01464    if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01465       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01466          fax_digit = 'f';
01467       }
01468 
01469       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01470          fax_digit = 'e';
01471       }
01472    }
01473 
01474    if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
01475       if (dsp->digitmode & DSP_DIGITMODE_MF)
01476          digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01477       else
01478          digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01479 
01480       if (dsp->digit_state.current_digits) {
01481          int event = 0, event_len = 0;
01482          char event_digit = 0;
01483 
01484          if (!dsp->dtmf_began) {
01485             /* We have not reported DTMF_BEGIN for anything yet */
01486 
01487             if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01488                event = AST_FRAME_DTMF_BEGIN;
01489                event_digit = dsp->digit_state.digits[0];
01490             }
01491             dsp->dtmf_began = 1;
01492 
01493          } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01494             /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
01495             if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01496                event = AST_FRAME_DTMF_END;
01497                event_digit = dsp->digit_state.digits[0];
01498                event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
01499             }
01500             memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
01501             memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
01502             dsp->digit_state.current_digits--;
01503             dsp->dtmf_began = 0;
01504 
01505             if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
01506                /* Reset Busy Detector as we have some confirmed activity */ 
01507                memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01508                memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01509                ast_debug(1, "DTMF Detected - Reset busydetector\n");
01510             }
01511          }
01512 
01513          if (event) {
01514             memset(&dsp->f, 0, sizeof(dsp->f));
01515             dsp->f.frametype = event;
01516             dsp->f.subclass.integer = event_digit;
01517             dsp->f.len = event_len;
01518             outf = &dsp->f;
01519             goto done;
01520          }
01521       }
01522    }
01523 
01524    if (fax_digit) {
01525       /* Fax was detected - digit is either 'f' or 'e' */
01526 
01527       memset(&dsp->f, 0, sizeof(dsp->f));
01528       dsp->f.frametype = AST_FRAME_DTMF;
01529       dsp->f.subclass.integer = fax_digit;
01530       outf = &dsp->f;
01531       goto done;
01532    }
01533 
01534    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01535       res = __ast_dsp_call_progress(dsp, shortdata, len);
01536       if (res) {
01537          switch (res) {
01538          case AST_CONTROL_ANSWER:
01539          case AST_CONTROL_BUSY:
01540          case AST_CONTROL_RINGING:
01541          case AST_CONTROL_CONGESTION:
01542          case AST_CONTROL_HANGUP:
01543             memset(&dsp->f, 0, sizeof(dsp->f));
01544             dsp->f.frametype = AST_FRAME_CONTROL;
01545             dsp->f.subclass.integer = res;
01546             dsp->f.src = "dsp_progress";
01547             if (chan) 
01548                ast_queue_frame(chan, &dsp->f);
01549             break;
01550          default:
01551             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01552          }
01553       }
01554    } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
01555       res = __ast_dsp_call_progress(dsp, shortdata, len);
01556    }
01557 
01558 done:
01559    /* Mute fragment of the frame */
01560    for (x = 0; x < dsp->mute_fragments; x++) {
01561       memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01562    }
01563 
01564    switch (af->subclass.codec) {
01565    case AST_FORMAT_SLINEAR:
01566       break;
01567    case AST_FORMAT_ULAW:
01568       for (x = 0; x < len; x++) {
01569          odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01570       }
01571       break;
01572    case AST_FORMAT_ALAW:
01573       for (x = 0; x < len; x++) {
01574          odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01575       }
01576       break;
01577    }
01578 
01579    if (outf) {
01580       if (chan) {
01581          ast_queue_frame(chan, af);
01582       }
01583       ast_frfree(af);
01584       return ast_frisolate(outf);
01585    } else {
01586       return af;
01587    }
01588 }

int ast_dsp_reload ( void   ) 

Reloads dsp settings from dsp.conf.

Since:
1.6.1

Definition at line 1890 of file dsp.c.

References _dsp_init().

01891 {
01892    return _dsp_init(1);
01893 }

void ast_dsp_reset ( struct ast_dsp dsp  ) 

Reset total silence count.

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

01726 {
01727    int x;
01728    
01729    dsp->totalsilence = 0;
01730    dsp->gsamps = 0;
01731    for (x = 0; x < 4; x++) {
01732       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01733    }
01734    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01735    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01736    dsp->ringtimeout= 0;
01737 }

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

References ast_dsp::busycompare.

Referenced by dahdi_new().

01675 {
01676   if (compare > 0)
01677       dsp->busycompare = 1;
01678   else
01679       dsp->busycompare = 0;
01680 }

void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Set number of required cadences for busy.

Definition at line 1663 of file dsp.c.

References ast_dsp::busycount, and DSP_HISTORY.

Referenced by dahdi_new().

01664 {
01665    if (cadences < 4) {
01666       cadences = 4;
01667    }
01668    if (cadences > DSP_HISTORY) {
01669       cadences = DSP_HISTORY;
01670    }
01671    dsp->busycount = cadences;
01672 }

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

01683 {
01684    dsp->busy_tonelength = tonelength;
01685    if (quietlength > 0)
01686       dsp->busy_quietlength = quietlength;
01687    else 
01688      dsp->busytoneonly = 1;
01689    ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01690    if( fuzzy > 0 && fuzzy < 50 ) 
01691       dsp->busy_pattern_fuzzy = fuzzy;
01692 }

int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Set zone for doing progress detection.

Definition at line 1763 of file dsp.c.

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

Referenced by dahdi_new().

01764 {
01765    int x;
01766    
01767    for (x = 0; x < ARRAY_LEN(aliases); x++) {
01768       if (!strcasecmp(aliases[x].name, zone)) {
01769          dsp->progmode = aliases[x].mode;
01770          ast_dsp_prog_reset(dsp);
01771          return 0;
01772       }
01773    }
01774    return -1;
01775 }

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 1739 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 analog_ss_thread(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), enable_dsp_detect(), mgcp_new(), mkintf(), and my_dsp_set_digitmode().

01740 {
01741    int new;
01742    int old;
01743    
01744    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01745    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01746    if (old != new) {
01747       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01748       ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01749    }
01750    dsp->digitmode = digitmode;
01751    return 0;
01752 }

int ast_dsp_set_faxmode ( struct ast_dsp dsp,
int  faxmode 
)

Set fax mode.

Definition at line 1754 of file dsp.c.

References ast_fax_detect_init(), and ast_dsp::faxmode.

01755 {
01756    if (dsp->faxmode != faxmode) {
01757       ast_fax_detect_init(dsp);
01758    }
01759    dsp->faxmode = faxmode;
01760    return 0;
01761 }

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.

Definition at line 1655 of file dsp.c.

References ast_dsp::threshold.

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

01656 {
01657    if (threshold < 256)
01658      dsp->threshold = 256;
01659    else
01660      dsp->threshold = threshold;
01661 }

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

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

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

01356 {
01357    short *s;
01358    int len;
01359    
01360    if (f->frametype != AST_FRAME_VOICE) {
01361       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01362       return 0;
01363    }
01364    if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01365       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01366       return 0;
01367    }
01368    s = f->data.ptr;
01369    len = f->datalen/2;
01370    return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
01371 }

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

References ast_dsp::mute_fragments.

Referenced by dahdi_read().

01778 {
01779    return (dsp->mute_fragments > 0);
01780 }


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1