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 #define DEFAULT_THRESHOLD 1024
00047 
00048 #define BUSY_PERCENT    10 /* The percentage diffrence between the two last silence periods */
00049 #define BUSY_THRESHOLD     100   /* Max number of ms difference between max and min times in busy */
00050 #define BUSY_MIN     75 /* Busy must be at least 80 ms in half-cadence */
00051 #define BUSY_MAX     1100  /* Busy can't be longer than 1100 ms in half-cadence */
00052 
00053 /* Remember last 15 units */
00054 #define DSP_HISTORY 15
00055 
00056 /* Number of goertzels for progress detect */
00057 #define GSAMP_SIZE 183
00058 
00059 #define HZ_350  0
00060 #define HZ_440  1
00061 #define HZ_480  2
00062 #define HZ_620  3
00063 #define HZ_950  4
00064 #define HZ_1400 5
00065 #define HZ_1800 6
00066 
00067 #define TONE_THRESH 10.0   /* How much louder the tone should be than channel energy */
00068 #define TONE_MIN_THRESH 1e8   /* How much tone there should be at least to attempt */
00069 #define COUNT_THRESH  3    /* Need at least 50ms of stuff to count it */
00070 
00071 #define TONE_STATE_SILENCE  0
00072 #define TONE_STATE_RINGING  1 
00073 #define TONE_STATE_DIALTONE 2
00074 #define TONE_STATE_TALKING  3
00075 #define TONE_STATE_BUSY     4
00076 #define TONE_STATE_SPECIAL1   5
00077 #define TONE_STATE_SPECIAL2 6
00078 #define TONE_STATE_SPECIAL3 7
00079 
00080 #define  MAX_DTMF_DIGITS 128
00081 
00082 /* Basic DTMF specs:
00083  *
00084  * Minimum tone on = 40ms
00085  * Minimum tone off = 50ms
00086  * Maximum digit rate = 10 per second
00087  * Normal twist <= 8dB accepted
00088  * Reverse twist <= 4dB accepted
00089  * S/N >= 15dB will detect OK
00090  * Attenuation <= 26dB will detect OK
00091  * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
00092  */
00093 
00094 #define DTMF_THRESHOLD              8.0e7
00095 #define FAX_THRESHOLD              8.0e7
00096 #define FAX_2ND_HARMONIC            2.0     /* 4dB */
00097 #define DTMF_NORMAL_TWIST           6.3     /* 8dB */
00098 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)     /* 4dB normal */
00099 #define DTMF_RELATIVE_PEAK_ROW      6.3     /* 8dB */
00100 #define DTMF_RELATIVE_PEAK_COL      6.3     /* 8dB */
00101 #define DTMF_2ND_HARMONIC_ROW       ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)     /* 4dB normal */
00102 #define DTMF_2ND_HARMONIC_COL       63.1    /* 18dB */
00103 
00104 #define MF_THRESHOLD              8.0e7
00105 #define MF_NORMAL_TWIST           5.3     /* 8dB */
00106 #define MF_REVERSE_TWIST          4.0     /* was 2.5 */
00107 #define MF_RELATIVE_PEAK      5.3     /* 8dB */
00108 #define MF_2ND_HARMONIC       1.7 /* was 2.5  */
00109 
00110 typedef struct {
00111    float v2;
00112    float v3;
00113    float fac;
00114 } goertzel_state_t;
00115 
00116 typedef struct
00117 {
00118     int hit1;
00119     int hit2;
00120     int hit3;
00121     int hit4;
00122     int mhit;
00123 
00124     goertzel_state_t row_out[4];
00125     goertzel_state_t col_out[4];
00126     goertzel_state_t row_out2nd[4];
00127     goertzel_state_t col_out2nd[4];
00128    goertzel_state_t fax_tone;
00129    goertzel_state_t fax_tone2nd;
00130     float energy;
00131     
00132     int current_sample;
00133     char digits[MAX_DTMF_DIGITS + 1];
00134     int current_digits;
00135     int detected_digits;
00136     int lost_digits;
00137     int digit_hits[16];
00138    int fax_hits;
00139 } dtmf_detect_state_t;
00140 
00141 typedef struct
00142 {
00143     int hit1;
00144     int hit2;
00145     int hit3;
00146     int hit4;
00147     int mhit;
00148 
00149     goertzel_state_t tone_out[6];
00150     goertzel_state_t tone_out2nd[6];
00151     float energy;
00152     
00153     int current_sample;
00154     char digits[MAX_DTMF_DIGITS + 1];
00155     int current_digits;
00156     int detected_digits;
00157     int lost_digits;
00158    int fax_hits;
00159 } mf_detect_state_t;
00160 
00161 static float dtmf_row[] =
00162 {
00163      697.0,  770.0,  852.0,  941.0
00164 };
00165 static float dtmf_col[] =
00166 {
00167     1209.0, 1336.0, 1477.0, 1633.0
00168 };
00169 
00170 static float mf_tones[] =
00171 {
00172    700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
00173 };
00174 
00175 static float fax_freq = 1100.0;
00176 
00177 static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
00178 
00179 static char mf_hit[6][6] = {
00180    /*  700 + */ {   0, '1', '2', '4', '7', 'C' },
00181    /*  900 + */ { '1',   0, '3', '5', '8', 'A' },
00182    /* 1100 + */ { '2', '3',   0, '6', '9', '*' },
00183    /* 1300 + */ { '4', '5', '6',   0, '0', 'B' },
00184    /* 1500 + */ { '7', '8', '9', '0',  0, '#' },
00185    /* 1700 + */ { 'C', 'A', '*', 'B', '#',  0  },
00186 };
00187 
00188 static inline void goertzel_sample(goertzel_state_t *s, short sample)
00189 {
00190    float v1;
00191    float fsamp  = sample;
00192    v1 = s->v2;
00193    s->v2 = s->v3;
00194    s->v3 = s->fac * s->v2 - v1 + fsamp;
00195 }
00196 
00197 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
00198 {
00199    int i;
00200    for (i=0;i<count;i++) 
00201       goertzel_sample(s, samps[i]);
00202 }
00203 
00204 
00205 static inline float goertzel_result(goertzel_state_t *s)
00206 {
00207    return s->v3 * s->v3 + s->v2 * s->v2 - s->v2 * s->v3 * s->fac;
00208 }
00209 
00210 static inline void goertzel_init(goertzel_state_t *s, float freq)
00211 {
00212    s->v2 = s->v3 = 0.0;
00213    s->fac = 2.0 * cos(2.0 * M_PI * (freq / 8000.0));
00214 }
00215 
00216 static inline void goertzel_reset(goertzel_state_t *s)
00217 {
00218    s->v2 = s->v3 = 0.0;
00219 }
00220 
00221 struct ast_dsp {
00222    struct ast_frame f;
00223    int threshold;
00224    int totalsilence;
00225    int totalnoise;
00226    int features;
00227    int busymaybe;
00228    int busycount;
00229    int historicnoise[DSP_HISTORY];
00230    int historicsilence[DSP_HISTORY];
00231    goertzel_state_t freqs[7];
00232    int gsamps;
00233    int tstate;
00234    int tcount;
00235    int digitmode;
00236    int thinkdigit;
00237    float genergy;
00238    union {
00239       dtmf_detect_state_t dtmf;
00240       mf_detect_state_t mf;
00241    } td;
00242 };
00243 
00244 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00245 {
00246     int i;
00247 
00248     s->hit1 = 
00249     s->hit2 = 0;
00250 
00251     for (i = 0;  i < 4;  i++)
00252     {
00253     
00254          goertzel_init (&s->row_out[i], dtmf_row[i]);
00255       goertzel_init (&s->col_out[i], dtmf_col[i]);
00256       goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0);
00257       goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0);
00258    
00259       s->energy = 0.0;
00260     }
00261 
00262    /* Same for the fax dector */
00263     goertzel_init (&s->fax_tone, fax_freq);
00264 
00265    /* Same for the fax dector 2nd harmonic */
00266     goertzel_init (&s->fax_tone2nd, fax_freq * 2.0);
00267    
00268     s->current_sample = 0;
00269     s->detected_digits = 0;
00270    s->current_digits = 0;
00271    memset(&s->digits, 0, sizeof(s->digits));
00272     s->lost_digits = 0;
00273     s->digits[0] = '\0';
00274     s->mhit = 0;
00275 }
00276 
00277 static void ast_mf_detect_init (mf_detect_state_t *s)
00278 {
00279     int i;
00280 
00281     s->hit1 = 
00282     s->hit2 = 0;
00283 
00284     for (i = 0;  i < 6;  i++)
00285     {
00286     
00287          goertzel_init (&s->tone_out[i], mf_tones[i]);
00288       goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0);
00289    
00290       s->energy = 0.0;
00291     }
00292 
00293    s->current_digits = 0;
00294    memset(&s->digits, 0, sizeof(s->digits));
00295     s->current_sample = 0;
00296     s->detected_digits = 0;
00297     s->lost_digits = 0;
00298     s->digits[0] = '\0';
00299     s->mhit = 0;
00300 }
00301 
00302 static int dtmf_detect (dtmf_detect_state_t *s,
00303                  int16_t amp[],
00304                  int samples, 
00305        int digitmode, int *writeback)
00306 {
00307 
00308     float row_energy[4];
00309     float col_energy[4];
00310     float fax_energy;
00311     float fax_energy_2nd;
00312     float famp;
00313     float v1;
00314     int i;
00315     int j;
00316     int sample;
00317     int best_row;
00318     int best_col;
00319     int hit;
00320     int limit;
00321 
00322     hit = 0;
00323     for (sample = 0;  sample < samples;  sample = limit)
00324     {
00325         /* 102 is optimised to meet the DTMF specs. */
00326         if ((samples - sample) >= (102 - s->current_sample))
00327             limit = sample + (102 - s->current_sample);
00328         else
00329             limit = samples;
00330 #if defined(USE_3DNOW)
00331         _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
00332         _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
00333         _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
00334         _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
00335       /* XXX Need to fax detect for 3dnow too XXX */
00336       #warning "Fax Support Broken"
00337 #else
00338         /* The following unrolled loop takes only 35% (rough estimate) of the 
00339            time of a rolled loop on the machine on which it was developed */
00340         for (j = sample;  j < limit;  j++)
00341         {
00342             famp = amp[j];
00343        
00344        s->energy += famp*famp;
00345        
00346             /* With GCC 2.95, the following unrolled code seems to take about 35%
00347                (rough estimate) as long as a neat little 0-3 loop */
00348             v1 = s->row_out[0].v2;
00349             s->row_out[0].v2 = s->row_out[0].v3;
00350             s->row_out[0].v3 = s->row_out[0].fac*s->row_out[0].v2 - v1 + famp;
00351     
00352             v1 = s->col_out[0].v2;
00353             s->col_out[0].v2 = s->col_out[0].v3;
00354             s->col_out[0].v3 = s->col_out[0].fac*s->col_out[0].v2 - v1 + famp;
00355     
00356             v1 = s->row_out[1].v2;
00357             s->row_out[1].v2 = s->row_out[1].v3;
00358             s->row_out[1].v3 = s->row_out[1].fac*s->row_out[1].v2 - v1 + famp;
00359     
00360             v1 = s->col_out[1].v2;
00361             s->col_out[1].v2 = s->col_out[1].v3;
00362             s->col_out[1].v3 = s->col_out[1].fac*s->col_out[1].v2 - v1 + famp;
00363     
00364             v1 = s->row_out[2].v2;
00365             s->row_out[2].v2 = s->row_out[2].v3;
00366             s->row_out[2].v3 = s->row_out[2].fac*s->row_out[2].v2 - v1 + famp;
00367     
00368             v1 = s->col_out[2].v2;
00369             s->col_out[2].v2 = s->col_out[2].v3;
00370             s->col_out[2].v3 = s->col_out[2].fac*s->col_out[2].v2 - v1 + famp;
00371     
00372             v1 = s->row_out[3].v2;
00373             s->row_out[3].v2 = s->row_out[3].v3;
00374             s->row_out[3].v3 = s->row_out[3].fac*s->row_out[3].v2 - v1 + famp;
00375 
00376             v1 = s->col_out[3].v2;
00377             s->col_out[3].v2 = s->col_out[3].v3;
00378             s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp;
00379 
00380             v1 = s->col_out2nd[0].v2;
00381             s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
00382             s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp;
00383         
00384             v1 = s->row_out2nd[0].v2;
00385             s->row_out2nd[0].v2 = s->row_out2nd[0].v3;
00386             s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp;
00387         
00388             v1 = s->col_out2nd[1].v2;
00389             s->col_out2nd[1].v2 = s->col_out2nd[1].v3;
00390             s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp;
00391     
00392             v1 = s->row_out2nd[1].v2;
00393             s->row_out2nd[1].v2 = s->row_out2nd[1].v3;
00394             s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp;
00395         
00396             v1 = s->col_out2nd[2].v2;
00397             s->col_out2nd[2].v2 = s->col_out2nd[2].v3;
00398             s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp;
00399         
00400             v1 = s->row_out2nd[2].v2;
00401             s->row_out2nd[2].v2 = s->row_out2nd[2].v3;
00402             s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp;
00403         
00404             v1 = s->col_out2nd[3].v2;
00405             s->col_out2nd[3].v2 = s->col_out2nd[3].v3;
00406             s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp;
00407         
00408             v1 = s->row_out2nd[3].v2;
00409             s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
00410             s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
00411 
00412          /* Update fax tone */
00413             v1 = s->fax_tone.v2;
00414             s->fax_tone.v2 = s->fax_tone.v3;
00415             s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp;
00416 
00417             v1 = s->fax_tone.v2;
00418             s->fax_tone2nd.v2 = s->fax_tone2nd.v3;
00419             s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp;
00420         }
00421 #endif
00422         s->current_sample += (limit - sample);
00423         if (s->current_sample < 102) {
00424          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00425             /* If we had a hit last time, go ahead and clear this out since likely it
00426                will be another hit */
00427             for (i=sample;i<limit;i++) 
00428                amp[i] = 0;
00429             *writeback = 1;
00430          }
00431             continue;
00432       }
00433 
00434       /* Detect the fax energy, too */
00435       fax_energy = goertzel_result(&s->fax_tone);
00436       
00437         /* We are at the end of a DTMF detection block */
00438         /* Find the peak row and the peak column */
00439         row_energy[0] = goertzel_result (&s->row_out[0]);
00440         col_energy[0] = goertzel_result (&s->col_out[0]);
00441 
00442    for (best_row = best_col = 0, i = 1;  i < 4;  i++)
00443    {
00444           row_energy[i] = goertzel_result (&s->row_out[i]);
00445             if (row_energy[i] > row_energy[best_row])
00446                 best_row = i;
00447           col_energy[i] = goertzel_result (&s->col_out[i]);
00448             if (col_energy[i] > col_energy[best_col])
00449                 best_col = i;
00450       }
00451         hit = 0;
00452         /* Basic signal level test and the twist test */
00453         if (row_energy[best_row] >= DTMF_THRESHOLD
00454        &&
00455        col_energy[best_col] >= DTMF_THRESHOLD
00456             &&
00457             col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST
00458             &&
00459             col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row])
00460         {
00461             /* Relative peak test */
00462             for (i = 0;  i < 4;  i++)
00463             {
00464                 if ((i != best_col  &&  col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col])
00465                     ||
00466                     (i != best_row  &&  row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row]))
00467                 {
00468                     break;
00469                 }
00470             }
00471             /* ... and second harmonic test */
00472             if (i >= 4
00473            &&
00474       (row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy
00475                 &&
00476                 goertzel_result (&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col]
00477                 &&
00478                 goertzel_result (&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row])
00479             {
00480             /* Got a hit */
00481                 hit = dtmf_positions[(best_row << 2) + best_col];
00482             if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
00483                /* Zero out frame data if this is part DTMF */
00484                for (i=sample;i<limit;i++) 
00485                   amp[i] = 0;
00486                *writeback = 1;
00487             }
00488                 /* Look for two successive similar results */
00489                 /* The logic in the next test is:
00490                    We need two successive identical clean detects, with
00491          something different preceeding it. This can work with
00492          back to back differing digits. More importantly, it
00493          can work with nasty phones that give a very wobbly start
00494          to a digit. */
00495                 if (hit == s->hit3  &&  s->hit3 != s->hit2)
00496                 {
00497           s->mhit = hit;
00498                     s->digit_hits[(best_row << 2) + best_col]++;
00499                     s->detected_digits++;
00500                     if (s->current_digits < MAX_DTMF_DIGITS)
00501                     {
00502                         s->digits[s->current_digits++] = hit;
00503                         s->digits[s->current_digits] = '\0';
00504                     }
00505                     else
00506                     {
00507                         s->lost_digits++;
00508                     }
00509                 }
00510             }
00511         } 
00512       if (!hit && (fax_energy >= FAX_THRESHOLD) && (fax_energy > s->energy * 21.0)) {
00513             fax_energy_2nd = goertzel_result(&s->fax_tone2nd);
00514             if (fax_energy_2nd * FAX_2ND_HARMONIC < fax_energy) {
00515 #if 0
00516                printf("Fax energy/Second Harmonic: %f/%f\n", fax_energy, fax_energy_2nd);
00517 #endif               
00518                /* XXX Probably need better checking than just this the energy XXX */
00519                hit = 'f';
00520                s->fax_hits++;
00521             } /* Don't reset fax hits counter */
00522       } else {
00523          if (s->fax_hits > 5) {
00524              hit = 'f';
00525              s->mhit = 'f';
00526                 s->detected_digits++;
00527                 if (s->current_digits < MAX_DTMF_DIGITS)
00528                 {
00529                      s->digits[s->current_digits++] = hit;
00530                      s->digits[s->current_digits] = '\0';
00531                 }
00532                 else
00533                 {
00534                       s->lost_digits++;
00535                 }
00536          }
00537          s->fax_hits = 0;
00538       }
00539         s->hit1 = s->hit2;
00540         s->hit2 = s->hit3;
00541         s->hit3 = hit;
00542         /* Reinitialise the detector for the next block */
00543         for (i = 0;  i < 4;  i++)
00544         {
00545              goertzel_reset(&s->row_out[i]);
00546             goertzel_reset(&s->col_out[i]);
00547           goertzel_reset(&s->row_out2nd[i]);
00548           goertzel_reset(&s->col_out2nd[i]);
00549         }
00550       goertzel_reset (&s->fax_tone);
00551       goertzel_reset (&s->fax_tone2nd);
00552       s->energy = 0.0;
00553         s->current_sample = 0;
00554     }
00555     if ((!s->mhit) || (s->mhit != hit))
00556     {
00557    s->mhit = 0;
00558    return(0);
00559     }
00560     return (hit);
00561 }
00562 
00563 /* MF goertzel size */
00564 #define  MF_GSIZE 160
00565 
00566 static int mf_detect (mf_detect_state_t *s,
00567                  int16_t amp[],
00568                  int samples, 
00569        int digitmode, int *writeback)
00570 {
00571 
00572     float tone_energy[6];
00573     float famp;
00574     float v1;
00575     int i;
00576     int j;
00577     int sample;
00578     int best1;
00579     int best2;
00580    float max;
00581     int hit;
00582     int limit;
00583    int sofarsogood;
00584 
00585     hit = 0;
00586     for (sample = 0;  sample < samples;  sample = limit)
00587     {
00588         /* 80 is optimised to meet the MF specs. */
00589         if ((samples - sample) >= (MF_GSIZE - s->current_sample))
00590             limit = sample + (MF_GSIZE - s->current_sample);
00591         else
00592             limit = samples;
00593 #if defined(USE_3DNOW)
00594         _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
00595         _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
00596         _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
00597         _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
00598       /* XXX Need to fax detect for 3dnow too XXX */
00599       #warning "Fax Support Broken"
00600 #else
00601         /* The following unrolled loop takes only 35% (rough estimate) of the 
00602            time of a rolled loop on the machine on which it was developed */
00603         for (j = sample;  j < limit;  j++)
00604         {
00605             famp = amp[j];
00606        
00607        s->energy += famp*famp;
00608        
00609             /* With GCC 2.95, the following unrolled code seems to take about 35%
00610                (rough estimate) as long as a neat little 0-3 loop */
00611             v1 = s->tone_out[0].v2;
00612             s->tone_out[0].v2 = s->tone_out[0].v3;
00613             s->tone_out[0].v3 = s->tone_out[0].fac*s->tone_out[0].v2 - v1 + famp;
00614 
00615             v1 = s->tone_out[1].v2;
00616             s->tone_out[1].v2 = s->tone_out[1].v3;
00617             s->tone_out[1].v3 = s->tone_out[1].fac*s->tone_out[1].v2 - v1 + famp;
00618     
00619             v1 = s->tone_out[2].v2;
00620             s->tone_out[2].v2 = s->tone_out[2].v3;
00621             s->tone_out[2].v3 = s->tone_out[2].fac*s->tone_out[2].v2 - v1 + famp;
00622     
00623             v1 = s->tone_out[3].v2;
00624             s->tone_out[3].v2 = s->tone_out[3].v3;
00625             s->tone_out[3].v3 = s->tone_out[3].fac*s->tone_out[3].v2 - v1 + famp;
00626 
00627             v1 = s->tone_out[4].v2;
00628             s->tone_out[4].v2 = s->tone_out[4].v3;
00629             s->tone_out[4].v3 = s->tone_out[4].fac*s->tone_out[4].v2 - v1 + famp;
00630 
00631             v1 = s->tone_out[5].v2;
00632             s->tone_out[5].v2 = s->tone_out[5].v3;
00633             s->tone_out[5].v3 = s->tone_out[5].fac*s->tone_out[5].v2 - v1 + famp;
00634 
00635             v1 = s->tone_out2nd[0].v2;
00636             s->tone_out2nd[0].v2 = s->tone_out2nd[0].v3;
00637             s->tone_out2nd[0].v3 = s->tone_out2nd[0].fac*s->tone_out2nd[0].v2 - v1 + famp;
00638         
00639             v1 = s->tone_out2nd[1].v2;
00640             s->tone_out2nd[1].v2 = s->tone_out2nd[1].v3;
00641             s->tone_out2nd[1].v3 = s->tone_out2nd[1].fac*s->tone_out2nd[1].v2 - v1 + famp;
00642         
00643             v1 = s->tone_out2nd[2].v2;
00644             s->tone_out2nd[2].v2 = s->tone_out2nd[2].v3;
00645             s->tone_out2nd[2].v3 = s->tone_out2nd[2].fac*s->tone_out2nd[2].v2 - v1 + famp;
00646         
00647             v1 = s->tone_out2nd[3].v2;
00648             s->tone_out2nd[3].v2 = s->tone_out2nd[3].v3;
00649             s->tone_out2nd[3].v3 = s->tone_out2nd[3].fac*s->tone_out2nd[3].v2 - v1 + famp;
00650 
00651             v1 = s->tone_out2nd[4].v2;
00652             s->tone_out2nd[4].v2 = s->tone_out2nd[4].v3;
00653             s->tone_out2nd[4].v3 = s->tone_out2nd[4].fac*s->tone_out2nd[2].v2 - v1 + famp;
00654         
00655             v1 = s->tone_out2nd[3].v2;
00656             s->tone_out2nd[5].v2 = s->tone_out2nd[6].v3;
00657             s->tone_out2nd[5].v3 = s->tone_out2nd[6].fac*s->tone_out2nd[3].v2 - v1 + famp;
00658 
00659         }
00660 #endif
00661         s->current_sample += (limit - sample);
00662         if (s->current_sample < MF_GSIZE) {
00663          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00664             /* If we had a hit last time, go ahead and clear this out since likely it
00665                will be another hit */
00666             for (i=sample;i<limit;i++) 
00667                amp[i] = 0;
00668             *writeback = 1;
00669          }
00670             continue;
00671       }
00672 
00673       /* We're at the end of an MF detection block.  Go ahead and calculate
00674          all the energies. */
00675       for (i=0;i<6;i++) {
00676          tone_energy[i] = goertzel_result(&s->tone_out[i]);
00677       }
00678       
00679       /* Find highest */
00680       best1 = 0;
00681       max = tone_energy[0];
00682       for (i=1;i<6;i++) {
00683          if (tone_energy[i] > max) {
00684             max = tone_energy[i];
00685             best1 = i;
00686          }
00687       }
00688 
00689       /* Find 2nd highest */
00690       if (best1)
00691          max = tone_energy[0];
00692       else
00693          max = tone_energy[1];
00694       best2 = 0;
00695       for (i=0;i<6;i++) {
00696          if (i == best1) continue;
00697          if (tone_energy[i] > max) {
00698             max = tone_energy[i];
00699             best2 = i;
00700          }
00701       }
00702       
00703         hit = 0;
00704       if (best1 != best2) sofarsogood=1;
00705       else sofarsogood=0;
00706       /* Check for relative energies */
00707       for (i=0;i<6;i++) {
00708          if (i == best1) continue;
00709          if (i == best2) continue;
00710          if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
00711             sofarsogood = 0;
00712             break;
00713          }
00714          if (tone_energy[best2] < tone_energy[i] * MF_RELATIVE_PEAK) {
00715             sofarsogood = 0;
00716             break;
00717          }
00718       }
00719       
00720       if (sofarsogood) {
00721          /* Check for 2nd harmonic */
00722          if (goertzel_result(&s->tone_out2nd[best1]) * MF_2ND_HARMONIC > tone_energy[best1]) 
00723             sofarsogood = 0;
00724          else if (goertzel_result(&s->tone_out2nd[best2]) * MF_2ND_HARMONIC > tone_energy[best2])
00725             sofarsogood = 0;
00726       }
00727       if (sofarsogood) {
00728          hit = mf_hit[best1][best2];
00729          if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
00730             /* Zero out frame data if this is part DTMF */
00731             for (i=sample;i<limit;i++) 
00732                amp[i] = 0;
00733             *writeback = 1;
00734          }
00735          /* Look for two consecutive clean hits */
00736          if ((hit == s->hit3) && (s->hit3 != s->hit2)) {
00737             s->mhit = hit;
00738             s->detected_digits++;
00739             if (s->current_digits < MAX_DTMF_DIGITS - 2) {
00740                s->digits[s->current_digits++] = hit;
00741                s->digits[s->current_digits] = '\0';
00742             } else {
00743                s->lost_digits++;
00744             }
00745          }
00746       }
00747       
00748         s->hit1 = s->hit2;
00749         s->hit2 = s->hit3;
00750         s->hit3 = hit;
00751         /* Reinitialise the detector for the next block */
00752         for (i = 0;  i < 6;  i++)
00753         {
00754              goertzel_reset(&s->tone_out[i]);
00755             goertzel_reset(&s->tone_out2nd[i]);
00756         }
00757       s->energy = 0.0;
00758         s->current_sample = 0;
00759     }
00760     if ((!s->mhit) || (s->mhit != hit))
00761     {
00762       s->mhit = 0;
00763       return(0);
00764     }
00765     return (hit);
00766 }
00767 
00768 static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
00769 {
00770    int res;
00771    if (dsp->digitmode & DSP_DIGITMODE_MF)
00772       res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00773    else
00774       res = dtmf_detect(&dsp->td.dtmf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00775    return res;
00776 }
00777 
00778 int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
00779 {
00780    short *s;
00781    int len;
00782    int ign=0;
00783    if (inf->frametype != AST_FRAME_VOICE) {
00784       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00785       return 0;
00786    }
00787    if (inf->subclass != AST_FORMAT_SLINEAR) {
00788       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00789       return 0;
00790    }
00791    s = inf->data;
00792    len = inf->datalen / 2;
00793    return __ast_dsp_digitdetect(dsp, s, len, &ign);
00794 }
00795 
00796 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
00797 {
00798    /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
00799    /* Make sure absolute levels are high enough */
00800    if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
00801       return 0;
00802    /* Amplify ignored stuff */
00803    i2 *= TONE_THRESH;
00804    i1 *= TONE_THRESH;
00805    e *= TONE_THRESH;
00806    /* Check first tone */
00807    if ((p1 < i1) || (p1 < i2) || (p1 < e))
00808       return 0;
00809    /* And second */
00810    if ((p2 < i1) || (p2 < i2) || (p2 < e))
00811       return 0;
00812    /* Guess it's there... */
00813    return 1;
00814 }
00815 
00816 int ast_dsp_getdigits (struct ast_dsp *dsp,
00817               char *buf,
00818               int max)
00819 {
00820    if (dsp->digitmode & DSP_DIGITMODE_MF) {
00821        if (max > dsp->td.mf.current_digits)
00822            max = dsp->td.mf.current_digits;
00823        if (max > 0)
00824        {
00825            memcpy (buf, dsp->td.mf.digits, max);
00826            memmove (dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
00827            dsp->td.mf.current_digits -= max;
00828        }
00829        buf[max] = '\0';
00830        return  max;
00831    } else {
00832        if (max > dsp->td.dtmf.current_digits)
00833            max = dsp->td.dtmf.current_digits;
00834        if (max > 0)
00835        {
00836            memcpy (buf, dsp->td.dtmf.digits, max);
00837            memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
00838            dsp->td.dtmf.current_digits -= max;
00839        }
00840        buf[max] = '\0';
00841        return  max;
00842    }
00843 }
00844 
00845 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
00846 {
00847    int x;
00848    int pass;
00849    int newstate = TONE_STATE_SILENCE;
00850    int res = 0;
00851    while(len) {
00852       /* Take the lesser of the number of samples we need and what we have */
00853       pass = len;
00854       if (pass > GSAMP_SIZE - dsp->gsamps) 
00855          pass = GSAMP_SIZE - dsp->gsamps;
00856       for (x=0;x<pass;x++) {
00857          goertzel_sample(&dsp->freqs[HZ_350], s[x]);
00858          goertzel_sample(&dsp->freqs[HZ_440], s[x]);
00859          goertzel_sample(&dsp->freqs[HZ_480], s[x]);
00860          goertzel_sample(&dsp->freqs[HZ_620], s[x]);
00861          goertzel_sample(&dsp->freqs[HZ_950], s[x]);
00862          goertzel_sample(&dsp->freqs[HZ_1400], s[x]);
00863          goertzel_sample(&dsp->freqs[HZ_1800], s[x]);
00864          dsp->genergy += s[x] * s[x];
00865       }
00866       s += pass;
00867       dsp->gsamps += pass;
00868       len -= pass;
00869       if (dsp->gsamps == GSAMP_SIZE) {
00870          float hz_350;
00871          float hz_440;
00872          float hz_480;
00873          float hz_620;
00874          float hz_950;
00875          float hz_1400;
00876          float hz_1800;
00877          hz_350 = goertzel_result(&dsp->freqs[HZ_350]);
00878          hz_440 = goertzel_result(&dsp->freqs[HZ_440]);
00879          hz_480 = goertzel_result(&dsp->freqs[HZ_480]);
00880          hz_620 = goertzel_result(&dsp->freqs[HZ_620]);
00881          hz_950 = goertzel_result(&dsp->freqs[HZ_950]);
00882          hz_1400 = goertzel_result(&dsp->freqs[HZ_1400]);
00883          hz_1800 = goertzel_result(&dsp->freqs[HZ_1800]);
00884 #if 0
00885          printf("Got whole dsp state: 350: %e, 440: %e, 480: %e, 620: %e, 950: %e, 1400: %e, 1800: %e, Energy: %e\n", 
00886             hz_350, hz_440, hz_480, hz_620, hz_950, hz_1400, hz_1800, dsp->genergy);
00887 #endif
00888          if (pair_there(hz_480, hz_620, hz_350, hz_440, dsp->genergy)) {
00889             newstate = TONE_STATE_BUSY;
00890          } else if (pair_there(hz_440, hz_480, hz_350, hz_620, dsp->genergy)) {
00891             newstate = TONE_STATE_RINGING;
00892          } else if (pair_there(hz_350, hz_440, hz_480, hz_620, dsp->genergy)) {
00893             newstate = TONE_STATE_DIALTONE;
00894          } else if (hz_950 > TONE_MIN_THRESH * TONE_THRESH) {
00895             newstate = TONE_STATE_SPECIAL1;
00896          } else if (hz_1400 > TONE_MIN_THRESH * TONE_THRESH) {
00897             if (dsp->tstate == TONE_STATE_SPECIAL1)
00898                newstate = TONE_STATE_SPECIAL2;
00899          } else if (hz_1800 > TONE_MIN_THRESH * TONE_THRESH) {
00900             if (dsp->tstate == TONE_STATE_SPECIAL2)
00901                newstate = TONE_STATE_SPECIAL3;
00902          } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
00903             newstate = TONE_STATE_TALKING;
00904          } else
00905             newstate = TONE_STATE_SILENCE;
00906          
00907          if (newstate == dsp->tstate) {
00908             dsp->tcount++;
00909             if (dsp->tcount == COUNT_THRESH) {
00910                if (dsp->tstate == TONE_STATE_BUSY) {
00911                   res = AST_CONTROL_BUSY;
00912                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00913                } else if (dsp->tstate == TONE_STATE_TALKING) {
00914                   res = AST_CONTROL_ANSWER;
00915                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00916                } else if (dsp->tstate == TONE_STATE_RINGING)
00917                   res = AST_CONTROL_RINGING;
00918                else if (dsp->tstate == TONE_STATE_SPECIAL3) {
00919                   res = AST_CONTROL_CONGESTION;
00920                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00921                }
00922                
00923             }
00924          } else {
00925 #if 0
00926             printf("Newstate: %d\n", newstate);
00927 #endif
00928             dsp->tstate = newstate;
00929             dsp->tcount = 1;
00930          }
00931          
00932          /* Reset goertzel */                
00933          for (x=0;x<7;x++)
00934             dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
00935          dsp->gsamps = 0;
00936          dsp->genergy = 0.0;
00937       }
00938    }
00939 #if 0
00940    if (res)
00941       printf("Returning %d\n", res);
00942 #endif      
00943    return res;
00944 }
00945 
00946 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
00947 {
00948    if (inf->frametype != AST_FRAME_VOICE) {
00949       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00950       return 0;
00951    }
00952    if (inf->subclass != AST_FORMAT_SLINEAR) {
00953       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00954       return 0;
00955    }
00956    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
00957 }
00958 
00959 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
00960 {
00961    int accum;
00962    int x;
00963    int res = 0;
00964    
00965    accum = 0;
00966    for (x=0;x<len; x++) 
00967       accum += abs(s[x]);
00968    accum /= len;
00969    if (accum < dsp->threshold) {
00970       dsp->totalsilence += len/8;
00971       if (dsp->totalnoise) {
00972          /* Move and save history */
00973          memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
00974          dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
00975 /* we don't want to check for busydetect that frequently */
00976 #if 0
00977          dsp->busymaybe = 1;
00978 #endif
00979       }
00980       dsp->totalnoise = 0;
00981       res = 1;
00982    } else {
00983       dsp->totalnoise += len/8;
00984       if (dsp->totalsilence) {
00985          int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
00986          int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
00987          /* Move and save history */
00988          memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
00989          dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
00990          /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
00991          if (silence1 < silence2) {
00992             if (silence1 + silence1/BUSY_PERCENT >= silence2)
00993                dsp->busymaybe = 1;
00994             else 
00995                dsp->busymaybe = 0;
00996          } else {
00997             if (silence1 - silence1/BUSY_PERCENT <= silence2)
00998                dsp->busymaybe = 1;
00999             else 
01000                dsp->busymaybe = 0;
01001          }
01002                
01003       }
01004       dsp->totalsilence = 0;
01005    }
01006    if (totalsilence)
01007       *totalsilence = dsp->totalsilence;
01008    return res;
01009 }
01010 #ifdef BUSYDETECT_MARTIN
01011 int ast_dsp_busydetect(struct ast_dsp *dsp)
01012 {
01013    int res = 0, x;
01014 #ifndef BUSYDETECT_TONEONLY
01015    int avgsilence = 0, hitsilence = 0;
01016 #endif
01017    int avgtone = 0, hittone = 0;
01018    if (!dsp->busymaybe)
01019       return res;
01020    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01021 #ifndef BUSYDETECT_TONEONLY
01022       avgsilence += dsp->historicsilence[x];
01023 #endif
01024       avgtone += dsp->historicnoise[x];
01025    }
01026 #ifndef BUSYDETECT_TONEONLY
01027    avgsilence /= dsp->busycount;
01028 #endif
01029    avgtone /= dsp->busycount;
01030    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01031 #ifndef BUSYDETECT_TONEONLY
01032       if (avgsilence > dsp->historicsilence[x]) {
01033          if (avgsilence - (avgsilence / BUSY_PERCENT) <= dsp->historicsilence[x])
01034             hitsilence++;
01035       } else {
01036          if (avgsilence + (avgsilence / BUSY_PERCENT) >= dsp->historicsilence[x])
01037             hitsilence++;
01038       }
01039 #endif
01040       if (avgtone > dsp->historicnoise[x]) {
01041          if (avgtone - (avgtone / BUSY_PERCENT) <= dsp->historicsilence[x])
01042             hittone++;
01043       } else {
01044          if (avgtone + (avgtone / BUSY_PERCENT) >= dsp->historicsilence[x])
01045             hittone++;
01046       }
01047    }
01048 #ifndef BUSYDETECT_TONEONLY
01049    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01050 #else
01051    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01052 #endif
01053 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01054 #ifdef BUSYDETECT_TONEONLY
01055 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01056 #endif
01057       if (avgtone > avgsilence) {
01058          if (avgtone - avgtone/(BUSY_PERCENT*2) <= avgsilence)
01059             res = 1;
01060       } else {
01061          if (avgtone + avgtone/(BUSY_PERCENT*2) >= avgsilence)
01062             res = 1;
01063       }
01064 #else
01065       res = 1;
01066 #endif
01067    }
01068 #if 0
01069    if (res)
01070       ast_log(LOG_NOTICE, "detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01071 #endif
01072    return res;
01073 }
01074 #endif
01075 
01076 #ifdef BUSYDETECT
01077 int ast_dsp_busydetect(struct ast_dsp *dsp)
01078 {
01079    int x;
01080    int res = 0;
01081    int max, min;
01082 
01083 #if 0
01084    if (dsp->busy_hits > 5);
01085    return 0;
01086 #endif
01087    if (dsp->busymaybe) {
01088 #if 0
01089       printf("Maybe busy!\n");
01090 #endif      
01091       dsp->busymaybe = 0;
01092       min = 9999;
01093       max = 0;
01094       for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01095 #if 0
01096          printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
01097 #endif         
01098          if (dsp->historicsilence[x] < min)
01099             min = dsp->historicsilence[x];
01100          if (dsp->historicnoise[x] < min)
01101             min = dsp->historicnoise[x];
01102          if (dsp->historicsilence[x] > max)
01103             max = dsp->historicsilence[x];
01104          if (dsp->historicnoise[x] > max)
01105             max = dsp->historicnoise[x];
01106       }
01107       if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
01108 #if 0
01109          printf("Busy!\n");
01110 #endif         
01111          res = 1;
01112       }
01113 #if 0
01114       printf("Min: %d, max: %d\n", min, max);
01115 #endif      
01116    }
01117    return res;
01118 }
01119 #endif
01120 
01121 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01122 {
01123    short *s;
01124    int len;
01125    
01126    if (f->frametype != AST_FRAME_VOICE) {
01127       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01128       return 0;
01129    }
01130    if (f->subclass != AST_FORMAT_SLINEAR) {
01131       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01132       return 0;
01133    }
01134    s = f->data;
01135    len = f->datalen/2;
01136    return __ast_dsp_silence(dsp, s, len, totalsilence);
01137 }
01138 
01139 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af, int needlock)
01140 {
01141    int silence;
01142    int res;
01143    int digit;
01144    int x;
01145    unsigned short *shortdata;
01146    unsigned char *odata;
01147    int len;
01148    int writeback = 0;
01149 
01150 #define FIX_INF(inf) do { \
01151       if (writeback) { \
01152          switch(inf->subclass) { \
01153          case AST_FORMAT_SLINEAR: \
01154             break; \
01155          case AST_FORMAT_ULAW: \
01156             for (x=0;x<len;x++) \
01157                odata[x] = AST_LIN2MU(shortdata[x]); \
01158             break; \
01159          case AST_FORMAT_ALAW: \
01160             for (x=0;x<len;x++) \
01161                odata[x] = AST_LIN2A(shortdata[x]); \
01162             break; \
01163          } \
01164       } \
01165    } while(0) 
01166 
01167    if (!af)
01168       return NULL;
01169    if (af->frametype != AST_FRAME_VOICE)
01170       return af;
01171    odata = af->data;
01172    len = af->datalen;
01173    /* Make sure we have short data */
01174    switch(af->subclass) {
01175    case AST_FORMAT_SLINEAR:
01176       shortdata = af->data;
01177       len = af->datalen / 2;
01178       break;
01179    case AST_FORMAT_ULAW:
01180       shortdata = alloca(af->datalen * 2);
01181       if (!shortdata) {
01182          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01183          return af;
01184       }
01185       for (x=0;x<len;x++) 
01186          shortdata[x] = AST_MULAW(odata[x]);
01187       break;
01188    case AST_FORMAT_ALAW:
01189       shortdata = alloca(af->datalen * 2);
01190       if (!shortdata) {
01191          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01192          return af;
01193       }
01194       for (x=0;x<len;x++) 
01195          shortdata[x] = AST_ALAW(odata[x]);
01196       break;
01197    default:
01198       ast_log(LOG_WARNING, "Unable to detect process %d frames\n", af->subclass);
01199       return af;
01200    }
01201    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01202    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01203       memset(&dsp->f, 0, sizeof(dsp->f));
01204       dsp->f.frametype = AST_FRAME_NULL;
01205       return &dsp->f;
01206    }
01207    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01208       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01209       memset(&dsp->f, 0, sizeof(dsp->f));
01210       dsp->f.frametype = AST_FRAME_CONTROL;
01211       dsp->f.subclass = AST_CONTROL_BUSY;
01212       ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01213       return &dsp->f;
01214    }
01215    if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01216       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01217 #if 0
01218       if (digit)
01219          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01220 #endif         
01221       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01222          if (!dsp->thinkdigit) {
01223             if (digit) {
01224                /* Looks like we might have something.  Request a conference mute for the moment */
01225                memset(&dsp->f, 0, sizeof(dsp->f));
01226                dsp->f.frametype = AST_FRAME_DTMF;
01227                dsp->f.subclass = 'm';
01228                dsp->thinkdigit = 'x';
01229                FIX_INF(af);
01230                if (chan)
01231                   ast_queue_frame(chan, af, needlock);
01232                ast_frfree(af);
01233                return &dsp->f;
01234             }
01235          } else {
01236             if (digit) {
01237                /* Thought we saw one last time.  Pretty sure we really have now */
01238                if (dsp->thinkdigit) {
01239                   if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01240                      /* If we found a digit, and we're changing digits, go
01241                         ahead and send this one, but DON'T stop confmute because
01242                         we're detecting something else, too... */
01243                      memset(&dsp->f, 0, sizeof(dsp->f));
01244                      dsp->f.frametype = AST_FRAME_DTMF;
01245                      dsp->f.subclass = dsp->thinkdigit;
01246                      FIX_INF(af);
01247                      if (chan)
01248                         ast_queue_frame(chan, af, needlock);
01249                      ast_frfree(af);
01250                   }
01251                   dsp->thinkdigit = digit;
01252                   return &dsp->f;
01253                }
01254                dsp->thinkdigit = digit;
01255             } else {
01256                if (dsp->thinkdigit) {
01257                   memset(&dsp->f, 0, sizeof(dsp->f));
01258                   if (dsp->thinkdigit != 'x') {
01259                      /* If we found a digit, send it now */
01260                      dsp->f.frametype = AST_FRAME_DTMF;
01261                      dsp->f.subclass = dsp->thinkdigit;
01262                      dsp->thinkdigit = 0;
01263                   } else {
01264                      dsp->f.frametype = AST_FRAME_DTMF;
01265                      dsp->f.subclass = 'u';
01266                      dsp->thinkdigit = 0;
01267                   }
01268                   FIX_INF(af);
01269                   if (chan)
01270                      ast_queue_frame(chan, af, needlock);
01271                   ast_frfree(af);
01272                   return &dsp->f;
01273                }
01274             }
01275          }
01276       } else if (!digit) {
01277          /* Only check when there is *not* a hit... */
01278          if (dsp->digitmode & DSP_DIGITMODE_MF) {
01279             if (dsp->td.mf.current_digits) {
01280                memset(&dsp->f, 0, sizeof(dsp->f));
01281                dsp->f.frametype = AST_FRAME_DTMF;
01282                dsp->f.subclass = dsp->td.mf.digits[0];
01283                memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01284                dsp->td.mf.current_digits--;
01285                FIX_INF(af);
01286                if (chan)
01287                   ast_queue_frame(chan, af, needlock);
01288                ast_frfree(af);
01289                return &dsp->f;
01290             }
01291          } else {
01292             if (dsp->td.dtmf.current_digits) {
01293                memset(&dsp->f, 0, sizeof(dsp->f));
01294                dsp->f.frametype = AST_FRAME_DTMF;
01295                dsp->f.subclass = dsp->td.dtmf.digits[0];
01296                memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01297                dsp->td.dtmf.current_digits--;
01298                FIX_INF(af);
01299                if (chan)
01300                   ast_queue_frame(chan, af, needlock);
01301                ast_frfree(af);
01302                return &dsp->f;
01303             }
01304          }
01305       }
01306    }
01307    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01308       res = __ast_dsp_call_progress(dsp, shortdata, len);
01309       memset(&dsp->f, 0, sizeof(dsp->f));
01310       dsp->f.frametype = AST_FRAME_CONTROL;
01311       if (res) {
01312          switch(res) {
01313          case AST_CONTROL_ANSWER:
01314          case AST_CONTROL_BUSY:
01315          case AST_CONTROL_RINGING:
01316          case AST_CONTROL_CONGESTION:
01317             dsp->f.subclass = res;
01318             if (chan) 
01319                ast_queue_frame(chan, &dsp->f, needlock);
01320             break;
01321          default:
01322             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01323          }
01324       }
01325    }
01326    FIX_INF(af);
01327    return af;
01328 }
01329 
01330 struct ast_dsp *ast_dsp_new(void)
01331 {
01332    struct ast_dsp *dsp;
01333    dsp = malloc(sizeof(struct ast_dsp));
01334    if (dsp) {
01335       memset(dsp, 0, sizeof(struct ast_dsp));
01336       dsp->threshold = DEFAULT_THRESHOLD;
01337       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01338       dsp->busycount = DSP_HISTORY;
01339       /* Initialize goertzels */
01340       goertzel_init(&dsp->freqs[HZ_350], 350.0);
01341       goertzel_init(&dsp->freqs[HZ_440], 440.0);
01342       goertzel_init(&dsp->freqs[HZ_480], 480.0);
01343       goertzel_init(&dsp->freqs[HZ_620], 620.0);
01344       goertzel_init(&dsp->freqs[HZ_950], 950.0);
01345       goertzel_init(&dsp->freqs[HZ_1400], 1400.0);
01346       goertzel_init(&dsp->freqs[HZ_1800], 1800.0);
01347       /* Initialize DTMF detector */
01348       ast_dtmf_detect_init(&dsp->td.dtmf);
01349    }
01350    return dsp;
01351 }
01352 
01353 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01354 {
01355    dsp->features = features;
01356 }
01357 
01358 void ast_dsp_free(struct ast_dsp *dsp)
01359 {
01360    free(dsp);
01361 }
01362 
01363 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01364 {
01365    dsp->threshold = threshold;
01366 }
01367 
01368 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01369 {
01370    if (cadences < 4)
01371       cadences = 4;
01372    if (cadences > DSP_HISTORY)
01373       cadences = DSP_HISTORY;
01374    dsp->busycount = cadences;
01375 }
01376 
01377 void ast_dsp_digitreset(struct ast_dsp *dsp)
01378 {
01379    int i;
01380    dsp->thinkdigit = 0;
01381    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01382       memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01383       dsp->td.mf.current_digits = 0;
01384       /* Reinitialise the detector for the next block */
01385       for (i = 0;  i < 6;  i++) {
01386             goertzel_reset(&dsp->td.mf.tone_out[i]);
01387           goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01388       }
01389       dsp->td.mf.energy = 0.0;
01390       dsp->td.mf.current_sample = 0;
01391        dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01392    } else {
01393       memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01394       dsp->td.dtmf.current_digits = 0;
01395       /* Reinitialise the detector for the next block */
01396       for (i = 0;  i < 4;  i++) {
01397             goertzel_reset(&dsp->td.dtmf.row_out[i]);
01398           goertzel_reset(&dsp->td.dtmf.col_out[i]);
01399          goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01400          goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01401       }
01402        goertzel_reset (&dsp->td.dtmf.fax_tone);
01403        goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01404       dsp->td.dtmf.energy = 0.0;
01405       dsp->td.dtmf.current_sample = 0;
01406        dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01407    }
01408 }
01409 
01410 void ast_dsp_reset(struct ast_dsp *dsp)
01411 {
01412    int x;
01413    dsp->totalsilence = 0;
01414    dsp->gsamps = 0;
01415    for (x=0;x<4;x++)
01416       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01417    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01418    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01419    
01420 }
01421 
01422 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01423 {
01424    int new, old;
01425    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01426    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01427    if (old != new) {
01428       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01429       if (new & DSP_DIGITMODE_MF)
01430          ast_mf_detect_init(&dsp->td.mf);
01431       else
01432          ast_dtmf_detect_init(&dsp->td.dtmf);
01433    }
01434    dsp->digitmode = digitmode;
01435    return 0;
01436 }
01437 

Generated on Fri Oct 31 07:05:06 2003 for Asterisk by doxygen 1.3.4