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