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