Fri Jun 19 12:10:33 2009

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_PROGRESS_BUSY   (1 << 18)
#define DSP_PROGRESS_CONGESTION   (1 << 19)
#define DSP_PROGRESS_RINGING   (1 << 17)
#define DSP_PROGRESS_TALK   (1 << 16)
#define DSP_TONE_STATE_BUSY   4
#define DSP_TONE_STATE_DIALTONE   2
#define DSP_TONE_STATE_HUNGUP   8
#define DSP_TONE_STATE_RINGING   1
#define DSP_TONE_STATE_SILENCE   0
#define DSP_TONE_STATE_SPECIAL1   5
#define DSP_TONE_STATE_SPECIAL2   6
#define DSP_TONE_STATE_SPECIAL3   7
#define DSP_TONE_STATE_TALKING   3

Enumerations

enum  threshold { THRESHOLD_SILENCE = 0, THRESHOLD_MAX = 1 }

Functions

int ast_dsp_busydetect (struct ast_dsp *dsp)
 Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called.
int ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf)
 Scans for progress indication in audio.
int ast_dsp_digitdetect (struct ast_dsp *dsp, struct ast_frame *f)
 Return non-zero if DTMF hit was found.
void ast_dsp_digitreset (struct ast_dsp *dsp)
 Reset DTMF detector.
void ast_dsp_frame_freed (struct ast_frame *fr)
 Hint that a frame from a dsp was freed.
void ast_dsp_free (struct ast_dsp *dsp)
int ast_dsp_get_tcount (struct ast_dsp *dsp)
 Get tcount (Threshold counter).
int ast_dsp_get_threshold_from_settings (enum threshold which)
 Get silence threshold from dsp.conf.
int ast_dsp_get_tstate (struct ast_dsp *dsp)
 Get tstate (Tone State).
int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max)
 Get pending DTMF/MF digits.
int ast_dsp_init (void)
 Load dsp settings from dsp.conf.
ast_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.
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

Detect DTMF digits

Definition at line 31 of file dsp.h.

Referenced by ast_dsp_new(), ast_dsp_set_digitmode(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), sip_new(), ss_thread(), and store_config().

#define DSP_DIGITMODE_MF   1

Detect MF digits

Definition at line 32 of file dsp.h.

Referenced by ast_dsp_digitreset(), ast_dsp_new(), ast_dsp_process(), ast_dsp_set_digitmode(), and ss_thread().

#define DSP_DIGITMODE_MUTECONF   (1 << 9)

Mute conference

Definition at line 35 of file dsp.h.

Referenced by ast_dsp_set_digitmode(), dahdi_setoption(), and store_config().

#define DSP_DIGITMODE_MUTEMAX   (1 << 10)

Delay audio by a frame to try to extra quelch

Definition at line 36 of file dsp.h.

Referenced by ast_dsp_set_digitmode(), and dahdi_setoption().

#define DSP_DIGITMODE_NOQUELCH   (1 << 8)

Do not quelch DTMF from in-band

Definition at line 34 of file dsp.h.

Referenced by ast_dsp_process(), and mgcp_new().

#define DSP_DIGITMODE_RELAXDTMF   (1 << 11)

"Radio" mode (relaxed DTMF)

Definition at line 37 of file dsp.h.

Referenced by ast_dsp_process(), dahdi_setoption(), sip_new(), and store_config().

#define DSP_FAXMODE_DETECT_ALL   (DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED)

Definition at line 47 of file dsp.h.

#define DSP_FAXMODE_DETECT_CED   (1 << 1)

Definition at line 46 of file dsp.h.

Referenced by ast_dsp_process().

#define DSP_FAXMODE_DETECT_CNG   (1 << 0)

Definition at line 45 of file dsp.h.

Referenced by ast_dsp_new(), ast_dsp_process(), and transmit_audio().

#define DSP_FEATURE_BUSY_DETECT   (1 << 1)

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_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(), dahdi_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), sip_new(), and store_config().

#define DSP_FEATURE_FAX_DETECT   (1 << 4)

Definition at line 29 of file dsp.h.

Referenced by ast_dsp_process(), dahdi_new(), misdn_set_opt_exec(), read_config(), and transmit_audio().

#define DSP_FEATURE_SILENCE_SUPPRESS   (1 << 0)

Definition at line 26 of file dsp.h.

Referenced by ast_dsp_new(), and ast_dsp_process().

#define DSP_PROGRESS_BUSY   (1 << 18)

Enable busy tone detection

Definition at line 41 of file dsp.h.

#define DSP_PROGRESS_CONGESTION   (1 << 19)

Enable congestion tone detection

Definition at line 42 of file dsp.h.

#define DSP_PROGRESS_RINGING   (1 << 17)

Enable calling tone detection

Definition at line 40 of file dsp.h.

#define DSP_PROGRESS_TALK   (1 << 16)

Enable talk detection

Definition at line 39 of file dsp.h.

Referenced by dahdi_new().

#define DSP_TONE_STATE_BUSY   4

Definition at line 53 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_DIALTONE   2

Definition at line 51 of file dsp.h.

#define DSP_TONE_STATE_HUNGUP   8

Definition at line 57 of file dsp.h.

#define DSP_TONE_STATE_RINGING   1

Definition at line 50 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SILENCE   0

Definition at line 49 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL1   5

Definition at line 54 of file dsp.h.

#define DSP_TONE_STATE_SPECIAL2   6

Definition at line 55 of file dsp.h.

#define DSP_TONE_STATE_SPECIAL3   7

Definition at line 56 of file dsp.h.

#define DSP_TONE_STATE_TALKING   3

Definition at line 52 of file dsp.h.


Enumeration Type Documentation

enum threshold

Enumerator:
THRESHOLD_SILENCE 
THRESHOLD_MAX 

Definition at line 61 of file dsp.h.

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


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

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

Referenced by ast_dsp_process().

01150 {
01151    int res = 0, x;
01152    int avgsilence = 0, hitsilence = 0;
01153    int avgtone = 0, hittone = 0;
01154 #ifdef DEBUG_DSP_BUSYDETECT
01155    char buf[16];
01156    char silence_list[64]="", tone_list[64]="";
01157 #endif
01158    
01159    if (!dsp->busymaybe)
01160       return res;
01161    dsp->busymaybe = 0;
01162 
01163    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01164       avgsilence += dsp->historicsilence[x];
01165       avgtone += dsp->historicnoise[x];
01166    }
01167    avgsilence /= dsp->busycount;
01168    avgtone /= dsp->busycount;
01169 #ifdef DEBUG_DSP_BUSYDETECT
01170    sprintf(silence_list,"Silences: ");
01171    sprintf(tone_list,"Tones:    ");
01172 #endif
01173    for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) {
01174 #ifdef DEBUG_DSP_BUSYDETECT
01175       snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]);
01176       strcat(silence_list, buf);
01177       snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]);
01178       strcat(tone_list, buf); 
01179 #endif
01180       if (!dsp->busytoneonly) {
01181          if (avgsilence > dsp->historicsilence[x]) {
01182             if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01183                hitsilence++;
01184          } else {
01185             if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01186                hitsilence++;
01187          }
01188       }
01189       if (avgtone > dsp->historicnoise[x]) {
01190          if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01191             hittone++;
01192       } else {
01193          if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01194             hittone++;
01195       }
01196    }
01197 #ifdef DEBUG_DSP_BUSYDETECT
01198    fprintf(stderr, "BUSY DETECTOR\n");   
01199    fprintf(stderr, "%s\n", tone_list);
01200    fprintf(stderr, "%s\n", silence_list)
01201 #endif
01202    if ((dsp->busytoneonly || 
01203        (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) &&
01204       (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01205       if (dsp->busycompare) {
01206            if (dsp->busytoneonly) {
01207              res = 1;
01208             ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare");
01209          } else {
01210               if (avgtone > avgsilence) {
01211                  if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01212                     res = 1;
01213             } else {
01214                  if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01215                    res = 1;
01216             }
01217          }
01218       } else {
01219          res = 1;
01220       }
01221    }
01222    /* If we know the expected busy tone length, check we are in the range */
01223    if (res && (dsp->busy_tonelength > 0)) {
01224       if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100)) {
01225 #ifdef BUSYDETECT_DEBUG
01226          if(option_debug) {
01227             ast_log(LOG_DEBUG, "busy detector: avgtone of %d not close enough to desired %d\n", avgtone, dsp->busy_tonelength);
01228          }
01229 #endif
01230          res = 0;
01231       }
01232    }
01233    /* If we know the expected busy tone silent-period length, check we are in the range */
01234    if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) {
01235       if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100)) {
01236 #ifdef BUSYDETECT_DEBUG
01237          if(option_debug) {
01238             ast_log(LOG_DEBUG, "busy detector: avgsilence of %d not close enough to desired %d\n", avgsilence, dsp->busy_quietlength);
01239          }
01240 #endif
01241          res = 0;
01242       }
01243    }
01244    if (res) {
01245       if (option_debug)
01246          ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01247    } else {
01248       if (option_debug)
01249          ast_log(LOG_NOTICE, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01250    }
01251    return res;
01252 }

int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Scans for progress indication in audio.

Definition at line 1077 of file dsp.c.

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

01078 {
01079    if (inf->frametype != AST_FRAME_VOICE) {
01080       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01081       return 0;
01082    }
01083    if (inf->subclass != AST_FORMAT_SLINEAR) {
01084       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01085       return 0;
01086    }
01087    return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
01088 }

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

References digit_detect_state_t::current_digits, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, DSP_DIGITMODE_MF, digit_detect_state_t::dtmf, ast_dsp::dtmf_began, goertzel_reset(), digit_detect_state_t::mf, s, and digit_detect_state_t::td.

Referenced by ss_thread().

01574 {
01575    int i;
01576    
01577    dsp->dtmf_began = 0;
01578    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01579       mf_detect_state_t *s = &dsp->digit_state.td.mf;
01580       /* Reinitialise the detector for the next block */
01581       for (i = 0;  i < 6;  i++) {
01582          goertzel_reset(&s->tone_out[i]);
01583       }
01584       s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01585       s->current_sample = 0;
01586    } else {
01587       dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01588       /* Reinitialise the detector for the next block */
01589       for (i = 0;  i < 4;  i++) {
01590          goertzel_reset(&s->row_out[i]);
01591          goertzel_reset(&s->col_out[i]);
01592       }
01593       s->lasthit = s->current_hit = 0;
01594       s->energy = 0.0;
01595       s->current_sample = 0;
01596       s->hits = 0;
01597       s->misses = 0;
01598    }
01599 
01600    dsp->digit_state.digits[0] = '\0';
01601    dsp->digit_state.current_digits = 0;
01602 }

void ast_dsp_frame_freed ( struct ast_frame fr  ) 

Hint that a frame from a dsp was freed.

This is called from ast_frame_free if AST_FRFLAG_FROM_DSP is set. This occurs because it is possible for the dsp to be freed while someone still holds a reference to the frame that is in that dsp. This has been known to happen when the dsp on a DAHDI channel detects a busy signal. The channel is hung up, and the application that read the frame to begin with still has a reference to the frame.

Returns:
nothing

Definition at line 1707 of file dsp.c.

References ast_clear_flag, ast_dsp_free(), AST_FRFLAG_FROM_DSP, ast_dsp::destroy, and f.

Referenced by ast_frame_free().

01708 {
01709    struct ast_dsp *dsp;
01710 
01711    ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
01712 
01713    dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f));
01714 
01715    if (!dsp->destroy)
01716       return;
01717    
01718    ast_dsp_free(dsp);
01719 }

void ast_dsp_free ( struct ast_dsp dsp  ) 

Definition at line 1521 of file dsp.c.

References ast_free, AST_FRFLAG_FROM_DSP, ast_test_flag, ast_dsp::destroy, and ast_dsp::f.

Referenced by __ast_play_and_record(), __oh323_destroy(), ast_dsp_frame_freed(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), conf_run(), dahdi_hangup(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_hangup(), sip_dtmfmode(), sip_hangup(), ss_thread(), transmit_audio(), and unload_module().

01522 {
01523    if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) {
01524       /* If this flag is still set, that means that the dsp's destruction 
01525        * been torn down, while we still have a frame out there being used.
01526        * When ast_frfree() gets called on that frame, this ast_trans_pvt
01527        * will get destroyed, too. */
01528 
01529       dsp->destroy = 1;
01530 
01531       return;
01532    }
01533    ast_free(dsp);
01534 }

int ast_dsp_get_tcount ( struct ast_dsp dsp  ) 

Get tcount (Threshold counter).

Definition at line 1665 of file dsp.c.

References ast_dsp::tcount.

01666 {
01667    return dsp->tcount;
01668 }

int ast_dsp_get_threshold_from_settings ( enum threshold  which  ) 

Get silence threshold from dsp.conf.

Since:
1.6.1

Definition at line 1692 of file dsp.c.

References thresholds.

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

01693 {
01694    return thresholds[which];
01695 }

int ast_dsp_get_tstate ( struct ast_dsp dsp  ) 

Get tstate (Tone State).

Definition at line 1660 of file dsp.c.

References ast_dsp::tstate.

01661 {
01662    return dsp->tstate;
01663 }

int ast_dsp_getdigits ( struct ast_dsp dsp,
char *  buf,
int  max 
)

Get pending DTMF/MF digits.

int ast_dsp_init ( void   ) 

Load dsp settings from dsp.conf.

Since:
1.6.1

Definition at line 1697 of file dsp.c.

References _dsp_init().

Referenced by main().

01698 {
01699    return _dsp_init(0);
01700 }

struct ast_dsp* ast_dsp_new ( void   ) 

Definition at line 1482 of file dsp.c.

References ast_calloc, ast_digit_detect_init(), ast_dsp_prog_reset(), ast_fax_detect_init(), BUSY_PAT_PERCENT, DEFAULT_THRESHOLD, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, and ast_dsp::threshold.

Referenced by __ast_play_and_record(), __oh323_new(), background_detect_exec(), conf_run(), dahdi_new(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), sip_new(), store_config(), and transmit_audio().

01483 {
01484    struct ast_dsp *dsp;
01485    
01486    if ((dsp = ast_calloc(1, sizeof(*dsp)))) {      
01487       dsp->threshold = DEFAULT_THRESHOLD;
01488       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01489       dsp->busycount = DSP_HISTORY;
01490       dsp->digitmode = DSP_DIGITMODE_DTMF;
01491       dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01492       dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT;
01493 #ifdef BUSYDETECT_TONEONLY
01494       dsp->busytoneonly = 1;
01495 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01496 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
01497 #endif
01498 #else
01499    dsp->busytoneonly = 0;
01500 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01501    dsp->busycompare = 1;
01502 #else
01503    dsp->busycompare = 0;
01504 #endif
01505 #endif
01506       /* Initialize digit detector */
01507       ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01508       /* Initialize initial DSP progress detect parameters */
01509       ast_dsp_prog_reset(dsp);
01510       /* Initialize fax detector */
01511       ast_fax_detect_init(dsp);
01512    }
01513    return dsp;
01514 }

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

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), f, len(), LOG_WARNING, and s.

Referenced by do_waiting().

01273 {
01274        short *s;
01275        int len;
01276 
01277        if (f->frametype != AST_FRAME_VOICE) {
01278                ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
01279                return 0;
01280        }
01281        if (f->subclass != AST_FORMAT_SLINEAR) {
01282                ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
01283                return 0;
01284        }
01285        s = f->data.ptr;
01286        len = f->datalen/2;
01287        return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
01288 }

struct ast_frame* ast_dsp_process ( struct ast_channel chan,
struct ast_dsp dsp,
struct ast_frame inf 
)

Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled.

Definition at line 1291 of file dsp.c.

References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), ast_channel::_softhangup, AST_ALAW, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_debug, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRFLAG_FROM_DSP, ast_frfree, ast_getformatname(), AST_LIN2A, AST_LIN2MU, ast_log(), AST_MULAW, ast_queue_frame(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_dsp::ced_tone_state, chan, ast_dsp::cng_tone_state, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, DSP_DIGITMODE_MF, DSP_DIGITMODE_NOQUELCH, DSP_DIGITMODE_RELAXDTMF, DSP_FAXMODE_DETECT_CED, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::dtmf_began, dtmf_detect(), fragment_t::end, ast_dsp::f, ast_dsp::faxmode, ast_dsp::features, ast_frame::frametype, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, ast_channel::name, ast_frame::ptr, ast_frame::src, fragment_t::start, ast_frame::subclass, and tone_detect().

Referenced by dahdi_read(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), sip_rtp_read(), transmit_audio(), and usbradio_read().

01292 {
01293    int silence;
01294    int res;
01295    int digit = 0, fax_digit = 0;
01296    int x;
01297    short *shortdata;
01298    unsigned char *odata;
01299    int len;
01300    struct ast_frame *outf = NULL;
01301 
01302    if (!af)
01303       return NULL;
01304    if (af->frametype != AST_FRAME_VOICE)
01305       return af;
01306 
01307    odata = af->data.ptr;
01308    len = af->datalen;
01309    /* Make sure we have short data */
01310    switch (af->subclass) {
01311    case AST_FORMAT_SLINEAR:
01312       shortdata = af->data.ptr;
01313       len = af->datalen / 2;
01314       break;
01315    case AST_FORMAT_ULAW:
01316       shortdata = alloca(af->datalen * 2);
01317       for (x = 0;x < len; x++) 
01318          shortdata[x] = AST_MULAW(odata[x]);
01319       break;
01320    case AST_FORMAT_ALAW:
01321       shortdata = alloca(af->datalen * 2);
01322       for (x = 0; x < len; x++) 
01323          shortdata[x] = AST_ALAW(odata[x]);
01324       break;
01325    default:
01326       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01327       return af;
01328    }
01329 
01330    /* Initially we do not want to mute anything */
01331    dsp->mute_fragments = 0;
01332 
01333    /* Need to run the silence detection stuff for silence suppression and busy detection */
01334    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01335       res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
01336    }
01337 
01338    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01339       memset(&dsp->f, 0, sizeof(dsp->f));
01340       dsp->f.frametype = AST_FRAME_NULL;
01341       ast_frfree(af);
01342       ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01343       return &dsp->f;
01344    }
01345    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01346       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01347       memset(&dsp->f, 0, sizeof(dsp->f));
01348       dsp->f.frametype = AST_FRAME_CONTROL;
01349       dsp->f.subclass = AST_CONTROL_BUSY;
01350       ast_frfree(af);
01351       ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01352       ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01353       return &dsp->f;
01354    }
01355 
01356    if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01357       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01358          fax_digit = 'f';
01359       }
01360 
01361       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01362          fax_digit = 'e';
01363       }
01364    }
01365 
01366    if ((dsp->features & DSP_FEATURE_DIGIT_DETECT)) {
01367       if ((dsp->digitmode & DSP_DIGITMODE_MF))
01368          digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01369       else
01370          digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01371 
01372       if (dsp->digit_state.current_digits) {
01373          int event = 0;
01374          char event_digit = 0;
01375 
01376          if (!dsp->dtmf_began) {
01377             /* We have not reported DTMF_BEGIN for anything yet */
01378 
01379             event = AST_FRAME_DTMF_BEGIN;
01380             event_digit = dsp->digit_state.digits[0];
01381             dsp->dtmf_began = 1;
01382 
01383          } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01384             /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
01385    
01386             event = AST_FRAME_DTMF_END;
01387             event_digit = dsp->digit_state.digits[0];
01388             memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits);
01389             dsp->digit_state.current_digits--;
01390             dsp->dtmf_began = 0;
01391          }
01392 
01393          if (event) {
01394             memset(&dsp->f, 0, sizeof(dsp->f));
01395             dsp->f.frametype = event;
01396             dsp->f.subclass = event_digit;
01397             outf = &dsp->f;
01398             goto done;
01399          }
01400       }
01401    }
01402 
01403    if (fax_digit) {
01404       /* Fax was detected - digit is either 'f' or 'e' */
01405 
01406       memset(&dsp->f, 0, sizeof(dsp->f));
01407       dsp->f.frametype = AST_FRAME_DTMF;
01408       dsp->f.subclass = fax_digit;
01409       outf = &dsp->f;
01410       goto done;
01411    }
01412 
01413    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01414       res = __ast_dsp_call_progress(dsp, shortdata, len);
01415       if (res) {
01416          switch (res) {
01417          case AST_CONTROL_ANSWER:
01418          case AST_CONTROL_BUSY:
01419          case AST_CONTROL_RINGING:
01420          case AST_CONTROL_CONGESTION:
01421          case AST_CONTROL_HANGUP:
01422             memset(&dsp->f, 0, sizeof(dsp->f));
01423             dsp->f.frametype = AST_FRAME_CONTROL;
01424             dsp->f.subclass = res;
01425             dsp->f.src = "dsp_progress";
01426             if (chan) 
01427                ast_queue_frame(chan, &dsp->f);
01428             break;
01429          default:
01430             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01431          }
01432       }
01433    }
01434 
01435 done:
01436    /* Mute fragment of the frame */
01437    for (x = 0; x < dsp->mute_fragments; x++) {
01438       memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01439    }
01440 
01441    switch (af->subclass) {
01442    case AST_FORMAT_SLINEAR:
01443       break;
01444    case AST_FORMAT_ULAW:
01445       for (x = 0; x < len; x++)
01446          odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01447       break;
01448    case AST_FORMAT_ALAW:
01449       for (x = 0; x < len; x++)
01450          odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01451       break;
01452    }
01453 
01454    if (outf) {
01455       if (chan) 
01456          ast_queue_frame(chan, af);
01457       ast_frfree(af);
01458       ast_set_flag(outf, AST_FRFLAG_FROM_DSP);
01459       return outf;
01460    } else {
01461       return af;
01462    }
01463 }

int ast_dsp_reload ( void   ) 

Reloads dsp settings from dsp.conf.

Since:
1.6.1

Definition at line 1702 of file dsp.c.

References _dsp_init().

01703 {
01704    return _dsp_init(1);
01705 }

void ast_dsp_reset ( struct ast_dsp dsp  ) 

Reset total silence count.

Definition at line 1604 of file dsp.c.

References ast_dsp::freqs, ast_dsp::gsamps, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp::ringtimeout, ast_dsp::totalsilence, goertzel_state_t::v2, and goertzel_state_t::v3.

01605 {
01606    int x;
01607    
01608    dsp->totalsilence = 0;
01609    dsp->gsamps = 0;
01610    for (x=0;x<4;x++)
01611       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01612    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01613    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01614    dsp->ringtimeout= 0;
01615 }

void ast_dsp_set_busy_compare ( struct ast_dsp dsp,
int  compare 
)

Set if silence and noice lengths must be compared for busy.

Definition at line 1553 of file dsp.c.

References ast_dsp::busycompare.

Referenced by dahdi_new().

01554 {
01555   if (compare > 0)
01556       dsp->busycompare = 1;
01557   else
01558       dsp->busycompare = 0;
01559 }

void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Set number of required cadences for busy.

Definition at line 1544 of file dsp.c.

References ast_dsp::busycount, and DSP_HISTORY.

Referenced by dahdi_new().

01545 {
01546    if (cadences < 4)
01547       cadences = 4;
01548    if (cadences > DSP_HISTORY)
01549       cadences = DSP_HISTORY;
01550    dsp->busycount = cadences;
01551 }

void ast_dsp_set_busy_pattern ( struct ast_dsp dsp,
int  tonelength,
int  quietlength,
int  fuzzy 
)

Set expected lengths of the busy tones.

Definition at line 1561 of file dsp.c.

References ast_debug, ast_dsp::busy_pattern_fuzzy, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, and ast_dsp::busytoneonly.

Referenced by dahdi_new().

01562 {
01563    dsp->busy_tonelength = tonelength;
01564    if (quietlength > 0)
01565       dsp->busy_quietlength = quietlength;
01566    else 
01567      dsp->busytoneonly = 1;
01568    ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01569    if( fuzzy > 0 && fuzzy < 50 ) 
01570       dsp->busy_pattern_fuzzy = fuzzy;
01571 }

int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Set zone for doing progress detection.

Definition at line 1641 of file dsp.c.

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

Referenced by dahdi_new().

01642 {
01643    int x;
01644    
01645    for (x = 0; x < ARRAY_LEN(aliases); x++) {
01646       if (!strcasecmp(aliases[x].name, zone)) {
01647          dsp->progmode = aliases[x].mode;
01648          ast_dsp_prog_reset(dsp);
01649          return 0;
01650       }
01651    }
01652    return -1;
01653 }

int ast_dsp_set_digitmode ( struct ast_dsp dsp,
int  digitmode 
)

Set digit mode.

Version:
1.6.1 renamed from ast_dsp_digitmode to ast_dsp_set_digitmode

Definition at line 1617 of file dsp.c.

References ast_digit_detect_init(), ast_dsp::digit_state, ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, and DSP_DIGITMODE_MUTEMAX.

Referenced by dahdi_hangup(), dahdi_new(), dahdi_setoption(), mgcp_new(), sip_new(), ss_thread(), and store_config().

01618 {
01619    int new;
01620    int old;
01621    
01622    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01623    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01624    if (old != new) {
01625       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01626       ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01627    }
01628    dsp->digitmode = digitmode;
01629    return 0;
01630 }

int ast_dsp_set_faxmode ( struct ast_dsp dsp,
int  faxmode 
)

Set fax mode.

Definition at line 1632 of file dsp.c.

References ast_fax_detect_init(), and ast_dsp::faxmode.

Referenced by transmit_audio().

01633 {
01634    if (dsp->faxmode != faxmode) {
01635       ast_fax_detect_init(dsp);
01636    }
01637    dsp->faxmode = faxmode;
01638    return 0;
01639 }

void ast_dsp_set_features ( struct ast_dsp dsp,
int  features 
)

Select feature set.

Definition at line 1516 of file dsp.c.

References ast_dsp::features.

Referenced by __oh323_new(), dahdi_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), read_config(), sip_dtmfmode(), sip_new(), store_config(), and transmit_audio().

01517 {
01518    dsp->features = features;
01519 }

void ast_dsp_set_threshold ( struct ast_dsp dsp,
int  threshold 
)

Set threshold value for silence.

Definition at line 1536 of file dsp.c.

References ast_dsp::threshold.

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

01537 {
01538    if (threshold < 256)
01539      dsp->threshold = 256;
01540    else
01541      dsp->threshold = threshold;
01542 }

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

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), f, len(), LOG_WARNING, and s.

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

01255 {
01256    short *s;
01257    int len;
01258    
01259    if (f->frametype != AST_FRAME_VOICE) {
01260       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01261       return 0;
01262    }
01263    if (f->subclass != AST_FORMAT_SLINEAR) {
01264       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01265       return 0;
01266    }
01267    s = f->data.ptr;
01268    len = f->datalen/2;
01269    return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
01270 }

int ast_dsp_was_muted ( struct ast_dsp dsp  ) 

Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio.

Since:
1.6.1

Definition at line 1655 of file dsp.c.

References ast_dsp::mute_fragments.

Referenced by dahdi_read().

01656 {
01657    return (dsp->mute_fragments > 0);
01658 }


Generated on Fri Jun 19 12:10:33 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7