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