Mon Mar 20 08:20:25 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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_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.
ast_dspast_dsp_new (void)
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.
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
 

Definition at line 31 of file dsp.h.

Referenced by ast_dsp_digitmode(), i4l_answer(), i4l_startrec(), mkif(), mkintf(), sip_new(), ss_thread(), zt_hangup(), zt_new(), and zt_setoption().

#define DSP_DIGITMODE_MF   1
 

Definition at line 32 of file dsp.h.

Referenced by ast_dsp_digitmode(), and ss_thread().

#define DSP_DIGITMODE_MUTECONF   (1 << 9)
 

Definition at line 35 of file dsp.h.

Referenced by ast_dsp_digitmode(), ast_dsp_process(), and zt_setoption().

#define DSP_DIGITMODE_MUTEMAX   (1 << 10)
 

Definition at line 36 of file dsp.h.

Referenced by zt_setoption().

#define DSP_DIGITMODE_NOQUELCH   (1 << 8)
 

Definition at line 34 of file dsp.h.

Referenced by mgcp_new().

#define DSP_DIGITMODE_RELAXDTMF   (1 << 11)
 

Definition at line 37 of file dsp.h.

Referenced by __ast_dsp_digitdetect(), mkif(), sip_new(), and zt_setoption().

#define DSP_FEATURE_BUSY_DETECT   (1 << 1)
 

Definition at line 27 of file dsp.h.

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

#define DSP_FEATURE_DTMF_DETECT   (1 << 3)
 

Definition at line 28 of file dsp.h.

Referenced by __oh323_new(), i4l_answer(), i4l_startrec(), mgcp_new(), misdn_set_opt_exec(), mkif(), sip_dtmfmode(), and sip_new().

#define DSP_FEATURE_FAX_DETECT   (1 << 4)
 

Definition at line 29 of file dsp.h.

Referenced by __ast_dsp_digitdetect(), i4l_answer(), i4l_startrec(), and misdn_set_opt_exec().

#define DSP_FEATURE_SILENCE_SUPPRESS   (1 << 0)
 

Definition at line 26 of file dsp.h.

#define DSP_PROGRESS_BUSY   (1 << 18)
 

Definition at line 41 of file dsp.h.

#define DSP_PROGRESS_CONGESTION   (1 << 19)
 

Definition at line 42 of file dsp.h.

#define DSP_PROGRESS_RINGING   (1 << 17)
 

Definition at line 40 of file dsp.h.

#define DSP_PROGRESS_TALK   (1 << 16)
 

Definition at line 39 of file dsp.h.

#define DSP_TONE_STATE_BUSY   4
 

Definition at line 49 of file dsp.h.

#define DSP_TONE_STATE_DIALTONE   2
 

Definition at line 47 of file dsp.h.

#define DSP_TONE_STATE_HUNGUP   8
 

Definition at line 53 of file dsp.h.

#define DSP_TONE_STATE_RINGING   1
 

Definition at line 46 of file dsp.h.

#define DSP_TONE_STATE_SILENCE   0
 

Definition at line 45 of file dsp.h.

#define DSP_TONE_STATE_SPECIAL1   5
 

Definition at line 50 of file dsp.h.

#define DSP_TONE_STATE_SPECIAL2   6
 

Definition at line 51 of file dsp.h.

#define DSP_TONE_STATE_SPECIAL3   7
 

Definition at line 52 of file dsp.h.

#define DSP_TONE_STATE_TALKING   3
 

Definition at line 48 of file dsp.h.


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

References ast_log(), BUSY_MIN, BUSY_PAT_PERCENT, BUSY_PERCENT, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busycount, ast_dsp::busymaybe, dsp, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::historicsilence, LOG_DEBUG, and LOG_NOTICE.

Referenced by ast_dsp_process().

01214 {
01215    int res = 0, x;
01216 #ifndef BUSYDETECT_TONEONLY
01217    int avgsilence = 0, hitsilence = 0;
01218 #endif
01219    int avgtone = 0, hittone = 0;
01220    if (!dsp->busymaybe)
01221       return res;
01222    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01223 #ifndef BUSYDETECT_TONEONLY
01224       avgsilence += dsp->historicsilence[x];
01225 #endif
01226       avgtone += dsp->historicnoise[x];
01227    }
01228 #ifndef BUSYDETECT_TONEONLY
01229    avgsilence /= dsp->busycount;
01230 #endif
01231    avgtone /= dsp->busycount;
01232    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01233 #ifndef BUSYDETECT_TONEONLY
01234       if (avgsilence > dsp->historicsilence[x]) {
01235          if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01236             hitsilence++;
01237       } else {
01238          if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01239             hitsilence++;
01240       }
01241 #endif
01242       if (avgtone > dsp->historicnoise[x]) {
01243          if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01244             hittone++;
01245       } else {
01246          if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01247             hittone++;
01248       }
01249    }
01250 #ifndef BUSYDETECT_TONEONLY
01251    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 
01252        (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 
01253        (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01254 #else
01255    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01256 #endif
01257 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01258 #ifdef BUSYDETECT_TONEONLY
01259 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01260 #endif
01261       if (avgtone > avgsilence) {
01262          if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01263             res = 1;
01264       } else {
01265          if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01266             res = 1;
01267       }
01268 #else
01269       res = 1;
01270 #endif
01271    }
01272    /* If we know the expected busy tone length, check we are in the range */
01273    if (res && (dsp->busy_tonelength > 0)) {
01274       if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
01275 #if 0
01276          ast_log(LOG_NOTICE, "busy detector: avgtone of %d not close enough to desired %d\n",
01277                   avgtone, dsp->busy_tonelength);
01278 #endif
01279          res = 0;
01280       }
01281    }
01282    /* If we know the expected busy tone silent-period length, check we are in the range */
01283    if (res && (dsp->busy_quietlength > 0)) {
01284       if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01285 #if 0
01286          ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
01287                   avgsilence, dsp->busy_quietlength);
01288 #endif
01289          res = 0;
01290       }
01291    }
01292 #if 1
01293    if (res)
01294       ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01295 #endif
01296    return res;
01297 }

int ast_dsp_call_progress struct ast_dsp dsp,
struct ast_frame inf
 

Scans for progress indication in audio.

Definition at line 1144 of file dsp.c.

References __ast_dsp_call_progress(), ast_log(), ast_frame::data, ast_frame::datalen, dsp, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.

01145 {
01146    if (inf->frametype != AST_FRAME_VOICE) {
01147       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01148       return 0;
01149    }
01150    if (inf->subclass != AST_FORMAT_SLINEAR) {
01151       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01152       return 0;
01153    }
01154    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01155 }

int ast_dsp_digitdetect struct ast_dsp dsp,
struct ast_frame f
 

Return non-zero if DTMF hit was found.

Definition at line 967 of file dsp.c.

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

00968 {
00969    short *s;
00970    int len;
00971    int ign=0;
00972 
00973    if (inf->frametype != AST_FRAME_VOICE) {
00974       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00975       return 0;
00976    }
00977    if (inf->subclass != AST_FORMAT_SLINEAR) {
00978       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00979       return 0;
00980    }
00981    s = inf->data;
00982    len = inf->datalen / 2;
00983    return __ast_dsp_digitdetect(dsp, s, len, &ign);
00984 }

int ast_dsp_digitmode struct ast_dsp dsp,
int  digitmode
 

Set digit mode.

Definition at line 1684 of file dsp.c.

References ast_dtmf_detect_init(), ast_mf_detect_init(), ast_dsp::digitmode, dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, ast_dsp::dtmf, ast_dsp::mf, and ast_dsp::td.

Referenced by i4l_answer(), i4l_startrec(), mgcp_new(), mkif(), mkintf(), sip_new(), ss_thread(), zt_hangup(), zt_new(), and zt_setoption().

01685 {
01686    int new;
01687    int old;
01688    
01689    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01690    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01691    if (old != new) {
01692       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01693       if (new & DSP_DIGITMODE_MF)
01694          ast_mf_detect_init(&dsp->td.mf);
01695       else
01696          ast_dtmf_detect_init(&dsp->td.dtmf);
01697    }
01698    dsp->digitmode = digitmode;
01699    return 0;
01700 }

void ast_dsp_digitreset struct ast_dsp dsp  ) 
 

Reset DTMF detector.

Definition at line 1622 of file dsp.c.

References dtmf_detect_state_t::col_out, dtmf_detect_state_t::current_digits, mf_detect_state_t::current_digits, dtmf_detect_state_t::current_sample, mf_detect_state_t::current_sample, ast_dsp::digitmode, dtmf_detect_state_t::digits, mf_detect_state_t::digits, dsp, ast_dsp::dtmf, dtmf_detect_state_t::energy, dtmf_detect_state_t::fax_tone, goertzel_reset(), dtmf_detect_state_t::hits, mf_detect_state_t::hits, ast_dsp::mf, dtmf_detect_state_t::mhit, mf_detect_state_t::mhit, dtmf_detect_state_t::row_out, ast_dsp::td, ast_dsp::thinkdigit, and mf_detect_state_t::tone_out.

Referenced by ss_thread().

01623 {
01624    int i;
01625    
01626    dsp->thinkdigit = 0;
01627    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01628       memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01629       dsp->td.mf.current_digits = 0;
01630       /* Reinitialise the detector for the next block */
01631       for (i = 0;  i < 6;  i++) {
01632          goertzel_reset(&dsp->td.mf.tone_out[i]);
01633 #ifdef OLD_DSP_ROUTINES
01634          goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01635 #endif         
01636       }
01637 #ifdef OLD_DSP_ROUTINES
01638       dsp->td.mf.energy = 0.0;
01639       dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01640 #else
01641       dsp->td.mf.hits[4] = dsp->td.mf.hits[3] = dsp->td.mf.hits[2] = dsp->td.mf.hits[1] = dsp->td.mf.hits[0] = dsp->td.mf.mhit = 0;
01642 #endif      
01643       dsp->td.mf.current_sample = 0;
01644    } else {
01645       memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01646       dsp->td.dtmf.current_digits = 0;
01647       /* Reinitialise the detector for the next block */
01648       for (i = 0;  i < 4;  i++) {
01649          goertzel_reset(&dsp->td.dtmf.row_out[i]);
01650          goertzel_reset(&dsp->td.dtmf.col_out[i]);
01651 #ifdef OLD_DSP_ROUTINES
01652          goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01653          goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01654 #endif         
01655       }
01656 #ifdef FAX_DETECT
01657       goertzel_reset (&dsp->td.dtmf.fax_tone);
01658 #endif
01659 #ifdef OLD_DSP_ROUTINES
01660 #ifdef FAX_DETECT
01661       goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01662 #endif
01663       dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01664 #else
01665       dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] =  dsp->td.dtmf.mhit = 0;
01666 #endif      
01667       dsp->td.dtmf.energy = 0.0;
01668       dsp->td.dtmf.current_sample = 0;
01669    }
01670 }

void ast_dsp_free struct ast_dsp dsp  ) 
 

Definition at line 1596 of file dsp.c.

References dsp, and free.

Referenced by __oh323_destroy(), ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record(), background_detect_exec(), cl_dequeue_chan(), cleanup_connection(), conf_run(), destroy_endpoint(), do_waiting(), handle_recordfile(), i4l_hangup(), mgcp_hangup(), record_exec(), sip_dtmfmode(), sip_hangup(), ss_thread(), vpb_hangup(), and zt_hangup().

01597 {
01598    free(dsp);
01599 }

int ast_dsp_get_tcount struct ast_dsp dsp  ) 
 

Get tcount (Threshold counter).

Definition at line 1721 of file dsp.c.

References dsp, and ast_dsp::tcount.

01722 {
01723    return dsp->tcount;
01724 }

int ast_dsp_get_tstate struct ast_dsp dsp  ) 
 

Get tstate (Tone State).

Definition at line 1716 of file dsp.c.

References dsp, and ast_dsp::tstate.

01717 {
01718    return dsp->tstate;
01719 }

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

Get pending DTMF/MF digits.

Definition at line 1006 of file dsp.c.

References dtmf_detect_state_t::current_digits, mf_detect_state_t::current_digits, ast_dsp::digitmode, dtmf_detect_state_t::digits, mf_detect_state_t::digits, dsp, ast_dsp::dtmf, ast_dsp::mf, and ast_dsp::td.

01007 {
01008    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01009       if (max > dsp->td.mf.current_digits)
01010          max = dsp->td.mf.current_digits;
01011       if (max > 0) {
01012          memcpy(buf, dsp->td.mf.digits, max);
01013          memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
01014          dsp->td.mf.current_digits -= max;
01015       }
01016       buf[max] = '\0';
01017       return  max;
01018    } else {
01019       if (max > dsp->td.dtmf.current_digits)
01020          max = dsp->td.dtmf.current_digits;
01021       if (max > 0) {
01022          memcpy (buf, dsp->td.dtmf.digits, max);
01023          memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
01024          dsp->td.dtmf.current_digits -= max;
01025       }
01026       buf[max] = '\0';
01027       return  max;
01028    }
01029 }

struct ast_dsp* ast_dsp_new void   ) 
 

Definition at line 1573 of file dsp.c.

References ast_dsp_prog_reset(), ast_dtmf_detect_init(), ast_dsp::busycount, dsp, ast_dsp::dtmf, ast_dsp::features, malloc, ast_dsp::td, and ast_dsp::threshold.

Referenced by __oh323_new(), ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record(), background_detect_exec(), conf_run(), do_waiting(), handle_recordfile(), i4l_answer(), i4l_startrec(), mgcp_new(), misdn_set_opt_exec(), mkif(), record_exec(), sip_dtmfmode(), sip_new(), and zt_new().

01574 {
01575    struct ast_dsp *dsp;
01576 
01577    dsp = malloc(sizeof(struct ast_dsp));
01578    if (dsp) {
01579       memset(dsp, 0, sizeof(struct ast_dsp));
01580       dsp->threshold = DEFAULT_THRESHOLD;
01581       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01582       dsp->busycount = DSP_HISTORY;
01583       /* Initialize DTMF detector */
01584       ast_dtmf_detect_init(&dsp->td.dtmf);
01585       /* Initialize initial DSP progress detect parameters */
01586       ast_dsp_prog_reset(dsp);
01587    }
01588    return dsp;
01589 }

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 1363 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_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, ast_frfree(), ast_getformatname(), ast_log(), AST_MULAW, ast_queue_frame(), dtmf_detect_state_t::current_digits, mf_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digitmode, dtmf_detect_state_t::digits, mf_detect_state_t::digits, dsp, DSP_DIGITMODE_MUTECONF, ast_dsp::dtmf, ast_dsp::f, ast_dsp::features, FIX_INF, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_dsp::mf, ast_channel::name, ast_frame::src, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit.

Referenced by do_chanreads(), i4l_read(), mgcp_rtp_read(), misdn_tx2ast_frm(), oh323_rtp_read(), sip_rtp_read(), and zt_read().

01364 {
01365    int silence;
01366    int res;
01367    int digit;
01368    int x;
01369    short *shortdata;
01370    unsigned char *odata;
01371    int len;
01372    int writeback = 0;
01373 
01374 #define FIX_INF(inf) do { \
01375       if (writeback) { \
01376          switch(inf->subclass) { \
01377          case AST_FORMAT_SLINEAR: \
01378             break; \
01379          case AST_FORMAT_ULAW: \
01380             for (x=0;x<len;x++) \
01381                odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01382             break; \
01383          case AST_FORMAT_ALAW: \
01384             for (x=0;x<len;x++) \
01385                odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01386             break; \
01387          } \
01388       } \
01389    } while(0) 
01390 
01391    if (!af)
01392       return NULL;
01393    if (af->frametype != AST_FRAME_VOICE)
01394       return af;
01395    odata = af->data;
01396    len = af->datalen;
01397    /* Make sure we have short data */
01398    switch(af->subclass) {
01399    case AST_FORMAT_SLINEAR:
01400       shortdata = af->data;
01401       len = af->datalen / 2;
01402       break;
01403    case AST_FORMAT_ULAW:
01404       shortdata = alloca(af->datalen * 2);
01405       if (!shortdata) {
01406          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01407          return af;
01408       }
01409       for (x=0;x<len;x++) 
01410          shortdata[x] = AST_MULAW(odata[x]);
01411       break;
01412    case AST_FORMAT_ALAW:
01413       shortdata = alloca(af->datalen * 2);
01414       if (!shortdata) {
01415          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01416          return af;
01417       }
01418       for (x=0;x<len;x++) 
01419          shortdata[x] = AST_ALAW(odata[x]);
01420       break;
01421    default:
01422       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01423       return af;
01424    }
01425    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01426    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01427       memset(&dsp->f, 0, sizeof(dsp->f));
01428       dsp->f.frametype = AST_FRAME_NULL;
01429       return &dsp->f;
01430    }
01431    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01432       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01433       memset(&dsp->f, 0, sizeof(dsp->f));
01434       dsp->f.frametype = AST_FRAME_CONTROL;
01435       dsp->f.subclass = AST_CONTROL_BUSY;
01436       ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01437       return &dsp->f;
01438    }
01439    if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01440       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01441 #if 0
01442       if (digit)
01443          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01444 #endif         
01445       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01446          if (!dsp->thinkdigit) {
01447             if (digit) {
01448                /* Looks like we might have something.  
01449                 * Request a conference mute for the moment */
01450                memset(&dsp->f, 0, sizeof(dsp->f));
01451                dsp->f.frametype = AST_FRAME_DTMF;
01452                dsp->f.subclass = 'm';
01453                dsp->thinkdigit = 'x';
01454                FIX_INF(af);
01455                if (chan)
01456                   ast_queue_frame(chan, af);
01457                ast_frfree(af);
01458                return &dsp->f;
01459             }
01460          } else {
01461             if (digit) {
01462                /* Thought we saw one last time.  Pretty sure we really have now */
01463                if (dsp->thinkdigit) {
01464                   if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01465                      /* If we found a digit, and we're changing digits, go
01466                         ahead and send this one, but DON'T stop confmute because
01467                         we're detecting something else, too... */
01468                      memset(&dsp->f, 0, sizeof(dsp->f));
01469                      dsp->f.frametype = AST_FRAME_DTMF;
01470                      dsp->f.subclass = dsp->thinkdigit;
01471                      FIX_INF(af);
01472                      if (chan)
01473                         ast_queue_frame(chan, af);
01474                      ast_frfree(af);
01475                   }
01476                   dsp->thinkdigit = digit;
01477                   return &dsp->f;
01478                }
01479                dsp->thinkdigit = digit;
01480             } else {
01481                if (dsp->thinkdigit) {
01482                   memset(&dsp->f, 0, sizeof(dsp->f));
01483                   if (dsp->thinkdigit != 'x') {
01484                      /* If we found a digit, send it now */
01485                      dsp->f.frametype = AST_FRAME_DTMF;
01486                      dsp->f.subclass = dsp->thinkdigit;
01487                      dsp->thinkdigit = 0;
01488                   } else {
01489                      dsp->f.frametype = AST_FRAME_DTMF;
01490                      dsp->f.subclass = 'u';
01491                      dsp->thinkdigit = 0;
01492                   }
01493                   FIX_INF(af);
01494                   if (chan)
01495                      ast_queue_frame(chan, af);
01496                   ast_frfree(af);
01497                   return &dsp->f;
01498                }
01499             }
01500          }
01501       } else if (!digit) {
01502          /* Only check when there is *not* a hit... */
01503          if (dsp->digitmode & DSP_DIGITMODE_MF) {
01504             if (dsp->td.mf.current_digits) {
01505                memset(&dsp->f, 0, sizeof(dsp->f));
01506                dsp->f.frametype = AST_FRAME_DTMF;
01507                dsp->f.subclass = dsp->td.mf.digits[0];
01508                memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01509                dsp->td.mf.current_digits--;
01510                FIX_INF(af);
01511                if (chan)
01512                   ast_queue_frame(chan, af);
01513                ast_frfree(af);
01514                return &dsp->f;
01515             }
01516          } else {
01517             if (dsp->td.dtmf.current_digits) {
01518                memset(&dsp->f, 0, sizeof(dsp->f));
01519                dsp->f.frametype = AST_FRAME_DTMF;
01520                dsp->f.subclass = dsp->td.dtmf.digits[0];
01521                memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01522                dsp->td.dtmf.current_digits--;
01523                FIX_INF(af);
01524                if (chan)
01525                   ast_queue_frame(chan, af);
01526                ast_frfree(af);
01527                return &dsp->f;
01528             }
01529          }
01530       }
01531    }
01532    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01533       res = __ast_dsp_call_progress(dsp, shortdata, len);
01534       if (res) {
01535          switch(res) {
01536          case AST_CONTROL_ANSWER:
01537          case AST_CONTROL_BUSY:
01538          case AST_CONTROL_RINGING:
01539          case AST_CONTROL_CONGESTION:
01540          case AST_CONTROL_HANGUP:
01541             memset(&dsp->f, 0, sizeof(dsp->f));
01542             dsp->f.frametype = AST_FRAME_CONTROL;
01543             dsp->f.subclass = res;
01544             dsp->f.src = "dsp_progress";
01545             if (chan) 
01546                ast_queue_frame(chan, &dsp->f);
01547             break;
01548          default:
01549             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01550          }
01551       }
01552    }
01553    FIX_INF(af);
01554    return af;
01555 }

void ast_dsp_reset struct ast_dsp dsp  ) 
 

Reset total silence count.

Definition at line 1672 of file dsp.c.

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

01673 {
01674    int x;
01675    
01676    dsp->totalsilence = 0;
01677    dsp->gsamps = 0;
01678    for (x=0;x<4;x++)
01679       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01680    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01681    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01682 }

void ast_dsp_set_busy_count struct ast_dsp dsp,
int  cadences
 

Set number of required cadences for busy.

Definition at line 1606 of file dsp.c.

References ast_dsp::busycount, and dsp.

Referenced by zt_new().

01607 {
01608    if (cadences < 4)
01609       cadences = 4;
01610    if (cadences > DSP_HISTORY)
01611       cadences = DSP_HISTORY;
01612    dsp->busycount = cadences;
01613 }

void ast_dsp_set_busy_pattern struct ast_dsp dsp,
int  tonelength,
int  quietlength
 

Set expected lengths of the busy tone.

Definition at line 1615 of file dsp.c.

References ast_log(), ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, dsp, and LOG_DEBUG.

Referenced by zt_new().

01616 {
01617    dsp->busy_tonelength = tonelength;
01618    dsp->busy_quietlength = quietlength;
01619    ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01620 }

int ast_dsp_set_call_progress_zone struct ast_dsp dsp,
char *  zone
 

Set zone for doing progress detection.

Definition at line 1702 of file dsp.c.

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

Referenced by zt_new().

01703 {
01704    int x;
01705    
01706    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01707       if (!strcasecmp(aliases[x].name, zone)) {
01708          dsp->progmode = aliases[x].mode;
01709          ast_dsp_prog_reset(dsp);
01710          return 0;
01711       }
01712    }
01713    return -1;
01714 }

void ast_dsp_set_features struct ast_dsp dsp,
int  features
 

Select feature set.

Definition at line 1591 of file dsp.c.

References dsp, and ast_dsp::features.

Referenced by __oh323_new(), disable_dtmf_detect(), enable_dtmf_detect(), i4l_answer(), i4l_startrec(), mgcp_new(), misdn_set_opt_exec(), mkif(), sip_dtmfmode(), sip_new(), and zt_new().

01592 {
01593    dsp->features = features;
01594 }

void ast_dsp_set_threshold struct ast_dsp dsp,
int  threshold
 

Set threshold value for silence.

Definition at line 1601 of file dsp.c.

References dsp, and ast_dsp::threshold.

Referenced by ast_play_and_prepend(), ast_play_and_record(), do_waiting(), handle_recordfile(), and record_exec().

01602 {
01603    dsp->threshold = threshold;
01604 }

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

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

Referenced by ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record(), background_detect_exec(), conf_run(), do_waiting(), handle_recordfile(), and record_exec().

01346 {
01347    short *s;
01348    int len;
01349    
01350    if (f->frametype != AST_FRAME_VOICE) {
01351       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01352       return 0;
01353    }
01354    if (f->subclass != AST_FORMAT_SLINEAR) {
01355       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01356       return 0;
01357    }
01358    s = f->data;
01359    len = f->datalen/2;
01360    return __ast_dsp_silence(dsp, s, len, totalsilence);
01361 }


Generated on Mon Mar 20 08:20:26 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1