Merge my applicationmap_fixup branch to address the issues described in this
[asterisk/asterisk.git] / 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
63 /*! Number of goertzels for progress detect */
64 enum gsamp_size {
65         GSAMP_SIZE_NA = 183,                    /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
66         GSAMP_SIZE_CR = 188,                    /*!< Costa Rica, Brazil - Only care about 425 Hz */
67         GSAMP_SIZE_UK = 160                     /*!< UK disconnect goertzel feed - should trigger 400hz */
68 };
69
70 enum prog_mode {
71         PROG_MODE_NA = 0,
72         PROG_MODE_CR,
73         PROG_MODE_UK
74 };
75
76 enum freq_index { 
77         /*! For US modes { */
78         HZ_350 = 0,
79         HZ_440,
80         HZ_480,
81         HZ_620,
82         HZ_950,
83         HZ_1400,
84         HZ_1800, /*!< } */
85
86         /*! For CR/BR modes */
87         HZ_425 = 0,
88
89         /*! For UK mode */
90         HZ_400 = 0
91 };
92
93 static struct progalias {
94         char *name;
95         enum prog_mode mode;
96 } aliases[] = {
97         { "us", PROG_MODE_NA },
98         { "ca", PROG_MODE_NA },
99         { "cr", PROG_MODE_CR },
100         { "br", PROG_MODE_CR },
101         { "uk", PROG_MODE_UK },
102 };
103
104 static struct progress {
105         enum gsamp_size size;
106         int freqs[7];
107 } modes[] = {
108         { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } },     /*!< North America */
109         { GSAMP_SIZE_CR, { 425 } },                                     /*!< Costa Rica, Brazil */
110         { GSAMP_SIZE_UK, { 400 } },                                     /*!< UK */
111 };
112
113 #define DEFAULT_THRESHOLD       512
114
115 enum busy_detect {
116         BUSY_PERCENT = 10,      /*!< The percentage difference between the two last silence periods */
117         BUSY_PAT_PERCENT = 7,   /*!< The percentage difference between measured and actual pattern */
118         BUSY_THRESHOLD = 100,   /*!< Max number of ms difference between max and min times in busy */
119         BUSY_MIN = 75,          /*!< Busy must be at least 80 ms in half-cadence */
120         BUSY_MAX =3100          /*!< Busy can't be longer than 3100 ms in half-cadence */
121 };
122
123 /*! Remember last 15 units */
124 #define DSP_HISTORY             15
125
126 /*! Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE */
127 #define FAX_DETECT
128
129 #define TONE_THRESH             10.0    /*!< How much louder the tone should be than channel energy */
130 #define TONE_MIN_THRESH         1e8     /*!< How much tone there should be at least to attempt */
131
132 /*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
133 enum gsamp_thresh {
134         THRESH_RING = 8,                /*!< Need at least 150ms ring to accept */
135         THRESH_TALK = 2,                /*!< Talk detection does not work continuously */
136         THRESH_BUSY = 4,                /*!< Need at least 80ms to accept */
137         THRESH_CONGESTION = 4,          /*!< Need at least 80ms to accept */
138         THRESH_HANGUP = 60,             /*!< Need at least 1300ms to accept hangup */
139         THRESH_RING2ANSWER = 300        /*!< Timeout from start of ring to answer (about 6600 ms) */
140 };
141
142 #define MAX_DTMF_DIGITS         128
143
144 /* Basic DTMF specs:
145  *
146  * Minimum tone on = 40ms
147  * Minimum tone off = 50ms
148  * Maximum digit rate = 10 per second
149  * Normal twist <= 8dB accepted
150  * Reverse twist <= 4dB accepted
151  * S/N >= 15dB will detect OK
152  * Attenuation <= 26dB will detect OK
153  * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
154  */
155
156 #define DTMF_THRESHOLD          8.0e7
157 #define FAX_THRESHOLD           8.0e7
158 #define FAX_2ND_HARMONIC        2.0     /* 4dB */
159 #define DTMF_NORMAL_TWIST       6.3     /* 8dB */
160 #ifdef  RADIO_RELAX
161 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5)     /* 4dB normal */
162 #else
163 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)     /* 4dB normal */
164 #endif
165 #define DTMF_RELATIVE_PEAK_ROW  6.3     /* 8dB */
166 #define DTMF_RELATIVE_PEAK_COL  6.3     /* 8dB */
167 #define DTMF_2ND_HARMONIC_ROW       ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)     /* 4dB normal */
168 #define DTMF_2ND_HARMONIC_COL   63.1    /* 18dB */
169 #define DTMF_TO_TOTAL_ENERGY    42.0
170
171 #ifdef OLD_DSP_ROUTINES
172 #define MF_THRESHOLD            8.0e7
173 #define MF_NORMAL_TWIST         5.3     /* 8dB */
174 #define MF_REVERSE_TWIST        4.0     /* was 2.5 */
175 #define MF_RELATIVE_PEAK        5.3     /* 8dB */
176 #define MF_2ND_HARMONIC         1.7     /* was 2.5  */
177 #else
178 #define BELL_MF_THRESHOLD       1.6e9
179 #define BELL_MF_TWIST           4.0     /* 6dB */
180 #define BELL_MF_RELATIVE_PEAK   12.6    /* 11dB */
181 #endif
182
183 #if !defined(BUSYDETECT_MARTIN) && !defined(BUSYDETECT) && !defined(BUSYDETECT_TONEONLY) && !defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
184 #define BUSYDETECT_MARTIN
185 #endif
186
187 typedef struct {
188         float v2;
189         float v3;
190         float fac;
191 #ifndef OLD_DSP_ROUTINES
192         int samples;
193 #endif  
194 } goertzel_state_t;
195
196 typedef struct
197 {
198         goertzel_state_t row_out[4];
199         goertzel_state_t col_out[4];
200 #ifdef FAX_DETECT
201         goertzel_state_t fax_tone;
202 #endif
203 #ifdef OLD_DSP_ROUTINES
204         goertzel_state_t row_out2nd[4];
205         goertzel_state_t col_out2nd[4];
206 #ifdef FAX_DETECT
207         goertzel_state_t fax_tone2nd;    
208 #endif
209         int hit1;
210         int hit2;
211         int hit3;
212         int hit4;
213 #else
214         int hits[3];
215 #endif  
216         int mhit;
217         float energy;
218         int current_sample;
219
220         char digits[MAX_DTMF_DIGITS + 1];
221         
222         int current_digits;
223         int detected_digits;
224         int lost_digits;
225         int digit_hits[16];
226 #ifdef FAX_DETECT
227         int fax_hits;
228 #endif
229 } dtmf_detect_state_t;
230
231 typedef struct
232 {
233         goertzel_state_t tone_out[6];
234         int mhit;
235 #ifdef OLD_DSP_ROUTINES
236         int hit1;
237         int hit2;
238         int hit3;
239         int hit4;
240         goertzel_state_t tone_out2nd[6];
241         float energy;
242 #else
243         int hits[5];
244 #endif
245         int current_sample;
246         
247         char digits[MAX_DTMF_DIGITS + 1];
248
249         int current_digits;
250         int detected_digits;
251         int lost_digits;
252 #ifdef FAX_DETECT
253         int fax_hits;
254 #endif
255 } mf_detect_state_t;
256
257 static float dtmf_row[] =
258 {
259         697.0,  770.0,  852.0,  941.0
260 };
261 static float dtmf_col[] =
262 {
263         1209.0, 1336.0, 1477.0, 1633.0
264 };
265
266 static float mf_tones[] =
267 {
268         700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
269 };
270
271 #ifdef FAX_DETECT
272 static float fax_freq = 1100.0;
273 #endif
274
275 static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
276
277 #ifdef OLD_DSP_ROUTINES
278 static char mf_hit[6][6] = {
279         /*  700 + */ {   0, '1', '2', '4', '7', 'C' },
280         /*  900 + */ { '1',   0, '3', '5', '8', 'A' },
281         /* 1100 + */ { '2', '3',   0, '6', '9', '*' },
282         /* 1300 + */ { '4', '5', '6',   0, '0', 'B' },
283         /* 1500 + */ { '7', '8', '9', '0',  0, '#' },
284         /* 1700 + */ { 'C', 'A', '*', 'B', '#',  0  },
285 };
286 #else
287 static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
288 #endif
289
290 static inline void goertzel_sample(goertzel_state_t *s, short sample)
291 {
292         float v1;
293         float fsamp  = sample;
294         
295         v1 = s->v2;
296         s->v2 = s->v3;
297         s->v3 = s->fac * s->v2 - v1 + fsamp;
298 }
299
300 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
301 {
302         int i;
303         
304         for (i=0;i<count;i++) 
305                 goertzel_sample(s, samps[i]);
306 }
307
308
309 static inline float goertzel_result(goertzel_state_t *s)
310 {
311         return s->v3 * s->v3 + s->v2 * s->v2 - s->v2 * s->v3 * s->fac;
312 }
313
314 static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
315 {
316         s->v2 = s->v3 = 0.0;
317         s->fac = 2.0 * cos(2.0 * M_PI * (freq / 8000.0));
318 #ifndef OLD_DSP_ROUTINES
319         s->samples = samples;
320 #endif
321 }
322
323 static inline void goertzel_reset(goertzel_state_t *s)
324 {
325         s->v2 = s->v3 = 0.0;
326 }
327
328 struct ast_dsp {
329         struct ast_frame f;
330         int threshold;
331         int totalsilence;
332         int totalnoise;
333         int features;
334         int ringtimeout;
335         int busymaybe;
336         int busycount;
337         int busy_tonelength;
338         int busy_quietlength;
339         int historicnoise[DSP_HISTORY];
340         int historicsilence[DSP_HISTORY];
341         goertzel_state_t freqs[7];
342         int freqcount;
343         int gsamps;
344         enum gsamp_size gsamp_size;
345         enum prog_mode progmode;
346         int tstate;
347         int tcount;
348         int digitmode;
349         int thinkdigit;
350         float genergy;
351         union {
352                 dtmf_detect_state_t dtmf;
353                 mf_detect_state_t mf;
354         } td;
355 };
356
357 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
358 {
359         int i;
360
361 #ifdef OLD_DSP_ROUTINES
362         s->hit1 = 
363         s->mhit = 
364         s->hit3 =
365         s->hit4 = 
366         s->hit2 = 0;
367 #else
368         s->hits[0] = s->hits[1] = s->hits[2] = 0;
369 #endif
370         for (i = 0;  i < 4;  i++) {
371                 goertzel_init (&s->row_out[i], dtmf_row[i], 102);
372                 goertzel_init (&s->col_out[i], dtmf_col[i], 102);
373 #ifdef OLD_DSP_ROUTINES
374                 goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0, 102);
375                 goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0, 102);
376 #endif  
377                 s->energy = 0.0;
378         }
379 #ifdef FAX_DETECT
380         /* Same for the fax dector */
381         goertzel_init (&s->fax_tone, fax_freq, 102);
382
383 #ifdef OLD_DSP_ROUTINES
384         /* Same for the fax dector 2nd harmonic */
385         goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
386 #endif  
387 #endif /* FAX_DETECT */
388         s->current_sample = 0;
389         s->detected_digits = 0;
390         s->current_digits = 0;
391         memset(&s->digits, 0, sizeof(s->digits));
392         s->lost_digits = 0;
393         s->digits[0] = '\0';
394 }
395
396 static void ast_mf_detect_init (mf_detect_state_t *s)
397 {
398         int i;
399 #ifdef OLD_DSP_ROUTINES
400         s->hit1 = 
401         s->hit2 = 0;
402 #else   
403         s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
404 #endif
405         for (i = 0;  i < 6;  i++) {
406                 goertzel_init (&s->tone_out[i], mf_tones[i], 160);
407 #ifdef OLD_DSP_ROUTINES
408                 goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
409                 s->energy = 0.0;
410 #endif
411         }
412         s->current_digits = 0;
413         memset(&s->digits, 0, sizeof(s->digits));
414         s->current_sample = 0;
415         s->detected_digits = 0;
416         s->lost_digits = 0;
417         s->digits[0] = '\0';
418         s->mhit = 0;
419 }
420
421 static int dtmf_detect (dtmf_detect_state_t *s, int16_t amp[], int samples, 
422                  int digitmode, int *writeback, int faxdetect)
423 {
424         float row_energy[4];
425         float col_energy[4];
426 #ifdef FAX_DETECT
427         float fax_energy;
428 #ifdef OLD_DSP_ROUTINES
429         float fax_energy_2nd;
430 #endif  
431 #endif /* FAX_DETECT */
432         float famp;
433         float v1;
434         int i;
435         int j;
436         int sample;
437         int best_row;
438         int best_col;
439         int hit;
440         int limit;
441
442         hit = 0;
443         for (sample = 0;  sample < samples;  sample = limit) {
444                 /* 102 is optimised to meet the DTMF specs. */
445                 if ((samples - sample) >= (102 - s->current_sample))
446                         limit = sample + (102 - s->current_sample);
447                 else
448                         limit = samples;
449 #if defined(USE_3DNOW)
450                 _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
451                 _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
452 #ifdef OLD_DSP_ROUTINES
453                 _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
454                 _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
455 #endif          
456                 /* XXX Need to fax detect for 3dnow too XXX */
457                 #warning "Fax Support Broken"
458 #else
459                 /* The following unrolled loop takes only 35% (rough estimate) of the 
460                    time of a rolled loop on the machine on which it was developed */
461                 for (j=sample;j<limit;j++) {
462                         famp = amp[j];
463                         s->energy += famp*famp;
464                         /* With GCC 2.95, the following unrolled code seems to take about 35%
465                            (rough estimate) as long as a neat little 0-3 loop */
466                         v1 = s->row_out[0].v2;
467                         s->row_out[0].v2 = s->row_out[0].v3;
468                         s->row_out[0].v3 = s->row_out[0].fac*s->row_out[0].v2 - v1 + famp;
469                         v1 = s->col_out[0].v2;
470                         s->col_out[0].v2 = s->col_out[0].v3;
471                         s->col_out[0].v3 = s->col_out[0].fac*s->col_out[0].v2 - v1 + famp;
472                         v1 = s->row_out[1].v2;
473                         s->row_out[1].v2 = s->row_out[1].v3;
474                         s->row_out[1].v3 = s->row_out[1].fac*s->row_out[1].v2 - v1 + famp;
475                         v1 = s->col_out[1].v2;
476                         s->col_out[1].v2 = s->col_out[1].v3;
477                         s->col_out[1].v3 = s->col_out[1].fac*s->col_out[1].v2 - v1 + famp;
478                         v1 = s->row_out[2].v2;
479                         s->row_out[2].v2 = s->row_out[2].v3;
480                         s->row_out[2].v3 = s->row_out[2].fac*s->row_out[2].v2 - v1 + famp;
481                         v1 = s->col_out[2].v2;
482                         s->col_out[2].v2 = s->col_out[2].v3;
483                         s->col_out[2].v3 = s->col_out[2].fac*s->col_out[2].v2 - v1 + famp;
484                         v1 = s->row_out[3].v2;
485                         s->row_out[3].v2 = s->row_out[3].v3;
486                         s->row_out[3].v3 = s->row_out[3].fac*s->row_out[3].v2 - v1 + famp;
487                         v1 = s->col_out[3].v2;
488                         s->col_out[3].v2 = s->col_out[3].v3;
489                         s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp;
490 #ifdef FAX_DETECT
491                         /* Update fax tone */
492                         v1 = s->fax_tone.v2;
493                         s->fax_tone.v2 = s->fax_tone.v3;
494                         s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp;
495 #endif /* FAX_DETECT */
496 #ifdef OLD_DSP_ROUTINES
497                         v1 = s->col_out2nd[0].v2;
498                         s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
499                         s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp;
500                         v1 = s->row_out2nd[0].v2;
501                         s->row_out2nd[0].v2 = s->row_out2nd[0].v3;
502                         s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp;
503                         v1 = s->col_out2nd[1].v2;
504                         s->col_out2nd[1].v2 = s->col_out2nd[1].v3;
505                         s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp;
506                         v1 = s->row_out2nd[1].v2;
507                         s->row_out2nd[1].v2 = s->row_out2nd[1].v3;
508                         s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp;
509                         v1 = s->col_out2nd[2].v2;
510                         s->col_out2nd[2].v2 = s->col_out2nd[2].v3;
511                         s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp;
512                         v1 = s->row_out2nd[2].v2;
513                         s->row_out2nd[2].v2 = s->row_out2nd[2].v3;
514                         s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp;
515                         v1 = s->col_out2nd[3].v2;
516                         s->col_out2nd[3].v2 = s->col_out2nd[3].v3;
517                         s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp;
518                         v1 = s->row_out2nd[3].v2;
519                         s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
520                         s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
521 #ifdef FAX_DETECT
522                         /* Update fax tone */            
523                         v1 = s->fax_tone.v2;
524                         s->fax_tone2nd.v2 = s->fax_tone2nd.v3;
525                         s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp;
526 #endif /* FAX_DETECT */
527 #endif
528                 }
529 #endif
530                 s->current_sample += (limit - sample);
531                 if (s->current_sample < 102) {
532                         if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
533                                 /* If we had a hit last time, go ahead and clear this out since likely it
534                                    will be another hit */
535                                 for (i=sample;i<limit;i++) 
536                                         amp[i] = 0;
537                                 *writeback = 1;
538                         }
539                         continue;
540                 }
541 #ifdef FAX_DETECT
542                 /* Detect the fax energy, too */
543                 fax_energy = goertzel_result(&s->fax_tone);
544 #endif
545                 /* We are at the end of a DTMF detection block */
546                 /* Find the peak row and the peak column */
547                 row_energy[0] = goertzel_result (&s->row_out[0]);
548                 col_energy[0] = goertzel_result (&s->col_out[0]);
549
550                 for (best_row = best_col = 0, i = 1;  i < 4;  i++) {
551                         row_energy[i] = goertzel_result (&s->row_out[i]);
552                         if (row_energy[i] > row_energy[best_row])
553                                 best_row = i;
554                         col_energy[i] = goertzel_result (&s->col_out[i]);
555                         if (col_energy[i] > col_energy[best_col])
556                                 best_col = i;
557                 }
558                 hit = 0;
559                 /* Basic signal level test and the twist test */
560                 if (row_energy[best_row] >= DTMF_THRESHOLD && 
561                     col_energy[best_col] >= DTMF_THRESHOLD &&
562                     col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
563                     col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
564                         /* Relative peak test */
565                         for (i = 0;  i < 4;  i++) {
566                                 if ((i != best_col &&
567                                     col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
568                                     (i != best_row 
569                                      && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
570                                         break;
571                                 }
572                         }
573 #ifdef OLD_DSP_ROUTINES
574                         /* ... and second harmonic test */
575                         if (i >= 4 && 
576                             (row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy &&
577                             goertzel_result(&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col]
578                             && goertzel_result(&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
579 #else
580                         /* ... and fraction of total energy test */
581                         if (i >= 4 &&
582                             (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy) {
583 #endif
584                                 /* Got a hit */
585                                 hit = dtmf_positions[(best_row << 2) + best_col];
586                                 if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
587                                         /* Zero out frame data if this is part DTMF */
588                                         for (i=sample;i<limit;i++) 
589                                                 amp[i] = 0;
590                                         *writeback = 1;
591                                 }
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 #ifdef OLD_DSP_ROUTINES
600                                 if (hit == s->hit3  &&  s->hit3 != s->hit2) {
601                                         s->mhit = hit;
602                                         s->digit_hits[(best_row << 2) + best_col]++;
603                                         s->detected_digits++;
604                                         if (s->current_digits < MAX_DTMF_DIGITS) {
605                                                 s->digits[s->current_digits++] = hit;
606                                                 s->digits[s->current_digits] = '\0';
607                                         } else {
608                                                 s->lost_digits++;
609                                         }
610                                 }
611 #else                           
612                                 if (hit == s->hits[2]  &&  hit != s->hits[1]  &&  hit != s->hits[0]) {
613                                         s->mhit = hit;
614                                         s->digit_hits[(best_row << 2) + best_col]++;
615                                         s->detected_digits++;
616                                         if (s->current_digits < MAX_DTMF_DIGITS) {
617                                                 s->digits[s->current_digits++] = hit;
618                                                 s->digits[s->current_digits] = '\0';
619                                         } else {
620                                                 s->lost_digits++;
621                                         }
622                                 }
623 #endif
624                         }
625                 } 
626 #ifdef FAX_DETECT
627                 if (!hit && (fax_energy >= FAX_THRESHOLD) && 
628                         (fax_energy >= DTMF_TO_TOTAL_ENERGY*s->energy) &&
629                         (faxdetect)) {
630 #if 0
631                         printf("Fax energy/Second Harmonic: %f\n", fax_energy);
632 #endif                                  
633                         /* XXX Probably need better checking than just this the energy XXX */
634                         hit = 'f';
635                         s->fax_hits++;
636                 } else {
637                         if (s->fax_hits > 5) {
638                                 hit = 'f';
639                                 s->mhit = 'f';
640                                 s->detected_digits++;
641                                 if (s->current_digits < MAX_DTMF_DIGITS) {
642                                         s->digits[s->current_digits++] = hit;
643                                         s->digits[s->current_digits] = '\0';
644                                 } else {
645                                         s->lost_digits++;
646                                 }
647                         }
648                         s->fax_hits = 0;
649                 }
650 #endif /* FAX_DETECT */
651 #ifdef OLD_DSP_ROUTINES
652                 s->hit1 = s->hit2;
653                 s->hit2 = s->hit3;
654                 s->hit3 = hit;
655 #else
656                 s->hits[0] = s->hits[1];
657                 s->hits[1] = s->hits[2];
658                 s->hits[2] = hit;
659 #endif          
660                 /* Reinitialise the detector for the next block */
661                 for (i = 0;  i < 4;  i++) {
662                         goertzel_reset(&s->row_out[i]);
663                         goertzel_reset(&s->col_out[i]);
664 #ifdef OLD_DSP_ROUTINES
665                         goertzel_reset(&s->row_out2nd[i]);
666                         goertzel_reset(&s->col_out2nd[i]);
667 #endif                  
668                 }
669 #ifdef FAX_DETECT
670                 goertzel_reset (&s->fax_tone);
671 #ifdef OLD_DSP_ROUTINES
672                 goertzel_reset (&s->fax_tone2nd);
673 #endif                  
674 #endif
675                 s->energy = 0.0;
676                 s->current_sample = 0;
677         }
678         if ((!s->mhit) || (s->mhit != hit)) {
679                 s->mhit = 0;
680                 return(0);
681         }
682         return (hit);
683 }
684
685 /* MF goertzel size */
686 #ifdef OLD_DSP_ROUTINES
687 #define MF_GSIZE 160
688 #else
689 #define MF_GSIZE 120
690 #endif
691
692 static int mf_detect (mf_detect_state_t *s, int16_t amp[],
693                  int samples, int digitmode, int *writeback)
694 {
695 #ifdef OLD_DSP_ROUTINES
696         float tone_energy[6];
697         int best1;
698         int best2;
699         float max;
700         int sofarsogood;
701 #else
702         float energy[6];
703         int best;
704         int second_best;
705 #endif
706         float famp;
707         float v1;
708         int i;
709         int j;
710         int sample;
711         int hit;
712         int limit;
713
714         hit = 0;
715         for (sample = 0;  sample < samples;  sample = limit) {
716                 /* 80 is optimised to meet the MF specs. */
717                 if ((samples - sample) >= (MF_GSIZE - s->current_sample))
718                         limit = sample + (MF_GSIZE - s->current_sample);
719                 else
720                         limit = samples;
721 #if defined(USE_3DNOW)
722                 _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
723                 _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
724 #ifdef OLD_DSP_ROUTINES
725                 _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
726                 _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
727 #endif
728                 /* XXX Need to fax detect for 3dnow too XXX */
729                 #warning "Fax Support Broken"
730 #else
731                 /* The following unrolled loop takes only 35% (rough estimate) of the 
732                    time of a rolled loop on the machine on which it was developed */
733                 for (j = sample;  j < limit;  j++) {
734                         famp = amp[j];
735 #ifdef OLD_DSP_ROUTINES
736                         s->energy += famp*famp;
737 #endif
738                         /* With GCC 2.95, the following unrolled code seems to take about 35%
739                            (rough estimate) as long as a neat little 0-3 loop */
740                         v1 = s->tone_out[0].v2;
741                         s->tone_out[0].v2 = s->tone_out[0].v3;
742                         s->tone_out[0].v3 = s->tone_out[0].fac*s->tone_out[0].v2 - v1 + famp;
743                         v1 = s->tone_out[1].v2;
744                         s->tone_out[1].v2 = s->tone_out[1].v3;
745                         s->tone_out[1].v3 = s->tone_out[1].fac*s->tone_out[1].v2 - v1 + famp;
746                         v1 = s->tone_out[2].v2;
747                         s->tone_out[2].v2 = s->tone_out[2].v3;
748                         s->tone_out[2].v3 = s->tone_out[2].fac*s->tone_out[2].v2 - v1 + famp;
749                         v1 = s->tone_out[3].v2;
750                         s->tone_out[3].v2 = s->tone_out[3].v3;
751                         s->tone_out[3].v3 = s->tone_out[3].fac*s->tone_out[3].v2 - v1 + famp;
752                         v1 = s->tone_out[4].v2;
753                         s->tone_out[4].v2 = s->tone_out[4].v3;
754                         s->tone_out[4].v3 = s->tone_out[4].fac*s->tone_out[4].v2 - v1 + famp;
755                         v1 = s->tone_out[5].v2;
756                         s->tone_out[5].v2 = s->tone_out[5].v3;
757                         s->tone_out[5].v3 = s->tone_out[5].fac*s->tone_out[5].v2 - v1 + famp;
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 #if 1
1338         if (res)
1339                 ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1340 #endif
1341         return res;
1342 }
1343 #endif
1344
1345 #ifdef BUSYDETECT
1346 int ast_dsp_busydetect(struct ast_dsp *dsp)
1347 {
1348         int x;
1349         int res = 0;
1350         int max, min;
1351
1352 #if 0
1353         if (dsp->busy_hits > 5);
1354         return 0;
1355 #endif
1356         if (dsp->busymaybe) {
1357 #if 0
1358                 printf("Maybe busy!\n");
1359 #endif          
1360                 dsp->busymaybe = 0;
1361                 min = 9999;
1362                 max = 0;
1363                 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
1364 #if 0
1365                         printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
1366 #endif                  
1367                         if (dsp->historicsilence[x] < min)
1368                                 min = dsp->historicsilence[x];
1369                         if (dsp->historicnoise[x] < min)
1370                                 min = dsp->historicnoise[x];
1371                         if (dsp->historicsilence[x] > max)
1372                                 max = dsp->historicsilence[x];
1373                         if (dsp->historicnoise[x] > max)
1374                                 max = dsp->historicnoise[x];
1375                 }
1376                 if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
1377 #if 0
1378                         printf("Busy!\n");
1379 #endif                  
1380                         res = 1;
1381                 }
1382 #if 0
1383                 printf("Min: %d, max: %d\n", min, max);
1384 #endif          
1385         }
1386         return res;
1387 }
1388 #endif
1389
1390 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
1391 {
1392         short *s;
1393         int len;
1394         
1395         if (f->frametype != AST_FRAME_VOICE) {
1396                 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
1397                 return 0;
1398         }
1399         if (f->subclass != AST_FORMAT_SLINEAR) {
1400                 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
1401                 return 0;
1402         }
1403         s = f->data;
1404         len = f->datalen/2;
1405         return __ast_dsp_silence(dsp, s, len, totalsilence);
1406 }
1407
1408 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
1409 {
1410         int silence;
1411         int res;
1412         int digit;
1413         int x;
1414         short *shortdata;
1415         unsigned char *odata;
1416         int len;
1417         int writeback = 0;
1418
1419 #define FIX_INF(inf) do { \
1420                 if (writeback) { \
1421                         switch(inf->subclass) { \
1422                         case AST_FORMAT_SLINEAR: \
1423                                 break; \
1424                         case AST_FORMAT_ULAW: \
1425                                 for (x=0;x<len;x++) \
1426                                         odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
1427                                 break; \
1428                         case AST_FORMAT_ALAW: \
1429                                 for (x=0;x<len;x++) \
1430                                         odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
1431                                 break; \
1432                         } \
1433                 } \
1434         } while(0) 
1435
1436         if (!af)
1437                 return NULL;
1438         if (af->frametype != AST_FRAME_VOICE)
1439                 return af;
1440         odata = af->data;
1441         len = af->datalen;
1442         /* Make sure we have short data */
1443         switch(af->subclass) {
1444         case AST_FORMAT_SLINEAR:
1445                 shortdata = af->data;
1446                 len = af->datalen / 2;
1447                 break;
1448         case AST_FORMAT_ULAW:
1449                 shortdata = alloca(af->datalen * 2);
1450                 for (x = 0;x < len; x++) 
1451                         shortdata[x] = AST_MULAW(odata[x]);
1452                 break;
1453         case AST_FORMAT_ALAW:
1454                 shortdata = alloca(af->datalen * 2);
1455                 for (x = 0; x < len; x++) 
1456                         shortdata[x] = AST_ALAW(odata[x]);
1457                 break;
1458         default:
1459                 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
1460                 return af;
1461         }
1462         silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
1463         if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
1464                 memset(&dsp->f, 0, sizeof(dsp->f));
1465                 dsp->f.frametype = AST_FRAME_NULL;
1466                 return &dsp->f;
1467         }
1468         if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
1469                 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1470                 memset(&dsp->f, 0, sizeof(dsp->f));
1471                 dsp->f.frametype = AST_FRAME_CONTROL;
1472                 dsp->f.subclass = AST_CONTROL_BUSY;
1473                 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
1474                 return &dsp->f;
1475         }
1476         if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
1477                 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
1478 #if 0
1479                 if (digit)
1480                         printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
1481 #endif                  
1482                 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
1483                         if (!dsp->thinkdigit) {
1484                                 if (digit) {
1485                                         /* Looks like we might have something.  
1486                                          * Request a conference mute for the moment */
1487                                         memset(&dsp->f, 0, sizeof(dsp->f));
1488                                         dsp->f.frametype = AST_FRAME_DTMF;
1489                                         dsp->f.subclass = 'm';
1490                                         dsp->thinkdigit = 'x';
1491                                         FIX_INF(af);
1492                                         if (chan)
1493                                                 ast_queue_frame(chan, af);
1494                                         ast_frfree(af);
1495                                         return &dsp->f;
1496                                 }
1497                         } else {
1498                                 if (digit) {
1499                                         /* Thought we saw one last time.  Pretty sure we really have now */
1500                                         if (dsp->thinkdigit) {
1501                                                 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
1502                                                         /* If we found a digit, and we're changing digits, go
1503                                                            ahead and send this one, but DON'T stop confmute because
1504                                                            we're detecting something else, too... */
1505                                                         memset(&dsp->f, 0, sizeof(dsp->f));
1506                                                         dsp->f.frametype = AST_FRAME_DTMF;
1507                                                         dsp->f.subclass = dsp->thinkdigit;
1508                                                         FIX_INF(af);
1509                                                         if (chan)
1510                                                                 ast_queue_frame(chan, af);
1511                                                         ast_frfree(af);
1512                                                 }
1513                                                 dsp->thinkdigit = digit;
1514                                                 return &dsp->f;
1515                                         }
1516                                         dsp->thinkdigit = digit;
1517                                 } else {
1518                                         if (dsp->thinkdigit) {
1519                                                 memset(&dsp->f, 0, sizeof(dsp->f));
1520                                                 if (dsp->thinkdigit != 'x') {
1521                                                         /* If we found a digit, send it now */
1522                                                         dsp->f.frametype = AST_FRAME_DTMF;
1523                                                         dsp->f.subclass = dsp->thinkdigit;
1524                                                         dsp->thinkdigit = 0;
1525                                                 } else {
1526                                                         dsp->f.frametype = AST_FRAME_DTMF;
1527                                                         dsp->f.subclass = 'u';
1528                                                         dsp->thinkdigit = 0;
1529                                                 }
1530                                                 FIX_INF(af);
1531                                                 if (chan)
1532                                                         ast_queue_frame(chan, af);
1533                                                 ast_frfree(af);
1534                                                 return &dsp->f;
1535                                         }
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;
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         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_log(LOG_DEBUG, "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.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] =  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<sizeof(aliases) / sizeof(aliases[0]);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 }