Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:30 2007

Asterisk developer's documentation :: Codename Pineapple


dsp.h File Reference


Detailed Description

Convenient Signal Processing routines.

Definition in file dsp.h.

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


Define Documentation

#define DSP_DIGITMODE_DTMF   0
 

Definition at line 31 of file dsp.h.

Referenced by ast_dsp_digitmode(), sip_new(), ss_thread(), zt_hangup(), and zt_setoption().

#define DSP_DIGITMODE_MF   1
 

Definition at line 32 of file dsp.h.

Referenced by __ast_dsp_digitdetect(), ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_getdigits(), ast_dsp_process(), 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 ast_dsp_digitmode(), ast_dsp_process(), and 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(), sip_new(), and zt_setoption().

#define DSP_FEATURE_BUSY_DETECT   (1 << 1)
 

Definition at line 27 of file dsp.h.

Referenced by ast_dsp_process().

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

#define DSP_FEATURE_DTMF_DETECT   (1 << 3)
 

Definition at line 28 of file dsp.h.

Referenced by __oh323_new(), ast_dsp_process(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), read_config(), 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(), and read_config().

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

Definition at line 41 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_PROGRESS_CONGESTION   (1 << 19)
 

Definition at line 42 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_PROGRESS_RINGING   (1 << 17)
 

Definition at line 40 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_PROGRESS_TALK   (1 << 16)
 

Definition at line 39 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_BUSY   4
 

Definition at line 49 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_DIALTONE   2
 

Definition at line 47 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_HUNGUP   8
 

Definition at line 53 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_RINGING   1
 

Definition at line 46 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SILENCE   0
 

Definition at line 45 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL1   5
 

Definition at line 50 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL2   6
 

Definition at line 51 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_SPECIAL3   7
 

Definition at line 52 of file dsp.h.

Referenced by __ast_dsp_call_progress().

#define DSP_TONE_STATE_TALKING   3
 

Definition at line 48 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 1257 of file dsp.c.

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

Referenced by ast_dsp_busydetect(), and ast_dsp_process().

01258 {
01259    int res = 0, x;
01260 #ifndef BUSYDETECT_TONEONLY
01261    int avgsilence = 0, hitsilence = 0;
01262 #endif
01263    int avgtone = 0, hittone = 0;
01264    if (!dsp->busymaybe)
01265       return res;
01266    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01267 #ifndef BUSYDETECT_TONEONLY
01268       avgsilence += dsp->historicsilence[x];
01269 #endif
01270       avgtone += dsp->historicnoise[x];
01271    }
01272 #ifndef BUSYDETECT_TONEONLY
01273    avgsilence /= dsp->busycount;
01274 #endif
01275    avgtone /= dsp->busycount;
01276    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01277 #ifndef BUSYDETECT_TONEONLY
01278       if (avgsilence > dsp->historicsilence[x]) {
01279          if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01280             hitsilence++;
01281       } else {
01282          if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01283             hitsilence++;
01284       }
01285 #endif
01286       if (avgtone > dsp->historicnoise[x]) {
01287          if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01288             hittone++;
01289       } else {
01290          if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01291             hittone++;
01292       }
01293    }
01294 #ifndef BUSYDETECT_TONEONLY
01295    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 
01296        (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 
01297        (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01298 #else
01299    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01300 #endif
01301 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01302 #ifdef BUSYDETECT_TONEONLY
01303 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01304 #endif
01305       if (avgtone > avgsilence) {
01306          if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01307             res = 1;
01308       } else {
01309          if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01310             res = 1;
01311       }
01312 #else
01313       res = 1;
01314 #endif
01315    }
01316    /* If we know the expected busy tone length, check we are in the range */
01317    if (res && (dsp->busy_tonelength > 0)) {
01318       if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
01319 #if 0
01320          ast_log(LOG_NOTICE, "busy detector: avgtone of %d not close enough to desired %d\n",
01321                   avgtone, dsp->busy_tonelength);
01322 #endif
01323          res = 0;
01324       }
01325    }
01326 #ifndef BUSYDETECT_TONEONLY
01327    /* If we know the expected busy tone silent-period length, check we are in the range */
01328    if (res && (dsp->busy_quietlength > 0)) {
01329       if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01330 #if 0
01331          ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
01332                   avgsilence, dsp->busy_quietlength);
01333 #endif
01334          res = 0;
01335       }
01336    }
01337 #endif
01338 #if 1
01339    if (res) {
01340       if (option_debug)
01341          ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01342    }
01343 #endif
01344    return res;
01345 }

int ast_dsp_call_progress struct ast_dsp dsp,
struct ast_frame inf
 

Scans for progress indication in audio.

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

01189 {
01190    if (inf->frametype != AST_FRAME_VOICE) {
01191       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01192       return 0;
01193    }
01194    if (inf->subclass != AST_FORMAT_SLINEAR) {
01195       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01196       return 0;
01197    }
01198    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01199 }

int ast_dsp_digitdetect struct ast_dsp dsp,
struct ast_frame f
 

Return non-zero if DTMF hit was found.

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

00988 {
00989    short *s;
00990    int len;
00991    int ign=0;
00992 
00993    if (inf->frametype != AST_FRAME_VOICE) {
00994       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00995       return 0;
00996    }
00997    if (inf->subclass != AST_FORMAT_SLINEAR) {
00998       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00999       return 0;
01000    }
01001    s = inf->data;
01002    len = inf->datalen / 2;
01003    return __ast_dsp_digitdetect(dsp, s, len, &ign);
01004 }

int ast_dsp_digitmode struct ast_dsp dsp,
int  digitmode
 

Set digit mode.

Definition at line 1729 of file dsp.c.

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

Referenced by mgcp_new(), sip_new(), ss_thread(), zt_hangup(), and zt_setoption().

01730 {
01731    int new;
01732    int old;
01733    
01734    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01735    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01736    if (old != new) {
01737       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01738       if (new & DSP_DIGITMODE_MF)
01739          ast_mf_detect_init(&dsp->td.mf);
01740       else
01741          ast_dtmf_detect_init(&dsp->td.dtmf);
01742    }
01743    dsp->digitmode = digitmode;
01744    return 0;
01745 }

void ast_dsp_digitreset struct ast_dsp dsp  ) 
 

Reset DTMF detector.

Definition at line 1666 of file dsp.c.

References mf_detect_state_t::current_digits, mf_detect_state_t::current_sample, ast_dsp::digitmode, mf_detect_state_t::digits, DSP_DIGITMODE_MF, goertzel_reset(), mf_detect_state_t::hits, ast_dsp::mf, mf_detect_state_t::mhit, ast_dsp::td, ast_dsp::thinkdigit, and mf_detect_state_t::tone_out.

Referenced by ss_thread().

01667 {
01668    int i;
01669    
01670    dsp->thinkdigit = 0;
01671    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01672       memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01673       dsp->td.mf.current_digits = 0;
01674       /* Reinitialise the detector for the next block */
01675       for (i = 0;  i < 6;  i++) {
01676          goertzel_reset(&dsp->td.mf.tone_out[i]);
01677 #ifdef OLD_DSP_ROUTINES
01678          goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01679 #endif         
01680       }
01681 #ifdef OLD_DSP_ROUTINES
01682       dsp->td.mf.energy = 0.0;
01683       dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01684 #else
01685       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;
01686 #endif      
01687       dsp->td.mf.current_sample = 0;
01688    } else {
01689       memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01690       dsp->td.dtmf.current_digits = 0;
01691       /* Reinitialise the detector for the next block */
01692       for (i = 0;  i < 4;  i++) {
01693          goertzel_reset(&dsp->td.dtmf.row_out[i]);
01694          goertzel_reset(&dsp->td.dtmf.col_out[i]);
01695 #ifdef OLD_DSP_ROUTINES
01696          goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01697          goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01698 #endif         
01699       }
01700 #ifdef FAX_DETECT
01701       goertzel_reset (&dsp->td.dtmf.fax_tone);
01702 #endif
01703 #ifdef OLD_DSP_ROUTINES
01704 #ifdef FAX_DETECT
01705       goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01706 #endif
01707       dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01708 #else
01709       dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] =  dsp->td.dtmf.mhit = 0;
01710 #endif      
01711       dsp->td.dtmf.energy = 0.0;
01712       dsp->td.dtmf.current_sample = 0;
01713    }
01714 }

void ast_dsp_free struct ast_dsp dsp  ) 
 

Definition at line 1639 of file dsp.c.

References free.

Referenced by __oh323_destroy(), cl_dequeue_chan(), cleanup_connection(), handle_recordfile(), mgcp_hangup(), sip_dtmfmode(), sip_hangup(), ss_thread(), and zt_hangup().

01640 {
01641    free(dsp);
01642 }

int ast_dsp_get_tcount struct ast_dsp dsp  ) 
 

Get tcount (Threshold counter).

Definition at line 1766 of file dsp.c.

References ast_dsp::tcount.

01767 {
01768    return dsp->tcount;
01769 }

int ast_dsp_get_tstate struct ast_dsp dsp  ) 
 

Get tstate (Tone State).

Definition at line 1761 of file dsp.c.

References ast_dsp::tstate.

01762 {
01763    return dsp->tstate;
01764 }

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

Get pending DTMF/MF digits.

Definition at line 1026 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_DIGITMODE_MF, ast_dsp::dtmf, ast_dsp::mf, and ast_dsp::td.

01027 {
01028    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01029       if (max > dsp->td.mf.current_digits)
01030          max = dsp->td.mf.current_digits;
01031       if (max > 0) {
01032          memcpy(buf, dsp->td.mf.digits, max);
01033          memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
01034          dsp->td.mf.current_digits -= max;
01035       }
01036       buf[max] = '\0';
01037       return  max;
01038    } else {
01039       if (max > dsp->td.dtmf.current_digits)
01040          max = dsp->td.dtmf.current_digits;
01041       if (max > 0) {
01042          memcpy (buf, dsp->td.dtmf.digits, max);
01043          memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
01044          dsp->td.dtmf.current_digits -= max;
01045       }
01046       buf[max] = '\0';
01047       return  max;
01048    }
01049 }

struct ast_dsp* ast_dsp_new void   ) 
 

Definition at line 1618 of file dsp.c.

References ast_calloc, ast_dsp_prog_reset(), ast_dtmf_detect_init(), DEFAULT_THRESHOLD, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, and ast_dsp::threshold.

Referenced by __oh323_new(), handle_recordfile(), mgcp_new(), read_config(), sip_dtmfmode(), and sip_new().

01619 {
01620    struct ast_dsp *dsp;
01621    
01622    if ((dsp = ast_calloc(1, sizeof(*dsp)))) {      
01623       dsp->threshold = DEFAULT_THRESHOLD;
01624       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01625       dsp->busycount = DSP_HISTORY;
01626       /* Initialize DTMF detector */
01627       ast_dtmf_detect_init(&dsp->td.dtmf);
01628       /* Initialize initial DSP progress detect parameters */
01629       ast_dsp_prog_reset(dsp);
01630    }
01631    return dsp;
01632 }

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 1411 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_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, 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_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::dtmf, ast_dsp::f, ast_dsp::features, FIX_INF, ast_frame::frametype, len, LOG_DEBUG, LOG_WARNING, ast_dsp::mf, option_debug, silence, ast_frame::src, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit.

Referenced by mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), sip_rtp_read(), and zt_read().

01412 {
01413    int silence;
01414    int res;
01415    int digit;
01416    int x;
01417    short *shortdata;
01418    unsigned char *odata;
01419    int len;
01420    int writeback = 0;
01421 
01422 #define FIX_INF(inf) do { \
01423       if (writeback) { \
01424          switch (inf->subclass) { \
01425          case AST_FORMAT_SLINEAR: \
01426             break; \
01427          case AST_FORMAT_ULAW: \
01428             for (x=0;x<len;x++) \
01429                odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01430             break; \
01431          case AST_FORMAT_ALAW: \
01432             for (x=0;x<len;x++) \
01433                odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01434             break; \
01435          } \
01436       } \
01437    } while(0) 
01438 
01439    if (!af)
01440       return NULL;
01441    if (af->frametype != AST_FRAME_VOICE)
01442       return af;
01443    odata = af->data;
01444    len = af->datalen;
01445    /* Make sure we have short data */
01446    switch (af->subclass) {
01447    case AST_FORMAT_SLINEAR:
01448       shortdata = af->data;
01449       len = af->datalen / 2;
01450       break;
01451    case AST_FORMAT_ULAW:
01452       shortdata = alloca(af->datalen * 2);
01453       for (x = 0;x < len; x++) 
01454          shortdata[x] = AST_MULAW(odata[x]);
01455       break;
01456    case AST_FORMAT_ALAW:
01457       shortdata = alloca(af->datalen * 2);
01458       for (x = 0; x < len; x++) 
01459          shortdata[x] = AST_ALAW(odata[x]);
01460       break;
01461    default:
01462       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01463       return af;
01464    }
01465    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01466    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01467       memset(&dsp->f, 0, sizeof(dsp->f));
01468       dsp->f.frametype = AST_FRAME_NULL;
01469       return &dsp->f;
01470    }
01471    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01472       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01473       memset(&dsp->f, 0, sizeof(dsp->f));
01474       dsp->f.frametype = AST_FRAME_CONTROL;
01475       dsp->f.subclass = AST_CONTROL_BUSY;
01476       if (option_debug)
01477          ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01478       return &dsp->f;
01479    }
01480    if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01481       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01482 #if 0
01483       if (digit)
01484          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01485 #endif         
01486       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01487          if (!dsp->thinkdigit) {
01488             if (digit) {
01489                /* Looks like we might have something.  
01490                 * Request a conference mute for the moment */
01491                memset(&dsp->f, 0, sizeof(dsp->f));
01492                dsp->f.frametype = AST_FRAME_DTMF;
01493                dsp->f.subclass = 'm';
01494                dsp->thinkdigit = 'x';
01495                FIX_INF(af);
01496                if (chan)
01497                   ast_queue_frame(chan, af);
01498                ast_frfree(af);
01499                return &dsp->f;
01500             }
01501          } else {
01502             if (digit) {
01503                /* Thought we saw one last time.  Pretty sure we really have now */
01504                if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01505                   /* If we found a digit, and we're changing digits, go
01506                      ahead and send this one, but DON'T stop confmute because
01507                      we're detecting something else, too... */
01508                   memset(&dsp->f, 0, sizeof(dsp->f));
01509                   dsp->f.frametype = AST_FRAME_DTMF_END;
01510                   dsp->f.subclass = dsp->thinkdigit;
01511                   FIX_INF(af);
01512                   if (chan)
01513                      ast_queue_frame(chan, af);
01514                   ast_frfree(af);
01515                } else {
01516                   dsp->thinkdigit = digit;
01517                   memset(&dsp->f, 0, sizeof(dsp->f));
01518                   dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
01519                   dsp->f.subclass = dsp->thinkdigit;
01520                   FIX_INF(af);
01521                   if (chan)
01522                      ast_queue_frame(chan, af);
01523                   ast_frfree(af);
01524                }
01525                return &dsp->f;
01526             } else {
01527                memset(&dsp->f, 0, sizeof(dsp->f));
01528                if (dsp->thinkdigit != 'x') {
01529                   /* If we found a digit, send it now */
01530                   dsp->f.frametype = AST_FRAME_DTMF_END;
01531                   dsp->f.subclass = dsp->thinkdigit;
01532                   dsp->thinkdigit = 0;
01533                } else {
01534                   dsp->f.frametype = AST_FRAME_DTMF;
01535                   dsp->f.subclass = 'u';
01536                   dsp->thinkdigit = 0;
01537                }
01538                FIX_INF(af);
01539                if (chan)
01540                   ast_queue_frame(chan, af);
01541                ast_frfree(af);
01542                return &dsp->f;
01543             }
01544          }
01545       } else if (!digit) {
01546          /* Only check when there is *not* a hit... */
01547          if (dsp->digitmode & DSP_DIGITMODE_MF) {
01548             if (dsp->td.mf.current_digits) {
01549                memset(&dsp->f, 0, sizeof(dsp->f));
01550                dsp->f.frametype = AST_FRAME_DTMF;
01551                dsp->f.subclass = dsp->td.mf.digits[0];
01552                memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01553                dsp->td.mf.current_digits--;
01554                FIX_INF(af);
01555                if (chan)
01556                   ast_queue_frame(chan, af);
01557                ast_frfree(af);
01558                return &dsp->f;
01559             }
01560          } else {
01561             if (dsp->td.dtmf.current_digits) {
01562                memset(&dsp->f, 0, sizeof(dsp->f));
01563                dsp->f.frametype = AST_FRAME_DTMF_END;
01564                dsp->f.subclass = dsp->td.dtmf.digits[0];
01565                memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01566                dsp->td.dtmf.current_digits--;
01567                FIX_INF(af);
01568                if (chan)
01569                   ast_queue_frame(chan, af);
01570                ast_frfree(af);
01571                return &dsp->f;
01572             }
01573          }
01574       }
01575    }
01576    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01577       res = __ast_dsp_call_progress(dsp, shortdata, len);
01578       if (res) {
01579          switch (res) {
01580          case AST_CONTROL_ANSWER:
01581          case AST_CONTROL_BUSY:
01582          case AST_CONTROL_RINGING:
01583          case AST_CONTROL_CONGESTION:
01584          case AST_CONTROL_HANGUP:
01585             memset(&dsp->f, 0, sizeof(dsp->f));
01586             dsp->f.frametype = AST_FRAME_CONTROL;
01587             dsp->f.subclass = res;
01588             dsp->f.src = "dsp_progress";
01589             if (chan) 
01590                ast_queue_frame(chan, &dsp->f);
01591             break;
01592          default:
01593             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01594          }
01595       }
01596    }
01597    FIX_INF(af);
01598    return af;
01599 }

void ast_dsp_reset struct ast_dsp dsp  ) 
 

Reset total silence count.

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

01717 {
01718    int x;
01719    
01720    dsp->totalsilence = 0;
01721    dsp->gsamps = 0;
01722    for (x=0;x<4;x++)
01723       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01724    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01725    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01726    dsp->ringtimeout= 0;
01727 }

void ast_dsp_set_busy_count struct ast_dsp dsp,
int  cadences
 

Set number of required cadences for busy.

Definition at line 1649 of file dsp.c.

References ast_dsp::busycount, and DSP_HISTORY.

01650 {
01651    if (cadences < 4)
01652       cadences = 4;
01653    if (cadences > DSP_HISTORY)
01654       cadences = DSP_HISTORY;
01655    dsp->busycount = cadences;
01656 }

void ast_dsp_set_busy_pattern struct ast_dsp dsp,
int  tonelength,
int  quietlength
 

Set expected lengths of the busy tone.

Definition at line 1658 of file dsp.c.

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

01659 {
01660    dsp->busy_tonelength = tonelength;
01661    dsp->busy_quietlength = quietlength;
01662    if (option_debug)
01663       ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01664 }

int ast_dsp_set_call_progress_zone struct ast_dsp dsp,
char *  zone
 

Set zone for doing progress detection.

Definition at line 1747 of file dsp.c.

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

01748 {
01749    int x;
01750    
01751    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01752       if (!strcasecmp(aliases[x].name, zone)) {
01753          dsp->progmode = aliases[x].mode;
01754          ast_dsp_prog_reset(dsp);
01755          return 0;
01756       }
01757    }
01758    return -1;
01759 }

void ast_dsp_set_features struct ast_dsp dsp,
int  features
 

Select feature set.

Definition at line 1634 of file dsp.c.

References ast_dsp::features.

Referenced by __oh323_new(), disable_dtmf_detect(), enable_dtmf_detect(), mgcp_new(), read_config(), sip_dtmfmode(), and sip_new().

01635 {
01636    dsp->features = features;
01637 }

void ast_dsp_set_threshold struct ast_dsp dsp,
int  threshold
 

Set threshold value for silence.

Definition at line 1644 of file dsp.c.

References ast_dsp::threshold.

Referenced by handle_recordfile().

01645 {
01646    dsp->threshold = threshold;
01647 }

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 1393 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 handle_recordfile().

01394 {
01395    short *s;
01396    int len;
01397    
01398    if (f->frametype != AST_FRAME_VOICE) {
01399       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01400       return 0;
01401    }
01402    if (f->subclass != AST_FORMAT_SLINEAR) {
01403       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01404       return 0;
01405    }
01406    s = f->data;
01407    len = f->datalen/2;
01408    return __ast_dsp_silence(dsp, s, len, totalsilence);
01409 }


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen