silly people that don't want to install/run autoconf :-)
[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 <sys/types.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include <math.h>
48 #include <errno.h>
49 #include <stdio.h>
50
51 #include "asterisk.h"
52
53 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
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         /* If we know the expected busy tone silent-period length, check we are in the range */
1326         if (res && (dsp->busy_quietlength > 0)) {
1327                 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
1328 #if 0
1329                         ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
1330                                                 avgsilence, dsp->busy_quietlength);
1331 #endif
1332                         res = 0;
1333                 }
1334         }
1335 #if 1
1336         if (res)
1337                 ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1338 #endif
1339         return res;
1340 }
1341 #endif
1342
1343 #ifdef BUSYDETECT
1344 int ast_dsp_busydetect(struct ast_dsp *dsp)
1345 {
1346         int x;
1347         int res = 0;
1348         int max, min;
1349
1350 #if 0
1351         if (dsp->busy_hits > 5);
1352         return 0;
1353 #endif
1354         if (dsp->busymaybe) {
1355 #if 0
1356                 printf("Maybe busy!\n");
1357 #endif          
1358                 dsp->busymaybe = 0;
1359                 min = 9999;
1360                 max = 0;
1361                 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
1362 #if 0
1363                         printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
1364 #endif                  
1365                         if (dsp->historicsilence[x] < min)
1366                                 min = dsp->historicsilence[x];
1367                         if (dsp->historicnoise[x] < min)
1368                                 min = dsp->historicnoise[x];
1369                         if (dsp->historicsilence[x] > max)
1370                                 max = dsp->historicsilence[x];
1371                         if (dsp->historicnoise[x] > max)
1372                                 max = dsp->historicnoise[x];
1373                 }
1374                 if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
1375 #if 0
1376                         printf("Busy!\n");
1377 #endif                  
1378                         res = 1;
1379                 }
1380 #if 0
1381                 printf("Min: %d, max: %d\n", min, max);
1382 #endif          
1383         }
1384         return res;
1385 }
1386 #endif
1387
1388 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
1389 {
1390         short *s;
1391         int len;
1392         
1393         if (f->frametype != AST_FRAME_VOICE) {
1394                 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
1395                 return 0;
1396         }
1397         if (f->subclass != AST_FORMAT_SLINEAR) {
1398                 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
1399                 return 0;
1400         }
1401         s = f->data;
1402         len = f->datalen/2;
1403         return __ast_dsp_silence(dsp, s, len, totalsilence);
1404 }
1405
1406 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
1407 {
1408         int silence;
1409         int res;
1410         int digit;
1411         int x;
1412         short *shortdata;
1413         unsigned char *odata;
1414         int len;
1415         int writeback = 0;
1416
1417 #define FIX_INF(inf) do { \
1418                 if (writeback) { \
1419                         switch(inf->subclass) { \
1420                         case AST_FORMAT_SLINEAR: \
1421                                 break; \
1422                         case AST_FORMAT_ULAW: \
1423                                 for (x=0;x<len;x++) \
1424                                         odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
1425                                 break; \
1426                         case AST_FORMAT_ALAW: \
1427                                 for (x=0;x<len;x++) \
1428                                         odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
1429                                 break; \
1430                         } \
1431                 } \
1432         } while(0) 
1433
1434         if (!af)
1435                 return NULL;
1436         if (af->frametype != AST_FRAME_VOICE)
1437                 return af;
1438         odata = af->data;
1439         len = af->datalen;
1440         /* Make sure we have short data */
1441         switch(af->subclass) {
1442         case AST_FORMAT_SLINEAR:
1443                 shortdata = af->data;
1444                 len = af->datalen / 2;
1445                 break;
1446         case AST_FORMAT_ULAW:
1447                 if (!(shortdata = alloca(af->datalen * 2))) {
1448                         ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
1449                         return af;
1450                 }
1451                 for (x=0;x<len;x++) 
1452                         shortdata[x] = AST_MULAW(odata[x]);
1453                 break;
1454         case AST_FORMAT_ALAW:
1455                 if (!(shortdata = alloca(af->datalen * 2))) {
1456                         ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
1457                         return af;
1458                 }
1459                 for (x=0;x<len;x++) 
1460                         shortdata[x] = AST_ALAW(odata[x]);
1461                 break;
1462         default:
1463                 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
1464                 return af;
1465         }
1466         silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
1467         if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
1468                 memset(&dsp->f, 0, sizeof(dsp->f));
1469                 dsp->f.frametype = AST_FRAME_NULL;
1470                 return &dsp->f;
1471         }
1472         if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
1473                 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1474                 memset(&dsp->f, 0, sizeof(dsp->f));
1475                 dsp->f.frametype = AST_FRAME_CONTROL;
1476                 dsp->f.subclass = AST_CONTROL_BUSY;
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) {
1505                                                 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
1506                                                         /* If we found a digit, and we're changing digits, go
1507                                                            ahead and send this one, but DON'T stop confmute because
1508                                                            we're detecting something else, too... */
1509                                                         memset(&dsp->f, 0, sizeof(dsp->f));
1510                                                         dsp->f.frametype = AST_FRAME_DTMF;
1511                                                         dsp->f.subclass = dsp->thinkdigit;
1512                                                         FIX_INF(af);
1513                                                         if (chan)
1514                                                                 ast_queue_frame(chan, af);
1515                                                         ast_frfree(af);
1516                                                 }
1517                                                 dsp->thinkdigit = digit;
1518                                                 return &dsp->f;
1519                                         }
1520                                         dsp->thinkdigit = digit;
1521                                 } else {
1522                                         if (dsp->thinkdigit) {
1523                                                 memset(&dsp->f, 0, sizeof(dsp->f));
1524                                                 if (dsp->thinkdigit != 'x') {
1525                                                         /* If we found a digit, send it now */
1526                                                         dsp->f.frametype = AST_FRAME_DTMF;
1527                                                         dsp->f.subclass = dsp->thinkdigit;
1528                                                         dsp->thinkdigit = 0;
1529                                                 } else {
1530                                                         dsp->f.frametype = AST_FRAME_DTMF;
1531                                                         dsp->f.subclass = 'u';
1532                                                         dsp->thinkdigit = 0;
1533                                                 }
1534                                                 FIX_INF(af);
1535                                                 if (chan)
1536                                                         ast_queue_frame(chan, af);
1537                                                 ast_frfree(af);
1538                                                 return &dsp->f;
1539                                         }
1540                                 }
1541                         }
1542                 } else if (!digit) {
1543                         /* Only check when there is *not* a hit... */
1544                         if (dsp->digitmode & DSP_DIGITMODE_MF) {
1545                                 if (dsp->td.mf.current_digits) {
1546                                         memset(&dsp->f, 0, sizeof(dsp->f));
1547                                         dsp->f.frametype = AST_FRAME_DTMF;
1548                                         dsp->f.subclass = dsp->td.mf.digits[0];
1549                                         memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
1550                                         dsp->td.mf.current_digits--;
1551                                         FIX_INF(af);
1552                                         if (chan)
1553                                                 ast_queue_frame(chan, af);
1554                                         ast_frfree(af);
1555                                         return &dsp->f;
1556                                 }
1557                         } else {
1558                                 if (dsp->td.dtmf.current_digits) {
1559                                         memset(&dsp->f, 0, sizeof(dsp->f));
1560                                         dsp->f.frametype = AST_FRAME_DTMF;
1561                                         dsp->f.subclass = dsp->td.dtmf.digits[0];
1562                                         memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
1563                                         dsp->td.dtmf.current_digits--;
1564                                         FIX_INF(af);
1565                                         if (chan)
1566                                                 ast_queue_frame(chan, af);
1567                                         ast_frfree(af);
1568                                         return &dsp->f;
1569                                 }
1570                         }
1571                 }
1572         }
1573         if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
1574                 res = __ast_dsp_call_progress(dsp, shortdata, len);
1575                 if (res) {
1576                         switch(res) {
1577                         case AST_CONTROL_ANSWER:
1578                         case AST_CONTROL_BUSY:
1579                         case AST_CONTROL_RINGING:
1580                         case AST_CONTROL_CONGESTION:
1581                         case AST_CONTROL_HANGUP:
1582                                 memset(&dsp->f, 0, sizeof(dsp->f));
1583                                 dsp->f.frametype = AST_FRAME_CONTROL;
1584                                 dsp->f.subclass = res;
1585                                 dsp->f.src = "dsp_progress";
1586                                 if (chan) 
1587                                         ast_queue_frame(chan, &dsp->f);
1588                                 break;
1589                         default:
1590                                 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
1591                         }
1592                 }
1593         }
1594         FIX_INF(af);
1595         return af;
1596 }
1597
1598 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
1599 {
1600         int max = 0;
1601         int x;
1602         
1603         dsp->gsamp_size = modes[dsp->progmode].size;
1604         dsp->gsamps = 0;
1605         for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
1606                 if (modes[dsp->progmode].freqs[x]) {
1607                         goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
1608                         max = x + 1;
1609                 }
1610         }
1611         dsp->freqcount = max;
1612         dsp->ringtimeout= 0;
1613 }
1614
1615 struct ast_dsp *ast_dsp_new(void)
1616 {
1617         struct ast_dsp *dsp;
1618         
1619         if ((dsp = ast_calloc(1, sizeof(*dsp)))) {              
1620                 dsp->threshold = DEFAULT_THRESHOLD;
1621                 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
1622                 dsp->busycount = DSP_HISTORY;
1623                 /* Initialize DTMF detector */
1624                 ast_dtmf_detect_init(&dsp->td.dtmf);
1625                 /* Initialize initial DSP progress detect parameters */
1626                 ast_dsp_prog_reset(dsp);
1627         }
1628         return dsp;
1629 }
1630
1631 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
1632 {
1633         dsp->features = features;
1634 }
1635
1636 void ast_dsp_free(struct ast_dsp *dsp)
1637 {
1638         free(dsp);
1639 }
1640
1641 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
1642 {
1643         dsp->threshold = threshold;
1644 }
1645
1646 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
1647 {
1648         if (cadences < 4)
1649                 cadences = 4;
1650         if (cadences > DSP_HISTORY)
1651                 cadences = DSP_HISTORY;
1652         dsp->busycount = cadences;
1653 }
1654
1655 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
1656 {
1657         dsp->busy_tonelength = tonelength;
1658         dsp->busy_quietlength = quietlength;
1659         ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
1660 }
1661
1662 void ast_dsp_digitreset(struct ast_dsp *dsp)
1663 {
1664         int i;
1665         
1666         dsp->thinkdigit = 0;
1667         if (dsp->digitmode & DSP_DIGITMODE_MF) {
1668                 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
1669                 dsp->td.mf.current_digits = 0;
1670                 /* Reinitialise the detector for the next block */
1671                 for (i = 0;  i < 6;  i++) {
1672                         goertzel_reset(&dsp->td.mf.tone_out[i]);
1673 #ifdef OLD_DSP_ROUTINES
1674                         goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
1675 #endif                  
1676                 }
1677 #ifdef OLD_DSP_ROUTINES
1678                 dsp->td.mf.energy = 0.0;
1679                 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
1680 #else
1681                 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;
1682 #endif          
1683                 dsp->td.mf.current_sample = 0;
1684         } else {
1685                 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
1686                 dsp->td.dtmf.current_digits = 0;
1687                 /* Reinitialise the detector for the next block */
1688                 for (i = 0;  i < 4;  i++) {
1689                         goertzel_reset(&dsp->td.dtmf.row_out[i]);
1690                         goertzel_reset(&dsp->td.dtmf.col_out[i]);
1691 #ifdef OLD_DSP_ROUTINES
1692                         goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
1693                         goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
1694 #endif                  
1695                 }
1696 #ifdef FAX_DETECT
1697                 goertzel_reset (&dsp->td.dtmf.fax_tone);
1698 #endif
1699 #ifdef OLD_DSP_ROUTINES
1700 #ifdef FAX_DETECT
1701                 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
1702 #endif
1703                 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
1704 #else
1705                 dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] =  dsp->td.dtmf.mhit = 0;
1706 #endif          
1707                 dsp->td.dtmf.energy = 0.0;
1708                 dsp->td.dtmf.current_sample = 0;
1709         }
1710 }
1711
1712 void ast_dsp_reset(struct ast_dsp *dsp)
1713 {
1714         int x;
1715         
1716         dsp->totalsilence = 0;
1717         dsp->gsamps = 0;
1718         for (x=0;x<4;x++)
1719                 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1720         memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1721         memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));      
1722         dsp->ringtimeout= 0;
1723 }
1724
1725 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
1726 {
1727         int new;
1728         int old;
1729         
1730         old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
1731         new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
1732         if (old != new) {
1733                 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1734                 if (new & DSP_DIGITMODE_MF)
1735                         ast_mf_detect_init(&dsp->td.mf);
1736                 else
1737                         ast_dtmf_detect_init(&dsp->td.dtmf);
1738         }
1739         dsp->digitmode = digitmode;
1740         return 0;
1741 }
1742
1743 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
1744 {
1745         int x;
1746         
1747         for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
1748                 if (!strcasecmp(aliases[x].name, zone)) {
1749                         dsp->progmode = aliases[x].mode;
1750                         ast_dsp_prog_reset(dsp);
1751                         return 0;
1752                 }
1753         }
1754         return -1;
1755 }
1756
1757 int ast_dsp_get_tstate(struct ast_dsp *dsp) 
1758 {
1759         return dsp->tstate;
1760 }
1761
1762 int ast_dsp_get_tcount(struct ast_dsp *dsp) 
1763 {
1764         return dsp->tcount;
1765 }