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