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