Main Page   Alphabetical List   Data Structures   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("Got whole dsp state: 350: %e, 440: %e, 480: %e, 620: %e, 950: %e, 1400: %e, 1800: %e, Energy: %e\n", 
01140             hz_350, hz_440, hz_480, hz_620, hz_950, hz_1400, hz_1800, dsp->genergy);
01141 #endif
01142          switch(dsp->progmode) {
01143          case PROG_MODE_NA:
01144             if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
01145                newstate = TONE_STATE_BUSY;
01146             } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01147                newstate = TONE_STATE_RINGING;
01148             } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01149                newstate = TONE_STATE_DIALTONE;
01150             } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01151                newstate = TONE_STATE_SPECIAL1;
01152             } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01153                if (dsp->tstate == TONE_STATE_SPECIAL1)
01154                   newstate = TONE_STATE_SPECIAL2;
01155             } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01156                if (dsp->tstate == TONE_STATE_SPECIAL2)
01157                   newstate = TONE_STATE_SPECIAL3;
01158             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01159                newstate = TONE_STATE_TALKING;
01160             } else
01161                newstate = TONE_STATE_SILENCE;
01162             break;
01163          case PROG_MODE_CR:
01164             if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01165                newstate = TONE_STATE_RINGING;
01166             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01167                newstate = TONE_STATE_TALKING;
01168             } else
01169                newstate = TONE_STATE_SILENCE;
01170             break;
01171          default:
01172             ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01173          }
01174          if (newstate == dsp->tstate) {
01175             dsp->tcount++;
01176             if (dsp->tcount == COUNT_THRESH) {
01177                if (dsp->tstate == TONE_STATE_BUSY) {
01178                   res = AST_CONTROL_BUSY;
01179                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01180                } else if (dsp->tstate == TONE_STATE_TALKING) {
01181                   res = AST_CONTROL_ANSWER;
01182                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01183                } else if (dsp->tstate == TONE_STATE_RINGING)
01184                   res = AST_CONTROL_RINGING;
01185                else if (dsp->tstate == TONE_STATE_SPECIAL3) {
01186                   res = AST_CONTROL_CONGESTION;
01187                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01188                }
01189                
01190             }
01191          } else {
01192 #if 0
01193             printf("Newstate: %d\n", newstate);
01194 #endif
01195             dsp->tstate = newstate;
01196             dsp->tcount = 1;
01197          }
01198          
01199          /* Reset goertzel */                
01200          for (x=0;x<7;x++)
01201             dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01202          dsp->gsamps = 0;
01203          dsp->genergy = 0.0;
01204       }
01205    }
01206 #if 0
01207    if (res)
01208       printf("Returning %d\n", res);
01209 #endif      
01210    return res;
01211 }
01212 
01213 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01214 {
01215    if (inf->frametype != AST_FRAME_VOICE) {
01216       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01217       return 0;
01218    }
01219    if (inf->subclass != AST_FORMAT_SLINEAR) {
01220       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01221       return 0;
01222    }
01223    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01224 }
01225 
01226 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
01227 {
01228    int accum;
01229    int x;
01230    int res = 0;
01231 
01232    if (!len)
01233       return 0;
01234    
01235    accum = 0;
01236    for (x=0;x<len; x++) 
01237       accum += abs(s[x]);
01238    accum /= len;
01239    if (accum < dsp->threshold) {
01240       dsp->totalsilence += len/8;
01241       if (dsp->totalnoise) {
01242          /* Move and save history */
01243          memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
01244          dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01245 /* we don't want to check for busydetect that frequently */
01246 #if 0
01247          dsp->busymaybe = 1;
01248 #endif
01249       }
01250       dsp->totalnoise = 0;
01251       res = 1;
01252    } else {
01253       dsp->totalnoise += len/8;
01254       if (dsp->totalsilence) {
01255          int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01256          int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01257          /* Move and save history */
01258          memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
01259          dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01260          /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
01261          if (silence1 < silence2) {
01262             if (silence1 + silence1/BUSY_PERCENT >= silence2)
01263                dsp->busymaybe = 1;
01264             else 
01265                dsp->busymaybe = 0;
01266          } else {
01267             if (silence1 - silence1/BUSY_PERCENT <= silence2)
01268                dsp->busymaybe = 1;
01269             else 
01270                dsp->busymaybe = 0;
01271          }
01272                
01273       }
01274       dsp->totalsilence = 0;
01275    }
01276    if (totalsilence)
01277       *totalsilence = dsp->totalsilence;
01278    return res;
01279 }
01280 #ifdef BUSYDETECT_MARTIN
01281 int ast_dsp_busydetect(struct ast_dsp *dsp)
01282 {
01283    int res = 0, x;
01284 #ifndef BUSYDETECT_TONEONLY
01285    int avgsilence = 0, hitsilence = 0;
01286 #endif
01287    int avgtone = 0, hittone = 0;
01288    if (!dsp->busymaybe)
01289       return res;
01290    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01291 #ifndef BUSYDETECT_TONEONLY
01292       avgsilence += dsp->historicsilence[x];
01293 #endif
01294       avgtone += dsp->historicnoise[x];
01295    }
01296 #ifndef BUSYDETECT_TONEONLY
01297    avgsilence /= dsp->busycount;
01298 #endif
01299    avgtone /= dsp->busycount;
01300    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01301 #ifndef BUSYDETECT_TONEONLY
01302       if (avgsilence > dsp->historicsilence[x]) {
01303          if (avgsilence - (avgsilence / BUSY_PERCENT) <= dsp->historicsilence[x])
01304             hitsilence++;
01305       } else {
01306          if (avgsilence + (avgsilence / BUSY_PERCENT) >= dsp->historicsilence[x])
01307             hitsilence++;
01308       }
01309 #endif
01310       if (avgtone > dsp->historicnoise[x]) {
01311          if (avgtone - (avgtone / BUSY_PERCENT) <= dsp->historicsilence[x])
01312             hittone++;
01313       } else {
01314          if (avgtone + (avgtone / BUSY_PERCENT) >= dsp->historicsilence[x])
01315             hittone++;
01316       }
01317    }
01318 #ifndef BUSYDETECT_TONEONLY
01319    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01320 #else
01321    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01322 #endif
01323 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01324 #ifdef BUSYDETECT_TONEONLY
01325 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01326 #endif
01327       if (avgtone > avgsilence) {
01328          if (avgtone - avgtone/(BUSY_PERCENT*2) <= avgsilence)
01329             res = 1;
01330       } else {
01331          if (avgtone + avgtone/(BUSY_PERCENT*2) >= avgsilence)
01332             res = 1;
01333       }
01334 #else
01335       res = 1;
01336 #endif
01337    }
01338 #if 0
01339    if (res)
01340       ast_log(LOG_NOTICE, "detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01341 #endif
01342    return res;
01343 }
01344 #endif
01345 
01346 #ifdef BUSYDETECT
01347 int ast_dsp_busydetect(struct ast_dsp *dsp)
01348 {
01349    int x;
01350    int res = 0;
01351    int max, min;
01352 
01353 #if 0
01354    if (dsp->busy_hits > 5);
01355    return 0;
01356 #endif
01357    if (dsp->busymaybe) {
01358 #if 0
01359       printf("Maybe busy!\n");
01360 #endif      
01361       dsp->busymaybe = 0;
01362       min = 9999;
01363       max = 0;
01364       for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01365 #if 0
01366          printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
01367 #endif         
01368          if (dsp->historicsilence[x] < min)
01369             min = dsp->historicsilence[x];
01370          if (dsp->historicnoise[x] < min)
01371             min = dsp->historicnoise[x];
01372          if (dsp->historicsilence[x] > max)
01373             max = dsp->historicsilence[x];
01374          if (dsp->historicnoise[x] > max)
01375             max = dsp->historicnoise[x];
01376       }
01377       if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
01378 #if 0
01379          printf("Busy!\n");
01380 #endif         
01381          res = 1;
01382       }
01383 #if 0
01384       printf("Min: %d, max: %d\n", min, max);
01385 #endif      
01386    }
01387    return res;
01388 }
01389 #endif
01390 
01391 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01392 {
01393    short *s;
01394    int len;
01395    
01396    if (f->frametype != AST_FRAME_VOICE) {
01397       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01398       return 0;
01399    }
01400    if (f->subclass != AST_FORMAT_SLINEAR) {
01401       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01402       return 0;
01403    }
01404    s = f->data;
01405    len = f->datalen/2;
01406    return __ast_dsp_silence(dsp, s, len, totalsilence);
01407 }
01408 
01409 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01410 {
01411    int silence;
01412    int res;
01413    int digit;
01414    int x;
01415    unsigned short *shortdata;
01416    unsigned char *odata;
01417    int len;
01418    int writeback = 0;
01419 
01420 #define FIX_INF(inf) do { \
01421       if (writeback) { \
01422          switch(inf->subclass) { \
01423          case AST_FORMAT_SLINEAR: \
01424             break; \
01425          case AST_FORMAT_ULAW: \
01426             for (x=0;x<len;x++) \
01427                odata[x] = AST_LIN2MU(shortdata[x]); \
01428             break; \
01429          case AST_FORMAT_ALAW: \
01430             for (x=0;x<len;x++) \
01431                odata[x] = AST_LIN2A(shortdata[x]); \
01432             break; \
01433          } \
01434       } \
01435    } while(0) 
01436 
01437    if (!af)
01438       return NULL;
01439    if (af->frametype != AST_FRAME_VOICE)
01440       return af;
01441    odata = af->data;
01442    len = af->datalen;
01443    /* Make sure we have short data */
01444    switch(af->subclass) {
01445    case AST_FORMAT_SLINEAR:
01446       shortdata = af->data;
01447       len = af->datalen / 2;
01448       break;
01449    case AST_FORMAT_ULAW:
01450       shortdata = alloca(af->datalen * 2);
01451       if (!shortdata) {
01452          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01453          return af;
01454       }
01455       for (x=0;x<len;x++) 
01456          shortdata[x] = AST_MULAW(odata[x]);
01457       break;
01458    case AST_FORMAT_ALAW:
01459       shortdata = alloca(af->datalen * 2);
01460       if (!shortdata) {
01461          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01462          return af;
01463       }
01464       for (x=0;x<len;x++) 
01465          shortdata[x] = AST_ALAW(odata[x]);
01466       break;
01467    default:
01468       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_codec2str(af->subclass));
01469       return af;
01470    }
01471    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01472    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01473       memset(&dsp->f, 0, sizeof(dsp->f));
01474       dsp->f.frametype = AST_FRAME_NULL;
01475       return &dsp->f;
01476    }
01477    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01478       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01479       memset(&dsp->f, 0, sizeof(dsp->f));
01480       dsp->f.frametype = AST_FRAME_CONTROL;
01481       dsp->f.subclass = AST_CONTROL_BUSY;
01482       ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01483       return &dsp->f;
01484    }
01485    if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01486       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01487 #if 0
01488       if (digit)
01489          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01490 #endif         
01491       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01492          if (!dsp->thinkdigit) {
01493             if (digit) {
01494                /* Looks like we might have something.  Request a conference mute for the moment */
01495                memset(&dsp->f, 0, sizeof(dsp->f));
01496                dsp->f.frametype = AST_FRAME_DTMF;
01497                dsp->f.subclass = 'm';
01498                dsp->thinkdigit = 'x';
01499                FIX_INF(af);
01500                if (chan)
01501                   ast_queue_frame(chan, af);
01502                ast_frfree(af);
01503                return &dsp->f;
01504             }
01505          } else {
01506             if (digit) {
01507                /* Thought we saw one last time.  Pretty sure we really have now */
01508                if (dsp->thinkdigit) {
01509                   if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01510                      /* If we found a digit, and we're changing digits, go
01511                         ahead and send this one, but DON'T stop confmute because
01512                         we're detecting something else, too... */
01513                      memset(&dsp->f, 0, sizeof(dsp->f));
01514                      dsp->f.frametype = AST_FRAME_DTMF;
01515                      dsp->f.subclass = dsp->thinkdigit;
01516                      FIX_INF(af);
01517                      if (chan)
01518                         ast_queue_frame(chan, af);
01519                      ast_frfree(af);
01520                   }
01521                   dsp->thinkdigit = digit;
01522                   return &dsp->f;
01523                }
01524                dsp->thinkdigit = digit;
01525             } else {
01526                if (dsp->thinkdigit) {
01527                   memset(&dsp->f, 0, sizeof(dsp->f));
01528                   if (dsp->thinkdigit != 'x') {
01529                      /* If we found a digit, send it now */
01530                      dsp->f.frametype = AST_FRAME_DTMF;
01531                      dsp->f.subclass = dsp->thinkdigit;
01532                      dsp->thinkdigit = 0;
01533                   } else {
01534                      dsp->f.frametype = AST_FRAME_DTMF;
01535                      dsp->f.subclass = 'u';
01536                      dsp->thinkdigit = 0;
01537                   }
01538                   FIX_INF(af);
01539                   if (chan)
01540                      ast_queue_frame(chan, af);
01541                   ast_frfree(af);
01542                   return &dsp->f;
01543                }
01544             }
01545          }
01546       } else if (!digit) {
01547          /* Only check when there is *not* a hit... */
01548          if (dsp->digitmode & DSP_DIGITMODE_MF) {
01549             if (dsp->td.mf.current_digits) {
01550                memset(&dsp->f, 0, sizeof(dsp->f));
01551                dsp->f.frametype = AST_FRAME_DTMF;
01552                dsp->f.subclass = dsp->td.mf.digits[0];
01553                memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01554                dsp->td.mf.current_digits--;
01555                FIX_INF(af);
01556                if (chan)
01557                   ast_queue_frame(chan, af);
01558                ast_frfree(af);
01559                return &dsp->f;
01560             }
01561          } else {
01562             if (dsp->td.dtmf.current_digits) {
01563                memset(&dsp->f, 0, sizeof(dsp->f));
01564                dsp->f.frametype = AST_FRAME_DTMF;
01565                dsp->f.subclass = dsp->td.dtmf.digits[0];
01566                memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01567                dsp->td.dtmf.current_digits--;
01568                FIX_INF(af);
01569                if (chan)
01570                   ast_queue_frame(chan, af);
01571                ast_frfree(af);
01572                return &dsp->f;
01573             }
01574          }
01575       }
01576    }
01577    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01578       res = __ast_dsp_call_progress(dsp, shortdata, len);
01579       memset(&dsp->f, 0, sizeof(dsp->f));
01580       dsp->f.frametype = AST_FRAME_CONTROL;
01581       if (res) {
01582          switch(res) {
01583          case AST_CONTROL_ANSWER:
01584          case AST_CONTROL_BUSY:
01585          case AST_CONTROL_RINGING:
01586          case AST_CONTROL_CONGESTION:
01587             dsp->f.subclass = res;
01588             if (chan) 
01589                ast_queue_frame(chan, &dsp->f);
01590             break;
01591          default:
01592             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01593          }
01594       }
01595    }
01596    FIX_INF(af);
01597    return af;
01598 }
01599 
01600 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01601 {
01602    int max = 0;
01603    int x;
01604    dsp->gsamp_size = modes[dsp->progmode].size;
01605    dsp->gsamps = 0;
01606    for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
01607       if (modes[dsp->progmode].freqs[x]) {
01608          goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01609          max = x;
01610       }
01611    }
01612    dsp->freqcount = max;
01613 }
01614 
01615 struct ast_dsp *ast_dsp_new(void)
01616 {
01617    struct ast_dsp *dsp;
01618    dsp = malloc(sizeof(struct ast_dsp));
01619    if (dsp) {
01620       memset(dsp, 0, sizeof(struct ast_dsp));
01621       dsp->threshold = DEFAULT_THRESHOLD;
01622       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01623       dsp->busycount = DSP_HISTORY;
01624       /* Initialize DTMF detector */
01625       ast_dtmf_detect_init(&dsp->td.dtmf);
01626       /* Initialize initial DSP progress detect parameters */
01627       ast_dsp_prog_reset(dsp);
01628    }
01629    return dsp;
01630 }
01631 
01632 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01633 {
01634    dsp->features = features;
01635 }
01636 
01637 void ast_dsp_free(struct ast_dsp *dsp)
01638 {
01639    free(dsp);
01640 }
01641 
01642 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01643 {
01644    dsp->threshold = threshold;
01645 }
01646 
01647 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01648 {
01649    if (cadences < 4)
01650       cadences = 4;
01651    if (cadences > DSP_HISTORY)
01652       cadences = DSP_HISTORY;
01653    dsp->busycount = cadences;
01654 }
01655 
01656 void ast_dsp_digitreset(struct ast_dsp *dsp)
01657 {
01658    int i;
01659    dsp->thinkdigit = 0;
01660    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01661       memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01662       dsp->td.mf.current_digits = 0;
01663       /* Reinitialise the detector for the next block */
01664       for (i = 0;  i < 6;  i++) {
01665             goertzel_reset(&dsp->td.mf.tone_out[i]);
01666 #ifdef OLD_DSP_ROUTINES
01667           goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01668 #endif         
01669       }
01670 #ifdef OLD_DSP_ROUTINES
01671       dsp->td.mf.energy = 0.0;
01672        dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01673 #else
01674        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;
01675 #endif      
01676       dsp->td.mf.current_sample = 0;
01677    } else {
01678       memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01679       dsp->td.dtmf.current_digits = 0;
01680       /* Reinitialise the detector for the next block */
01681       for (i = 0;  i < 4;  i++) {
01682             goertzel_reset(&dsp->td.dtmf.row_out[i]);
01683           goertzel_reset(&dsp->td.dtmf.col_out[i]);
01684 #ifdef OLD_DSP_ROUTINES
01685          goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01686          goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01687 #endif         
01688       }
01689 #ifdef FAX_DETECT
01690        goertzel_reset (&dsp->td.dtmf.fax_tone);
01691 #endif
01692 #ifdef OLD_DSP_ROUTINES
01693 #ifdef FAX_DETECT
01694        goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01695 #endif
01696        dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01697 #else
01698        dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] =  dsp->td.dtmf.mhit = 0;
01699 #endif      
01700       dsp->td.dtmf.energy = 0.0;
01701       dsp->td.dtmf.current_sample = 0;
01702    }
01703 }
01704 
01705 void ast_dsp_reset(struct ast_dsp *dsp)
01706 {
01707    int x;
01708    dsp->totalsilence = 0;
01709    dsp->gsamps = 0;
01710    for (x=0;x<4;x++)
01711       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01712    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01713    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01714    
01715 }
01716 
01717 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01718 {
01719    int new, old;
01720    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01721    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01722    if (old != new) {
01723       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01724       if (new & DSP_DIGITMODE_MF)
01725          ast_mf_detect_init(&dsp->td.mf);
01726       else
01727          ast_dtmf_detect_init(&dsp->td.dtmf);
01728    }
01729    dsp->digitmode = digitmode;
01730    return 0;
01731 }
01732 
01733 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01734 {
01735    int x;
01736    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01737       if (!strcasecmp(aliases[x].name, zone)) {
01738          dsp->progmode = aliases[x].mode;
01739          ast_dsp_prog_reset(dsp);
01740          return 0;
01741       }
01742    }
01743    return -1;
01744 }

Generated on Thu Oct 28 11:32:53 2004 for Asterisk by doxygen1.2.15