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