Codename Pineapple

Home page | Mailing list | Docs

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

Asterisk developer's documentation :: Codename Pineapple


dsp.c File Reference


Detailed Description

Convenience Signal Processing routines.

Author:
Mark Spencer <markster@digium.com>

Steve Underwood <steveu@coppice.org>

Definition in file dsp.c.

#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 "asterisk/options.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_2ND_HARMONIC_COL   63.1
#define DTMF_2ND_HARMONIC_ROW   ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)
#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_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 *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 []


Define Documentation

#define BELL_MF_RELATIVE_PEAK   12.6
 

Definition at line 181 of file dsp.c.

#define BELL_MF_THRESHOLD   1.6e9
 

Definition at line 179 of file dsp.c.

#define BELL_MF_TWIST   4.0
 

Definition at line 180 of file dsp.c.

#define BUSYDETECT_MARTIN
 

Definition at line 185 of file dsp.c.

#define DEFAULT_THRESHOLD   512
 

Definition at line 114 of file dsp.c.

Referenced by ast_dsp_new().

#define DSP_HISTORY   15
 

Remember last 15 units

Definition at line 125 of file dsp.c.

Referenced by __ast_dsp_silence(), ast_dsp_busydetect(), ast_dsp_new(), and ast_dsp_set_busy_count().

#define DTMF_2ND_HARMONIC_COL   63.1
 

Definition at line 169 of file dsp.c.

#define DTMF_2ND_HARMONIC_ROW   ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)
 

Definition at line 168 of file dsp.c.

#define DTMF_NORMAL_TWIST   6.3
 

Definition at line 160 of file dsp.c.

#define DTMF_RELATIVE_PEAK_COL   6.3
 

Definition at line 167 of file dsp.c.

#define DTMF_RELATIVE_PEAK_ROW   6.3
 

Definition at line 166 of file dsp.c.

#define DTMF_REVERSE_TWIST   ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)
 

Definition at line 164 of file dsp.c.

#define DTMF_THRESHOLD   8.0e7
 

Definition at line 157 of file dsp.c.

#define DTMF_TO_TOTAL_ENERGY   42.0
 

Definition at line 170 of file dsp.c.

#define FAX_2ND_HARMONIC   2.0
 

Definition at line 159 of file dsp.c.

#define FAX_DETECT
 

Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE

Definition at line 128 of file dsp.c.

#define FAX_THRESHOLD   8.0e7
 

Definition at line 158 of file dsp.c.

#define FIX_INF inf   ) 
 

Referenced by ast_dsp_process().

#define MAX_DTMF_DIGITS   128
 

Definition at line 143 of file dsp.c.

#define MF_GSIZE   120
 

Definition at line 690 of file dsp.c.

Referenced by mf_detect().

#define TONE_MIN_THRESH   1e8
 

How much tone there should be at least to attempt

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

Referenced by __ast_dsp_call_progress(), and pair_there().


Enumeration Type Documentation

enum busy_detect
 

Enumerator:
BUSY_PERCENT  The percentage difference between the two last silence periods
BUSY_PAT_PERCENT  The percentage difference between measured and actual pattern
BUSY_THRESHOLD  Max number of ms difference between max and min times in busy
BUSY_MIN  Busy must be at least 80 ms in half-cadence
BUSY_MAX  Busy can't be longer than 3100 ms in half-cadence

Definition at line 116 of file dsp.c.

00116                  {
00117    BUSY_PERCENT = 10,      /*!< The percentage difference between the two last silence periods */
00118    BUSY_PAT_PERCENT = 7,   /*!< The percentage difference between measured and actual pattern */
00119    BUSY_THRESHOLD = 100,   /*!< Max number of ms difference between max and min times in busy */
00120    BUSY_MIN = 75,          /*!< Busy must be at least 80 ms in half-cadence */
00121    BUSY_MAX =3100          /*!< Busy can't be longer than 3100 ms in half-cadence */
00122 };

enum freq_index
 

Enumerator:
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 77 of file dsp.c.

00077                 { 
00078    /*! For US modes { */
00079    HZ_350 = 0,
00080    HZ_440,
00081    HZ_480,
00082    HZ_620,
00083    HZ_950,
00084    HZ_1400,
00085    HZ_1800, /*!< } */
00086 
00087    /*! For CR/BR modes */
00088    HZ_425 = 0,
00089 
00090    /*! For UK mode */
00091    HZ_400 = 0
00092 };

enum gsamp_size
 

Number of goertzels for progress detect

Enumerator:
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 65 of file dsp.c.

00065                 {
00066    GSAMP_SIZE_NA = 183,       /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
00067    GSAMP_SIZE_CR = 188,       /*!< Costa Rica, Brazil - Only care about 425 Hz */
00068    GSAMP_SIZE_UK = 160        /*!< UK disconnect goertzel feed - should trigger 400hz */
00069 };

enum gsamp_thresh
 

All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms)

Enumerator:
THRESH_RING  Need at least 150ms ring to accept
THRESH_TALK  Talk detection does not work continuously
THRESH_BUSY  Need at least 80ms to accept
THRESH_CONGESTION  Need at least 80ms to accept
THRESH_HANGUP  Need at least 1300ms to accept hangup
THRESH_RING2ANSWER  Timeout from start of ring to answer (about 6600 ms)

Definition at line 134 of file dsp.c.

00134                   {
00135    THRESH_RING = 8,           /*!< Need at least 150ms ring to accept */
00136    THRESH_TALK = 2,           /*!< Talk detection does not work continuously */
00137    THRESH_BUSY = 4,           /*!< Need at least 80ms to accept */
00138    THRESH_CONGESTION = 4,     /*!< Need at least 80ms to accept */
00139    THRESH_HANGUP = 60,        /*!< Need at least 1300ms to accept hangup */
00140    THRESH_RING2ANSWER = 300   /*!< Timeout from start of ring to answer (about 6600 ms) */
00141 };

enum prog_mode
 

Enumerator:
PROG_MODE_NA 
PROG_MODE_CR 
PROG_MODE_UK 

Definition at line 71 of file dsp.c.

00071                {
00072    PROG_MODE_NA = 0,
00073    PROG_MODE_CR,
00074    PROG_MODE_UK
00075 };


Function Documentation

static int __ast_dsp_call_progress struct ast_dsp dsp,
short *  s,
int  len
[static]
 

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

01052 {
01053    int x;
01054    int y;
01055    int pass;
01056    int newstate = DSP_TONE_STATE_SILENCE;
01057    int res = 0;
01058    while (len) {
01059       /* Take the lesser of the number of samples we need and what we have */
01060       pass = len;
01061       if (pass > dsp->gsamp_size - dsp->gsamps) 
01062          pass = dsp->gsamp_size - dsp->gsamps;
01063       for (x=0;x<pass;x++) {
01064          for (y=0;y<dsp->freqcount;y++) 
01065             goertzel_sample(&dsp->freqs[y], s[x]);
01066          dsp->genergy += s[x] * s[x];
01067       }
01068       s += pass;
01069       dsp->gsamps += pass;
01070       len -= pass;
01071       if (dsp->gsamps == dsp->gsamp_size) {
01072          float hz[7];
01073          for (y=0;y<7;y++)
01074             hz[y] = goertzel_result(&dsp->freqs[y]);
01075 #if 0
01076          printf("\n350:     425:     440:     480:     620:     950:     1400:    1800:    Energy:   \n");
01077          printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n", 
01078             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);
01079 #endif
01080          switch (dsp->progmode) {
01081          case PROG_MODE_NA:
01082             if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
01083                newstate = DSP_TONE_STATE_BUSY;
01084             } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01085                newstate = DSP_TONE_STATE_RINGING;
01086             } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01087                newstate = DSP_TONE_STATE_DIALTONE;
01088             } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01089                newstate = DSP_TONE_STATE_SPECIAL1;
01090             } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01091                if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
01092                   newstate = DSP_TONE_STATE_SPECIAL2;
01093             } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01094                if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
01095                   newstate = DSP_TONE_STATE_SPECIAL3;
01096             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01097                newstate = DSP_TONE_STATE_TALKING;
01098             } else
01099                newstate = DSP_TONE_STATE_SILENCE;
01100             break;
01101          case PROG_MODE_CR:
01102             if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01103                newstate = DSP_TONE_STATE_RINGING;
01104             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01105                newstate = DSP_TONE_STATE_TALKING;
01106             } else
01107                newstate = DSP_TONE_STATE_SILENCE;
01108             break;
01109          case PROG_MODE_UK:
01110             if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
01111                newstate = DSP_TONE_STATE_HUNGUP;
01112             }
01113             break;
01114          default:
01115             ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01116          }
01117          if (newstate == dsp->tstate) {
01118             dsp->tcount++;
01119             if (dsp->ringtimeout)
01120                dsp->ringtimeout++;
01121             switch (dsp->tstate) {
01122                case DSP_TONE_STATE_RINGING:
01123                   if ((dsp->features & DSP_PROGRESS_RINGING) &&
01124                       (dsp->tcount==THRESH_RING)) {
01125                      res = AST_CONTROL_RINGING;
01126                      dsp->ringtimeout= 1;
01127                   }
01128                   break;
01129                case DSP_TONE_STATE_BUSY:
01130                   if ((dsp->features & DSP_PROGRESS_BUSY) &&
01131                       (dsp->tcount==THRESH_BUSY)) {
01132                      res = AST_CONTROL_BUSY;
01133                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01134                   }
01135                   break;
01136                case DSP_TONE_STATE_TALKING:
01137                   if ((dsp->features & DSP_PROGRESS_TALK) &&
01138                       (dsp->tcount==THRESH_TALK)) {
01139                      res = AST_CONTROL_ANSWER;
01140                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01141                   }
01142                   break;
01143                case DSP_TONE_STATE_SPECIAL3:
01144                   if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
01145                       (dsp->tcount==THRESH_CONGESTION)) {
01146                      res = AST_CONTROL_CONGESTION;
01147                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01148                   }
01149                   break;
01150                case DSP_TONE_STATE_HUNGUP:
01151                   if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
01152                       (dsp->tcount==THRESH_HANGUP)) {
01153                      res = AST_CONTROL_HANGUP;
01154                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01155                   }
01156                   break;
01157             }
01158             if (dsp->ringtimeout==THRESH_RING2ANSWER) {
01159 #if 0
01160                ast_log(LOG_NOTICE, "Consider call as answered because of timeout after last ring\n");
01161 #endif
01162                res = AST_CONTROL_ANSWER;
01163                dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01164             }
01165          } else {
01166 #if 0
01167             ast_log(LOG_NOTICE, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
01168             ast_log(LOG_NOTICE, "Start state %d\n", newstate);
01169 #endif
01170             dsp->tstate = newstate;
01171             dsp->tcount = 1;
01172          }
01173          
01174          /* Reset goertzel */                
01175          for (x=0;x<7;x++)
01176             dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01177          dsp->gsamps = 0;
01178          dsp->genergy = 0.0;
01179       }
01180    }
01181 #if 0
01182    if (res)
01183       printf("Returning %d\n", res);
01184 #endif      
01185    return res;
01186 }

static int __ast_dsp_digitdetect struct ast_dsp dsp,
short *  s,
int  len,
int *  writeback
[static]
 

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

00977 {
00978    int res;
00979    
00980    if (dsp->digitmode & DSP_DIGITMODE_MF)
00981       res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00982    else
00983       res = dtmf_detect(&dsp->td.dtmf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback, dsp->features & DSP_FEATURE_FAX_DETECT);
00984    return res;
00985 }

static int __ast_dsp_silence struct ast_dsp dsp,
short *  s,
int  len,
int *  totalsilence
[static]
 

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

01202 {
01203    int accum;
01204    int x;
01205    int res = 0;
01206 
01207    if (!len)
01208       return 0;
01209    accum = 0;
01210    for (x=0;x<len; x++) 
01211       accum += abs(s[x]);
01212    accum /= len;
01213    if (accum < dsp->threshold) {
01214       /* Silent */
01215       dsp->totalsilence += len/8;
01216       if (dsp->totalnoise) {
01217          /* Move and save history */
01218          memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
01219          dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01220 /* we don't want to check for busydetect that frequently */
01221 #if 0
01222          dsp->busymaybe = 1;
01223 #endif
01224       }
01225       dsp->totalnoise = 0;
01226       res = 1;
01227    } else {
01228       /* Not silent */
01229       dsp->totalnoise += len/8;
01230       if (dsp->totalsilence) {
01231          int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01232          int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01233          /* Move and save history */
01234          memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
01235          dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01236          /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
01237          if (silence1 < silence2) {
01238             if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
01239                dsp->busymaybe = 1;
01240             else 
01241                dsp->busymaybe = 0;
01242          } else {
01243             if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
01244                dsp->busymaybe = 1;
01245             else 
01246                dsp->busymaybe = 0;
01247          }
01248       }
01249       dsp->totalsilence = 0;
01250    }
01251    if (totalsilence)
01252       *totalsilence = dsp->totalsilence;
01253    return res;
01254 }

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