Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:48 2009

## Asterisk developer's documentation

# dsp.h File Reference

Convenient Signal Processing routines. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

## Defines

#define | DSP_DIGITMODE_DTMF 0
#define | DSP_DIGITMODE_MF 1
#define | DSP_DIGITMODE_MUTECONF (1 << 9)
#define | DSP_DIGITMODE_MUTEMAX (1 << 10)
#define | DSP_DIGITMODE_NOQUELCH (1 << 8)
#define | DSP_DIGITMODE_RELAXDTMF (1 << 11)
#define | DSP_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_dsp * | ast_dsp_new (void)
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.
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_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 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(), mkif(), setup_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)

Definition at line 28 of file dsp.h.

Referenced by __oh323_new(), ast_dsp_process(), disable_dtmf_detect(), enable_dtmf_detect(), i4l_answer(), i4l_startrec(), mgcp_new(), misdn_set_opt_exec(), mkif(), sip_dtmfmode(), sip_new(), and zt_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(), misdn_set_opt_exec(), 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 1213 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().

    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 #ifndef BUSYDETECT_TONEONLY
    01283    /* If we know the expected busy tone silent-period length, check we are in the range */
    01284    if (res && (dsp->busy_quietlength > 0)) {
    01285       if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
    01286 #if 0
    01287          ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
    01288                   avgsilence, dsp->busy_quietlength);
    01289 #endif
    01290          res = 0;
    01291       }
    01292    }
    01293 #endif
    01294 #if 1
    01295 #ifndef BUSYDETECT_TONEONLY
    01296    if (res)
    01297       ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
    01298 #endif
    01299 #endif
    01300    return res;
    01301 }

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_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, 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_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, 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 1688 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 i4l_answer(), i4l_startrec(), mgcp_new(), mkif(), mkintf(), sip_new(), ss_thread(), zt_hangup(), zt_new(), and zt_setoption().

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

void ast_dsp_digitreset | ( | struct ast_dsp * | dsp | ) |

Reset DTMF detector.

Definition at line 1626 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(), 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().

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

void ast_dsp_free | ( | struct ast_dsp * | dsp | ) |

Definition at line 1600 of file dsp.c.

References free.

Referenced by __oh323_destroy(), ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), 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().

    01601 {
    01602    free(dsp);
    01603 }

int ast_dsp_get_tcount | ( | struct ast_dsp * | dsp | ) |

Get tcount (Threshold counter).

Definition at line 1725 of file dsp.c.

References ast_dsp::tcount.

    01726 {
    01727    return dsp->tcount;
    01728 }

int ast_dsp_get_tstate | ( | struct ast_dsp * | dsp | ) |

Get tstate (Tone State).

Definition at line 1720 of file dsp.c.

References ast_dsp::tstate.

    01721 {
    01722    return dsp->tstate;
    01723 }

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_DIGITMODE_MF, 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 |  | ) | `[read]`

Definition at line 1577 of file dsp.c.

References 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, malloc, ast_dsp::td, and ast_dsp::threshold.

Referenced by __oh323_new(), ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), 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().

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

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 1367 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_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, LOG_DEBUG, LOG_WARNING, ast_dsp::mf, ast_channel::name, silence, ast_frame::src, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit.

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

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

void ast_dsp_reset | ( | struct ast_dsp * | dsp | ) |

Reset total silence count.

Definition at line 1676 of file dsp.c.

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

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

void ast_dsp_set_busy_count | ( | struct ast_dsp * | dsp,
|  | int | cadences |
| ) |  |  |

Set number of required cadences for busy.

Definition at line 1610 of file dsp.c.

References ast_dsp::busycount, and DSP_HISTORY.

Referenced by zt_new().

    01611 {
    01612    if (cadences < 4)
    01613       cadences = 4;
    01614    if (cadences > DSP_HISTORY)
    01615       cadences = DSP_HISTORY;
    01616    dsp->busycount = cadences;
    01617 }

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

Set expected lengths of the busy tone.

Definition at line 1619 of file dsp.c.

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

Referenced by zt_new().

    01620 {
    01621    dsp->busy_tonelength = tonelength;
    01622    dsp->busy_quietlength = quietlength;
    01623    ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
    01624 }

int ast_dsp_set_call_progress_zone | ( | struct ast_dsp * | dsp,
|  | char * | zone |
| ) |  |  |

Set zone for doing progress detection.

Definition at line 1706 of file dsp.c.

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

Referenced by zt_new().

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

void ast_dsp_set_features | ( | struct ast_dsp * | dsp,
|  | int | features |
| ) |  |  |

Select feature set.

Definition at line 1595 of file dsp.c.

References 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().

    01596 {
    01597    dsp->features = features;
    01598 }

void ast_dsp_set_threshold | ( | struct ast_dsp * | dsp,
|  | int | threshold |
| ) |  |  |

Set threshold value for silence.

Definition at line 1605 of file dsp.c.

References ast_dsp::threshold.

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

    01606 {
    01607    dsp->threshold = threshold;
    01608 }

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

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

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