Sat Apr 12 07:12:46 2008

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_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.
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(), mkintf(), sip_new(), ss_thread(), zt_hangup(), zt_new(), and zt_setoption().

#define DSP_DIGITMODE_MF   1

#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 dtmf_detect(), mf_detect(), and mgcp_new().

#define DSP_DIGITMODE_RELAXDTMF   (1 << 11)

Definition at line 37 of file dsp.h.

Referenced by __ast_dsp_digitdetect(), process_zap(), 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(), and zt_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 zt_new().

#define DSP_FEATURE_DTMF_DETECT   (1 << 3)

#define DSP_FEATURE_FAX_DETECT   (1 << 4)

Definition at line 29 of file dsp.h.

Referenced by __ast_dsp_digitdetect(), misdn_set_opt_exec(), read_config(), and zt_new().

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

#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 1276 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, and LOG_NOTICE.

Referenced by ast_dsp_busydetect(), and ast_dsp_process().

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

int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Scans for progress indication in audio.

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

01208 {
01209    if (inf->frametype != AST_FRAME_VOICE) {
01210       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01211       return 0;
01212    }
01213    if (inf->subclass != AST_FORMAT_SLINEAR) {
01214       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01215       return 0;
01216    }
01217    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01218 }

int ast_dsp_digitdetect ( struct ast_dsp dsp,
struct ast_frame f 
)

Return non-zero if DTMF hit was found.

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

01007 {
01008    short *s;
01009    int len;
01010    int ign=0;
01011 
01012    if (inf->frametype != AST_FRAME_VOICE) {
01013       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01014       return 0;
01015    }
01016    if (inf->subclass != AST_FORMAT_SLINEAR) {
01017       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01018       return 0;
01019    }
01020    s = inf->data;
01021    len = inf->datalen / 2;
01022    return __ast_dsp_digitdetect(dsp, s, len, &ign);
01023 }

int ast_dsp_digitmode ( struct ast_dsp dsp,
int  digitmode 
)

Set digit mode.

Definition at line 1748 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(), mkintf(), sip_new(), ss_thread(), zt_hangup(), zt_new(), and zt_setoption().

01749 {
01750    int new;
01751    int old;
01752    
01753    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01754    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01755    if (old != new) {
01756       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01757       if (new & DSP_DIGITMODE_MF)
01758          ast_mf_detect_init(&dsp->td.mf);
01759       else
01760          ast_dtmf_detect_init(&dsp->td.dtmf);
01761    }
01762    dsp->digitmode = digitmode;
01763    return 0;
01764 }

void ast_dsp_digitreset ( struct ast_dsp dsp  ) 

Reset DTMF detector.

Definition at line 1685 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_DIGITMODE_MF, ast_dsp::dtmf, dtmf_detect_state_t::energy, dtmf_detect_state_t::fax_tone, goertzel_reset(), mf_detect_state_t::hits, dtmf_detect_state_t::lasthit, 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().

01686 {
01687    int i;
01688    
01689    dsp->thinkdigit = 0;
01690    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01691       memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01692       dsp->td.mf.current_digits = 0;
01693       /* Reinitialise the detector for the next block */
01694       for (i = 0;  i < 6;  i++) {
01695          goertzel_reset(&dsp->td.mf.tone_out[i]);
01696 #ifdef OLD_DSP_ROUTINES
01697          goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01698 #endif         
01699       }
01700 #ifdef OLD_DSP_ROUTINES
01701       dsp->td.mf.energy = 0.0;
01702       dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01703 #else
01704       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;
01705 #endif      
01706       dsp->td.mf.current_sample = 0;
01707    } else {
01708       memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01709       dsp->td.dtmf.current_digits = 0;
01710       /* Reinitialise the detector for the next block */
01711       for (i = 0;  i < 4;  i++) {
01712          goertzel_reset(&dsp->td.dtmf.row_out[i]);
01713          goertzel_reset(&dsp->td.dtmf.col_out[i]);
01714 #ifdef OLD_DSP_ROUTINES
01715          goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01716          goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01717 #endif         
01718       }
01719 #ifdef FAX_DETECT
01720       goertzel_reset (&dsp->td.dtmf.fax_tone);
01721 #endif
01722 #ifdef OLD_DSP_ROUTINES
01723 #ifdef FAX_DETECT
01724       goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01725 #endif
01726       dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01727 #else
01728       dsp->td.dtmf.lasthit = dsp->td.dtmf.mhit = 0;
01729 #endif      
01730       dsp->td.dtmf.energy = 0.0;
01731       dsp->td.dtmf.current_sample = 0;
01732    }
01733 }

void ast_dsp_free ( struct ast_dsp dsp  ) 

int ast_dsp_get_tcount ( struct ast_dsp dsp  ) 

Get tcount (Threshold counter).

Definition at line 1785 of file dsp.c.

References ast_dsp::tcount.

01786 {
01787    return dsp->tcount;
01788 }

int ast_dsp_get_tstate ( struct ast_dsp dsp  ) 

Get tstate (Tone State).

Definition at line 1780 of file dsp.c.

References ast_dsp::tstate.

01781 {
01782    return dsp->tstate;
01783 }

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

Get pending DTMF/MF digits.

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

01046 {
01047    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01048       if (max > dsp->td.mf.current_digits)
01049          max = dsp->td.mf.current_digits;
01050       if (max > 0) {
01051          memcpy(buf, dsp->td.mf.digits, max);
01052          memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
01053          dsp->td.mf.current_digits -= max;
01054       }
01055       buf[max] = '\0';
01056       return  max;
01057    } else {
01058       if (max > dsp->td.dtmf.current_digits)
01059          max = dsp->td.dtmf.current_digits;
01060       if (max > 0) {
01061          memcpy (buf, dsp->td.dtmf.digits, max);
01062          memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
01063          dsp->td.dtmf.current_digits -= max;
01064       }
01065       buf[max] = '\0';
01066       return  max;
01067    }
01068 }

struct ast_dsp* ast_dsp_new ( void   )  [read]

Definition at line 1638 of file dsp.c.

References ast_calloc, ast_dsp_prog_reset(), ast_dtmf_detect_init(), ast_dsp::busycount, DEFAULT_THRESHOLD, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, ast_dsp::dtmf, ast_dsp::features, ast_dsp::td, and ast_dsp::threshold.

Referenced by __ast_play_and_record(), __oh323_new(), background_detect_exec(), conf_run(), do_waiting(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), read_config(), record_exec(), sip_dtmfmode(), sip_new(), and zt_new().

01639 {
01640    struct ast_dsp *dsp;
01641    
01642    if ((dsp = ast_calloc(1, sizeof(*dsp)))) {      
01643       dsp->threshold = DEFAULT_THRESHOLD;
01644       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01645       dsp->busycount = DSP_HISTORY;
01646       /* Initialize DTMF detector */
01647       ast_dtmf_detect_init(&dsp->td.dtmf);
01648       /* Initialize initial DSP progress detect parameters */
01649       ast_dsp_prog_reset(dsp);
01650    }
01651    return dsp;
01652 }

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

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

void ast_dsp_reset ( struct ast_dsp dsp  ) 

Reset total silence count.

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

01736 {
01737    int x;
01738    
01739    dsp->totalsilence = 0;
01740    dsp->gsamps = 0;
01741    for (x=0;x<4;x++)
01742       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01743    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01744    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01745    dsp->ringtimeout= 0;
01746 }

void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Set number of required cadences for busy.

Definition at line 1669 of file dsp.c.

References ast_dsp::busycount, and DSP_HISTORY.

Referenced by zt_new().

01670 {
01671    if (cadences < 4)
01672       cadences = 4;
01673    if (cadences > DSP_HISTORY)
01674       cadences = DSP_HISTORY;
01675    dsp->busycount = cadences;
01676 }

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

Set expected lengths of the busy tone.

Definition at line 1678 of file dsp.c.

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

Referenced by zt_new().

01679 {
01680    dsp->busy_tonelength = tonelength;
01681    dsp->busy_quietlength = quietlength;
01682    ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01683 }

int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Set zone for doing progress detection.

Definition at line 1766 of file dsp.c.

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

Referenced by zt_new().

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

void ast_dsp_set_features ( struct ast_dsp dsp,
int  features 
)

Select feature set.

Definition at line 1654 of file dsp.c.

References ast_dsp::features.

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

01655 {
01656    dsp->features = features;
01657 }

void ast_dsp_set_threshold ( struct ast_dsp dsp,
int  threshold 
)

Set threshold value for silence.

Definition at line 1664 of file dsp.c.

References ast_dsp::threshold.

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

01665 {
01666    dsp->threshold = threshold;
01667 }

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 1412 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, and ast_frame::subclass.

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

01413 {
01414    short *s;
01415    int len;
01416    
01417    if (f->frametype != AST_FRAME_VOICE) {
01418       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01419       return 0;
01420    }
01421    if (f->subclass != AST_FORMAT_SLINEAR) {
01422       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01423       return 0;
01424    }
01425    s = f->data;
01426    len = f->datalen/2;
01427    return __ast_dsp_silence(dsp, s, len, totalsilence);
01428 }


Generated on Sat Apr 12 07:12:46 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5