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