Wed Oct 28 11:46:08 2009

Asterisk developer's documentation


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.

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_DTMF_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

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.
int ast_dsp_digitmode (struct ast_dsp *dsp, int digitmode)
 Set digit mode.
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_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.
struct ast_dspast_dsp_new (void)
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.
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, int tonelength, int quietlength)
 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_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.


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_digitmode(), ast_dsp_new(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), mkintf(), 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_digitdetect(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_new(), and ss_thread().

#define DSP_DIGITMODE_MUTECONF   (1 << 9)

Mute conference

Definition at line 35 of file dsp.h.

Referenced by ast_dsp_digitmode(), ast_dsp_process(), 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_digitmode(), ast_dsp_process(), 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 dtmf_detect(), mf_detect(), 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_digitdetect(), dahdi_setoption(), process_dahdi(), 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_digitdetect().

#define DSP_FAXMODE_DETECT_CNG   (1 << 0)

Definition at line 45 of file dsp.h.

Referenced by __ast_dsp_digitdetect(), and ast_dsp_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_DTMF_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_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 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.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_HUNGUP   8

Definition at line 57 of file dsp.h.

Referenced by __ast_dsp_call_progress().

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

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL2   6

Definition at line 55 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL3   7

Definition at line 56 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_TALKING   3

Definition at line 52 of file dsp.h.

Referenced by __ast_dsp_call_progress().


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

References ast_debug, BUSY_MAX, BUSY_MIN, BUSY_PAT_PERCENT, BUSY_PERCENT, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busycount, ast_dsp::busymaybe, DSP_HISTORY, ast_dsp::historicnoise, and ast_dsp::historicsilence.

Referenced by ast_dsp_process().

01080 {
01081    int res = 0, x;
01082 #ifndef BUSYDETECT_TONEONLY
01083    int avgsilence = 0, hitsilence = 0;
01084 #endif
01085    int avgtone = 0, hittone = 0;
01086    if (!dsp->busymaybe)
01087       return res;
01088    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01089 #ifndef BUSYDETECT_TONEONLY
01090       avgsilence += dsp->historicsilence[x];
01091 #endif
01092       avgtone += dsp->historicnoise[x];
01093    }
01094 #ifndef BUSYDETECT_TONEONLY
01095    avgsilence /= dsp->busycount;
01096 #endif
01097    avgtone /= dsp->busycount;
01098    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01099 #ifndef BUSYDETECT_TONEONLY
01100       if (avgsilence > dsp->historicsilence[x]) {
01101          if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01102             hitsilence++;
01103       } else {
01104          if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01105             hitsilence++;
01106       }
01107 #endif
01108       if (avgtone > dsp->historicnoise[x]) {
01109          if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01110             hittone++;
01111       } else {
01112          if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01113             hittone++;
01114       }
01115    }
01116 #ifndef BUSYDETECT_TONEONLY
01117    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 
01118        (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 
01119        (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01120 #else
01121    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01122 #endif
01123 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01124       if (avgtone > avgsilence) {
01125          if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01126             res = 1;
01127       } else {
01128          if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01129             res = 1;
01130       }
01131 #else
01132       res = 1;
01133 #endif
01134    }
01135    /* If we know the expected busy tone length, check we are in the range */
01136    if (res && (dsp->busy_tonelength > 0)) {
01137       if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
01138 #ifdef BUSYDETECT_DEBUG
01139          ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01140             avgtone, dsp->busy_tonelength);
01141 #endif
01142          res = 0;
01143       }
01144    }
01145 #ifndef BUSYDETECT_TONEONLY
01146    /* If we know the expected busy tone silent-period length, check we are in the range */
01147    if (res && (dsp->busy_quietlength > 0)) {
01148       if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01149 #ifdef BUSYDETECT_DEBUG
01150       ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01151          avgsilence, dsp->busy_quietlength);
01152 #endif
01153          res = 0;
01154       }
01155    }
01156 #endif
01157 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
01158    if (res) {
01159       ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01160    } else {
01161       ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01162    }
01163 #endif
01164    return res;
01165 }

int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Scans for progress indication in audio.

Definition at line 1011 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, and ast_frame::subclass.

01012 {
01013    if (inf->frametype != AST_FRAME_VOICE) {
01014       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01015       return 0;
01016    }
01017    if (inf->subclass != AST_FORMAT_SLINEAR) {
01018       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01019       return 0;
01020    }
01021    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01022 }

int ast_dsp_digitdetect ( struct ast_dsp dsp,
struct ast_frame f 
)

Return non-zero if DTMF hit was found.

Definition at line 834 of file dsp.c.

References __ast_dsp_digitdetect(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, s, and ast_frame::subclass.

00835 {
00836    short *s;
00837    int len;
00838    int ign=0;
00839 
00840    if (inf->frametype != AST_FRAME_VOICE) {
00841       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00842       return 0;
00843    }
00844    if (inf->subclass != AST_FORMAT_SLINEAR) {
00845       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00846       return 0;
00847    }
00848    s = inf->data;
00849    len = inf->datalen / 2;
00850    return __ast_dsp_digitdetect(dsp, s, len, &ign);
00851 }

int ast_dsp_digitmode ( struct ast_dsp dsp,
int  digitmode 
)

Set digit mode.

Definition at line 1472 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(), mkintf(), sip_new(), ss_thread(), and store_config().

01473 {
01474    int new;
01475    int old;
01476    
01477    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01478    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01479    if (old != new) {
01480       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01481       ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01482    }
01483    dsp->digitmode = digitmode;
01484    return 0;
01485 }

void ast_dsp_digitreset ( struct ast_dsp dsp  ) 

Reset DTMF detector.

Definition at line 1430 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, dtmf_detect_state_t::energy, goertzel_reset(), mf_detect_state_t::hits, dtmf_detect_state_t::lasthit, digit_detect_state_t::mf, dtmf_detect_state_t::row_out, s, digit_detect_state_t::td, ast_dsp::thinkdigit, and mf_detect_state_t::tone_out.

Referenced by ss_thread().

01431 {
01432    int i;
01433    
01434    dsp->thinkdigit = 0;
01435    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01436       mf_detect_state_t *s = &dsp->digit_state.td.mf;
01437       /* Reinitialise the detector for the next block */
01438       for (i = 0;  i < 6;  i++) {
01439          goertzel_reset(&s->tone_out[i]);
01440       }
01441       s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01442       s->current_sample = 0;
01443    } else {
01444       dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01445       /* Reinitialise the detector for the next block */
01446       for (i = 0;  i < 4;  i++) {
01447          goertzel_reset(&s->row_out[i]);
01448          goertzel_reset(&s->col_out[i]);
01449       }
01450       s->lasthit = s->current_hit = 0;
01451       s->energy = 0.0;
01452       s->current_sample = 0;
01453    }
01454 
01455    dsp->digit_state.digits[0] = '\0';
01456    dsp->digit_state.current_digits = 0;
01457 }

void ast_dsp_free ( struct ast_dsp dsp  ) 

int ast_dsp_get_tcount ( struct ast_dsp dsp  ) 

Get tcount (Threshold counter).

Definition at line 1515 of file dsp.c.

References ast_dsp::tcount.

01516 {
01517    return dsp->tcount;
01518 }

int ast_dsp_get_tstate ( struct ast_dsp dsp  ) 

Get tstate (Tone State).

Definition at line 1510 of file dsp.c.

References ast_dsp::tstate.

01511 {
01512    return dsp->tstate;
01513 }

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

Get pending DTMF/MF digits.

Definition at line 873 of file dsp.c.

References digit_detect_state_t::current_digits, ast_dsp::digit_state, and digit_detect_state_t::digits.

00874 {
00875    if (max > dsp->digit_state.current_digits)
00876       max = dsp->digit_state.current_digits;
00877    if (max > 0) {
00878       memcpy(buf, dsp->digit_state.digits, max);
00879       memmove(dsp->digit_state.digits, dsp->digit_state.digits + max, dsp->digit_state.current_digits - max);
00880       dsp->digit_state.current_digits -= max;
00881    }
00882    buf[max] = '\0';
00883    return  max;
00884 }

struct ast_dsp* ast_dsp_new ( void   )  [read]

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

References __ast_dsp_call_progress(), __ast_dsp_digitdetect(), __ast_dsp_silence(), 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_frfree, ast_frisolate(), ast_getformatname(), ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, 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_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::f, ast_dsp::features, FIX_INF, ast_frame::frametype, len(), LOG_WARNING, ast_channel::name, ast_frame::src, ast_frame::subclass, and ast_dsp::thinkdigit.

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

01186 {
01187    int silence;
01188    int res;
01189    int digit;
01190    int x;
01191    short *shortdata;
01192    unsigned char *odata;
01193    int len;
01194    int writeback = 0;
01195 
01196 #define FIX_INF(inf) do { \
01197       if (writeback) { \
01198          switch (inf->subclass) { \
01199          case AST_FORMAT_SLINEAR: \
01200             break; \
01201          case AST_FORMAT_ULAW: \
01202             for (x=0;x<len;x++) \
01203                odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01204             break; \
01205          case AST_FORMAT_ALAW: \
01206             for (x=0;x<len;x++) \
01207                odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01208             break; \
01209          } \
01210       } \
01211    } while(0) 
01212 
01213    if (!af)
01214       return NULL;
01215    if (af->frametype != AST_FRAME_VOICE)
01216       return af;
01217    odata = af->data;
01218    len = af->datalen;
01219    /* Make sure we have short data */
01220    switch (af->subclass) {
01221    case AST_FORMAT_SLINEAR:
01222       shortdata = af->data;
01223       len = af->datalen / 2;
01224       break;
01225    case AST_FORMAT_ULAW:
01226       shortdata = alloca(af->datalen * 2);
01227       for (x = 0;x < len; x++) 
01228          shortdata[x] = AST_MULAW(odata[x]);
01229       break;
01230    case AST_FORMAT_ALAW:
01231       shortdata = alloca(af->datalen * 2);
01232       for (x = 0; x < len; x++) 
01233          shortdata[x] = AST_ALAW(odata[x]);
01234       break;
01235    default:
01236       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01237       return af;
01238    }
01239    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01240    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01241       memset(&dsp->f, 0, sizeof(dsp->f));
01242       dsp->f.frametype = AST_FRAME_NULL;
01243       ast_frfree(af);
01244       return ast_frisolate(&dsp->f);
01245    }
01246    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01247       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01248       memset(&dsp->f, 0, sizeof(dsp->f));
01249       dsp->f.frametype = AST_FRAME_CONTROL;
01250       dsp->f.subclass = AST_CONTROL_BUSY;
01251       ast_frfree(af);
01252       ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01253       return ast_frisolate(&dsp->f);
01254    }
01255    if (((dsp->features & DSP_FEATURE_DTMF_DETECT) || (dsp->features & DSP_FEATURE_FAX_DETECT))) {
01256       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01257 #if 0
01258       if (digit)
01259          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01260 #endif
01261       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01262          if (!dsp->thinkdigit) {
01263             if (digit) {
01264                /* Looks like we might have something.  
01265                 * Request a conference mute for the moment */
01266                memset(&dsp->f, 0, sizeof(dsp->f));
01267                dsp->f.frametype = AST_FRAME_DTMF;
01268                dsp->f.subclass = 'm';
01269                dsp->thinkdigit = 'x';
01270                FIX_INF(af);
01271                if (chan)
01272                   ast_queue_frame(chan, af);
01273                ast_frfree(af);
01274                return ast_frisolate(&dsp->f);
01275             }
01276          } else {
01277             if (digit) {
01278                /* Thought we saw one last time.  Pretty sure we really have now */
01279                if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01280                   /* If we found a digit, and we're changing digits, go
01281                      ahead and send this one, but DON'T stop confmute because
01282                      we're detecting something else, too... */
01283                   memset(&dsp->f, 0, sizeof(dsp->f));
01284                   dsp->f.frametype = AST_FRAME_DTMF_END;
01285                   dsp->f.subclass = dsp->thinkdigit;
01286                   FIX_INF(af);
01287                   if (chan)
01288                      ast_queue_frame(chan, af);
01289                   ast_frfree(af);
01290                } else {
01291                   dsp->thinkdigit = digit;
01292                   memset(&dsp->f, 0, sizeof(dsp->f));
01293                   dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
01294                   dsp->f.subclass = dsp->thinkdigit;
01295                   FIX_INF(af);
01296                   if (chan)
01297                      ast_queue_frame(chan, af);
01298                   ast_frfree(af);
01299                }
01300                return ast_frisolate(&dsp->f);
01301             } else {
01302                memset(&dsp->f, 0, sizeof(dsp->f));
01303                if (dsp->thinkdigit != 'x') {
01304                   /* If we found a digit, send it now */
01305                   dsp->f.frametype = AST_FRAME_DTMF_END;
01306                   dsp->f.subclass = dsp->thinkdigit;
01307                   dsp->thinkdigit = 0;
01308                } else {
01309                   dsp->f.frametype = AST_FRAME_DTMF;
01310                   dsp->f.subclass = 'u';
01311                   dsp->thinkdigit = 0;
01312                }
01313                FIX_INF(af);
01314                if (chan)
01315                   ast_queue_frame(chan, af);
01316                ast_frfree(af);
01317                return ast_frisolate(&dsp->f);
01318             }
01319          }
01320       } else if (dsp->digit_state.current_digits > 1 ||
01321          (dsp->digit_state.current_digits == 1 && digit != dsp->digit_state.digits[0])) {
01322          /* Since we basically generate DTMF_END frames we do it only when a digit
01323             has finished. */
01324 
01325          memset(&dsp->f, 0, sizeof(dsp->f));
01326          dsp->f.frametype = AST_FRAME_DTMF;
01327          dsp->f.subclass = dsp->digit_state.digits[0];
01328          memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits);
01329          dsp->digit_state.current_digits--;
01330          FIX_INF(af);
01331          if (chan)
01332             ast_queue_frame(chan, af);
01333          ast_frfree(af);
01334          return ast_frisolate(&dsp->f);
01335       }
01336    }
01337    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01338       res = __ast_dsp_call_progress(dsp, shortdata, len);
01339       if (res) {
01340          switch (res) {
01341          case AST_CONTROL_ANSWER:
01342          case AST_CONTROL_BUSY:
01343          case AST_CONTROL_RINGING:
01344          case AST_CONTROL_CONGESTION:
01345          case AST_CONTROL_HANGUP:
01346             memset(&dsp->f, 0, sizeof(dsp->f));
01347             dsp->f.frametype = AST_FRAME_CONTROL;
01348             dsp->f.subclass = res;
01349             dsp->f.src = "dsp_progress";
01350             if (chan) 
01351                ast_queue_frame(chan, &dsp->f);
01352             break;
01353          default:
01354             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01355          }
01356       }
01357    }
01358    FIX_INF(af);
01359    return af;
01360 }

void ast_dsp_reset ( struct ast_dsp dsp  ) 

Reset total silence count.

Definition at line 1459 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.

01460 {
01461    int x;
01462    
01463    dsp->totalsilence = 0;
01464    dsp->gsamps = 0;
01465    for (x=0;x<4;x++)
01466       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01467    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01468    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01469    dsp->ringtimeout= 0;
01470 }

void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Set number of required cadences for busy.

Definition at line 1414 of file dsp.c.

References ast_dsp::busycount, and DSP_HISTORY.

Referenced by dahdi_new().

01415 {
01416    if (cadences < 4)
01417       cadences = 4;
01418    if (cadences > DSP_HISTORY)
01419       cadences = DSP_HISTORY;
01420    dsp->busycount = cadences;
01421 }

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

Set expected lengths of the busy tone.

Definition at line 1423 of file dsp.c.

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

Referenced by dahdi_new().

01424 {
01425    dsp->busy_tonelength = tonelength;
01426    dsp->busy_quietlength = quietlength;
01427    ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01428 }

int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Set zone for doing progress detection.

Definition at line 1496 of file dsp.c.

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

Referenced by dahdi_new().

01497 {
01498    int x;
01499    
01500    for (x = 0; x < ARRAY_LEN(aliases); x++) {
01501       if (!strcasecmp(aliases[x].name, zone)) {
01502          dsp->progmode = aliases[x].mode;
01503          ast_dsp_prog_reset(dsp);
01504          return 0;
01505       }
01506    }
01507    return -1;
01508 }

int ast_dsp_set_faxmode ( struct ast_dsp dsp,
int  faxmode 
)

Set fax mode.

Definition at line 1487 of file dsp.c.

References ast_fax_detect_init(), and ast_dsp::faxmode.

01488 {
01489    if (dsp->faxmode != faxmode) {
01490       ast_fax_detect_init(dsp);
01491    }
01492    dsp->faxmode = faxmode;
01493    return 0;
01494 }

void ast_dsp_set_features ( struct ast_dsp dsp,
int  features 
)

Select feature set.

Definition at line 1399 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(), and store_config().

01400 {
01401    dsp->features = features;
01402 }

void ast_dsp_set_threshold ( struct ast_dsp dsp,
int  threshold 
)

Set threshold value for silence.

Definition at line 1409 of file dsp.c.

References ast_dsp::threshold.

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

01410 {
01411    dsp->threshold = threshold;
01412 }

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

References __ast_dsp_silence(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, s, and ast_frame::subclass.

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

01168 {
01169    short *s;
01170    int len;
01171    
01172    if (f->frametype != AST_FRAME_VOICE) {
01173       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01174       return 0;
01175    }
01176    if (f->subclass != AST_FORMAT_SLINEAR) {
01177       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01178       return 0;
01179    }
01180    s = f->data;
01181    len = f->datalen/2;
01182    return __ast_dsp_silence(dsp, s, len, totalsilence);
01183 }


Generated on Wed Oct 28 11:46:08 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6