Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

dsp.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- A telephony toolkit for Linux.
00003  *
00004  * Convenience Signal Processing routines
00005  * 
00006  * Copyright (C) 2002, Digium
00007  *
00008  * Mark Spencer <markster@linux-support.net>
00009  *
00010  * This program is free software, distributed under the terms of
00011  * the GNU General Public License.
00012  *
00013  * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
00014  * DTMF detector.
00015  *
00016  */
00017 
00018 /* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
00019 /*
00020    tone_detect.c - General telephony tone detection, and specific
00021                         detection of DTMF.
00022 
00023         Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
00024 
00025         Despite my general liking of the GPL, I place this code in the
00026         public domain for the benefit of all mankind - even the slimy
00027         ones who might try to proprietize my work and use it to my
00028         detriment.
00029 */
00030 
00031 #include <sys/types.h>
00032 #include <asterisk/frame.h>
00033 #include <asterisk/channel.h>
00034 #include <asterisk/channel_pvt.h>
00035 #include <asterisk/logger.h>
00036 #include <asterisk/dsp.h>
00037 #include <asterisk/ulaw.h>
00038 #include <asterisk/alaw.h>
00039 #include <stdlib.h>
00040 #include <unistd.h>
00041 #include <string.h>
00042 #include <math.h>
00043 #include <errno.h>
00044 #include <stdio.h>
00045 
00046 /* Number of goertzels for progress detect */
00047 #define GSAMP_SIZE_NA 183        /* North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
00048 #define GSAMP_SIZE_CR 188        /* Costa Rica - Only care about 425 Hz */
00049 
00050 #define PROG_MODE_NA    0
00051 #define PROG_MODE_CR    1  
00052 
00053 /* For US modes */
00054 #define HZ_350  0
00055 #define HZ_440  1
00056 #define HZ_480  2
00057 #define HZ_620  3
00058 #define HZ_950  4
00059 #define HZ_1400 5
00060 #define HZ_1800 6
00061 
00062 /* For CR modes */
00063 #define HZ_425 0
00064 
00065 static struct progalias {
00066    char *name;
00067    int mode;
00068 } aliases[] = {
00069    { "us", PROG_MODE_NA },
00070    { "ca", PROG_MODE_NA },
00071    { "cr", PROG_MODE_CR },
00072 };
00073 
00074 static struct progress {
00075    int size;
00076    int freqs[7];
00077 } modes[] = {
00078    { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /* North America */
00079    { GSAMP_SIZE_CR, { 425 } },
00080 };
00081 
00082 #define DEFAULT_THRESHOLD 512
00083 
00084 #define BUSY_PERCENT    10 /* The percentage diffrence between the two last silence periods */
00085 #define BUSY_THRESHOLD     100   /* Max number of ms difference between max and min times in busy */
00086 #define BUSY_MIN     75 /* Busy must be at least 80 ms in half-cadence */
00087 #define BUSY_MAX     1100  /* Busy can't be longer than 1100 ms in half-cadence */
00088 
00089 /* Remember last 15 units */
00090 #define DSP_HISTORY 15
00091 
00092 /* Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE */
00093 #define FAX_DETECT
00094 
00095 #define TONE_THRESH 10.0   /* How much louder the tone should be than channel energy */
00096 #define TONE_MIN_THRESH 1e8   /* How much tone there should be at least to attempt */
00097 #define COUNT_THRESH  3    /* Need at least 50ms of stuff to count it */
00098 
00099 #define TONE_STATE_SILENCE  0
00100 #define TONE_STATE_RINGING  1 
00101 #define TONE_STATE_DIALTONE 2
00102 #define TONE_STATE_TALKING  3
00103 #define TONE_STATE_BUSY     4
00104 #define TONE_STATE_SPECIAL1   5
00105 #define TONE_STATE_SPECIAL2 6
00106 #define TONE_STATE_SPECIAL3 7
00107 
00108 #define  MAX_DTMF_DIGITS 128
00109 
00110 /* Basic DTMF specs:
00111  *
00112  * Minimum tone on = 40ms
00113  * Minimum tone off = 50ms
00114  * Maximum digit rate = 10 per second
00115  * Normal twist <= 8dB accepted
00116  * Reverse twist <= 4dB accepted
00117  * S/N >= 15dB will detect OK
00118  * Attenuation <= 26dB will detect OK
00119  * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
00120  */
00121 
00122 #define DTMF_THRESHOLD              8.0e7
00123 #define FAX_THRESHOLD              8.0e7
00124 #define FAX_2ND_HARMONIC            2.0     /* 4dB */
00125 #define DTMF_NORMAL_TWIST           6.3     /* 8dB */
00126 #ifdef   RADIO_RELAX
00127 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5)     /* 4dB normal */
00128 #else
00129 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)     /* 4dB normal */
00130 #endif
00131 #define DTMF_RELATIVE_PEAK_ROW      6.3     /* 8dB */
00132 #define DTMF_RELATIVE_PEAK_COL      6.3     /* 8dB */
00133 #define DTMF_2ND_HARMONIC_ROW       ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)     /* 4dB normal */
00134 #define DTMF_2ND_HARMONIC_COL       63.1    /* 18dB */
00135 #define DTMF_TO_TOTAL_ENERGY      42.0
00136 
00137 #ifdef OLD_DSP_ROUTINES
00138 #define MF_THRESHOLD              8.0e7
00139 #define MF_NORMAL_TWIST           5.3     /* 8dB */
00140 #define MF_REVERSE_TWIST          4.0     /* was 2.5 */
00141 #define MF_RELATIVE_PEAK      5.3     /* 8dB */
00142 #define MF_2ND_HARMONIC       1.7 /* was 2.5  */
00143 #else
00144 #define BELL_MF_THRESHOLD           1.6e9
00145 #define BELL_MF_TWIST               4.0     /* 6dB */
00146 #define BELL_MF_RELATIVE_PEAK       12.6    /* 11dB */
00147 #endif
00148 
00149 typedef struct {
00150    float v2;
00151    float v3;
00152    float fac;
00153 #ifndef OLD_DSP_ROUTINES
00154    int samples;
00155 #endif   
00156 } goertzel_state_t;
00157 
00158 typedef struct
00159 {
00160 
00161     goertzel_state_t row_out[4];
00162     goertzel_state_t col_out[4];
00163 #ifdef FAX_DETECT
00164    goertzel_state_t fax_tone;
00165 #endif
00166 #ifdef OLD_DSP_ROUTINES
00167     goertzel_state_t row_out2nd[4];
00168     goertzel_state_t col_out2nd[4];
00169 #ifdef FAX_DETECT
00170    goertzel_state_t fax_tone2nd;    
00171 #endif
00172     int hit1;
00173     int hit2;
00174     int hit3;
00175     int hit4;
00176 #else
00177     int hits[3];
00178 #endif   
00179     int mhit;
00180     float energy;
00181     int current_sample;
00182 
00183     char digits[MAX_DTMF_DIGITS + 1];
00184     int current_digits;
00185     int detected_digits;
00186     int lost_digits;
00187     int digit_hits[16];
00188 
00189 
00190 #ifdef FAX_DETECT
00191    int fax_hits;
00192 #endif
00193 } dtmf_detect_state_t;
00194 
00195 typedef struct
00196 {
00197     goertzel_state_t tone_out[6];
00198     int mhit;
00199 #ifdef OLD_DSP_ROUTINES
00200     int hit1;
00201     int hit2;
00202     int hit3;
00203     int hit4;
00204     goertzel_state_t tone_out2nd[6];
00205     float energy;
00206 #else
00207     int hits[5];
00208 #endif
00209 
00210     int current_sample;
00211     char digits[MAX_DTMF_DIGITS + 1];
00212     int current_digits;
00213     int detected_digits;
00214     int lost_digits;
00215 #ifdef FAX_DETECT
00216    int fax_hits;
00217 #endif
00218 } mf_detect_state_t;
00219 
00220 static float dtmf_row[] =
00221 {
00222      697.0,  770.0,  852.0,  941.0
00223 };
00224 static float dtmf_col[] =
00225 {
00226     1209.0, 1336.0, 1477.0, 1633.0
00227 };
00228 
00229 static float mf_tones[] =
00230 {
00231    700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
00232 };
00233 
00234 #ifdef FAX_DETECT
00235 static float fax_freq = 1100.0;
00236 #endif
00237 
00238 static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
00239 
00240 #ifdef OLD_DSP_ROUTINES
00241 static char mf_hit[6][6] = {
00242    /*  700 + */ {   0, '1', '2', '4', '7', 'C' },
00243    /*  900 + */ { '1',   0, '3', '5', '8', 'A' },
00244    /* 1100 + */ { '2', '3',   0, '6', '9', '*' },
00245    /* 1300 + */ { '4', '5', '6',   0, '0', 'B' },
00246    /* 1500 + */ { '7', '8', '9', '0',  0, '#' },
00247    /* 1700 + */ { 'C', 'A', '*', 'B', '#',  0  },
00248 };
00249 #else
00250 static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
00251 #endif
00252 
00253 static inline void goertzel_sample(goertzel_state_t *s, short sample)
00254 {
00255    float v1;
00256    float fsamp  = sample;
00257    v1 = s->v2;
00258    s->v2 = s->v3;
00259    s->v3 = s->fac * s->v2 - v1 + fsamp;
00260 }
00261 
00262 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
00263 {
00264    int i;
00265    for (i=0;i<count;i++) 
00266       goertzel_sample(s, samps[i]);
00267 }
00268 
00269 
00270 static inline float goertzel_result(goertzel_state_t *s)
00271 {
00272    return s->v3 * s->v3 + s->v2 * s->v2 - s->v2 * s->v3 * s->fac;
00273 }
00274 
00275 static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
00276 {
00277    s->v2 = s->v3 = 0.0;
00278    s->fac = 2.0 * cos(2.0 * M_PI * (freq / 8000.0));
00279 #ifndef OLD_DSP_ROUTINES
00280    s->samples = samples;
00281 #endif
00282 }
00283 
00284 static inline void goertzel_reset(goertzel_state_t *s)
00285 {
00286    s->v2 = s->v3 = 0.0;
00287 }
00288 
00289 struct ast_dsp {
00290    struct ast_frame f;
00291    int threshold;
00292    int totalsilence;
00293    int totalnoise;
00294    int features;
00295    int busymaybe;
00296    int busycount;
00297    int historicnoise[DSP_HISTORY];
00298    int historicsilence[DSP_HISTORY];
00299    goertzel_state_t freqs[7];
00300    int freqcount;
00301    int gsamps;
00302    int gsamp_size;
00303    int progmode;
00304    int tstate;
00305    int tcount;
00306    int digitmode;
00307    int thinkdigit;
00308    float genergy;
00309    union {
00310       dtmf_detect_state_t dtmf;
00311       mf_detect_state_t mf;
00312    } td;
00313 };
00314 
00315 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00316 {
00317     int i;
00318 
00319 #ifdef OLD_DSP_ROUTINES
00320     s->hit1 = 
00321     s->mhit = 
00322    s->hit3 =
00323    s->hit4 = 
00324     s->hit2 = 0;
00325 #else
00326    s->hits[0] = s->hits[1] = s->hits[2] = 0;
00327 #endif
00328     for (i = 0;  i < 4;  i++)
00329     {
00330     
00331          goertzel_init (&s->row_out[i], dtmf_row[i], 102);
00332       goertzel_init (&s->col_out[i], dtmf_col[i], 102);
00333 #ifdef OLD_DSP_ROUTINES
00334       goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0, 102);
00335       goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0, 102);
00336 #endif   
00337       s->energy = 0.0;
00338     }
00339 
00340 #ifdef FAX_DETECT
00341    /* Same for the fax dector */
00342     goertzel_init (&s->fax_tone, fax_freq, 102);
00343 
00344 #ifdef OLD_DSP_ROUTINES
00345    /* Same for the fax dector 2nd harmonic */
00346     goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
00347 #endif   
00348 #endif /* FAX_DETECT */
00349    
00350     s->current_sample = 0;
00351     s->detected_digits = 0;
00352    s->current_digits = 0;
00353    memset(&s->digits, 0, sizeof(s->digits));
00354     s->lost_digits = 0;
00355     s->digits[0] = '\0';
00356 }
00357 
00358 static void ast_mf_detect_init (mf_detect_state_t *s)
00359 {
00360     int i;
00361 
00362 #ifdef OLD_DSP_ROUTINES
00363     s->hit1 = 
00364     s->hit2 = 0;
00365 #else 
00366    s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
00367 #endif
00368     for (i = 0;  i < 6;  i++)
00369     {
00370     
00371          goertzel_init (&s->tone_out[i], mf_tones[i], 160);
00372 #ifdef OLD_DSP_ROUTINES
00373       goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
00374       s->energy = 0.0;
00375 #endif
00376    
00377     }
00378 
00379    s->current_digits = 0;
00380    memset(&s->digits, 0, sizeof(s->digits));
00381     s->current_sample = 0;
00382     s->detected_digits = 0;
00383     s->lost_digits = 0;
00384     s->digits[0] = '\0';
00385     s->mhit = 0;
00386 }
00387 
00388 static int dtmf_detect (dtmf_detect_state_t *s,
00389                  int16_t amp[],
00390                  int samples, 
00391        int digitmode, int *writeback, int faxdetect)
00392 {
00393 
00394     float row_energy[4];
00395     float col_energy[4];
00396 #ifdef FAX_DETECT
00397     float fax_energy;
00398 #ifdef OLD_DSP_ROUTINES
00399     float fax_energy_2nd;
00400 #endif   
00401 #endif /* FAX_DETECT */
00402     float famp;
00403     float v1;
00404     int i;
00405     int j;
00406     int sample;
00407     int best_row;
00408     int best_col;
00409     int hit;
00410     int limit;
00411 
00412     hit = 0;
00413     for (sample = 0;  sample < samples;  sample = limit)
00414     {
00415         /* 102 is optimised to meet the DTMF specs. */
00416         if ((samples - sample) >= (102 - s->current_sample))
00417             limit = sample + (102 - s->current_sample);
00418         else
00419             limit = samples;
00420 #if defined(USE_3DNOW)
00421         _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
00422         _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
00423 #ifdef OLD_DSP_ROUTINES
00424         _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
00425         _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
00426 #endif      
00427       /* XXX Need to fax detect for 3dnow too XXX */
00428       #warning "Fax Support Broken"
00429 #else
00430         /* The following unrolled loop takes only 35% (rough estimate) of the 
00431            time of a rolled loop on the machine on which it was developed */
00432         for (j = sample;  j < limit;  j++)
00433         {
00434             famp = amp[j];
00435        
00436        s->energy += famp*famp;
00437        
00438             /* With GCC 2.95, the following unrolled code seems to take about 35%
00439                (rough estimate) as long as a neat little 0-3 loop */
00440             v1 = s->row_out[0].v2;
00441             s->row_out[0].v2 = s->row_out[0].v3;
00442             s->row_out[0].v3 = s->row_out[0].fac*s->row_out[0].v2 - v1 + famp;
00443     
00444             v1 = s->col_out[0].v2;
00445             s->col_out[0].v2 = s->col_out[0].v3;
00446             s->col_out[0].v3 = s->col_out[0].fac*s->col_out[0].v2 - v1 + famp;
00447     
00448             v1 = s->row_out[1].v2;
00449             s->row_out[1].v2 = s->row_out[1].v3;
00450             s->row_out[1].v3 = s->row_out[1].fac*s->row_out[1].v2 - v1 + famp;
00451     
00452             v1 = s->col_out[1].v2;
00453             s->col_out[1].v2 = s->col_out[1].v3;
00454             s->col_out[1].v3 = s->col_out[1].fac*s->col_out[1].v2 - v1 + famp;
00455     
00456             v1 = s->row_out[2].v2;
00457             s->row_out[2].v2 = s->row_out[2].v3;
00458             s->row_out[2].v3 = s->row_out[2].fac*s->row_out[2].v2 - v1 + famp;
00459     
00460             v1 = s->col_out[2].v2;
00461             s->col_out[2].v2 = s->col_out[2].v3;
00462             s->col_out[2].v3 = s->col_out[2].fac*s->col_out[2].v2 - v1 + famp;
00463     
00464             v1 = s->row_out[3].v2;
00465             s->row_out[3].v2 = s->row_out[3].v3;
00466             s->row_out[3].v3 = s->row_out[3].fac*s->row_out[3].v2 - v1 + famp;
00467 
00468             v1 = s->col_out[3].v2;
00469             s->col_out[3].v2 = s->col_out[3].v3;
00470             s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp;
00471 
00472 #ifdef FAX_DETECT
00473          /* Update fax tone */
00474             v1 = s->fax_tone.v2;
00475             s->fax_tone.v2 = s->fax_tone.v3;
00476             s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp;
00477 #endif /* FAX_DETECT */
00478 #ifdef OLD_DSP_ROUTINES
00479             v1 = s->col_out2nd[0].v2;
00480             s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
00481             s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp;
00482         
00483             v1 = s->row_out2nd[0].v2;
00484             s->row_out2nd[0].v2 = s->row_out2nd[0].v3;
00485             s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp;
00486         
00487             v1 = s->col_out2nd[1].v2;
00488             s->col_out2nd[1].v2 = s->col_out2nd[1].v3;
00489             s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp;
00490     
00491             v1 = s->row_out2nd[1].v2;
00492             s->row_out2nd[1].v2 = s->row_out2nd[1].v3;
00493             s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp;
00494         
00495             v1 = s->col_out2nd[2].v2;
00496             s->col_out2nd[2].v2 = s->col_out2nd[2].v3;
00497             s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp;
00498         
00499             v1 = s->row_out2nd[2].v2;
00500             s->row_out2nd[2].v2 = s->row_out2nd[2].v3;
00501             s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp;
00502         
00503             v1 = s->col_out2nd[3].v2;
00504             s->col_out2nd[3].v2 = s->col_out2nd[3].v3;
00505             s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp;
00506         
00507             v1 = s->row_out2nd[3].v2;
00508             s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
00509             s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
00510 
00511 
00512 #ifdef FAX_DETECT
00513       /* Update fax tone */            
00514        v1 = s->fax_tone.v2;
00515             s->fax_tone2nd.v2 = s->fax_tone2nd.v3;
00516             s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp;
00517 #endif /* FAX_DETECT */
00518 #endif
00519         }
00520 #endif
00521         s->current_sample += (limit - sample);
00522         if (s->current_sample < 102) {
00523          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00524             /* If we had a hit last time, go ahead and clear this out since likely it
00525                will be another hit */
00526             for (i=sample;i<limit;i++) 
00527                amp[i] = 0;
00528             *writeback = 1;
00529          }
00530             continue;
00531       }
00532 
00533 #ifdef FAX_DETECT
00534       /* Detect the fax energy, too */
00535       fax_energy = goertzel_result(&s->fax_tone);
00536 #endif
00537       
00538         /* We are at the end of a DTMF detection block */
00539         /* Find the peak row and the peak column */
00540         row_energy[0] = goertzel_result (&s->row_out[0]);
00541         col_energy[0] = goertzel_result (&s->col_out[0]);
00542 
00543    for (best_row = best_col = 0, i = 1;  i < 4;  i++)
00544    {
00545           row_energy[i] = goertzel_result (&s->row_out[i]);
00546             if (row_energy[i] > row_energy[best_row])
00547                 best_row = i;
00548           col_energy[i] = goertzel_result (&s->col_out[i]);
00549             if (col_energy[i] > col_energy[best_col])
00550                 best_col = i;
00551       }
00552         hit = 0;
00553         /* Basic signal level test and the twist test */
00554         if (row_energy[best_row] >= DTMF_THRESHOLD
00555        &&
00556        col_energy[best_col] >= DTMF_THRESHOLD
00557             &&
00558             col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST
00559             &&
00560             col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row])
00561         {
00562             /* Relative peak test */
00563             for (i = 0;  i < 4;  i++)
00564             {
00565                 if ((i != best_col  &&  col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col])
00566                     ||
00567                     (i != best_row  &&  row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row]))
00568                 {
00569                     break;
00570                 }
00571             }
00572 #ifdef OLD_DSP_ROUTINES
00573             /* ... and second harmonic test */
00574             if (i >= 4
00575            &&
00576       (row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy
00577                 &&
00578                 goertzel_result (&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col]
00579                 &&
00580                 goertzel_result (&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row])
00581 #else
00582             /* ... and fraction of total energy test */
00583             if (i >= 4
00584                 &&
00585                 (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy)
00586 #endif
00587             {
00588             /* Got a hit */
00589                 hit = dtmf_positions[(best_row << 2) + best_col];
00590             if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
00591                /* Zero out frame data if this is part DTMF */
00592                for (i=sample;i<limit;i++) 
00593                   amp[i] = 0;
00594                *writeback = 1;
00595             }
00596                 /* Look for two successive similar results */
00597                 /* The logic in the next test is:
00598                    We need two successive identical clean detects, with
00599          something different preceeding it. This can work with
00600          back to back differing digits. More importantly, it
00601          can work with nasty phones that give a very wobbly start
00602          to a digit. */
00603          
00604 #ifdef OLD_DSP_ROUTINES
00605                 if (hit == s->hit3  &&  s->hit3 != s->hit2)
00606                 {
00607                 s->mhit = hit;
00608                     s->digit_hits[(best_row << 2) + best_col]++;
00609                     s->detected_digits++;
00610                     if (s->current_digits < MAX_DTMF_DIGITS)
00611                     {
00612                         s->digits[s->current_digits++] = hit;
00613                         s->digits[s->current_digits] = '\0';
00614                     }
00615                     else
00616                     {
00617                         s->lost_digits++;
00618                     }
00619                 }
00620 #else          
00621                 if (hit == s->hits[2]  &&  hit != s->hits[1]  &&  hit != s->hits[0])
00622                 {
00623                 s->mhit = hit;
00624                     s->digit_hits[(best_row << 2) + best_col]++;
00625                     s->detected_digits++;
00626                     if (s->current_digits < MAX_DTMF_DIGITS)
00627                     {
00628                         s->digits[s->current_digits++] = hit;
00629                         s->digits[s->current_digits] = '\0';
00630                     }
00631                     else
00632                     {
00633                         s->lost_digits++;
00634                     }
00635                 }
00636 #endif
00637             }
00638         } 
00639 #ifdef FAX_DETECT
00640       if (!hit && (fax_energy >= FAX_THRESHOLD) && (fax_energy >= DTMF_TO_TOTAL_ENERGY*s->energy) && (faxdetect)) {
00641 #if 0
00642             printf("Fax energy/Second Harmonic: %f\n", fax_energy);
00643 #endif               
00644                /* XXX Probably need better checking than just this the energy XXX */
00645             hit = 'f';
00646             s->fax_hits++;
00647       }
00648       else {
00649          if (s->fax_hits > 5) {
00650              hit = 'f';
00651              s->mhit = 'f';
00652                 s->detected_digits++;
00653                 if (s->current_digits < MAX_DTMF_DIGITS)
00654                 {
00655                      s->digits[s->current_digits++] = hit;
00656                      s->digits[s->current_digits] = '\0';
00657                 }
00658                 else
00659                 {
00660                       s->lost_digits++;
00661                 }
00662          }
00663          s->fax_hits = 0;
00664       }
00665 #endif /* FAX_DETECT */
00666 #ifdef OLD_DSP_ROUTINES
00667         s->hit1 = s->hit2;
00668         s->hit2 = s->hit3;
00669         s->hit3 = hit;
00670 #else
00671         s->hits[0] = s->hits[1];
00672         s->hits[1] = s->hits[2];
00673         s->hits[2] = hit;
00674 #endif      
00675         /* Reinitialise the detector for the next block */
00676         for (i = 0;  i < 4;  i++)
00677         {
00678              goertzel_reset(&s->row_out[i]);
00679             goertzel_reset(&s->col_out[i]);
00680 #ifdef OLD_DSP_ROUTINES
00681           goertzel_reset(&s->row_out2nd[i]);
00682           goertzel_reset(&s->col_out2nd[i]);
00683 #endif         
00684         }
00685 #ifdef FAX_DETECT
00686       goertzel_reset (&s->fax_tone);
00687 #ifdef OLD_DSP_ROUTINES
00688       goertzel_reset (&s->fax_tone2nd);
00689 #endif         
00690 #endif
00691       s->energy = 0.0;
00692         s->current_sample = 0;
00693     }
00694     if ((!s->mhit) || (s->mhit != hit))
00695     {
00696    s->mhit = 0;
00697    return(0);
00698     }
00699     return (hit);
00700 }
00701 
00702 /* MF goertzel size */
00703 #ifdef OLD_DSP_ROUTINES
00704 #define  MF_GSIZE 160
00705 #else
00706 #define MF_GSIZE 120
00707 #endif
00708 
00709 static int mf_detect (mf_detect_state_t *s,
00710                  int16_t amp[],
00711                  int samples, 
00712        int digitmode, int *writeback)
00713 {
00714 
00715 #ifdef OLD_DSP_ROUTINES
00716     float tone_energy[6];
00717     int best1;
00718     int best2;
00719    float max;
00720    int sofarsogood;
00721 #else
00722     float energy[6];
00723     int best;
00724     int second_best;
00725 #endif
00726     float famp;
00727     float v1;
00728     int i;
00729     int j;
00730     int sample;
00731     int hit;
00732     int limit;
00733 
00734     hit = 0;
00735     for (sample = 0;  sample < samples;  sample = limit)
00736     {
00737         /* 80 is optimised to meet the MF specs. */
00738         if ((samples - sample) >= (MF_GSIZE - s->current_sample))
00739             limit = sample + (MF_GSIZE - s->current_sample);
00740         else
00741             limit = samples;
00742 #if defined(USE_3DNOW)
00743         _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
00744         _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
00745 #ifdef OLD_DSP_ROUTINES
00746         _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
00747         _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
00748 #endif
00749       /* XXX Need to fax detect for 3dnow too XXX */
00750       #warning "Fax Support Broken"
00751 #else
00752         /* The following unrolled loop takes only 35% (rough estimate) of the 
00753            time of a rolled loop on the machine on which it was developed */
00754         for (j = sample;  j < limit;  j++)
00755         {
00756             famp = amp[j];
00757        
00758 #ifdef OLD_DSP_ROUTINES
00759        s->energy += famp*famp;
00760 #endif
00761        
00762             /* With GCC 2.95, the following unrolled code seems to take about 35%
00763                (rough estimate) as long as a neat little 0-3 loop */
00764             v1 = s->tone_out[0].v2;
00765             s->tone_out[0].v2 = s->tone_out[0].v3;
00766             s->tone_out[0].v3 = s->tone_out[0].fac*s->tone_out[0].v2 - v1 + famp;
00767 
00768             v1 = s->tone_out[1].v2;
00769             s->tone_out[1].v2 = s->tone_out[1].v3;
00770             s->tone_out[1].v3 = s->tone_out[1].fac*s->tone_out[1].v2 - v1 + famp;
00771     
00772             v1 = s->tone_out[2].v2;
00773             s->tone_out[2].v2 = s->tone_out[2].v3;
00774             s->tone_out[2].v3 = s->tone_out[2].fac*s->tone_out[2].v2 - v1 + famp;
00775     
00776             v1 = s->tone_out[3].v2;
00777             s->tone_out[3].v2 = s->tone_out[3].v3;
00778             s->tone_out[3].v3 = s->tone_out[3].fac*s->tone_out[3].v2 - v1 + famp;
00779 
00780             v1 = s->tone_out[4].v2;
00781             s->tone_out[4].v2 = s->tone_out[4].v3;
00782             s->tone_out[4].v3 = s->tone_out[4].fac*s->tone_out[4].v2 - v1 + famp;
00783 
00784             v1 = s->tone_out[5].v2;
00785             s->tone_out[5].v2 = s->tone_out[5].v3;
00786             s->tone_out[5].v3 = s->tone_out[5].fac*s->tone_out[5].v2 - v1 + famp;
00787 
00788 #ifdef OLD_DSP_ROUTINES
00789             v1 = s->tone_out2nd[0].v2;
00790             s->tone_out2nd[0].v2 = s->tone_out2nd[0].v3;
00791             s->tone_out2nd[0].v3 = s->tone_out2nd[0].fac*s->tone_out2nd[0].v2 - v1 + famp;
00792         
00793             v1 = s->tone_out2nd[1].v2;
00794             s->tone_out2nd[1].v2 = s->tone_out2nd[1].v3;
00795             s->tone_out2nd[1].v3 = s->tone_out2nd[1].fac*s->tone_out2nd[1].v2 - v1 + famp;
00796         
00797             v1 = s->tone_out2nd[2].v2;
00798             s->tone_out2nd[2].v2 = s->tone_out2nd[2].v3;
00799             s->tone_out2nd[2].v3 = s->tone_out2nd[2].fac*s->tone_out2nd[2].v2 - v1 + famp;
00800         
00801             v1 = s->tone_out2nd[3].v2;
00802             s->tone_out2nd[3].v2 = s->tone_out2nd[3].v3;
00803             s->tone_out2nd[3].v3 = s->tone_out2nd[3].fac*s->tone_out2nd[3].v2 - v1 + famp;
00804 
00805             v1 = s->tone_out2nd[4].v2;
00806             s->tone_out2nd[4].v2 = s->tone_out2nd[4].v3;
00807             s->tone_out2nd[4].v3 = s->tone_out2nd[4].fac*s->tone_out2nd[2].v2 - v1 + famp;
00808         
00809             v1 = s->tone_out2nd[3].v2;
00810             s->tone_out2nd[5].v2 = s->tone_out2nd[6].v3;
00811             s->tone_out2nd[5].v3 = s->tone_out2nd[6].fac*s->tone_out2nd[3].v2 - v1 + famp;
00812 #endif
00813         }
00814 #endif
00815         s->current_sample += (limit - sample);
00816         if (s->current_sample < MF_GSIZE) {
00817          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00818             /* If we had a hit last time, go ahead and clear this out since likely it
00819                will be another hit */
00820             for (i=sample;i<limit;i++) 
00821                amp[i] = 0;
00822             *writeback = 1;
00823          }
00824             continue;
00825       }
00826 
00827 
00828 #ifdef OLD_DSP_ROUTINES    
00829       /* We're at the end of an MF detection block.  Go ahead and calculate
00830          all the energies. */
00831       for (i=0;i<6;i++) {
00832          tone_energy[i] = goertzel_result(&s->tone_out[i]);
00833       }
00834       /* Find highest */
00835       best1 = 0;
00836       max = tone_energy[0];
00837       for (i=1;i<6;i++) {
00838          if (tone_energy[i] > max) {
00839             max = tone_energy[i];
00840             best1 = i;
00841          }
00842       }
00843 
00844       /* Find 2nd highest */
00845       if (best1) {
00846          max = tone_energy[0];
00847          best2 = 0;
00848       } else {
00849          max = tone_energy[1];
00850          best2 = 1;
00851       }
00852 
00853       for (i=0;i<6;i++) {
00854          if (i == best1) continue;
00855          if (tone_energy[i] > max) {
00856             max = tone_energy[i];
00857             best2 = i;
00858          }
00859       }
00860             
00861         hit = 0;
00862       if (best1 != best2) sofarsogood=1;
00863       else sofarsogood=0;
00864       /* Check for relative energies */
00865       for (i=0;i<6;i++) {
00866          if (i == best1) continue;
00867          if (i == best2) continue;
00868          if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
00869             sofarsogood = 0;
00870             break;
00871          }
00872          if (tone_energy[best2] < tone_energy[i] * MF_RELATIVE_PEAK) {
00873             sofarsogood = 0;
00874             break;
00875          }
00876       }
00877       
00878       if (sofarsogood) {
00879          /* Check for 2nd harmonic */
00880          if (goertzel_result(&s->tone_out2nd[best1]) * MF_2ND_HARMONIC > tone_energy[best1]) 
00881             sofarsogood = 0;
00882          else if (goertzel_result(&s->tone_out2nd[best2]) * MF_2ND_HARMONIC > tone_energy[best2])
00883             sofarsogood = 0;
00884       }
00885       if (sofarsogood) {
00886          hit = mf_hit[best1][best2];
00887          if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
00888             /* Zero out frame data if this is part DTMF */
00889             for (i=sample;i<limit;i++) 
00890                amp[i] = 0;
00891             *writeback = 1;
00892          }
00893          /* Look for two consecutive clean hits */
00894          if ((hit == s->hit3) && (s->hit3 != s->hit2)) {
00895             s->mhit = hit;
00896             s->detected_digits++;
00897             if (s->current_digits < MAX_DTMF_DIGITS - 2) {
00898                s->digits[s->current_digits++] = hit;
00899                s->digits[s->current_digits] = '\0';
00900             } else {
00901                s->lost_digits++;
00902             }
00903          }
00904       }
00905       
00906         s->hit1 = s->hit2;
00907         s->hit2 = s->hit3;
00908         s->hit3 = hit;
00909         /* Reinitialise the detector for the next block */
00910         for (i = 0;  i < 6;  i++)
00911         {
00912              goertzel_reset(&s->tone_out[i]);
00913             goertzel_reset(&s->tone_out2nd[i]);
00914         }
00915       s->energy = 0.0;
00916         s->current_sample = 0;
00917     }
00918 #else
00919       /* We're at the end of an MF detection block.  */
00920         /* Find the two highest energies. The spec says to look for
00921            two tones and two tones only. Taking this literally -ie
00922            only two tones pass the minimum threshold - doesn't work
00923            well. The sinc function mess, due to rectangular windowing
00924            ensure that! Find the two highest energies and ensure they
00925            are considerably stronger than any of the others. */
00926         energy[0] = goertzel_result(&s->tone_out[0]);
00927         energy[1] = goertzel_result(&s->tone_out[1]);
00928         if (energy[0] > energy[1])
00929         {
00930             best = 0;
00931             second_best = 1;
00932         }
00933         else
00934         {
00935             best = 1;
00936             second_best = 0;
00937         }
00938         /*endif*/
00939         for (i = 2;  i < 6;  i++)
00940         {
00941             energy[i] = goertzel_result(&s->tone_out[i]);
00942             if (energy[i] >= energy[best])
00943             {
00944                 second_best = best;
00945                 best = i;
00946             }
00947             else if (energy[i] >= energy[second_best])
00948             {
00949                 second_best = i;
00950             }
00951         }
00952         /* Basic signal level and twist tests */
00953         hit = 0;
00954         if (energy[best] >= BELL_MF_THRESHOLD
00955             &&
00956             energy[second_best] >= BELL_MF_THRESHOLD
00957             &&
00958             energy[best] < energy[second_best]*BELL_MF_TWIST
00959             &&
00960             energy[best]*BELL_MF_TWIST > energy[second_best])
00961         {
00962             /* Relative peak test */
00963             hit = -1;
00964             for (i = 0;  i < 6;  i++)
00965             {
00966                 if (i != best  &&  i != second_best)
00967                 {
00968                     if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best])
00969                     {
00970                         /* The best two are not clearly the best */
00971                         hit = 0;
00972                         break;
00973                     }
00974                 }
00975             }
00976         }
00977         if (hit)
00978         {
00979             /* Get the values into ascending order */
00980             if (second_best < best)
00981             {
00982                 i = best;
00983                 best = second_best;
00984                 second_best = i;
00985             }
00986             best = best*5 + second_best - 1;
00987             hit = bell_mf_positions[best];
00988             /* Look for two successive similar results */
00989             /* The logic in the next test is:
00990                For KP we need 4 successive identical clean detects, with
00991                two blocks of something different preceeding it. For anything
00992                else we need two successive identical clean detects, with
00993                two blocks of something different preceeding it. */
00994             if (hit == s->hits[4]
00995                 &&
00996                 hit == s->hits[3]
00997                 &&
00998                    ((hit != '*'  &&  hit != s->hits[2]  &&  hit != s->hits[1])
00999                     ||
01000                     (hit == '*'  &&  hit == s->hits[2]  &&  hit != s->hits[1]  &&  hit != s->hits[0])))
01001             {
01002                 s->detected_digits++;
01003                 if (s->current_digits < MAX_DTMF_DIGITS)
01004                 {
01005                     s->digits[s->current_digits++] = hit;
01006                     s->digits[s->current_digits] = '\0';
01007                 }
01008                 else
01009                 {
01010                     s->lost_digits++;
01011                 }
01012             }
01013         }
01014         else
01015         {
01016             hit = 0;
01017         }
01018         s->hits[0] = s->hits[1];
01019         s->hits[1] = s->hits[2];
01020         s->hits[2] = s->hits[3];
01021         s->hits[3] = s->hits[4];
01022         s->hits[4] = hit;
01023         /* Reinitialise the detector for the next block */
01024         for (i = 0;  i < 6;  i++)
01025              goertzel_reset(&s->tone_out[i]);
01026         s->current_sample = 0;
01027     }
01028 #endif   
01029     if ((!s->mhit) || (s->mhit != hit))
01030     {
01031       s->mhit = 0;
01032       return(0);
01033     }
01034     return (hit);
01035 }
01036 
01037 static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
01038 {
01039    int res;
01040    if (dsp->digitmode & DSP_DIGITMODE_MF)
01041       res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
01042    else
01043       res = dtmf_detect(&dsp->td.dtmf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback, dsp->features & DSP_FEATURE_FAX_DETECT);
01044    return res;
01045 }
01046 
01047 int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
01048 {
01049    short *s;
01050    int len;
01051    int ign=0;
01052    if (inf->frametype != AST_FRAME_VOICE) {
01053       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01054       return 0;
01055    }
01056    if (inf->subclass != AST_FORMAT_SLINEAR) {
01057       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01058       return 0;
01059    }
01060    s = inf->data;
01061    len = inf->datalen / 2;
01062    return __ast_dsp_digitdetect(dsp, s, len, &ign);
01063 }
01064 
01065 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
01066 {
01067    /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
01068    /* Make sure absolute levels are high enough */
01069    if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
01070       return 0;
01071    /* Amplify ignored stuff */
01072    i2 *= TONE_THRESH;
01073    i1 *= TONE_THRESH;
01074    e *= TONE_THRESH;
01075    /* Check first tone */
01076    if ((p1 < i1) || (p1 < i2) || (p1 < e))
01077       return 0;
01078    /* And second */
01079    if ((p2 < i1) || (p2 < i2) || (p2 < e))
01080       return 0;
01081    /* Guess it's there... */
01082    return 1;
01083 }
01084 
01085 int ast_dsp_getdigits (struct ast_dsp *dsp,
01086               char *buf,
01087               int max)
01088 {
01089    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01090        if (max > dsp->td.mf.current_digits)
01091            max = dsp->td.mf.current_digits;
01092        if (max > 0)
01093        {
01094            memcpy (buf, dsp->td.mf.digits, max);
01095            memmove (dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
01096            dsp->td.mf.current_digits -= max;
01097        }
01098        buf[max] = '\0';
01099        return  max;
01100    } else {
01101        if (max > dsp->td.dtmf.current_digits)
01102            max = dsp->td.dtmf.current_digits;
01103        if (max > 0)
01104        {
01105            memcpy (buf, dsp->td.dtmf.digits, max);
01106            memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
01107            dsp->td.dtmf.current_digits -= max;
01108        }
01109        buf[max] = '\0';
01110        return  max;
01111    }
01112 }
01113 
01114 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
01115 {
01116    int x;
01117    int y;
01118    int pass;
01119    int newstate = TONE_STATE_SILENCE;
01120    int res = 0;
01121    while(len) {
01122       /* Take the lesser of the number of samples we need and what we have */
01123       pass = len;
01124       if (pass > dsp->gsamp_size - dsp->gsamps) 
01125          pass = dsp->gsamp_size - dsp->gsamps;
01126       for (x=0;x<pass;x++) {
01127          for (y=0;y<=dsp->freqcount;y++) 
01128             goertzel_sample(&dsp->freqs[y], s[x]);
01129          dsp->genergy += s[x] * s[x];
01130       }
01131       s += pass;
01132       dsp->gsamps += pass;
01133       len -= pass;
01134       if (dsp->gsamps == dsp->gsamp_size) {
01135          float hz[7];
01136          for (y=0;y<7;y++)
01137             hz[y] = goertzel_result(&dsp->freqs[y]);
01138 #if 0
01139          printf("\n350:     425:     440:     480:     620:     950:     1400:    1800:    Energy:   \n");
01140          printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n", 
01141             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);
01142 #endif
01143          switch(dsp->progmode) {
01144          case PROG_MODE_NA:
01145             if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
01146                newstate = TONE_STATE_BUSY;
01147             } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01148                newstate = TONE_STATE_RINGING;
01149             } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01150                newstate = TONE_STATE_DIALTONE;
01151             } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01152                newstate = TONE_STATE_SPECIAL1;
01153             } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01154                if (dsp->tstate == TONE_STATE_SPECIAL1)
01155                   newstate = TONE_STATE_SPECIAL2;
01156             } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01157                if (dsp->tstate == TONE_STATE_SPECIAL2)
01158                   newstate = TONE_STATE_SPECIAL3;
01159             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01160                newstate = TONE_STATE_TALKING;
01161             } else
01162                newstate = TONE_STATE_SILENCE;
01163             break;
01164          case PROG_MODE_CR:
01165             if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01166                newstate = TONE_STATE_RINGING;
01167             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01168                newstate = TONE_STATE_TALKING;
01169             } else
01170                newstate = TONE_STATE_SILENCE;
01171             break;
01172          default:
01173             ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01174          }
01175          if (newstate == dsp->tstate) {
01176             dsp->tcount++;
01177             if (dsp->tcount == COUNT_THRESH) {
01178                if (dsp->tstate == TONE_STATE_BUSY) {
01179                   res = AST_CONTROL_BUSY;
01180                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01181                } else if (dsp->tstate == TONE_STATE_TALKING) {
01182                   res = AST_CONTROL_ANSWER;
01183                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01184                } else if (dsp->tstate == TONE_STATE_RINGING)
01185                   res = AST_CONTROL_RINGING;
01186                else if (dsp->tstate == TONE_STATE_SPECIAL3) {
01187                   res = AST_CONTROL_CONGESTION;
01188                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01189                }
01190                
01191             }
01192          } else {
01193 #if 0
01194             printf("Newstate: %d\n", newstate);
01195 #endif
01196             dsp->tstate = newstate;
01197             dsp->tcount = 1;
01198          }
01199          
01200          /* Reset goertzel */                
01201          for (x=0;x<7;x++)
01202             dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01203          dsp->gsamps = 0;
01204          dsp->genergy = 0.0;
01205       }
01206    }
01207 #if 0
01208    if (res)
01209       printf("Returning %d\n", res);
01210 #endif      
01211    return res;
01212 }
01213 
01214 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01215 {
01216    if (inf->frametype != AST_FRAME_VOICE) {
01217       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01218       return 0;
01219    }
01220    if (inf->subclass != AST_FORMAT_SLINEAR) {
01221       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01222       return 0;
01223    }
01224    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01225 }
01226 
01227 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
01228 {
01229    int accum;
01230    int x;
01231    int res = 0;
01232 
01233    if (!len)
01234       return 0;
01235    
01236    accum = 0;
01237    for (x=0;x<len; x++) 
01238       accum += abs(s[x]);
01239    accum /= len;
01240    if (accum < dsp->threshold) {
01241       dsp->totalsilence += len/8;
01242       if (dsp->totalnoise) {
01243          /* Move and save history */
01244          memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
01245          dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01246 /* we don't want to check for busydetect that frequently */
01247 #if 0
01248          dsp->busymaybe = 1;
01249 #endif
01250       }
01251       dsp->totalnoise = 0;
01252       res = 1;
01253    } else {
01254       dsp->totalnoise += len/8;
01255       if (dsp->totalsilence) {
01256          int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01257          int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01258          /* Move and save history */
01259          memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
01260          dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01261          /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
01262          if (silence1 < silence2) {
01263             if (silence1 + silence1/BUSY_PERCENT >= silence2)
01264                dsp->busymaybe = 1;
01265             else 
01266                dsp->busymaybe = 0;
01267          } else {
01268             if (silence1 - silence1/BUSY_PERCENT <= silence2)
01269                dsp->busymaybe = 1;
01270             else 
01271                dsp->busymaybe = 0;
01272          }
01273                
01274       }
01275       dsp->totalsilence = 0;
01276    }
01277    if (totalsilence)
01278       *totalsilence = dsp->totalsilence;
01279    return res;
01280 }
01281 #ifdef BUSYDETECT_MARTIN
01282 int ast_dsp_busydetect(struct ast_dsp *dsp)
01283 {
01284    int res = 0, x;
01285 #ifndef BUSYDETECT_TONEONLY
01286    int avgsilence = 0, hitsilence = 0;
01287 #endif
01288    int avgtone = 0, hittone = 0;
01289    if (!dsp->busymaybe)
01290       return res;
01291    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01292 #ifndef BUSYDETECT_TONEONLY
01293       avgsilence += dsp->historicsilence[x];
01294 #endif
01295       avgtone += dsp->historicnoise[x];
01296    }
01297 #ifndef BUSYDETECT_TONEONLY
01298    avgsilence /= dsp->busycount;
01299 #endif
01300    avgtone /= dsp->busycount;
01301    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01302 #ifndef BUSYDETECT_TONEONLY
01303       if (avgsilence > dsp->historicsilence[x]) {
01304          if (avgsilence - (avgsilence / BUSY_PERCENT) <= dsp->historicsilence[x])
01305             hitsilence++;
01306       } else {
01307          if (avgsilence + (avgsilence / BUSY_PERCENT) >= dsp->historicsilence[x])
01308             hitsilence++;
01309       }
01310 #endif
01311       if (avgtone > dsp->historicnoise[x]) {
01312          if (avgtone - (avgtone / BUSY_PERCENT) <= dsp->historicnoise[x])
01313             hittone++;
01314       } else {
01315          if (avgtone + (avgtone / BUSY_PERCENT) >= dsp->historicnoise[x])
01316             hittone++;
01317       }
01318    }
01319 #ifndef BUSYDETECT_TONEONLY
01320    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01321 #else
01322    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01323 #endif
01324 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01325 #ifdef BUSYDETECT_TONEONLY
01326 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01327 #endif
01328       if (avgtone > avgsilence) {
01329          if (avgtone - avgtone/(BUSY_PERCENT*2) <= avgsilence)
01330             res = 1;
01331       } else {
01332          if (avgtone + avgtone/(BUSY_PERCENT*2) >= avgsilence)
01333             res = 1;
01334       }
01335 #else
01336       res = 1;
01337 #endif
01338    }
01339 #if 0
01340    if (res)
01341       ast_log(LOG_NOTICE, "detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01342 #endif
01343    return res;
01344 }
01345 #endif
01346 
01347 #ifdef BUSYDETECT
01348 int ast_dsp_busydetect(struct ast_dsp *dsp)
01349 {
01350    int x;
01351    int res = 0;
01352    int max, min;
01353 
01354 #if 0
01355    if (dsp->busy_hits > 5);
01356    return 0;
01357 #endif
01358    if (dsp->busymaybe) {
01359 #if 0
01360       printf("Maybe busy!\n");
01361 #endif      
01362       dsp->busymaybe = 0;
01363       min = 9999;
01364       max = 0;
01365       for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01366 #if 0
01367          printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
01368 #endif         
01369          if (dsp->historicsilence[x] < min)
01370             min = dsp->historicsilence[x];
01371          if (dsp->historicnoise[x] < min)
01372             min = dsp->historicnoise[x];
01373          if (dsp->historicsilence[x] > max)
01374             max = dsp->historicsilence[x];
01375          if (dsp->historicnoise[x] > max)
01376             max = dsp->historicnoise[x];
01377       }
01378       if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
01379 #if 0
01380          printf("Busy!\n");
01381 #endif         
01382          res = 1;
01383       }
01384 #if 0
01385       printf("Min: %d, max: %d\n", min, max);
01386 #endif      
01387    }
01388    return res;
01389 }
01390 #endif
01391 
01392 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01393 {
01394    short *s;
01395    int len;
01396    
01397    if (f->frametype != AST_FRAME_VOICE) {
01398       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01399       return 0;
01400    }
01401    if (f->subclass != AST_FORMAT_SLINEAR) {
01402       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01403       return 0;
01404    }
01405    s = f->data;
01406    len = f->datalen/2;
01407    return __ast_dsp_silence(dsp, s, len, totalsilence);
01408 }
01409 
01410 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01411 {
01412    int silence;
01413    int res;
01414    int digit;
01415    int x;
01416    unsigned short *shortdata;
01417    unsigned char *odata;
01418    int len;
01419    int writeback = 0;
01420 
01421 #define FIX_INF(inf) do { \
01422       if (writeback) { \
01423          switch(inf->subclass) { \
01424          case AST_FORMAT_SLINEAR: \
01425             break; \
01426          case AST_FORMAT_ULAW: \
01427             for (x=0;x<len;x++) \
01428                odata[x] = AST_LIN2MU(shortdata[x]); \
01429             break; \
01430          case AST_FORMAT_ALAW: \
01431             for (x=0;x<len;x++) \
01432                odata[x] = AST_LIN2A(shortdata[x]); \
01433             break; \
01434          } \
01435       } \
01436    } while(0) 
01437 
01438    if (!af)
01439       return NULL;
01440    if (af->frametype != AST_FRAME_VOICE)
01441       return af;
01442    odata = af->data;
01443    len = af->datalen;
01444    /* Make sure we have short data */
01445    switch(af->subclass) {
01446    case AST_FORMAT_SLINEAR:
01447       shortdata = af->data;
01448       len = af->datalen / 2;
01449       break;
01450    case AST_FORMAT_ULAW:
01451       shortdata = alloca(af->datalen * 2);
01452       if (!shortdata) {
01453          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01454          return af;
01455       }
01456       for (x=0;x<len;x++) 
01457          shortdata[x] = AST_MULAW(odata[x]);
01458       break;
01459    case AST_FORMAT_ALAW:
01460       shortdata = alloca(af->datalen * 2);
01461       if (!shortdata) {
01462          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01463          return af;
01464       }
01465       for (x=0;x<len;x++) 
01466          shortdata[x] = AST_ALAW(odata[x]);
01467       break;
01468    default:
01469       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01470       return af;
01471    }
01472    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01473    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01474       memset(&dsp->f, 0, sizeof(dsp->f));
01475       dsp->f.frametype = AST_FRAME_NULL;
01476       return &dsp->f;
01477    }
01478    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01479       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01480       memset(&dsp->f, 0, sizeof(dsp->f));
01481       dsp->f.frametype = AST_FRAME_CONTROL;
01482       dsp->f.subclass = AST_CONTROL_BUSY;
01483       ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01484       return &dsp->f;
01485    }
01486    if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01487       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01488 #if 0
01489       if (digit)
01490          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01491 #endif         
01492       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01493          if (!dsp->thinkdigit) {
01494             if (digit) {
01495                /* Looks like we might have something.  Request a conference mute for the moment */
01496                memset(&dsp->f, 0, sizeof(dsp->f));
01497                dsp->f.frametype = AST_FRAME_DTMF;
01498                dsp->f.subclass = 'm';
01499                dsp->thinkdigit = 'x';
01500                FIX_INF(af);
01501                if (chan)
01502                   ast_queue_frame(chan, af);
01503                ast_frfree(af);
01504                return &dsp->f;
01505             }
01506          } else {
01507             if (digit) {
01508                /* Thought we saw one last time.  Pretty sure we really have now */
01509                if (dsp->thinkdigit) {
01510                   if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01511                      /* If we found a digit, and we're changing digits, go
01512                         ahead and send this one, but DON'T stop confmute because
01513                         we're detecting something else, too... */
01514                      memset(&dsp->f, 0, sizeof(dsp->f));
01515                      dsp->f.frametype = AST_FRAME_DTMF;
01516                      dsp->f.subclass = dsp->thinkdigit;
01517                      FIX_INF(af);
01518                      if (chan)
01519                         ast_queue_frame(chan, af);
01520                      ast_frfree(af);
01521                   }
01522                   dsp->thinkdigit = digit;
01523                   return &dsp->f;
01524                }
01525                dsp->thinkdigit = digit;
01526             } else {
01527                if (dsp->thinkdigit) {
01528                   memset(&dsp->f, 0, sizeof(dsp->f));
01529                   if (dsp->thinkdigit != 'x') {
01530                      /* If we found a digit, send it now */
01531                      dsp->f.frametype = AST_FRAME_DTMF;
01532                      dsp->f.subclass = dsp->thinkdigit;
01533                      dsp->thinkdigit = 0;
01534                   } else {
01535                      dsp->f.frametype = AST_FRAME_DTMF;
01536                      dsp->f.subclass = 'u';
01537                      dsp->thinkdigit = 0;
01538                   }
01539                   FIX_INF(af);
01540                   if (chan)
01541                      ast_queue_frame(chan, af);
01542                   ast_frfree(af);
01543                   return &dsp->f;
01544                }
01545             }
01546          }
01547       } else if (!digit) {
01548          /* Only check when there is *not* a hit... */
01549          if (dsp->digitmode & DSP_DIGITMODE_MF) {
01550             if (dsp->td.mf.current_digits) {
01551                memset(&dsp->f, 0, sizeof(dsp->f));
01552                dsp->f.frametype = AST_FRAME_DTMF;
01553                dsp->f.subclass = dsp->td.mf.digits[0];
01554                memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01555                dsp->td.mf.current_digits--;
01556                FIX_INF(af);
01557                if (chan)
01558                   ast_queue_frame(chan, af);
01559                ast_frfree(af);
01560                return &dsp->f;
01561             }
01562          } else {
01563             if (dsp->td.dtmf.current_digits) {
01564                memset(&dsp->f, 0, sizeof(dsp->f));
01565                dsp->f.frametype = AST_FRAME_DTMF;
01566                dsp->f.subclass = dsp->td.dtmf.digits[0];
01567                memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01568                dsp->td.dtmf.current_digits--;
01569                FIX_INF(af);
01570                if (chan)
01571                   ast_queue_frame(chan, af);
01572                ast_frfree(af);
01573                return &dsp->f;
01574             }
01575          }
01576       }
01577    }
01578    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01579       res = __ast_dsp_call_progress(dsp, shortdata, len);
01580       memset(&dsp->f, 0, sizeof(dsp->f));
01581       dsp->f.frametype = AST_FRAME_CONTROL;
01582       if (res) {
01583          switch(res) {
01584          case AST_CONTROL_ANSWER:
01585          case AST_CONTROL_BUSY:
01586          case AST_CONTROL_RINGING:
01587          case AST_CONTROL_CONGESTION:
01588             dsp->f.subclass = res;
01589             if (chan) 
01590                ast_queue_frame(chan, &dsp->f);
01591             break;
01592          default:
01593             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01594          }
01595       }
01596    }
01597    FIX_INF(af);
01598    return af;
01599 }
01600 
01601 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01602 {
01603    int max = 0;
01604    int x;
01605    dsp->gsamp_size = modes[dsp->progmode].size;
01606    dsp->gsamps = 0;
01607    for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
01608       if (modes[dsp->progmode].freqs[x]) {
01609          goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01610          max = x;
01611       }
01612    }
01613    dsp->freqcount = max;
01614 }
01615 
01616 struct ast_dsp *ast_dsp_new(void)
01617 {
01618    struct ast_dsp *dsp;
01619    dsp = malloc(sizeof(struct ast_dsp));
01620    if (dsp) {
01621       memset(dsp, 0, sizeof(struct ast_dsp));
01622       dsp->threshold = DEFAULT_THRESHOLD;
01623       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01624       dsp->busycount = DSP_HISTORY;
01625       /* Initialize DTMF detector */
01626       ast_dtmf_detect_init(&dsp->td.dtmf);
01627       /* Initialize initial DSP progress detect parameters */
01628       ast_dsp_prog_reset(dsp);
01629    }
01630    return dsp;
01631 }
01632 
01633 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01634 {
01635    dsp->features = features;
01636 }
01637 
01638 void ast_dsp_free(struct ast_dsp *dsp)
01639 {
01640    free(dsp);
01641 }
01642 
01643 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01644 {
01645    dsp->threshold = threshold;
01646 }
01647 
01648 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01649 {
01650    if (cadences < 4)
01651       cadences = 4;
01652    if (cadences > DSP_HISTORY)
01653       cadences = DSP_HISTORY;
01654    dsp->busycount = cadences;
01655 }
01656 
01657 void ast_dsp_digitreset(struct ast_dsp *dsp)
01658 {
01659    int i;
01660    dsp->thinkdigit = 0;
01661    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01662       memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01663       dsp->td.mf.current_digits = 0;
01664       /* Reinitialise the detector for the next block */
01665       for (i = 0;  i < 6;  i++) {
01666             goertzel_reset(&dsp->td.mf.tone_out[i]);
01667 #ifdef OLD_DSP_ROUTINES
01668           goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01669 #endif         
01670       }
01671 #ifdef OLD_DSP_ROUTINES
01672       dsp->td.mf.energy = 0.0;
01673        dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01674 #else
01675        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;
01676 #endif      
01677       dsp->td.mf.current_sample = 0;
01678    } else {
01679       memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01680       dsp->td.dtmf.current_digits = 0;
01681       /* Reinitialise the detector for the next block */
01682       for (i = 0;  i < 4;  i++) {
01683             goertzel_reset(&dsp->td.dtmf.row_out[i]);
01684           goertzel_reset(&dsp->td.dtmf.col_out[i]);
01685 #ifdef OLD_DSP_ROUTINES
01686          goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01687          goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01688 #endif         
01689       }
01690 #ifdef FAX_DETECT
01691        goertzel_reset (&dsp->td.dtmf.fax_tone);
01692 #endif
01693 #ifdef OLD_DSP_ROUTINES
01694 #ifdef FAX_DETECT
01695        goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01696 #endif
01697        dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01698 #else
01699        dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] =  dsp->td.dtmf.mhit = 0;
01700 #endif      
01701       dsp->td.dtmf.energy = 0.0;
01702       dsp->td.dtmf.current_sample = 0;
01703    }
01704 }
01705 
01706 void ast_dsp_reset(struct ast_dsp *dsp)
01707 {
01708    int x;
01709    dsp->totalsilence = 0;
01710    dsp->gsamps = 0;
01711    for (x=0;x<4;x++)
01712       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01713    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01714    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01715    
01716 }
01717 
01718 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01719 {
01720    int new, old;
01721    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01722    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01723    if (old != new) {
01724       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01725       if (new & DSP_DIGITMODE_MF)
01726          ast_mf_detect_init(&dsp->td.mf);
01727       else
01728          ast_dtmf_detect_init(&dsp->td.dtmf);
01729    }
01730    dsp->digitmode = digitmode;
01731    return 0;
01732 }
01733 
01734 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01735 {
01736    int x;
01737    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01738       if (!strcasecmp(aliases[x].name, zone)) {
01739          dsp->progmode = aliases[x].mode;
01740          ast_dsp_prog_reset(dsp);
01741          return 0;
01742       }
01743    }
01744    return -1;
01745 }

Generated on Wed Mar 16 20:08:34 2005 for Asterisk by  doxygen 1.4.0