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