#include "asterisk.h"
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#include <stdio.h>
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/dsp.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/utils.h"
Include dependency graph for dsp.c:

Go to the source code of this file.
Data Structures | |
| struct | ast_dsp |
| struct | dtmf_detect_state_t |
| struct | goertzel_state_t |
| struct | mf_detect_state_t |
| struct | progalias |
| struct | progress |
Defines | |
| #define | BELL_MF_RELATIVE_PEAK 12.6 |
| #define | BELL_MF_THRESHOLD 1.6e9 |
| #define | BELL_MF_TWIST 4.0 |
| #define | BUSYDETECT_MARTIN |
| #define | DEFAULT_THRESHOLD 512 |
| #define | DSP_HISTORY 15 |
| #define | DTMF_NORMAL_TWIST 6.3 |
| #define | DTMF_RELATIVE_PEAK_COL 6.3 |
| #define | DTMF_RELATIVE_PEAK_ROW 6.3 |
| #define | DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5) |
| #define | DTMF_THRESHOLD 8.0e7 |
| #define | DTMF_TO_TOTAL_ENERGY 42.0 |
| #define | FAX_2ND_HARMONIC 2.0 |
| #define | FAX_DETECT |
| #define | FAX_THRESHOLD 8.0e7 |
| #define | FIX_INF(inf) |
| #define | MAX_DTMF_DIGITS 128 |
| #define | MF_GSIZE 120 |
| #define | TONE_MIN_THRESH 1e8 |
| #define | TONE_THRESH 10.0 |
Enumerations | |
| enum | busy_detect { BUSY_PERCENT = 10, BUSY_PAT_PERCENT = 7, BUSY_THRESHOLD = 100, BUSY_MIN = 75, BUSY_MAX = 3100 } |
| enum | freq_index { HZ_350 = 0, HZ_440, HZ_480, HZ_620, HZ_950, HZ_1400, HZ_1800, HZ_425 = 0, HZ_400 = 0 } |
| enum | gsamp_size { GSAMP_SIZE_NA = 183, GSAMP_SIZE_CR = 188, GSAMP_SIZE_UK = 160 } |
| enum | gsamp_thresh { THRESH_RING = 8, THRESH_TALK = 2, THRESH_BUSY = 4, THRESH_CONGESTION = 4, THRESH_HANGUP = 60, THRESH_RING2ANSWER = 300 } |
| enum | prog_mode { PROG_MODE_NA = 0, PROG_MODE_CR, PROG_MODE_UK } |
Functions | |
| static int | __ast_dsp_call_progress (struct ast_dsp *dsp, short *s, int len) |
| static int | __ast_dsp_digitdetect (struct ast_dsp *dsp, short *s, int len, int *writeback) |
| static int | __ast_dsp_silence (struct ast_dsp *dsp, short *s, int len, int *totalsilence) |
| 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 *inf) |
| 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_frame_freed (struct ast_frame *fr) |
| Hint that a frame from a dsp was freed. | |
| 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_dsp * | ast_dsp_new (void) |
| ast_frame * | ast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af) |
| Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled. | |
| static void | ast_dsp_prog_reset (struct ast_dsp *dsp) |
| 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. | |
| static void | ast_dtmf_detect_init (dtmf_detect_state_t *s) |
| static void | ast_mf_detect_init (mf_detect_state_t *s) |
| static int | dtmf_detect (dtmf_detect_state_t *s, int16_t amp[], int samples, int digitmode, int *writeback, int faxdetect) |
| static void | goertzel_init (goertzel_state_t *s, float freq, int samples) |
| static void | goertzel_reset (goertzel_state_t *s) |
| static float | goertzel_result (goertzel_state_t *s) |
| static void | goertzel_sample (goertzel_state_t *s, short sample) |
| static void | goertzel_update (goertzel_state_t *s, short *samps, int count) |
| static int | mf_detect (mf_detect_state_t *s, int16_t amp[], int samples, int digitmode, int *writeback) |
| static int | pair_there (float p1, float p2, float i1, float i2, float e) |
Variables | |
| static struct progalias | aliases [] |
| static char | bell_mf_positions [] = "1247C-358A--69*---0B----#" |
| static float | dtmf_col [] |
| static char | dtmf_positions [] = "123A" "456B" "789C" "*0#D" |
| static float | dtmf_row [] |
| static float | fax_freq = 1100.0 |
| static float | mf_tones [] |
| static struct progress | modes [] |
Definition in file dsp.c.
| #define DEFAULT_THRESHOLD 512 |
| #define DSP_HISTORY 15 |
Remember last 15 units
Definition at line 124 of file dsp.c.
Referenced by __ast_dsp_silence(), ast_dsp_busydetect(), ast_dsp_new(), and ast_dsp_set_busy_count().
| #define DTMF_NORMAL_TWIST 6.3 |
| #define DTMF_RELATIVE_PEAK_COL 6.3 |
| #define DTMF_RELATIVE_PEAK_ROW 6.3 |
| #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5) |
| #define DTMF_THRESHOLD 8.0e7 |
| #define DTMF_TO_TOTAL_ENERGY 42.0 |
| #define FAX_DETECT |
| #define FIX_INF | ( | inf | ) |
Referenced by ast_dsp_process().
| #define MAX_DTMF_DIGITS 128 |
| #define MF_GSIZE 120 |
| #define TONE_MIN_THRESH 1e8 |
How much tone there should be at least to attempt
Definition at line 130 of file dsp.c.
Referenced by __ast_dsp_call_progress(), and pair_there().
| #define TONE_THRESH 10.0 |
How much louder the tone should be than channel energy
Definition at line 129 of file dsp.c.
Referenced by __ast_dsp_call_progress(), and pair_there().
| enum busy_detect |
Definition at line 115 of file dsp.c.
00115 { 00116 BUSY_PERCENT = 10, /*!< The percentage difference between the two last silence periods */ 00117 BUSY_PAT_PERCENT = 7, /*!< The percentage difference between measured and actual pattern */ 00118 BUSY_THRESHOLD = 100, /*!< Max number of ms difference between max and min times in busy */ 00119 BUSY_MIN = 75, /*!< Busy must be at least 80 ms in half-cadence */ 00120 BUSY_MAX =3100 /*!< Busy can't be longer than 3100 ms in half-cadence */ 00121 };
| enum freq_index |
| HZ_350 | For US modes { |
| HZ_440 | |
| HZ_480 | |
| HZ_620 | |
| HZ_950 | |
| HZ_1400 | |
| HZ_1800 | } |
| HZ_425 | For CR/BR modes |
| HZ_400 | For UK mode |
Definition at line 76 of file dsp.c.
00076 { 00077 /*! For US modes { */ 00078 HZ_350 = 0, 00079 HZ_440, 00080 HZ_480, 00081 HZ_620, 00082 HZ_950, 00083 HZ_1400, 00084 HZ_1800, /*!< } */ 00085 00086 /*! For CR/BR modes */ 00087 HZ_425 = 0, 00088 00089 /*! For UK mode */ 00090 HZ_400 = 0 00091 };
| enum gsamp_size |
Number of goertzels for progress detect
| GSAMP_SIZE_NA | North America - 350, 440, 480, 620, 950, 1400, 1800 Hz |
| GSAMP_SIZE_CR | Costa Rica, Brazil - Only care about 425 Hz |
| GSAMP_SIZE_UK | UK disconnect goertzel feed - should trigger 400hz |
Definition at line 64 of file dsp.c.
00064 { 00065 GSAMP_SIZE_NA = 183, /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */ 00066 GSAMP_SIZE_CR = 188, /*!< Costa Rica, Brazil - Only care about 425 Hz */ 00067 GSAMP_SIZE_UK = 160 /*!< UK disconnect goertzel feed - should trigger 400hz */ 00068 };
| enum gsamp_thresh |
All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms)
Definition at line 133 of file dsp.c.
00133 { 00134 THRESH_RING = 8, /*!< Need at least 150ms ring to accept */ 00135 THRESH_TALK = 2, /*!< Talk detection does not work continuously */ 00136 THRESH_BUSY = 4, /*!< Need at least 80ms to accept */ 00137 THRESH_CONGESTION = 4, /*!< Need at least 80ms to accept */ 00138 THRESH_HANGUP = 60, /*!< Need at least 1300ms to accept hangup */ 00139 THRESH_RING2ANSWER = 300 /*!< Timeout from start of ring to answer (about 6600 ms) */ 00140 };
| enum prog_mode |
Definition at line 70 of file dsp.c.
00070 { 00071 PROG_MODE_NA = 0, 00072 PROG_MODE_CR, 00073 PROG_MODE_UK 00074 };
| static int __ast_dsp_call_progress | ( | struct ast_dsp * | dsp, | |
| short * | s, | |||
| int | len | |||
| ) | [static] |
Definition at line 1070 of file dsp.c.
References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_log(), DSP_FEATURE_CALL_PROGRESS, DSP_PROGRESS_BUSY, DSP_PROGRESS_CONGESTION, DSP_PROGRESS_RINGING, DSP_PROGRESS_TALK, DSP_TONE_STATE_BUSY, DSP_TONE_STATE_DIALTONE, DSP_TONE_STATE_HUNGUP, DSP_TONE_STATE_RINGING, DSP_TONE_STATE_SILENCE, DSP_TONE_STATE_SPECIAL1, DSP_TONE_STATE_SPECIAL2, DSP_TONE_STATE_SPECIAL3, DSP_TONE_STATE_TALKING, ast_dsp::features, ast_dsp::freqcount, ast_dsp::freqs, ast_dsp::genergy, goertzel_result(), goertzel_sample(), ast_dsp::gsamp_size, ast_dsp::gsamps, HZ_1400, HZ_1800, HZ_350, HZ_400, HZ_425, HZ_440, HZ_480, HZ_620, HZ_950, LOG_NOTICE, LOG_WARNING, pair_there(), PROG_MODE_CR, PROG_MODE_NA, PROG_MODE_UK, ast_dsp::progmode, ast_dsp::ringtimeout, ast_dsp::tcount, THRESH_BUSY, THRESH_CONGESTION, THRESH_HANGUP, THRESH_RING, THRESH_RING2ANSWER, THRESH_TALK, TONE_MIN_THRESH, TONE_THRESH, ast_dsp::tstate, goertzel_state_t::v2, and goertzel_state_t::v3.
Referenced by ast_dsp_call_progress(), and ast_dsp_process().
01071 { 01072 int x; 01073 int y; 01074 int pass; 01075 int newstate = DSP_TONE_STATE_SILENCE; 01076 int res = 0; 01077 while(len) { 01078 /* Take the lesser of the number of samples we need and what we have */ 01079 pass = len; 01080 if (pass > dsp->gsamp_size - dsp->gsamps) 01081 pass = dsp->gsamp_size - dsp->gsamps; 01082 for (x=0;x<pass;x++) { 01083 for (y=0;y<dsp->freqcount;y++) 01084 goertzel_sample(&dsp->freqs[y], s[x]); 01085 dsp->genergy += s[x] * s[x]; 01086 } 01087 s += pass; 01088 dsp->gsamps += pass; 01089 len -= pass; 01090 if (dsp->gsamps == dsp->gsamp_size) { 01091 float hz[7]; 01092 for (y=0;y<7;y++) 01093 hz[y] = goertzel_result(&dsp->freqs[y]); 01094 #if 0 01095 printf("\n350: 425: 440: 480: 620: 950: 1400: 1800: Energy: \n"); 01096 printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n", 01097 hz[HZ_350], hz[HZ_425], hz[HZ_440], hz[HZ_480], hz[HZ_620], hz[HZ_950], hz[HZ_1400], hz[HZ_1800], dsp->genergy); 01098 #endif 01099 switch(dsp->progmode) { 01100 case PROG_MODE_NA: 01101 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) { 01102 newstate = DSP_TONE_STATE_BUSY; 01103 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) { 01104 newstate = DSP_TONE_STATE_RINGING; 01105 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) { 01106 newstate = DSP_TONE_STATE_DIALTONE; 01107 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) { 01108 newstate = DSP_TONE_STATE_SPECIAL1; 01109 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) { 01110 if (dsp->tstate == DSP_TONE_STATE_SPECIAL1) 01111 newstate = DSP_TONE_STATE_SPECIAL2; 01112 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) { 01113 if (dsp->tstate == DSP_TONE_STATE_SPECIAL2) 01114 newstate = DSP_TONE_STATE_SPECIAL3; 01115 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) { 01116 newstate = DSP_TONE_STATE_TALKING; 01117 } else 01118 newstate = DSP_TONE_STATE_SILENCE; 01119 break; 01120 case PROG_MODE_CR: 01121 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) { 01122 newstate = DSP_TONE_STATE_RINGING; 01123 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) { 01124 newstate = DSP_TONE_STATE_TALKING; 01125 } else 01126 newstate = DSP_TONE_STATE_SILENCE; 01127 break; 01128 case PROG_MODE_UK: 01129 if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) { 01130 newstate = DSP_TONE_STATE_HUNGUP; 01131 } 01132 break; 01133 default: 01134 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode); 01135 } 01136 if (newstate == dsp->tstate) { 01137 dsp->tcount++; 01138 if (dsp->ringtimeout) 01139 dsp->ringtimeout++; 01140 switch (dsp->tstate) { 01141 case DSP_TONE_STATE_RINGING: 01142 if ((dsp->features & DSP_PROGRESS_RINGING) && 01143 (dsp->tcount==THRESH_RING)) { 01144 res = AST_CONTROL_RINGING; 01145 dsp->ringtimeout= 1; 01146 } 01147 break; 01148 case DSP_TONE_STATE_BUSY: 01149 if ((dsp->features & DSP_PROGRESS_BUSY) && 01150 (dsp->tcount==THRESH_BUSY)) { 01151 res = AST_CONTROL_BUSY; 01152 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; 01153 } 01154 break; 01155 case DSP_TONE_STATE_TALKING: 01156 if ((dsp->features & DSP_PROGRESS_TALK) && 01157 (dsp->tcount==THRESH_TALK)) { 01158 res = AST_CONTROL_ANSWER; 01159 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; 01160 } 01161 break; 01162 case DSP_TONE_STATE_SPECIAL3: 01163 if ((dsp->features & DSP_PROGRESS_CONGESTION) && 01164 (dsp->tcount==THRESH_CONGESTION)) { 01165 res = AST_CONTROL_CONGESTION; 01166 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; 01167 } 01168 break; 01169 case DSP_TONE_STATE_HUNGUP: 01170 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) && 01171 (dsp->tcount==THRESH_HANGUP)) { 01172 res = AST_CONTROL_HANGUP; 01173 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; 01174 } 01175 break; 01176 } 01177 if (dsp->ringtimeout==THRESH_RING2ANSWER) { 01178 #if 0 01179 ast_log(LOG_NOTICE, "Consider call as answered because of timeout after last ring\n"); 01180 #endif 01181 res = AST_CONTROL_ANSWER; 01182 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; 01183 } 01184 } else { 01185 #if 0 01186 ast_log(LOG_NOTICE, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount); 01187 ast_log(LOG_NOTICE, "Start state %d\n", newstate); 01188 #endif 01189 dsp->tstate = newstate; 01190 dsp->tcount = 1; 01191 } 01192 01193 /* Reset goertzel */ 01194 for (x=0;x<7;x++) 01195 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 01196 dsp->gsamps = 0; 01197 dsp->genergy = 0.0; 01198 } 01199 } 01200 #if 0 01201 if (res) 01202 printf("Returning %d\n", res); 01203 #endif 01204 return res; 01205 }
| static int __ast_dsp_digitdetect | ( | struct ast_dsp * | dsp, | |
| short * | s, | |||
| int | len, | |||
| int * | writeback | |||
| ) | [static] |
Definition at line 995 of file dsp.c.
References ast_dsp::digitmode, DSP_DIGITMODE_MF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_FAX_DETECT, ast_dsp::dtmf, dtmf_detect(), ast_dsp::features, ast_dsp::mf, mf_detect(), and ast_dsp::td.
Referenced by ast_dsp_digitdetect(), and ast_dsp_process().
00996 { 00997 int res; 00998 00999 if (dsp->digitmode & DSP_DIGITMODE_MF) 01000 res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback); 01001 else 01002 res = dtmf_detect(&dsp->td.dtmf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback, dsp->features & DSP_FEATURE_FAX_DETECT); 01003 return res; 01004 }
| static int __ast_dsp_silence | ( | struct ast_dsp * | dsp, | |
| short * | s, | |||
| int | len, | |||
| int * | totalsilence | |||
| ) | [static] |
Definition at line 1220 of file dsp.c.
References ast_dsp::busycount, ast_dsp::busymaybe, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::totalnoise, and ast_dsp::totalsilence.
Referenced by ast_dsp_process(), and ast_dsp_silence().
01221 { 01222 int accum; 01223 int x; 01224 int res = 0; 01225 01226 if (!len) 01227 return 0; 01228 accum = 0; 01229 for (x=0;x<len; x++) 01230 accum += abs(s[x]); 01231 accum /= len; 01232 if (accum < dsp->threshold) { 01233 /* Silent */ 01234 dsp->totalsilence += len/8; 01235 if (dsp->totalnoise) { 01236 /* Move and save history */ 01237 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0])); 01238 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise; 01239 /* we don't want to check for busydetect that frequently */ 01240 #if 0 01241 dsp->busymaybe = 1; 01242 #endif 01243 } 01244 dsp->totalnoise = 0; 01245 res = 1; 01246 } else { 01247 /* Not silent */ 01248 dsp->totalnoise += len/8; 01249 if (dsp->totalsilence) { 01250 int silence1 = dsp->historicsilence[DSP_HISTORY - 1]; 01251 int silence2 = dsp->historicsilence[DSP_HISTORY - 2]; 01252 /* Move and save history */ 01253 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0])); 01254 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence; 01255 /* check if the previous sample differs only by BUSY_PERCENT from the one before it */ 01256 if (silence1 < silence2) { 01257 if (silence1 + silence1*BUSY_PERCENT/100 >= silence2) 01258 dsp->busymaybe = 1; 01259 else 01260 dsp->busymaybe = 0; 01261 } else { 01262 if (silence1 - silence1*BUSY_PERCENT/100 <= silence2) 01263 dsp->busymaybe = 1; 01264 else 01265 dsp->busymaybe = 0; 01266 } 01267 } 01268 dsp->totalsilence = 0; 01269 } 01270 if (totalsilence) 01271 *totalsilence = dsp->totalsilence; 01272 return res; 01273 }
| 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 }
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 }
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, s, 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 1765 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 dahdi_hangup(), dahdi_new(), dahdi_setoption(), mgcp_new(), sip_new(), and ss_thread().