80fdf95eb0ea4ff3ed4eabe48fc13138f335cca5
[asterisk/asterisk.git] / main / dsp.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
9  * DTMF detector.
10  *
11  * See http://www.asterisk.org for more information about
12  * the Asterisk project. Please do not directly contact
13  * any of the maintainers of this project for assistance;
14  * the project provides a web site, mailing lists and IRC
15  * channels for your use.
16  *
17  * This program is free software, distributed under the terms of
18  * the GNU General Public License Version 2. See the LICENSE file
19  * at the top of the source tree.
20  */
21
22 /*! \file
23  *
24  * \brief Convenience Signal Processing routines
25  *
26  * \author Mark Spencer <markster@digium.com>
27  * \author Steve Underwood <steveu@coppice.org>
28  */
29
30 /* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
31 /*
32         tone_detect.c - General telephony tone detection, and specific
33                         detection of DTMF.
34
35         Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
36
37         Despite my general liking of the GPL, I place this code in the
38         public domain for the benefit of all mankind - even the slimy
39         ones who might try to proprietize my work and use it to my
40         detriment.
41 */
42
43 #include "asterisk.h"
44
45 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
46
47 #include <math.h>
48 #include <errno.h>
49
50 #include "asterisk/frame.h"
51 #include "asterisk/channel.h"
52 #include "asterisk/dsp.h"
53 #include "asterisk/ulaw.h"
54 #include "asterisk/alaw.h"
55 #include "asterisk/utils.h"
56 #include "asterisk/options.h"
57
58 /*! Number of goertzels for progress detect */
59 enum gsamp_size {
60         GSAMP_SIZE_NA = 183,                    /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
61         GSAMP_SIZE_CR = 188,                    /*!< Costa Rica, Brazil - Only care about 425 Hz */
62         GSAMP_SIZE_UK = 160                     /*!< UK disconnect goertzel feed - should trigger 400hz */
63 };
64
65 enum prog_mode {
66         PROG_MODE_NA = 0,
67         PROG_MODE_CR,
68         PROG_MODE_UK
69 };
70
71 enum freq_index { 
72         /*! For US modes { */
73         HZ_350 = 0,
74         HZ_440,
75         HZ_480,
76         HZ_620,
77         HZ_950,
78         HZ_1400,
79         HZ_1800, /*!< } */
80
81         /*! For CR/BR modes */
82         HZ_425 = 0,
83
84         /*! For UK mode */
85         HZ_400 = 0
86 };
87
88 static struct progalias {
89         char *name;
90         enum prog_mode mode;
91 } aliases[] = {
92         { "us", PROG_MODE_NA },
93         { "ca", PROG_MODE_NA },
94         { "cr", PROG_MODE_CR },
95         { "br", PROG_MODE_CR },
96         { "uk", PROG_MODE_UK },
97 };
98
99 static struct progress {
100         enum gsamp_size size;
101         int freqs[7];
102 } modes[] = {
103         { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } },     /*!< North America */
104         { GSAMP_SIZE_CR, { 425 } },                                     /*!< Costa Rica, Brazil */
105         { GSAMP_SIZE_UK, { 400 } },                                     /*!< UK */
106 };
107
108 #define DEFAULT_THRESHOLD       512
109
110 enum busy_detect {
111         BUSY_PERCENT = 10,      /*!< The percentage difference between the two last silence periods */
112         BUSY_PAT_PERCENT = 7,   /*!< The percentage difference between measured and actual pattern */
113         BUSY_THRESHOLD = 100,   /*!< Max number of ms difference between max and min times in busy */
114         BUSY_MIN = 75,          /*!< Busy must be at least 80 ms in half-cadence */
115         BUSY_MAX =3100          /*!< Busy can't be longer than 3100 ms in half-cadence */
116 };
117
118 /*! Remember last 15 units */
119 #define DSP_HISTORY             15
120
121 /*! Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE */
122 #define FAX_DETECT
123
124 #define TONE_THRESH             10.0    /*!< How much louder the tone should be than channel energy */
125 #define TONE_MIN_THRESH         1e8     /*!< How much tone there should be at least to attempt */
126
127 /*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
128 enum gsamp_thresh {
129         THRESH_RING = 8,                /*!< Need at least 150ms ring to accept */
130         THRESH_TALK = 2,                /*!< Talk detection does not work continuously */
131         THRESH_BUSY = 4,                /*!< Need at least 80ms to accept */
132         THRESH_CONGESTION = 4,          /*!< Need at least 80ms to accept */
133         THRESH_HANGUP = 60,             /*!< Need at least 1300ms to accept hangup */
134         THRESH_RING2ANSWER = 300        /*!< Timeout from start of ring to answer (about 6600 ms) */
135 };
136
137 #define MAX_DTMF_DIGITS         128
138
139 /* Basic DTMF specs:
140  *
141  * Minimum tone on = 40ms
142  * Minimum tone off = 50ms
143  * Maximum digit rate = 10 per second
144  * Normal twist <= 8dB accepted
145  * Reverse twist <= 4dB accepted
146  * S/N >= 15dB will detect OK
147  * Attenuation <= 26dB will detect OK
148  * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
149  */
150
151 #define DTMF_THRESHOLD          8.0e7
152 #define FAX_THRESHOLD           8.0e7
153 #define FAX_2ND_HARMONIC        2.0     /* 4dB */
154 #define DTMF_NORMAL_TWIST       6.3     /* 8dB */
155 #ifdef  RADIO_RELAX
156 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5)     /* 4dB normal */
157 #else
158 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)     /* 4dB normal */
159 #endif
160 #define DTMF_RELATIVE_PEAK_ROW  6.3     /* 8dB */
161 #define DTMF_RELATIVE_PEAK_COL  6.3     /* 8dB */
162 #define DTMF_2ND_HARMONIC_ROW       ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)     /* 4dB normal */
163 #define DTMF_2ND_HARMONIC_COL   63.1    /* 18dB */
164 #define DTMF_TO_TOTAL_ENERGY    42.0
165
166 #ifdef OLD_DSP_ROUTINES
167 #define MF_THRESHOLD            8.0e7
168 #define MF_NORMAL_TWIST         5.3     /* 8dB */
169 #define MF_REVERSE_TWIST        4.0     /* was 2.5 */
170 #define MF_RELATIVE_PEAK        5.3     /* 8dB */
171 #define MF_2ND_HARMONIC         1.7     /* was 2.5  */
172 #else
173 #define BELL_MF_THRESHOLD       1.6e9
174 #define BELL_MF_TWIST           4.0     /* 6dB */
175 #define BELL_MF_RELATIVE_PEAK   12.6    /* 11dB */
176 #endif
177
178 #if !defined(BUSYDETECT_MARTIN) && !defined(BUSYDETECT) && !defined(BUSYDETECT_TONEONLY) && !defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
179 #define BUSYDETECT_MARTIN
180 #endif
181
182 typedef struct {
183         int v2;
184         int v3;
185         int chunky;
186         int fac;
187 #ifndef OLD_DSP_ROUTINES
188         int samples;
189 #endif  
190 } goertzel_state_t;
191
192 typedef struct {
193         int value;
194         int power;
195 } goertzel_result_t;
196
197 typedef struct
198 {
199         goertzel_state_t row_out[4];
200         goertzel_state_t col_out[4];
201 #ifdef FAX_DETECT
202         goertzel_state_t fax_tone;
203 #endif
204 #ifdef OLD_DSP_ROUTINES
205         goertzel_state_t row_out2nd[4];
206         goertzel_state_t col_out2nd[4];
207 #ifdef FAX_DETECT
208         goertzel_state_t fax_tone2nd;    
209 #endif
210         int hit1;
211         int hit2;
212         int hit3;
213         int hit4;
214 #else
215         int lasthit;
216 #endif  
217         int mhit;
218         float energy;
219         int current_sample;
220
221         char digits[MAX_DTMF_DIGITS + 1];
222         
223         int current_digits;
224         int detected_digits;
225         int lost_digits;
226         int digit_hits[16];
227 #ifdef FAX_DETECT
228         int fax_hits;
229 #endif
230 } dtmf_detect_state_t;
231
232 typedef struct
233 {
234         goertzel_state_t tone_out[6];
235         int mhit;
236 #ifdef OLD_DSP_ROUTINES
237         int hit1;
238         int hit2;
239         int hit3;
240         int hit4;
241         goertzel_state_t tone_out2nd[6];
242         float energy;
243 #else
244         int hits[5];
245 #endif
246         int current_sample;
247         
248         char digits[MAX_DTMF_DIGITS + 1];
249
250         int current_digits;
251         int detected_digits;
252         int lost_digits;
253 #ifdef FAX_DETECT
254         int fax_hits;
255 #endif
256 } mf_detect_state_t;
257
258 static float dtmf_row[] =
259 {
260         697.0,  770.0,  852.0,  941.0
261 };
262 static float dtmf_col[] =
263 {
264         1209.0, 1336.0, 1477.0, 1633.0
265 };
266
267 static float mf_tones[] =
268 {
269         700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
270 };
271
272 #ifdef FAX_DETECT
273 static float fax_freq = 1100.0;
274 #endif
275
276 static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
277
278 #ifdef OLD_DSP_ROUTINES
279 static char mf_hit[6][6] = {
280         /*  700 + */ {   0, '1', '2', '4', '7', 'C' },
281         /*  900 + */ { '1',   0, '3', '5', '8', 'A' },
282         /* 1100 + */ { '2', '3',   0, '6', '9', '*' },
283         /* 1300 + */ { '4', '5', '6',   0, '0', 'B' },
284         /* 1500 + */ { '7', '8', '9', '0',  0, '#' },
285         /* 1700 + */ { 'C', 'A', '*', 'B', '#',  0  },
286 };
287 #else
288 static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
289 #endif
290
291 static inline void goertzel_sample(goertzel_state_t *s, short sample)
292 {
293         int v1;
294         
295         v1 = s->v2;
296         s->v2 = s->v3;
297         
298         s->v3 = (s->fac * s->v2) >> 15;
299         s->v3 = s->v3 - v1 + (sample >> s->chunky);
300         if (abs(s->v3) > 32768) {
301                 s->chunky++;
302                 s->v3 = s->v3 >> 1;
303                 s->v2 = s->v2 >> 1;
304                 v1 = v1 >> 1;
305         }
306 }
307
308 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
309 {
310         int i;
311         
312         for (i=0;i<count;i++) 
313                 goertzel_sample(s, samps[i]);
314 }
315
316
317 static inline float goertzel_result(goertzel_state_t *s)
318 {
319         goertzel_result_t r;
320         r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
321         r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
322         r.power = s->chunky * 2;
323         return (float)r.value * (float)(1 << r.power);
324 }
325
326 static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
327 {
328         s->v2 = s->v3 = s->chunky = 0.0;
329         s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * (freq / 8000.0)));
330 #ifndef OLD_DSP_ROUTINES
331         s->samples = samples;
332 #endif
333 }
334
335 static inline void goertzel_reset(goertzel_state_t *s)
336 {
337         s->v2 = s->v3 = s->chunky = 0.0;
338 }
339
340 struct ast_dsp {
341         struct ast_frame f;
342         int threshold;
343         int totalsilence;
344         int totalnoise;
345         int features;
346         int ringtimeout;
347         int busymaybe;
348         int busycount;
349         int busy_tonelength;
350         int busy_quietlength;
351         int historicnoise[DSP_HISTORY];
352         int historicsilence[DSP_HISTORY];
353         goertzel_state_t freqs[7];
354         int freqcount;
355         int gsamps;
356         enum gsamp_size gsamp_size;
357         enum prog_mode progmode;
358         int tstate;
359         int tcount;
360         int digitmode;
361         int thinkdigit;
362         float genergy;
363         union {
364                 dtmf_detect_state_t dtmf;
365                 mf_detect_state_t mf;
366         } td;
367 };
368
369 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
370 {
371         int i;
372
373 #ifdef OLD_DSP_ROUTINES
374         s->hit1 = 
375         s->mhit = 
376         s->hit3 =
377         s->hit4 = 
378         s->hit2 = 0;
379 #else
380         s->lasthit = 0;
381 #endif
382         for (i = 0;  i < 4;  i++) {
383                 goertzel_init (&s->row_out[i], dtmf_row[i], 102);
384                 goertzel_init (&s->col_out[i], dtmf_col[i], 102);
385 #ifdef OLD_DSP_ROUTINES
386                 goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0, 102);
387                 goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0, 102);
388 #endif  
389                 s->energy = 0.0;
390         }
391 #ifdef FAX_DETECT
392         /* Same for the fax dector */
393         goertzel_init (&s->fax_tone, fax_freq, 102);
394
395 #ifdef OLD_DSP_ROUTINES
396         /* Same for the fax dector 2nd harmonic */
397         goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
398 #endif  
399 #endif /* FAX_DETECT */
400         s->current_sample = 0;
401         s->detected_digits = 0;
402         s->current_digits = 0;
403         memset(&s->digits, 0, sizeof(s->digits));
404         s->lost_digits = 0;
405         s->digits[0] = '\0';
406 }
407
408 static void ast_mf_detect_init (mf_detect_state_t *s)
409 {
410         int i;
411 #ifdef OLD_DSP_ROUTINES
412         s->hit1 = 
413         s->hit2 = 0;
414 #else   
415         s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
416 #endif
417         for (i = 0;  i < 6;  i++) {
418                 goertzel_init (&s->tone_out[i], mf_tones[i], 160);
419 #ifdef OLD_DSP_ROUTINES
420                 goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
421                 s->energy = 0.0;
422 #endif
423         }
424         s->current_digits = 0;
425         memset(&s->digits, 0, sizeof(s->digits));
426         s->current_sample = 0;
427         s->detected_digits = 0;
428         s->lost_digits = 0;
429         s->digits[0] = '\0';
430         s->mhit = 0;
431 }
432
433 static int dtmf_detect (dtmf_detect_state_t *s, int16_t amp[], int samples, 
434                  int digitmode, int *writeback, int faxdetect)
435 {
436         float row_energy[4];
437         float col_energy[4];
438 #ifdef FAX_DETECT
439         float fax_energy;
440 #ifdef OLD_DSP_ROUTINES
441         float fax_energy_2nd;
442 #endif  
443 #endif /* FAX_DETECT */
444         float famp;
445         int i;
446         int j;
447         int sample;
448         int best_row;
449         int best_col;
450         int hit;
451         int limit;
452
453         hit = 0;
454         for (sample = 0;  sample < samples;  sample = limit) {
455                 /* 102 is optimised to meet the DTMF specs. */
456                 if ((samples - sample) >= (102 - s->current_sample))
457                         limit = sample + (102 - s->current_sample);
458                 else
459                         limit = samples;
460 #if defined(USE_3DNOW)
461                 _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
462                 _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
463 #ifdef OLD_DSP_ROUTINES
464                 _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
465                 _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
466 #endif          
467                 /* XXX Need to fax detect for 3dnow too XXX */
468                 #warning "Fax Support Broken"
469 #else
470                 /* The following unrolled loop takes only 35% (rough estimate) of the 
471                    time of a rolled loop on the machine on which it was developed */
472                 for (j = sample; j < limit; j++) {
473                         famp = amp[j];
474                         s->energy += famp*famp;
475                         /* With GCC 2.95, the following unrolled code seems to take about 35%
476                            (rough estimate) as long as a neat little 0-3 loop */
477                         goertzel_sample(s->row_out, amp[j]);
478                         goertzel_sample(s->col_out, amp[j]);
479                         goertzel_sample(s->row_out + 1, amp[j]);
480                         goertzel_sample(s->col_out + 1, amp[j]);
481                         goertzel_sample(s->row_out + 2, amp[j]);
482                         goertzel_sample(s->col_out + 2, amp[j]);
483                         goertzel_sample(s->row_out + 3, amp[j]);
484                         goertzel_sample(s->col_out + 3, amp[j]);
485 #ifdef FAX_DETECT
486                         /* Update fax tone */
487                         goertzel_sample(&s->fax_tone, amp[j]);
488 #endif /* FAX_DETECT */
489 #ifdef OLD_DSP_ROUTINES
490                         v1 = s->col_out2nd[0].v2;
491                         s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
492                         s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp;
493                         v1 = s->row_out2nd[0].v2;
494                         s->row_out2nd[0].v2 = s->row_out2nd[0].v3;
495                         s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp;
496                         v1 = s->col_out2nd[1].v2;
497                         s->col_out2nd[1].v2 = s->col_out2nd[1].v3;
498                         s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp;
499                         v1 = s->row_out2nd[1].v2;
500                         s->row_out2nd[1].v2 = s->row_out2nd[1].v3;
501                         s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp;
502                         v1 = s->col_out2nd[2].v2;
503                         s->col_out2nd[2].v2 = s->col_out2nd[2].v3;
504                         s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp;
505                         v1 = s->row_out2nd[2].v2;
506                         s->row_out2nd[2].v2 = s->row_out2nd[2].v3;
507                         s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp;
508                         v1 = s->col_out2nd[3].v2;
509                         s->col_out2nd[3].v2 = s->col_out2nd[3].v3;
510                         s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp;
511                         v1 = s->row_out2nd[3].v2;
512                         s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
513                         s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
514 #ifdef FAX_DETECT
515                         /* Update fax tone */            
516                         v1 = s->fax_tone.v2;
517                         s->fax_tone2nd.v2 = s->fax_tone2nd.v3;
518                         s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp;
519 #endif /* FAX_DETECT */
520 #endif
521                 }
522 #endif
523                 s->current_sample += (limit - sample);
524                 if (s->current_sample < 102) {
525                         if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
526                                 /* If we had a hit last time, go ahead and clear this out since likely it
527                                    will be another hit */
528                                 for (i=sample;i<limit;i++) 
529                                         amp[i] = 0;
530                                 *writeback = 1;
531                         }
532                         continue;
533                 }
534 #ifdef FAX_DETECT
535                 /* Detect the fax energy, too */
536                 fax_energy = goertzel_result(&s->fax_tone);
537 #endif
538                 /* We are at the end of a DTMF detection block */
539                 /* Find the peak row and the peak column */
540                 row_energy[0] = goertzel_result (&s->row_out[0]);
541                 col_energy[0] = goertzel_result (&s->col_out[0]);
542
543                 for (best_row = best_col = 0, i = 1;  i < 4;  i++) {
544                         row_energy[i] = goertzel_result (&s->row_out[i]);
545                         if (row_energy[i] > row_energy[best_row])
546                                 best_row = i;
547                         col_energy[i] = goertzel_result (&s->col_out[i]);
548                         if (col_energy[i] > col_energy[best_col])
549                                 best_col = i;
550                 }
551                 hit = 0;
552                 /* Basic signal level test and the twist test */
553                 if (row_energy[best_row] >= DTMF_THRESHOLD && 
554                     col_energy[best_col] >= DTMF_THRESHOLD &&
555                     col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
556                     col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
557                         /* Relative peak test */
558                         for (i = 0;  i < 4;  i++) {
559                                 if ((i != best_col &&
560                                     col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
561                                     (i != best_row 
562                                      && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
563                                         break;
564                                 }
565                         }
566 #ifdef OLD_DSP_ROUTINES
567                         /* ... and second harmonic test */
568                         if (i >= 4 && 
569                             (row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy &&
570                             goertzel_result(&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col]
571                             && goertzel_result(&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
572 #else
573                         /* ... and fraction of total energy test */
574                         if (i >= 4 &&
575                             (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy) {
576 #endif
577                                 /* Got a hit */
578                                 hit = dtmf_positions[(best_row << 2) + best_col];
579                                 if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
580                                         /* Zero out frame data if this is part DTMF */
581                                         for (i=sample;i<limit;i++) 
582                                                 amp[i] = 0;
583                                         *writeback = 1;
584                                 }
585 #ifdef OLD_DSP_ROUTINES
586                                 /* Look for two successive similar results */
587                                 /* The logic in the next test is:
588                                    We need two successive identical clean detects, with
589                                    something different preceeding it. This can work with
590                                    back to back differing digits. More importantly, it
591                                    can work with nasty phones that give a very wobbly start
592                                    to a digit */
593                                 if (hit == s->hit3  &&  s->hit3 != s->hit2) {
594                                         s->mhit = hit;
595                                         s->digit_hits[(best_row << 2) + best_col]++;
596                                         s->detected_digits++;
597                                         if (s->current_digits < MAX_DTMF_DIGITS) {
598                                                 s->digits[s->current_digits++] = hit;
599                                                 s->digits[s->current_digits] = '\0';
600                                         } else {
601                                                 s->lost_digits++;
602                                         }
603                                 }
604 #endif
605                         }
606                 } 
607
608 #ifndef OLD_DSP_ROUTINES
609                 /* Look for two successive similar results */
610                 /* The logic in the next test is:
611                    We need two successive identical clean detects, with
612                    something different preceeding it. This can work with
613                    back to back differing digits. More importantly, it
614                    can work with nasty phones that give a very wobbly start
615                    to a digit */
616                 if (hit == s->lasthit  &&  hit != s->mhit) {
617                         if (hit) {
618                                 s->digit_hits[(best_row << 2) + best_col]++;
619                                 s->detected_digits++;
620                                 if (s->current_digits < MAX_DTMF_DIGITS) {
621                                         s->digits[s->current_digits++] = hit;
622                                         s->digits[s->current_digits] = '\0';
623                                 } else {
624                                         s->lost_digits++;
625                                 }
626                         }
627                         s->mhit = hit;
628                 }
629 #endif
630
631 #ifdef FAX_DETECT
632                 if (!hit && (fax_energy >= FAX_THRESHOLD) && 
633                         (fax_energy >= DTMF_TO_TOTAL_ENERGY*s->energy) &&
634                         (faxdetect)) {
635 #if 0
636                         printf("Fax energy/Second Harmonic: %f\n", fax_energy);
637 #endif                                  
638                         /* XXX Probably need better checking than just this the energy XXX */
639                         hit = 'f';
640                         s->fax_hits++;
641                 } else {
642                         if (s->fax_hits > 5) {
643                                 hit = 'f';
644                                 s->mhit = 'f';
645                                 s->detected_digits++;
646                                 if (s->current_digits < MAX_DTMF_DIGITS) {
647                                         s->digits[s->current_digits++] = hit;
648                                         s->digits[s->current_digits] = '\0';
649                                 } else {
650                                         s->lost_digits++;
651                                 }
652                         }
653                         s->fax_hits = 0;
654                 }
655 #endif /* FAX_DETECT */
656 #ifdef OLD_DSP_ROUTINES
657                 s->hit1 = s->hit2;
658                 s->hit2 = s->hit3;
659                 s->hit3 = hit;
660 #else
661                 s->lasthit = hit;
662 #endif          
663                 /* Reinitialise the detector for the next block */
664                 for (i = 0;  i < 4;  i++) {
665                         goertzel_reset(&s->row_out[i]);
666                         goertzel_reset(&s->col_out[i]);
667 #ifdef OLD_DSP_ROUTINES
668                         goertzel_reset(&s->row_out2nd[i]);
669                         goertzel_reset(&s->col_out2nd[i]);
670 #endif                  
671                 }
672 #ifdef FAX_DETECT
673                 goertzel_reset (&s->fax_tone);
674 #ifdef OLD_DSP_ROUTINES
675                 goertzel_reset (&s->fax_tone2nd);
676 #endif                  
677 #endif
678                 s->energy = 0.0;
679                 s->current_sample = 0;
680         }
681 #ifdef OLD_DSP_ROUTINES
682         if ((!s->mhit) || (s->mhit != hit)) {
683                 s->mhit = 0;
684                 return(0);
685         }
686         return (hit);
687 #else
688         return (s->mhit);       /* return the debounced hit */
689 #endif
690 }
691
692 /* MF goertzel size */
693 #ifdef OLD_DSP_ROUTINES
694 #define MF_GSIZE 160
695 #else
696 #define MF_GSIZE 120
697 #endif
698
699 static int mf_detect (mf_detect_state_t *s, int16_t amp[],
700                  int samples, int digitmode, int *writeback)
701 {
702 #ifdef OLD_DSP_ROUTINES
703         float tone_energy[6];
704         int best1;
705         int best2;
706         float max;
707         int sofarsogood;
708 #else
709         float energy[6];
710         int best;
711         int second_best;
712 #endif
713         float famp;
714         int i;
715         int j;
716         int sample;
717         int hit;
718         int limit;
719
720         hit = 0;
721         for (sample = 0;  sample < samples;  sample = limit) {
722                 /* 80 is optimised to meet the MF specs. */
723                 if ((samples - sample) >= (MF_GSIZE - s->current_sample))
724                         limit = sample + (MF_GSIZE - s->current_sample);
725                 else
726                         limit = samples;
727 #if defined(USE_3DNOW)
728                 _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
729                 _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
730 #ifdef OLD_DSP_ROUTINES
731                 _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
732                 _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
733 #endif
734                 /* XXX Need to fax detect for 3dnow too XXX */
735                 #warning "Fax Support Broken"
736 #else
737                 /* The following unrolled loop takes only 35% (rough estimate) of the 
738                    time of a rolled loop on the machine on which it was developed */
739                 for (j = sample;  j < limit;  j++) {
740                         famp = amp[j];
741 #ifdef OLD_DSP_ROUTINES
742                         s->energy += famp*famp;
743 #endif
744                         /* With GCC 2.95, the following unrolled code seems to take about 35%
745                            (rough estimate) as long as a neat little 0-3 loop */
746                         goertzel_sample(s->tone_out, amp[j]);
747                         goertzel_sample(s->tone_out + 1, amp[j]);
748                         goertzel_sample(s->tone_out + 2, amp[j]);
749                         goertzel_sample(s->tone_out + 3, amp[j]);
750                         goertzel_sample(s->tone_out + 4, amp[j]);
751                         goertzel_sample(s->tone_out + 5, amp[j]);
752 #ifdef OLD_DSP_ROUTINES
753                         v1 = s->tone_out2nd[0].v2;
754                         s->tone_out2nd[0].v2 = s->tone_out2nd[0].v3;
755                         s->tone_out2nd[0].v3 = s->tone_out2nd[0].fac*s->tone_out2nd[0].v2 - v1 + famp;
756                         v1 = s->tone_out2nd[1].v2;
757                         s->tone_out2nd[1].v2 = s->tone_out2nd[1].v3;
758                         s->tone_out2nd[1].v3 = s->tone_out2nd[1].fac*s->tone_out2nd[1].v2 - v1 + famp;
759                         v1 = s->tone_out2nd[2].v2;
760                         s->tone_out2nd[2].v2 = s->tone_out2nd[2].v3;
761                         s->tone_out2nd[2].v3 = s->tone_out2nd[2].fac*s->tone_out2nd[2].v2 - v1 + famp;
762                         v1 = s->tone_out2nd[3].v2;
763                         s->tone_out2nd[3].v2 = s->tone_out2nd[3].v3;
764                         s->tone_out2nd[3].v3 = s->tone_out2nd[3].fac*s->tone_out2nd[3].v2 - v1 + famp;
765                         v1 = s->tone_out2nd[4].v2;
766                         s->tone_out2nd[4].v2 = s->tone_out2nd[4].v3;
767                         s->tone_out2nd[4].v3 = s->tone_out2nd[4].fac*s->tone_out2nd[2].v2 - v1 + famp;
768                         v1 = s->tone_out2nd[3].v2;
769                         s->tone_out2nd[5].v2 = s->tone_out2nd[6].v3;
770                         s->tone_out2nd[5].v3 = s->tone_out2nd[6].fac*s->tone_out2nd[3].v2 - v1 + famp;
771 #endif
772                 }
773 #endif
774                 s->current_sample += (limit - sample);
775                 if (s->current_sample < MF_GSIZE) {
776                         if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
777                                 /* If we had a hit last time, go ahead and clear this out since likely it
778                                    will be another hit */
779                                 for (i=sample;i<limit;i++) 
780                                         amp[i] = 0;
781                                 *writeback = 1;
782                         }
783                         continue;
784                 }
785 #ifdef OLD_DSP_ROUTINES         
786                 /* We're at the end of an MF detection block.  Go ahead and calculate
787                    all the energies. */
788                 for (i=0;i<6;i++) {
789                         tone_energy[i] = goertzel_result(&s->tone_out[i]);
790                 }
791                 /* Find highest */
792                 best1 = 0;
793                 max = tone_energy[0];
794                 for (i=1;i<6;i++) {
795                         if (tone_energy[i] > max) {
796                                 max = tone_energy[i];
797                                 best1 = i;
798                         }
799                 }
800
801                 /* Find 2nd highest */
802                 if (best1) {
803                         max = tone_energy[0];
804                         best2 = 0;
805                 } else {
806                         max = tone_energy[1];
807                         best2 = 1;
808                 }
809
810                 for (i=0;i<6;i++) {
811                         if (i == best1) continue;
812                         if (tone_energy[i] > max) {
813                                 max = tone_energy[i];
814                                 best2 = i;
815                         }
816                 }
817                 hit = 0;
818                 if (best1 != best2) 
819                         sofarsogood=1;
820                 else 
821                         sofarsogood=0;
822                 /* Check for relative energies */
823                 for (i=0;i<6;i++) {
824                         if (i == best1) 
825                                 continue;
826                         if (i == best2) 
827                                 continue;
828                         if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
829                                 sofarsogood = 0;
830                                 break;
831                         }
832                         if (tone_energy[best2] < tone_energy[i] * MF_RELATIVE_PEAK) {
833                                 sofarsogood = 0;
834                                 break;
835                         }
836                 }
837                 
838                 if (sofarsogood) {
839                         /* Check for 2nd harmonic */
840                         if (goertzel_result(&s->tone_out2nd[best1]) * MF_2ND_HARMONIC > tone_energy[best1]) 
841                                 sofarsogood = 0;
842                         else if (goertzel_result(&s->tone_out2nd[best2]) * MF_2ND_HARMONIC > tone_energy[best2])
843                                 sofarsogood = 0;
844                 }
845                 if (sofarsogood) {
846                         hit = mf_hit[best1][best2];
847                         if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
848                                 /* Zero out frame data if this is part DTMF */
849                                 for (i=sample;i<limit;i++) 
850                                         amp[i] = 0;
851                                 *writeback = 1;
852                         }
853                         /* Look for two consecutive clean hits */
854                         if ((hit == s->hit3) && (s->hit3 != s->hit2)) {
855                                 s->mhit = hit;
856                                 s->detected_digits++;
857                                 if (s->current_digits < MAX_DTMF_DIGITS - 2) {
858                                         s->digits[s->current_digits++] = hit;
859                                         s->digits[s->current_digits] = '\0';
860                                 } else {
861                                         s->lost_digits++;
862                                 }
863                         }
864                 }
865                 
866                 s->hit1 = s->hit2;
867                 s->hit2 = s->hit3;
868                 s->hit3 = hit;
869                 /* Reinitialise the detector for the next block */
870                 for (i = 0;  i < 6;  i++) {
871                         goertzel_reset(&s->tone_out[i]);
872                         goertzel_reset(&s->tone_out2nd[i]);
873                 }
874                 s->energy = 0.0;
875                 s->current_sample = 0;
876         }
877 #else
878                 /* We're at the end of an MF detection block.  */
879                 /* Find the two highest energies. The spec says to look for
880                    two tones and two tones only. Taking this literally -ie
881                    only two tones pass the minimum threshold - doesn't work
882                    well. The sinc function mess, due to rectangular windowing
883                    ensure that! Find the two highest energies and ensure they
884                    are considerably stronger than any of the others. */
885                 energy[0] = goertzel_result(&s->tone_out[0]);
886                 energy[1] = goertzel_result(&s->tone_out[1]);
887                 if (energy[0] > energy[1]) {
888                         best = 0;
889                         second_best = 1;
890                 } else {
891                         best = 1;
892                         second_best = 0;
893                 }
894                 /*endif*/
895                 for (i=2;i<6;i++) {
896                         energy[i] = goertzel_result(&s->tone_out[i]);
897                         if (energy[i] >= energy[best]) {
898                                 second_best = best;
899                                 best = i;
900                         } else if (energy[i] >= energy[second_best]) {
901                                 second_best = i;
902                         }
903                 }
904                 /* Basic signal level and twist tests */
905                 hit = 0;
906                 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
907                     && energy[best] < energy[second_best]*BELL_MF_TWIST
908                     && energy[best]*BELL_MF_TWIST > energy[second_best]) {
909                         /* Relative peak test */
910                         hit = -1;
911                         for (i=0;i<6;i++) {
912                                 if (i != best && i != second_best) {
913                                         if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
914                                                 /* The best two are not clearly the best */
915                                                 hit = 0;
916                                                 break;
917                                         }
918                                 }
919                         }
920                 }
921                 if (hit) {
922                         /* Get the values into ascending order */
923                         if (second_best < best) {
924                                 i = best;
925                                 best = second_best;
926                                 second_best = i;
927                         }
928                         best = best*5 + second_best - 1;
929                         hit = bell_mf_positions[best];
930                         /* Look for two successive similar results */
931                         /* The logic in the next test is:
932                            For KP we need 4 successive identical clean detects, with
933                            two blocks of something different preceeding it. For anything
934                            else we need two successive identical clean detects, with
935                            two blocks of something different preceeding it. */
936                         if (hit == s->hits[4] && hit == s->hits[3] &&
937                            ((hit != '*' && hit != s->hits[2] && hit != s->hits[1])||
938                             (hit == '*' && hit == s->hits[2] && hit != s->hits[1] && 
939                             hit != s->hits[0]))) {
940                                 s->detected_digits++;
941                                 if (s->current_digits < MAX_DTMF_DIGITS) {
942                                         s->digits[s->current_digits++] = hit;
943                                         s->digits[s->current_digits] = '\0';
944                                 } else {
945                                         s->lost_digits++;
946                                 }
947                         }
948                 } else {
949                         hit = 0;
950                 }
951                 s->hits[0] = s->hits[1];
952                 s->hits[1] = s->hits[2];
953                 s->hits[2] = s->hits[3];
954                 s->hits[3] = s->hits[4];
955                 s->hits[4] = hit;
956                 /* Reinitialise the detector for the next block */
957                 for (i = 0;  i < 6;  i++)
958                         goertzel_reset(&s->tone_out[i]);
959                 s->current_sample = 0;
960         }
961 #endif  
962         if ((!s->mhit) || (s->mhit != hit)) {
963                 s->mhit = 0;
964                 return(0);
965         }
966         return (hit);
967 }
968
969 static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
970 {
971         int res;
972         
973         if (dsp->digitmode & DSP_DIGITMODE_MF)
974                 res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
975         else
976                 res = dtmf_detect(&dsp->td.dtmf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback, dsp->features & DSP_FEATURE_FAX_DETECT);
977         return res;
978 }
979
980 int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
981 {
982         short *s;
983         int len;
984         int ign=0;
985
986         if (inf->frametype != AST_FRAME_VOICE) {
987                 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
988                 return 0;
989         }
990         if (inf->subclass != AST_FORMAT_SLINEAR) {
991                 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
992                 return 0;
993         }
994         s = inf->data;
995         len = inf->datalen / 2;
996         return __ast_dsp_digitdetect(dsp, s, len, &ign);
997 }
998
999 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
1000 {
1001         /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
1002         /* Make sure absolute levels are high enough */
1003         if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
1004                 return 0;
1005         /* Amplify ignored stuff */
1006         i2 *= TONE_THRESH;
1007         i1 *= TONE_THRESH;
1008         e *= TONE_THRESH;
1009         /* Check first tone */
1010         if ((p1 < i1) || (p1 < i2) || (p1 < e))
1011                 return 0;
1012         /* And second */
1013         if ((p2 < i1) || (p2 < i2) || (p2 < e))
1014                 return 0;
1015         /* Guess it's there... */
1016         return 1;
1017 }
1018
1019 int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max)
1020 {
1021         if (dsp->digitmode & DSP_DIGITMODE_MF) {
1022                 if (max > dsp->td.mf.current_digits)
1023                         max = dsp->td.mf.current_digits;
1024                 if (max > 0) {
1025                         memcpy(buf, dsp->td.mf.digits, max);
1026                         memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
1027                         dsp->td.mf.current_digits -= max;
1028                 }
1029                 buf[max] = '\0';
1030                 return  max;
1031         } else {
1032                 if (max > dsp->td.dtmf.current_digits)
1033                         max = dsp->td.dtmf.current_digits;
1034                 if (max > 0) {
1035                         memcpy (buf, dsp->td.dtmf.digits, max);
1036                         memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
1037                         dsp->td.dtmf.current_digits -= max;
1038                 }
1039                 buf[max] = '\0';
1040                 return  max;
1041         }
1042 }
1043
1044 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
1045 {
1046         int x;
1047         int y;
1048         int pass;
1049         int newstate = DSP_TONE_STATE_SILENCE;
1050         int res = 0;
1051         while (len) {
1052                 /* Take the lesser of the number of samples we need and what we have */
1053                 pass = len;
1054                 if (pass > dsp->gsamp_size - dsp->gsamps) 
1055                         pass = dsp->gsamp_size - dsp->gsamps;
1056                 for (x=0;x<pass;x++) {
1057                         for (y=0;y<dsp->freqcount;y++) 
1058                                 goertzel_sample(&dsp->freqs[y], s[x]);
1059                         dsp->genergy += s[x] * s[x];
1060                 }
1061                 s += pass;
1062                 dsp->gsamps += pass;
1063                 len -= pass;
1064                 if (dsp->gsamps == dsp->gsamp_size) {
1065                         float hz[7];
1066                         for (y=0;y<7;y++)
1067                                 hz[y] = goertzel_result(&dsp->freqs[y]);
1068 #if 0
1069                         printf("\n350:     425:     440:     480:     620:     950:     1400:    1800:    Energy:   \n");
1070                         printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n", 
1071                                 hz[HZ_350], hz[HZ_425], hz[HZ_440], hz[HZ_480], hz[HZ_620], hz[HZ_950], hz[HZ_1400], hz[HZ_1800], dsp->genergy);
1072 #endif
1073                         switch (dsp->progmode) {
1074                         case PROG_MODE_NA:
1075                                 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
1076                                         newstate = DSP_TONE_STATE_BUSY;
1077                                 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
1078                                         newstate = DSP_TONE_STATE_RINGING;
1079                                 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
1080                                         newstate = DSP_TONE_STATE_DIALTONE;
1081                                 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
1082                                         newstate = DSP_TONE_STATE_SPECIAL1;
1083                                 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
1084                                         if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
1085                                                 newstate = DSP_TONE_STATE_SPECIAL2;
1086                                 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
1087                                         if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
1088                                                 newstate = DSP_TONE_STATE_SPECIAL3;
1089                                 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1090                                         newstate = DSP_TONE_STATE_TALKING;
1091                                 } else
1092                                         newstate = DSP_TONE_STATE_SILENCE;
1093                                 break;
1094                         case PROG_MODE_CR:
1095                                 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
1096                                         newstate = DSP_TONE_STATE_RINGING;
1097                                 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1098                                         newstate = DSP_TONE_STATE_TALKING;
1099                                 } else
1100                                         newstate = DSP_TONE_STATE_SILENCE;
1101                                 break;
1102                         case PROG_MODE_UK:
1103                                 if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
1104                                         newstate = DSP_TONE_STATE_HUNGUP;
1105                                 }
1106                                 break;
1107                         default:
1108                                 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
1109                         }
1110                         if (newstate == dsp->tstate) {
1111                                 dsp->tcount++;
1112                                 if (dsp->ringtimeout)
1113                                         dsp->ringtimeout++;
1114                                 switch (dsp->tstate) {
1115                                         case DSP_TONE_STATE_RINGING:
1116                                                 if ((dsp->features & DSP_PROGRESS_RINGING) &&
1117                                                     (dsp->tcount==THRESH_RING)) {
1118                                                         res = AST_CONTROL_RINGING;
1119                                                         dsp->ringtimeout= 1;
1120                                                 }
1121                                                 break;
1122                                         case DSP_TONE_STATE_BUSY:
1123                                                 if ((dsp->features & DSP_PROGRESS_BUSY) &&
1124                                                     (dsp->tcount==THRESH_BUSY)) {
1125                                                         res = AST_CONTROL_BUSY;
1126                                                         dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1127                                                 }
1128                                                 break;
1129                                         case DSP_TONE_STATE_TALKING:
1130                                                 if ((dsp->features & DSP_PROGRESS_TALK) &&
1131                                                     (dsp->tcount==THRESH_TALK)) {
1132                                                         res = AST_CONTROL_ANSWER;
1133                                                         dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1134                                                 }
1135                                                 break;
1136                                         case DSP_TONE_STATE_SPECIAL3:
1137                                                 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
1138                                                     (dsp->tcount==THRESH_CONGESTION)) {
1139                                                         res = AST_CONTROL_CONGESTION;
1140                                                         dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1141                                                 }
1142                                                 break;
1143                                         case DSP_TONE_STATE_HUNGUP:
1144                                                 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
1145                                                     (dsp->tcount==THRESH_HANGUP)) {
1146                                                         res = AST_CONTROL_HANGUP;
1147                                                         dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1148                                                 }
1149                                                 break;
1150                                 }
1151                                 if (dsp->ringtimeout==THRESH_RING2ANSWER) {
1152 #if 0
1153                                         ast_log(LOG_NOTICE, "Consider call as answered because of timeout after last ring\n");
1154 #endif
1155                                         res = AST_CONTROL_ANSWER;
1156                                         dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1157                                 }
1158                         } else {
1159 #if 0
1160                                 ast_log(LOG_NOTICE, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
1161                                 ast_log(LOG_NOTICE, "Start state %d\n", newstate);
1162 #endif
1163                                 dsp->tstate = newstate;
1164                                 dsp->tcount = 1;
1165                         }
1166                         
1167                         /* Reset goertzel */                                            
1168                         for (x=0;x<7;x++)
1169                                 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1170                         dsp->gsamps = 0;
1171                         dsp->genergy = 0.0;
1172                 }
1173         }
1174 #if 0
1175         if (res)
1176                 printf("Returning %d\n", res);
1177 #endif          
1178         return res;
1179 }
1180
1181 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
1182 {
1183         if (inf->frametype != AST_FRAME_VOICE) {
1184                 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
1185                 return 0;
1186         }
1187         if (inf->subclass != AST_FORMAT_SLINEAR) {
1188                 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
1189                 return 0;
1190         }
1191         return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
1192 }
1193
1194 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
1195 {
1196         int accum;
1197         int x;
1198         int res = 0;
1199
1200         if (!len)
1201                 return 0;
1202         accum = 0;
1203         for (x=0;x<len; x++) 
1204                 accum += abs(s[x]);
1205         accum /= len;
1206         if (accum < dsp->threshold) {
1207                 /* Silent */
1208                 dsp->totalsilence += len/8;
1209                 if (dsp->totalnoise) {
1210                         /* Move and save history */
1211                         memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
1212                         dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
1213 /* we don't want to check for busydetect that frequently */
1214 #if 0
1215                         dsp->busymaybe = 1;
1216 #endif
1217                 }
1218                 dsp->totalnoise = 0;
1219                 res = 1;
1220         } else {
1221                 /* Not silent */
1222                 dsp->totalnoise += len/8;
1223                 if (dsp->totalsilence) {
1224                         int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
1225                         int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
1226                         /* Move and save history */
1227                         memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
1228                         dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
1229                         /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
1230                         if (silence1 < silence2) {
1231                                 if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
1232                                         dsp->busymaybe = 1;
1233                                 else 
1234                                         dsp->busymaybe = 0;
1235                         } else {
1236                                 if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
1237                                         dsp->busymaybe = 1;
1238                                 else 
1239                                         dsp->busymaybe = 0;
1240                         }
1241                 }
1242                 dsp->totalsilence = 0;
1243         }
1244         if (totalsilence)
1245                 *totalsilence = dsp->totalsilence;
1246         return res;
1247 }
1248
1249 #ifdef BUSYDETECT_MARTIN
1250 int ast_dsp_busydetect(struct ast_dsp *dsp)
1251 {
1252         int res = 0, x;
1253 #ifndef BUSYDETECT_TONEONLY
1254         int avgsilence = 0, hitsilence = 0;
1255 #endif
1256         int avgtone = 0, hittone = 0;
1257         if (!dsp->busymaybe)
1258                 return res;
1259         for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
1260 #ifndef BUSYDETECT_TONEONLY
1261                 avgsilence += dsp->historicsilence[x];
1262 #endif
1263                 avgtone += dsp->historicnoise[x];
1264         }
1265 #ifndef BUSYDETECT_TONEONLY
1266         avgsilence /= dsp->busycount;
1267 #endif
1268         avgtone /= dsp->busycount;
1269         for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
1270 #ifndef BUSYDETECT_TONEONLY
1271                 if (avgsilence > dsp->historicsilence[x]) {
1272                         if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
1273                                 hitsilence++;
1274                 } else {
1275                         if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
1276                                 hitsilence++;
1277                 }
1278 #endif
1279                 if (avgtone > dsp->historicnoise[x]) {
1280                         if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
1281                                 hittone++;
1282                 } else {
1283                         if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
1284                                 hittone++;
1285                 }
1286         }
1287 #ifndef BUSYDETECT_TONEONLY
1288         if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 
1289             (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 
1290             (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
1291 #else
1292         if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
1293 #endif
1294 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1295 #ifdef BUSYDETECT_TONEONLY
1296 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
1297 #endif
1298                 if (avgtone > avgsilence) {
1299                         if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
1300                                 res = 1;
1301                 } else {
1302                         if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
1303                                 res = 1;
1304                 }
1305 #else
1306                 res = 1;
1307 #endif
1308         }
1309         /* If we know the expected busy tone length, check we are in the range */
1310         if (res && (dsp->busy_tonelength > 0)) {
1311                 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
1312 #if 0
1313                         ast_log(LOG_NOTICE, "busy detector: avgtone of %d not close enough to desired %d\n",
1314                                                 avgtone, dsp->busy_tonelength);
1315 #endif
1316                         res = 0;
1317                 }
1318         }
1319 #ifndef BUSYDETECT_TONEONLY
1320         /* If we know the expected busy tone silent-period length, check we are in the range */
1321         if (res && (dsp->busy_quietlength > 0)) {
1322                 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
1323 #if 0
1324                         ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
1325                                                 avgsilence, dsp->busy_quietlength);
1326 #endif
1327                         res = 0;
1328                 }
1329         }
1330 #endif
1331 #ifndef BUSYDETECT_TONEONLY
1332 #if 1
1333         if (res) {
1334                 ast_debug(1, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1335         }
1336 #endif
1337 #endif
1338         return res;
1339 }
1340 #endif
1341
1342 #ifdef BUSYDETECT
1343 int ast_dsp_busydetect(struct ast_dsp *dsp)
1344 {
1345         int x;
1346         int res = 0;
1347         int max, min;
1348
1349 #if 0
1350         if (dsp->busy_hits > 5);
1351         return 0;
1352 #endif
1353         if (dsp->busymaybe) {
1354 #if 0
1355                 printf("Maybe busy!\n");
1356 #endif          
1357                 dsp->busymaybe = 0;
1358                 min = 9999;
1359                 max = 0;
1360                 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
1361 #if 0
1362                         printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
1363 #endif                  
1364                         if (dsp->historicsilence[x] < min)
1365                                 min = dsp->historicsilence[x];
1366                         if (dsp->historicnoise[x] < min)
1367                                 min = dsp->historicnoise[x];
1368                         if (dsp->historicsilence[x] > max)
1369                                 max = dsp->historicsilence[x];
1370                         if (dsp->historicnoise[x] > max)
1371                                 max = dsp->historicnoise[x];
1372                 }
1373                 if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
1374 #if 0
1375                         printf("Busy!\n");
1376 #endif                  
1377                         res = 1;
1378                 }
1379 #if 0
1380                 printf("Min: %d, max: %d\n", min, max);
1381 #endif          
1382         }
1383         return res;
1384 }
1385 #endif
1386
1387 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
1388 {
1389         short *s;
1390         int len;
1391         
1392         if (f->frametype != AST_FRAME_VOICE) {
1393                 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
1394                 return 0;
1395         }
1396         if (f->subclass != AST_FORMAT_SLINEAR) {
1397                 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
1398                 return 0;
1399         }
1400         s = f->data;
1401         len = f->datalen/2;
1402         return __ast_dsp_silence(dsp, s, len, totalsilence);
1403 }
1404
1405 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
1406 {
1407         int silence;
1408         int res;
1409         int digit;
1410         int x;
1411         short *shortdata;
1412         unsigned char *odata;
1413         int len;
1414         int writeback = 0;
1415
1416 #define FIX_INF(inf) do { \
1417                 if (writeback) { \
1418                         switch (inf->subclass) { \
1419                         case AST_FORMAT_SLINEAR: \
1420                                 break; \
1421                         case AST_FORMAT_ULAW: \
1422                                 for (x=0;x<len;x++) \
1423                                         odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
1424                                 break; \
1425                         case AST_FORMAT_ALAW: \
1426                                 for (x=0;x<len;x++) \
1427                                         odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
1428                                 break; \
1429                         } \
1430                 } \
1431         } while(0) 
1432
1433         if (!af)
1434                 return NULL;
1435         if (af->frametype != AST_FRAME_VOICE)
1436                 return af;
1437         odata = af->data;
1438         len = af->datalen;
1439         /* Make sure we have short data */
1440         switch (af->subclass) {
1441         case AST_FORMAT_SLINEAR:
1442                 shortdata = af->data;
1443                 len = af->datalen / 2;
1444                 break;
1445         case AST_FORMAT_ULAW:
1446                 shortdata = alloca(af->datalen * 2);
1447                 for (x = 0;x < len; x++) 
1448                         shortdata[x] = AST_MULAW(odata[x]);
1449                 break;
1450         case AST_FORMAT_ALAW:
1451                 shortdata = alloca(af->datalen * 2);
1452                 for (x = 0; x < len; x++) 
1453                         shortdata[x] = AST_ALAW(odata[x]);
1454                 break;
1455         default:
1456                 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
1457                 return af;
1458         }
1459         silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
1460         if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
1461                 memset(&dsp->f, 0, sizeof(dsp->f));
1462                 dsp->f.frametype = AST_FRAME_NULL;
1463                 return &dsp->f;
1464         }
1465         if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
1466                 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1467                 memset(&dsp->f, 0, sizeof(dsp->f));
1468                 dsp->f.frametype = AST_FRAME_CONTROL;
1469                 dsp->f.subclass = AST_CONTROL_BUSY;
1470                 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
1471                 return &dsp->f;
1472         }
1473         if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
1474                 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
1475 #if 0
1476                 if (digit)
1477                         printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
1478 #endif                  
1479                 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
1480                         if (!dsp->thinkdigit) {
1481                                 if (digit) {
1482                                         /* Looks like we might have something.  
1483                                          * Request a conference mute for the moment */
1484                                         memset(&dsp->f, 0, sizeof(dsp->f));
1485                                         dsp->f.frametype = AST_FRAME_DTMF;
1486                                         dsp->f.subclass = 'm';
1487                                         dsp->thinkdigit = 'x';
1488                                         FIX_INF(af);
1489                                         if (chan)
1490                                                 ast_queue_frame(chan, af);
1491                                         ast_frfree(af);
1492                                         return &dsp->f;
1493                                 }
1494                         } else {
1495                                 if (digit) {
1496                                         /* Thought we saw one last time.  Pretty sure we really have now */
1497                                         if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
1498                                                 /* If we found a digit, and we're changing digits, go
1499                                                    ahead and send this one, but DON'T stop confmute because
1500                                                    we're detecting something else, too... */
1501                                                 memset(&dsp->f, 0, sizeof(dsp->f));
1502                                                 dsp->f.frametype = AST_FRAME_DTMF_END;
1503                                                 dsp->f.subclass = dsp->thinkdigit;
1504                                                 FIX_INF(af);
1505                                                 if (chan)
1506                                                         ast_queue_frame(chan, af);
1507                                                 ast_frfree(af);
1508                                         } else {
1509                                                 dsp->thinkdigit = digit;
1510                                                 memset(&dsp->f, 0, sizeof(dsp->f));
1511                                                 dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
1512                                                 dsp->f.subclass = dsp->thinkdigit;
1513                                                 FIX_INF(af);
1514                                                 if (chan)
1515                                                         ast_queue_frame(chan, af);
1516                                                 ast_frfree(af);
1517                                         }
1518                                         return &dsp->f;
1519                                 } else {
1520                                         memset(&dsp->f, 0, sizeof(dsp->f));
1521                                         if (dsp->thinkdigit != 'x') {
1522                                                 /* If we found a digit, send it now */
1523                                                 dsp->f.frametype = AST_FRAME_DTMF_END;
1524                                                 dsp->f.subclass = dsp->thinkdigit;
1525                                                 dsp->thinkdigit = 0;
1526                                         } else {
1527                                                 dsp->f.frametype = AST_FRAME_DTMF;
1528                                                 dsp->f.subclass = 'u';
1529                                                 dsp->thinkdigit = 0;
1530                                         }
1531                                         FIX_INF(af);
1532                                         if (chan)
1533                                                 ast_queue_frame(chan, af);
1534                                         ast_frfree(af);
1535                                         return &dsp->f;
1536                                 }
1537                         }
1538                 } else if (!digit) {
1539                         /* Only check when there is *not* a hit... */
1540                         if (dsp->digitmode & DSP_DIGITMODE_MF) {
1541                                 if (dsp->td.mf.current_digits) {
1542                                         memset(&dsp->f, 0, sizeof(dsp->f));
1543                                         dsp->f.frametype = AST_FRAME_DTMF;
1544                                         dsp->f.subclass = dsp->td.mf.digits[0];
1545                                         memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
1546                                         dsp->td.mf.current_digits--;
1547                                         FIX_INF(af);
1548                                         if (chan)
1549                                                 ast_queue_frame(chan, af);
1550                                         ast_frfree(af);
1551                                         return &dsp->f;
1552                                 }
1553                         } else {
1554                                 if (dsp->td.dtmf.current_digits) {
1555                                         memset(&dsp->f, 0, sizeof(dsp->f));
1556                                         dsp->f.frametype = AST_FRAME_DTMF_END;
1557                                         dsp->f.subclass = dsp->td.dtmf.digits[0];
1558                                         memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
1559                                         dsp->td.dtmf.current_digits--;
1560                                         FIX_INF(af);
1561                                         if (chan)
1562                                                 ast_queue_frame(chan, af);
1563                                         ast_frfree(af);
1564                                         return &dsp->f;
1565                                 }
1566                         }
1567                 }
1568         }
1569         if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
1570                 res = __ast_dsp_call_progress(dsp, shortdata, len);
1571                 if (res) {
1572                         switch (res) {
1573                         case AST_CONTROL_ANSWER:
1574                         case AST_CONTROL_BUSY:
1575                         case AST_CONTROL_RINGING:
1576                         case AST_CONTROL_CONGESTION:
1577                         case AST_CONTROL_HANGUP:
1578                                 memset(&dsp->f, 0, sizeof(dsp->f));
1579                                 dsp->f.frametype = AST_FRAME_CONTROL;
1580                                 dsp->f.subclass = res;
1581                                 dsp->f.src = "dsp_progress";
1582                                 if (chan) 
1583                                         ast_queue_frame(chan, &dsp->f);
1584                                 break;
1585                         default:
1586                                 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
1587                         }
1588                 }
1589         }
1590         FIX_INF(af);
1591         return af;
1592 }
1593
1594 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
1595 {
1596         int max = 0;
1597         int x;
1598         
1599         dsp->gsamp_size = modes[dsp->progmode].size;
1600         dsp->gsamps = 0;
1601         for (x = 0; x < sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]); x++) {
1602                 if (modes[dsp->progmode].freqs[x]) {
1603                         goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
1604                         max = x + 1;
1605                 }
1606         }
1607         dsp->freqcount = max;
1608         dsp->ringtimeout= 0;
1609 }
1610
1611 struct ast_dsp *ast_dsp_new(void)
1612 {
1613         struct ast_dsp *dsp;
1614         
1615         if ((dsp = ast_calloc(1, sizeof(*dsp)))) {              
1616                 dsp->threshold = DEFAULT_THRESHOLD;
1617                 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
1618                 dsp->busycount = DSP_HISTORY;
1619                 /* Initialize DTMF detector */
1620                 ast_dtmf_detect_init(&dsp->td.dtmf);
1621                 /* Initialize initial DSP progress detect parameters */
1622                 ast_dsp_prog_reset(dsp);
1623         }
1624         return dsp;
1625 }
1626
1627 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
1628 {
1629         dsp->features = features;
1630 }
1631
1632 void ast_dsp_free(struct ast_dsp *dsp)
1633 {
1634         ast_free(dsp);
1635 }
1636
1637 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
1638 {
1639         dsp->threshold = threshold;
1640 }
1641
1642 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
1643 {
1644         if (cadences < 4)
1645                 cadences = 4;
1646         if (cadences > DSP_HISTORY)
1647                 cadences = DSP_HISTORY;
1648         dsp->busycount = cadences;
1649 }
1650
1651 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
1652 {
1653         dsp->busy_tonelength = tonelength;
1654         dsp->busy_quietlength = quietlength;
1655         ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
1656 }
1657
1658 void ast_dsp_digitreset(struct ast_dsp *dsp)
1659 {
1660         int i;
1661         
1662         dsp->thinkdigit = 0;
1663         if (dsp->digitmode & DSP_DIGITMODE_MF) {
1664                 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
1665                 dsp->td.mf.current_digits = 0;
1666                 /* Reinitialise the detector for the next block */
1667                 for (i = 0;  i < 6;  i++) {
1668                         goertzel_reset(&dsp->td.mf.tone_out[i]);
1669 #ifdef OLD_DSP_ROUTINES
1670                         goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
1671 #endif                  
1672                 }
1673 #ifdef OLD_DSP_ROUTINES
1674                 dsp->td.mf.energy = 0.0;
1675                 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
1676 #else
1677                 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;
1678 #endif          
1679                 dsp->td.mf.current_sample = 0;
1680         } else {
1681                 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
1682                 dsp->td.dtmf.current_digits = 0;
1683                 /* Reinitialise the detector for the next block */
1684                 for (i = 0;  i < 4;  i++) {
1685                         goertzel_reset(&dsp->td.dtmf.row_out[i]);
1686                         goertzel_reset(&dsp->td.dtmf.col_out[i]);
1687 #ifdef OLD_DSP_ROUTINES
1688                         goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
1689                         goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
1690 #endif                  
1691                 }
1692 #ifdef FAX_DETECT
1693                 goertzel_reset (&dsp->td.dtmf.fax_tone);
1694 #endif
1695 #ifdef OLD_DSP_ROUTINES
1696 #ifdef FAX_DETECT
1697                 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
1698 #endif
1699                 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
1700 #else
1701                 dsp->td.dtmf.lasthit = dsp->td.dtmf.mhit = 0;
1702 #endif          
1703                 dsp->td.dtmf.energy = 0.0;
1704                 dsp->td.dtmf.current_sample = 0;
1705         }
1706 }
1707
1708 void ast_dsp_reset(struct ast_dsp *dsp)
1709 {
1710         int x;
1711         
1712         dsp->totalsilence = 0;
1713         dsp->gsamps = 0;
1714         for (x=0;x<4;x++)
1715                 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1716         memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1717         memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));      
1718         dsp->ringtimeout= 0;
1719 }
1720
1721 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
1722 {
1723         int new;
1724         int old;
1725         
1726         old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
1727         new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
1728         if (old != new) {
1729                 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1730                 if (new & DSP_DIGITMODE_MF)
1731                         ast_mf_detect_init(&dsp->td.mf);
1732                 else
1733                         ast_dtmf_detect_init(&dsp->td.dtmf);
1734         }
1735         dsp->digitmode = digitmode;
1736         return 0;
1737 }
1738
1739 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
1740 {
1741         int x;
1742         
1743         for (x = 0; x < ARRAY_LEN(aliases); x++) {
1744                 if (!strcasecmp(aliases[x].name, zone)) {
1745                         dsp->progmode = aliases[x].mode;
1746                         ast_dsp_prog_reset(dsp);
1747                         return 0;
1748                 }
1749         }
1750         return -1;
1751 }
1752
1753 int ast_dsp_get_tstate(struct ast_dsp *dsp) 
1754 {
1755         return dsp->tstate;
1756 }
1757
1758 int ast_dsp_get_tcount(struct ast_dsp *dsp) 
1759 {
1760         return dsp->tcount;
1761 }