2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
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.
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.
24 * \brief Convenience Signal Processing routines
26 * \author Mark Spencer <markster@digium.com>
27 * \author Steve Underwood <steveu@coppice.org>
30 /* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
32 tone_detect.c - General telephony tone detection, and specific
35 Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
37 Despite my general liking of the GPL, I place this code in the
38 public domain for the benefit of all mankind - even the slimy
39 ones who might try to proprietize my work and use it to my
45 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
47 #include <sys/types.h>
55 #include "asterisk/frame.h"
56 #include "asterisk/channel.h"
57 #include "asterisk/logger.h"
58 #include "asterisk/dsp.h"
59 #include "asterisk/ulaw.h"
60 #include "asterisk/alaw.h"
61 #include "asterisk/utils.h"
63 /*! Number of goertzels for progress detect */
65 GSAMP_SIZE_NA
= 183, /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
66 GSAMP_SIZE_CR
= 188, /*!< Costa Rica, Brazil - Only care about 425 Hz */
67 GSAMP_SIZE_UK
= 160 /*!< UK disconnect goertzel feed - should trigger 400hz */
86 /*! For CR/BR modes */
93 static struct progalias
{
97 { "us", PROG_MODE_NA
},
98 { "ca", PROG_MODE_NA
},
99 { "cr", PROG_MODE_CR
},
100 { "br", PROG_MODE_CR
},
101 { "uk", PROG_MODE_UK
},
104 static struct progress
{
105 enum gsamp_size size
;
108 { GSAMP_SIZE_NA
, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
109 { GSAMP_SIZE_CR
, { 425 } }, /*!< Costa Rica, Brazil */
110 { GSAMP_SIZE_UK
, { 400 } }, /*!< UK */
113 #define DEFAULT_THRESHOLD 512
116 BUSY_PERCENT
= 10, /*!< The percentage difference between the two last silence periods */
117 BUSY_PAT_PERCENT
= 7, /*!< The percentage difference between measured and actual pattern */
118 BUSY_THRESHOLD
= 100, /*!< Max number of ms difference between max and min times in busy */
119 BUSY_MIN
= 75, /*!< Busy must be at least 80 ms in half-cadence */
120 BUSY_MAX
=3100 /*!< Busy can't be longer than 3100 ms in half-cadence */
123 /*! Remember last 15 units */
124 #define DSP_HISTORY 15
126 /*! Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE */
129 #define TONE_THRESH 10.0 /*!< How much louder the tone should be than channel energy */
130 #define TONE_MIN_THRESH 1e8 /*!< How much tone there should be at least to attempt */
132 /*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
134 THRESH_RING
= 8, /*!< Need at least 150ms ring to accept */
135 THRESH_TALK
= 2, /*!< Talk detection does not work continuously */
136 THRESH_BUSY
= 4, /*!< Need at least 80ms to accept */
137 THRESH_CONGESTION
= 4, /*!< Need at least 80ms to accept */
138 THRESH_HANGUP
= 60, /*!< Need at least 1300ms to accept hangup */
139 THRESH_RING2ANSWER
= 300 /*!< Timeout from start of ring to answer (about 6600 ms) */
142 #define MAX_DTMF_DIGITS 128
146 * Minimum tone on = 40ms
147 * Minimum tone off = 50ms
148 * Maximum digit rate = 10 per second
149 * Normal twist <= 8dB accepted
150 * Reverse twist <= 4dB accepted
151 * S/N >= 15dB will detect OK
152 * Attenuation <= 26dB will detect OK
153 * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
156 #define DTMF_THRESHOLD 8.0e7
157 #define FAX_THRESHOLD 8.0e7
158 #define FAX_2ND_HARMONIC 2.0 /* 4dB */
161 #define DTMF_NORMAL_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 11.3 : 6.3) /* 8dB sph 12.3 was 6.3 */
162 #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 9.5 : 2.5) /* 4dB normal sph 12.5 : 5.5 was 6.5 : 2.5 */
163 #define DTMF_RELATIVE_PEAK_ROW ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 3.3 : 6.3) /* 8dB sph was 6.3 */
164 #define DTMF_RELATIVE_PEAK_COL ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 3.3 : 6.3) /* 8dB sph was 6.3 */
165 #define DTMF_TO_TOTAL_ENERGY ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 26.0 : 42.0)
167 #define DTMF_NORMAL_TWIST 6.3
168 #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5) /* 4dB normal */
169 #define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
170 #define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
171 #define DTMF_TO_TOTAL_ENERGY 42.0
174 #ifdef OLD_DSP_ROUTINES
175 #define DTMF_2ND_HARMONIC_ROW ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5) /* 4dB normal */
176 #define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
178 #define MF_THRESHOLD 8.0e7
179 #define MF_NORMAL_TWIST 5.3 /* 8dB */
180 #define MF_REVERSE_TWIST 4.0 /* was 2.5 */
181 #define MF_RELATIVE_PEAK 5.3 /* 8dB */
182 #define MF_2ND_HARMONIC 1.7 /* was 2.5 */
184 #define BELL_MF_THRESHOLD 1.6e9
185 #define BELL_MF_TWIST 4.0 /* 6dB */
186 #define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */
189 #if !defined(BUSYDETECT_MARTIN) && !defined(BUSYDETECT) && !defined(BUSYDETECT_TONEONLY) && !defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
190 #define BUSYDETECT_MARTIN
197 #ifndef OLD_DSP_ROUTINES
204 goertzel_state_t row_out
[4];
205 goertzel_state_t col_out
[4];
207 goertzel_state_t fax_tone
;
209 #ifdef OLD_DSP_ROUTINES
210 goertzel_state_t row_out2nd
[4];
211 goertzel_state_t col_out2nd
[4];
213 goertzel_state_t fax_tone2nd
;
226 char digits
[MAX_DTMF_DIGITS
+ 1];
235 } dtmf_detect_state_t
;
239 goertzel_state_t tone_out
[6];
241 #ifdef OLD_DSP_ROUTINES
246 goertzel_state_t tone_out2nd
[6];
253 char digits
[MAX_DTMF_DIGITS
+ 1];
263 static float dtmf_row
[] =
265 697.0, 770.0, 852.0, 941.0
267 static float dtmf_col
[] =
269 1209.0, 1336.0, 1477.0, 1633.0
272 static float mf_tones
[] =
274 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
278 static float fax_freq
= 1100.0;
281 static char dtmf_positions
[] = "123A" "456B" "789C" "*0#D";
283 #ifdef OLD_DSP_ROUTINES
284 static char mf_hit
[6][6] = {
285 /* 700 + */ { 0, '1', '2', '4', '7', 'C' },
286 /* 900 + */ { '1', 0, '3', '5', '8', 'A' },
287 /* 1100 + */ { '2', '3', 0, '6', '9', '*' },
288 /* 1300 + */ { '4', '5', '6', 0, '0', 'B' },
289 /* 1500 + */ { '7', '8', '9', '0', 0, '#' },
290 /* 1700 + */ { 'C', 'A', '*', 'B', '#', 0 },
293 static char bell_mf_positions
[] = "1247C-358A--69*---0B----#";
296 static inline void goertzel_sample(goertzel_state_t
*s
, short sample
)
299 float fsamp
= sample
;
303 s
->v3
= s
->fac
* s
->v2
- v1
+ fsamp
;
306 static inline void goertzel_update(goertzel_state_t
*s
, short *samps
, int count
)
310 for (i
=0;i
<count
;i
++)
311 goertzel_sample(s
, samps
[i
]);
315 static inline float goertzel_result(goertzel_state_t
*s
)
317 return s
->v3
* s
->v3
+ s
->v2
* s
->v2
- s
->v2
* s
->v3
* s
->fac
;
320 static inline void goertzel_init(goertzel_state_t
*s
, float freq
, int samples
)
323 s
->fac
= 2.0 * cos(2.0 * M_PI
* (freq
/ 8000.0));
324 #ifndef OLD_DSP_ROUTINES
325 s
->samples
= samples
;
329 static inline void goertzel_reset(goertzel_state_t
*s
)
344 int busy_quietlength
;
345 int historicnoise
[DSP_HISTORY
];
346 int historicsilence
[DSP_HISTORY
];
347 goertzel_state_t freqs
[7];
350 enum gsamp_size gsamp_size
;
351 enum prog_mode progmode
;
358 dtmf_detect_state_t dtmf
;
359 mf_detect_state_t mf
;
363 static void ast_dtmf_detect_init (dtmf_detect_state_t
*s
)
367 #ifdef OLD_DSP_ROUTINES
376 for (i
= 0; i
< 4; i
++) {
377 goertzel_init (&s
->row_out
[i
], dtmf_row
[i
], 102);
378 goertzel_init (&s
->col_out
[i
], dtmf_col
[i
], 102);
379 #ifdef OLD_DSP_ROUTINES
380 goertzel_init (&s
->row_out2nd
[i
], dtmf_row
[i
] * 2.0, 102);
381 goertzel_init (&s
->col_out2nd
[i
], dtmf_col
[i
] * 2.0, 102);
386 /* Same for the fax dector */
387 goertzel_init (&s
->fax_tone
, fax_freq
, 102);
389 #ifdef OLD_DSP_ROUTINES
390 /* Same for the fax dector 2nd harmonic */
391 goertzel_init (&s
->fax_tone2nd
, fax_freq
* 2.0, 102);
393 #endif /* FAX_DETECT */
394 s
->current_sample
= 0;
395 s
->detected_digits
= 0;
396 s
->current_digits
= 0;
397 memset(&s
->digits
, 0, sizeof(s
->digits
));
402 static void ast_mf_detect_init (mf_detect_state_t
*s
)
405 #ifdef OLD_DSP_ROUTINES
409 s
->hits
[0] = s
->hits
[1] = s
->hits
[2] = s
->hits
[3] = s
->hits
[4] = 0;
411 for (i
= 0; i
< 6; i
++) {
412 goertzel_init (&s
->tone_out
[i
], mf_tones
[i
], 160);
413 #ifdef OLD_DSP_ROUTINES
414 goertzel_init (&s
->tone_out2nd
[i
], mf_tones
[i
] * 2.0, 160);
418 s
->current_digits
= 0;
419 memset(&s
->digits
, 0, sizeof(s
->digits
));
420 s
->current_sample
= 0;
421 s
->detected_digits
= 0;
427 static int dtmf_detect (dtmf_detect_state_t
*s
, int16_t amp
[], int samples
,
428 int digitmode
, int *writeback
, int faxdetect
)
434 #ifdef OLD_DSP_ROUTINES
435 float fax_energy_2nd
;
437 #endif /* FAX_DETECT */
449 for (sample
= 0; sample
< samples
; sample
= limit
) {
450 /* 102 is optimised to meet the DTMF specs. */
451 if ((samples
- sample
) >= (102 - s
->current_sample
))
452 limit
= sample
+ (102 - s
->current_sample
);
455 #if defined(USE_3DNOW)
456 _dtmf_goertzel_update (s
->row_out
, amp
+ sample
, limit
- sample
);
457 _dtmf_goertzel_update (s
->col_out
, amp
+ sample
, limit
- sample
);
458 #ifdef OLD_DSP_ROUTINES
459 _dtmf_goertzel_update (s
->row_out2nd
, amp
+ sample
, limit2
- sample
);
460 _dtmf_goertzel_update (s
->col_out2nd
, amp
+ sample
, limit2
- sample
);
462 /* XXX Need to fax detect for 3dnow too XXX */
463 #warning "Fax Support Broken"
465 /* The following unrolled loop takes only 35% (rough estimate) of the
466 time of a rolled loop on the machine on which it was developed */
467 for (j
=sample
;j
<limit
;j
++) {
469 s
->energy
+= famp
*famp
;
470 /* With GCC 2.95, the following unrolled code seems to take about 35%
471 (rough estimate) as long as a neat little 0-3 loop */
472 v1
= s
->row_out
[0].v2
;
473 s
->row_out
[0].v2
= s
->row_out
[0].v3
;
474 s
->row_out
[0].v3
= s
->row_out
[0].fac
*s
->row_out
[0].v2
- v1
+ famp
;
475 v1
= s
->col_out
[0].v2
;
476 s
->col_out
[0].v2
= s
->col_out
[0].v3
;
477 s
->col_out
[0].v3
= s
->col_out
[0].fac
*s
->col_out
[0].v2
- v1
+ famp
;
478 v1
= s
->row_out
[1].v2
;
479 s
->row_out
[1].v2
= s
->row_out
[1].v3
;
480 s
->row_out
[1].v3
= s
->row_out
[1].fac
*s
->row_out
[1].v2
- v1
+ famp
;
481 v1
= s
->col_out
[1].v2
;
482 s
->col_out
[1].v2
= s
->col_out
[1].v3
;
483 s
->col_out
[1].v3
= s
->col_out
[1].fac
*s
->col_out
[1].v2
- v1
+ famp
;
484 v1
= s
->row_out
[2].v2
;
485 s
->row_out
[2].v2
= s
->row_out
[2].v3
;
486 s
->row_out
[2].v3
= s
->row_out
[2].fac
*s
->row_out
[2].v2
- v1
+ famp
;
487 v1
= s
->col_out
[2].v2
;
488 s
->col_out
[2].v2
= s
->col_out
[2].v3
;
489 s
->col_out
[2].v3
= s
->col_out
[2].fac
*s
->col_out
[2].v2
- v1
+ famp
;
490 v1
= s
->row_out
[3].v2
;
491 s
->row_out
[3].v2
= s
->row_out
[3].v3
;
492 s
->row_out
[3].v3
= s
->row_out
[3].fac
*s
->row_out
[3].v2
- v1
+ famp
;
493 v1
= s
->col_out
[3].v2
;
494 s
->col_out
[3].v2
= s
->col_out
[3].v3
;
495 s
->col_out
[3].v3
= s
->col_out
[3].fac
*s
->col_out
[3].v2
- v1
+ famp
;
497 /* Update fax tone */
499 s
->fax_tone
.v2
= s
->fax_tone
.v3
;
500 s
->fax_tone
.v3
= s
->fax_tone
.fac
*s
->fax_tone
.v2
- v1
+ famp
;
501 #endif /* FAX_DETECT */
502 #ifdef OLD_DSP_ROUTINES
503 v1
= s
->col_out2nd
[0].v2
;
504 s
->col_out2nd
[0].v2
= s
->col_out2nd
[0].v3
;
505 s
->col_out2nd
[0].v3
= s
->col_out2nd
[0].fac
*s
->col_out2nd
[0].v2
- v1
+ famp
;
506 v1
= s
->row_out2nd
[0].v2
;
507 s
->row_out2nd
[0].v2
= s
->row_out2nd
[0].v3
;
508 s
->row_out2nd
[0].v3
= s
->row_out2nd
[0].fac
*s
->row_out2nd
[0].v2
- v1
+ famp
;
509 v1
= s
->col_out2nd
[1].v2
;
510 s
->col_out2nd
[1].v2
= s
->col_out2nd
[1].v3
;
511 s
->col_out2nd
[1].v3
= s
->col_out2nd
[1].fac
*s
->col_out2nd
[1].v2
- v1
+ famp
;
512 v1
= s
->row_out2nd
[1].v2
;
513 s
->row_out2nd
[1].v2
= s
->row_out2nd
[1].v3
;
514 s
->row_out2nd
[1].v3
= s
->row_out2nd
[1].fac
*s
->row_out2nd
[1].v2
- v1
+ famp
;
515 v1
= s
->col_out2nd
[2].v2
;
516 s
->col_out2nd
[2].v2
= s
->col_out2nd
[2].v3
;
517 s
->col_out2nd
[2].v3
= s
->col_out2nd
[2].fac
*s
->col_out2nd
[2].v2
- v1
+ famp
;
518 v1
= s
->row_out2nd
[2].v2
;
519 s
->row_out2nd
[2].v2
= s
->row_out2nd
[2].v3
;
520 s
->row_out2nd
[2].v3
= s
->row_out2nd
[2].fac
*s
->row_out2nd
[2].v2
- v1
+ famp
;
521 v1
= s
->col_out2nd
[3].v2
;
522 s
->col_out2nd
[3].v2
= s
->col_out2nd
[3].v3
;
523 s
->col_out2nd
[3].v3
= s
->col_out2nd
[3].fac
*s
->col_out2nd
[3].v2
- v1
+ famp
;
524 v1
= s
->row_out2nd
[3].v2
;
525 s
->row_out2nd
[3].v2
= s
->row_out2nd
[3].v3
;
526 s
->row_out2nd
[3].v3
= s
->row_out2nd
[3].fac
*s
->row_out2nd
[3].v2
- v1
+ famp
;
528 /* Update fax tone */
530 s
->fax_tone2nd
.v2
= s
->fax_tone2nd
.v3
;
531 s
->fax_tone2nd
.v3
= s
->fax_tone2nd
.fac
*s
->fax_tone2nd
.v2
- v1
+ famp
;
532 #endif /* FAX_DETECT */
536 s
->current_sample
+= (limit
- sample
);
537 if (s
->current_sample
< 102) {
538 if (hit
&& !((digitmode
& DSP_DIGITMODE_NOQUELCH
))) {
539 /* If we had a hit last time, go ahead and clear this out since likely it
540 will be another hit */
541 for (i
=sample
;i
<limit
;i
++)
548 /* Detect the fax energy, too */
549 fax_energy
= goertzel_result(&s
->fax_tone
);
551 /* We are at the end of a DTMF detection block */
552 /* Find the peak row and the peak column */
553 row_energy
[0] = goertzel_result (&s
->row_out
[0]);
554 col_energy
[0] = goertzel_result (&s
->col_out
[0]);
556 for (best_row
= best_col
= 0, i
= 1; i
< 4; i
++) {
557 row_energy
[i
] = goertzel_result (&s
->row_out
[i
]);
558 if (row_energy
[i
] > row_energy
[best_row
])
560 col_energy
[i
] = goertzel_result (&s
->col_out
[i
]);
561 if (col_energy
[i
] > col_energy
[best_col
])
565 /* Basic signal level test and the twist test */
566 if (row_energy
[best_row
] >= DTMF_THRESHOLD
&&
567 col_energy
[best_col
] >= DTMF_THRESHOLD
&&
568 col_energy
[best_col
] < row_energy
[best_row
]*DTMF_REVERSE_TWIST
&&
569 col_energy
[best_col
]*DTMF_NORMAL_TWIST
> row_energy
[best_row
]) {
570 /* Relative peak test */
571 for (i
= 0; i
< 4; i
++) {
572 if ((i
!= best_col
&&
573 col_energy
[i
]*DTMF_RELATIVE_PEAK_COL
> col_energy
[best_col
]) ||
575 && row_energy
[i
]*DTMF_RELATIVE_PEAK_ROW
> row_energy
[best_row
])) {
579 #ifdef OLD_DSP_ROUTINES
580 /* ... and second harmonic test */
582 (row_energy
[best_row
] + col_energy
[best_col
]) > 42.0*s
->energy
&&
583 goertzel_result(&s
->col_out2nd
[best_col
])*DTMF_2ND_HARMONIC_COL
< col_energy
[best_col
]
584 && goertzel_result(&s
->row_out2nd
[best_row
])*DTMF_2ND_HARMONIC_ROW
< row_energy
[best_row
]) {
586 /* ... and fraction of total energy test */
588 (row_energy
[best_row
] + col_energy
[best_col
]) > DTMF_TO_TOTAL_ENERGY
*s
->energy
) {
591 hit
= dtmf_positions
[(best_row
<< 2) + best_col
];
592 if (!(digitmode
& DSP_DIGITMODE_NOQUELCH
)) {
593 /* Zero out frame data if this is part DTMF */
594 for (i
=sample
;i
<limit
;i
++)
598 #ifdef OLD_DSP_ROUTINES
599 /* Look for two successive similar results */
600 /* The logic in the next test is:
601 We need two successive identical clean detects, with
602 something different preceeding it. This can work with
603 back to back differing digits. More importantly, it
604 can work with nasty phones that give a very wobbly start
606 if (hit
== s
->hit3
&& s
->hit3
!= s
->hit2
) {
608 s
->digit_hits
[(best_row
<< 2) + best_col
]++;
609 s
->detected_digits
++;
610 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
611 s
->digits
[s
->current_digits
++] = hit
;
612 s
->digits
[s
->current_digits
] = '\0';
621 #ifndef OLD_DSP_ROUTINES
622 /* Look for two successive similar results */
623 /* The logic in the next test is:
624 We need two successive identical clean detects, with
625 something different preceeding it. This can work with
626 back to back differing digits. More importantly, it
627 can work with nasty phones that give a very wobbly start
629 if (hit
== s
->lasthit
&& hit
!= s
->mhit
) {
631 s
->digit_hits
[(best_row
<< 2) + best_col
]++;
632 s
->detected_digits
++;
633 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
634 s
->digits
[s
->current_digits
++] = hit
;
635 s
->digits
[s
->current_digits
] = '\0';
645 if (!hit
&& (fax_energy
>= FAX_THRESHOLD
) &&
646 (fax_energy
>= DTMF_TO_TOTAL_ENERGY
*s
->energy
) &&
649 printf("Fax energy/Second Harmonic: %f\n", fax_energy
);
651 /* XXX Probably need better checking than just this the energy XXX */
655 if (s
->fax_hits
> 5) {
658 s
->detected_digits
++;
659 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
660 s
->digits
[s
->current_digits
++] = hit
;
661 s
->digits
[s
->current_digits
] = '\0';
668 #endif /* FAX_DETECT */
669 #ifdef OLD_DSP_ROUTINES
676 /* Reinitialise the detector for the next block */
677 for (i
= 0; i
< 4; i
++) {
678 goertzel_reset(&s
->row_out
[i
]);
679 goertzel_reset(&s
->col_out
[i
]);
680 #ifdef OLD_DSP_ROUTINES
681 goertzel_reset(&s
->row_out2nd
[i
]);
682 goertzel_reset(&s
->col_out2nd
[i
]);
686 goertzel_reset (&s
->fax_tone
);
687 #ifdef OLD_DSP_ROUTINES
688 goertzel_reset (&s
->fax_tone2nd
);
692 s
->current_sample
= 0;
694 #ifdef OLD_DSP_ROUTINES
695 if ((!s
->mhit
) || (s
->mhit
!= hit
)) {
701 return (s
->mhit
); /* return the debounced hit */
705 /* MF goertzel size */
706 #ifdef OLD_DSP_ROUTINES
712 static int mf_detect (mf_detect_state_t
*s
, int16_t amp
[],
713 int samples
, int digitmode
, int *writeback
)
715 #ifdef OLD_DSP_ROUTINES
716 float tone_energy
[6];
735 for (sample
= 0; sample
< samples
; sample
= limit
) {
736 /* 80 is optimised to meet the MF specs. */
737 if ((samples
- sample
) >= (MF_GSIZE
- s
->current_sample
))
738 limit
= sample
+ (MF_GSIZE
- s
->current_sample
);
741 #if defined(USE_3DNOW)
742 _dtmf_goertzel_update (s
->row_out
, amp
+ sample
, limit
- sample
);
743 _dtmf_goertzel_update (s
->col_out
, amp
+ sample
, limit
- sample
);
744 #ifdef OLD_DSP_ROUTINES
745 _dtmf_goertzel_update (s
->row_out2nd
, amp
+ sample
, limit2
- sample
);
746 _dtmf_goertzel_update (s
->col_out2nd
, amp
+ sample
, limit2
- sample
);
748 /* XXX Need to fax detect for 3dnow too XXX */
749 #warning "Fax Support Broken"
751 /* The following unrolled loop takes only 35% (rough estimate) of the
752 time of a rolled loop on the machine on which it was developed */
753 for (j
= sample
; j
< limit
; j
++) {
755 #ifdef OLD_DSP_ROUTINES
756 s
->energy
+= famp
*famp
;
758 /* With GCC 2.95, the following unrolled code seems to take about 35%
759 (rough estimate) as long as a neat little 0-3 loop */
760 v1
= s
->tone_out
[0].v2
;
761 s
->tone_out
[0].v2
= s
->tone_out
[0].v3
;
762 s
->tone_out
[0].v3
= s
->tone_out
[0].fac
*s
->tone_out
[0].v2
- v1
+ famp
;
763 v1
= s
->tone_out
[1].v2
;
764 s
->tone_out
[1].v2
= s
->tone_out
[1].v3
;
765 s
->tone_out
[1].v3
= s
->tone_out
[1].fac
*s
->tone_out
[1].v2
- v1
+ famp
;
766 v1
= s
->tone_out
[2].v2
;
767 s
->tone_out
[2].v2
= s
->tone_out
[2].v3
;
768 s
->tone_out
[2].v3
= s
->tone_out
[2].fac
*s
->tone_out
[2].v2
- v1
+ famp
;
769 v1
= s
->tone_out
[3].v2
;
770 s
->tone_out
[3].v2
= s
->tone_out
[3].v3
;
771 s
->tone_out
[3].v3
= s
->tone_out
[3].fac
*s
->tone_out
[3].v2
- v1
+ famp
;
772 v1
= s
->tone_out
[4].v2
;
773 s
->tone_out
[4].v2
= s
->tone_out
[4].v3
;
774 s
->tone_out
[4].v3
= s
->tone_out
[4].fac
*s
->tone_out
[4].v2
- v1
+ famp
;
775 v1
= s
->tone_out
[5].v2
;
776 s
->tone_out
[5].v2
= s
->tone_out
[5].v3
;
777 s
->tone_out
[5].v3
= s
->tone_out
[5].fac
*s
->tone_out
[5].v2
- v1
+ famp
;
778 #ifdef OLD_DSP_ROUTINES
779 v1
= s
->tone_out2nd
[0].v2
;
780 s
->tone_out2nd
[0].v2
= s
->tone_out2nd
[0].v3
;
781 s
->tone_out2nd
[0].v3
= s
->tone_out2nd
[0].fac
*s
->tone_out2nd
[0].v2
- v1
+ famp
;
782 v1
= s
->tone_out2nd
[1].v2
;
783 s
->tone_out2nd
[1].v2
= s
->tone_out2nd
[1].v3
;
784 s
->tone_out2nd
[1].v3
= s
->tone_out2nd
[1].fac
*s
->tone_out2nd
[1].v2
- v1
+ famp
;
785 v1
= s
->tone_out2nd
[2].v2
;
786 s
->tone_out2nd
[2].v2
= s
->tone_out2nd
[2].v3
;
787 s
->tone_out2nd
[2].v3
= s
->tone_out2nd
[2].fac
*s
->tone_out2nd
[2].v2
- v1
+ famp
;
788 v1
= s
->tone_out2nd
[3].v2
;
789 s
->tone_out2nd
[3].v2
= s
->tone_out2nd
[3].v3
;
790 s
->tone_out2nd
[3].v3
= s
->tone_out2nd
[3].fac
*s
->tone_out2nd
[3].v2
- v1
+ famp
;
791 v1
= s
->tone_out2nd
[4].v2
;
792 s
->tone_out2nd
[4].v2
= s
->tone_out2nd
[4].v3
;
793 s
->tone_out2nd
[4].v3
= s
->tone_out2nd
[4].fac
*s
->tone_out2nd
[2].v2
- v1
+ famp
;
794 v1
= s
->tone_out2nd
[3].v2
;
795 s
->tone_out2nd
[5].v2
= s
->tone_out2nd
[6].v3
;
796 s
->tone_out2nd
[5].v3
= s
->tone_out2nd
[6].fac
*s
->tone_out2nd
[3].v2
- v1
+ famp
;
800 s
->current_sample
+= (limit
- sample
);
801 if (s
->current_sample
< MF_GSIZE
) {
802 if (hit
&& !((digitmode
& DSP_DIGITMODE_NOQUELCH
))) {
803 /* If we had a hit last time, go ahead and clear this out since likely it
804 will be another hit */
805 for (i
=sample
;i
<limit
;i
++)
811 #ifdef OLD_DSP_ROUTINES
812 /* We're at the end of an MF detection block. Go ahead and calculate
815 tone_energy
[i
] = goertzel_result(&s
->tone_out
[i
]);
819 max
= tone_energy
[0];
821 if (tone_energy
[i
] > max
) {
822 max
= tone_energy
[i
];
827 /* Find 2nd highest */
829 max
= tone_energy
[0];
832 max
= tone_energy
[1];
837 if (i
== best1
) continue;
838 if (tone_energy
[i
] > max
) {
839 max
= tone_energy
[i
];
848 /* Check for relative energies */
854 if (tone_energy
[best1
] < tone_energy
[i
] * MF_RELATIVE_PEAK
) {
858 if (tone_energy
[best2
] < tone_energy
[i
] * MF_RELATIVE_PEAK
) {
865 /* Check for 2nd harmonic */
866 if (goertzel_result(&s
->tone_out2nd
[best1
]) * MF_2ND_HARMONIC
> tone_energy
[best1
])
868 else if (goertzel_result(&s
->tone_out2nd
[best2
]) * MF_2ND_HARMONIC
> tone_energy
[best2
])
872 hit
= mf_hit
[best1
][best2
];
873 if (!(digitmode
& DSP_DIGITMODE_NOQUELCH
)) {
874 /* Zero out frame data if this is part DTMF */
875 for (i
=sample
;i
<limit
;i
++)
879 /* Look for two consecutive clean hits */
880 if ((hit
== s
->hit3
) && (s
->hit3
!= s
->hit2
)) {
882 s
->detected_digits
++;
883 if (s
->current_digits
< MAX_DTMF_DIGITS
- 2) {
884 s
->digits
[s
->current_digits
++] = hit
;
885 s
->digits
[s
->current_digits
] = '\0';
895 /* Reinitialise the detector for the next block */
896 for (i
= 0; i
< 6; i
++) {
897 goertzel_reset(&s
->tone_out
[i
]);
898 goertzel_reset(&s
->tone_out2nd
[i
]);
901 s
->current_sample
= 0;
904 /* We're at the end of an MF detection block. */
905 /* Find the two highest energies. The spec says to look for
906 two tones and two tones only. Taking this literally -ie
907 only two tones pass the minimum threshold - doesn't work
908 well. The sinc function mess, due to rectangular windowing
909 ensure that! Find the two highest energies and ensure they
910 are considerably stronger than any of the others. */
911 energy
[0] = goertzel_result(&s
->tone_out
[0]);
912 energy
[1] = goertzel_result(&s
->tone_out
[1]);
913 if (energy
[0] > energy
[1]) {
922 energy
[i
] = goertzel_result(&s
->tone_out
[i
]);
923 if (energy
[i
] >= energy
[best
]) {
926 } else if (energy
[i
] >= energy
[second_best
]) {
930 /* Basic signal level and twist tests */
932 if (energy
[best
] >= BELL_MF_THRESHOLD
&& energy
[second_best
] >= BELL_MF_THRESHOLD
933 && energy
[best
] < energy
[second_best
]*BELL_MF_TWIST
934 && energy
[best
]*BELL_MF_TWIST
> energy
[second_best
]) {
935 /* Relative peak test */
938 if (i
!= best
&& i
!= second_best
) {
939 if (energy
[i
]*BELL_MF_RELATIVE_PEAK
>= energy
[second_best
]) {
940 /* The best two are not clearly the best */
948 /* Get the values into ascending order */
949 if (second_best
< best
) {
954 best
= best
*5 + second_best
- 1;
955 hit
= bell_mf_positions
[best
];
956 /* Look for two successive similar results */
957 /* The logic in the next test is:
958 For KP we need 4 successive identical clean detects, with
959 two blocks of something different preceeding it. For anything
960 else we need two successive identical clean detects, with
961 two blocks of something different preceeding it. */
962 if (hit
== s
->hits
[4] && hit
== s
->hits
[3] &&
963 ((hit
!= '*' && hit
!= s
->hits
[2] && hit
!= s
->hits
[1])||
964 (hit
== '*' && hit
== s
->hits
[2] && hit
!= s
->hits
[1] &&
965 hit
!= s
->hits
[0]))) {
966 s
->detected_digits
++;
967 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
968 s
->digits
[s
->current_digits
++] = hit
;
969 s
->digits
[s
->current_digits
] = '\0';
977 s
->hits
[0] = s
->hits
[1];
978 s
->hits
[1] = s
->hits
[2];
979 s
->hits
[2] = s
->hits
[3];
980 s
->hits
[3] = s
->hits
[4];
982 /* Reinitialise the detector for the next block */
983 for (i
= 0; i
< 6; i
++)
984 goertzel_reset(&s
->tone_out
[i
]);
985 s
->current_sample
= 0;
988 if ((!s
->mhit
) || (s
->mhit
!= hit
)) {
995 static int __ast_dsp_digitdetect(struct ast_dsp
*dsp
, short *s
, int len
, int *writeback
)
999 if (dsp
->digitmode
& DSP_DIGITMODE_MF
)
1000 res
= mf_detect(&dsp
->td
.mf
, s
, len
, dsp
->digitmode
& DSP_DIGITMODE_RELAXDTMF
, writeback
);
1002 res
= dtmf_detect(&dsp
->td
.dtmf
, s
, len
, dsp
->digitmode
& DSP_DIGITMODE_RELAXDTMF
, writeback
, dsp
->features
& DSP_FEATURE_FAX_DETECT
);
1006 int ast_dsp_digitdetect(struct ast_dsp
*dsp
, struct ast_frame
*inf
)
1012 if (inf
->frametype
!= AST_FRAME_VOICE
) {
1013 ast_log(LOG_WARNING
, "Can't check call progress of non-voice frames\n");
1016 if (inf
->subclass
!= AST_FORMAT_SLINEAR
) {
1017 ast_log(LOG_WARNING
, "Can only check call progress in signed-linear frames\n");
1021 len
= inf
->datalen
/ 2;
1022 return __ast_dsp_digitdetect(dsp
, s
, len
, &ign
);
1025 static inline int pair_there(float p1
, float p2
, float i1
, float i2
, float e
)
1027 /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
1028 /* Make sure absolute levels are high enough */
1029 if ((p1
< TONE_MIN_THRESH
) || (p2
< TONE_MIN_THRESH
))
1031 /* Amplify ignored stuff */
1035 /* Check first tone */
1036 if ((p1
< i1
) || (p1
< i2
) || (p1
< e
))
1039 if ((p2
< i1
) || (p2
< i2
) || (p2
< e
))
1041 /* Guess it's there... */
1045 int ast_dsp_getdigits (struct ast_dsp
*dsp
, char *buf
, int max
)
1047 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1048 if (max
> dsp
->td
.mf
.current_digits
)
1049 max
= dsp
->td
.mf
.current_digits
;
1051 memcpy(buf
, dsp
->td
.mf
.digits
, max
);
1052 memmove(dsp
->td
.mf
.digits
, dsp
->td
.mf
.digits
+ max
, dsp
->td
.mf
.current_digits
- max
);
1053 dsp
->td
.mf
.current_digits
-= max
;
1058 if (max
> dsp
->td
.dtmf
.current_digits
)
1059 max
= dsp
->td
.dtmf
.current_digits
;
1061 memcpy (buf
, dsp
->td
.dtmf
.digits
, max
);
1062 memmove (dsp
->td
.dtmf
.digits
, dsp
->td
.dtmf
.digits
+ max
, dsp
->td
.dtmf
.current_digits
- max
);
1063 dsp
->td
.dtmf
.current_digits
-= max
;
1070 static int __ast_dsp_call_progress(struct ast_dsp
*dsp
, short *s
, int len
)
1075 int newstate
= DSP_TONE_STATE_SILENCE
;
1078 /* Take the lesser of the number of samples we need and what we have */
1080 if (pass
> dsp
->gsamp_size
- dsp
->gsamps
)
1081 pass
= dsp
->gsamp_size
- dsp
->gsamps
;
1082 for (x
=0;x
<pass
;x
++) {
1083 for (y
=0;y
<dsp
->freqcount
;y
++)
1084 goertzel_sample(&dsp
->freqs
[y
], s
[x
]);
1085 dsp
->genergy
+= s
[x
] * s
[x
];
1088 dsp
->gsamps
+= pass
;
1090 if (dsp
->gsamps
== dsp
->gsamp_size
) {
1093 hz
[y
] = goertzel_result(&dsp
->freqs
[y
]);
1095 printf("\n350: 425: 440: 480: 620: 950: 1400: 1800: Energy: \n");
1096 printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n",
1097 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
);
1099 switch(dsp
->progmode
) {
1101 if (pair_there(hz
[HZ_480
], hz
[HZ_620
], hz
[HZ_350
], hz
[HZ_440
], dsp
->genergy
)) {
1102 newstate
= DSP_TONE_STATE_BUSY
;
1103 } else if (pair_there(hz
[HZ_440
], hz
[HZ_480
], hz
[HZ_350
], hz
[HZ_620
], dsp
->genergy
)) {
1104 newstate
= DSP_TONE_STATE_RINGING
;
1105 } else if (pair_there(hz
[HZ_350
], hz
[HZ_440
], hz
[HZ_480
], hz
[HZ_620
], dsp
->genergy
)) {
1106 newstate
= DSP_TONE_STATE_DIALTONE
;
1107 } else if (hz
[HZ_950
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1108 newstate
= DSP_TONE_STATE_SPECIAL1
;
1109 } else if (hz
[HZ_1400
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1110 if (dsp
->tstate
== DSP_TONE_STATE_SPECIAL1
)
1111 newstate
= DSP_TONE_STATE_SPECIAL2
;
1112 } else if (hz
[HZ_1800
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1113 if (dsp
->tstate
== DSP_TONE_STATE_SPECIAL2
)
1114 newstate
= DSP_TONE_STATE_SPECIAL3
;
1115 } else if (dsp
->genergy
> TONE_MIN_THRESH
* TONE_THRESH
) {
1116 newstate
= DSP_TONE_STATE_TALKING
;
1118 newstate
= DSP_TONE_STATE_SILENCE
;
1121 if (hz
[HZ_425
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1122 newstate
= DSP_TONE_STATE_RINGING
;
1123 } else if (dsp
->genergy
> TONE_MIN_THRESH
* TONE_THRESH
) {
1124 newstate
= DSP_TONE_STATE_TALKING
;
1126 newstate
= DSP_TONE_STATE_SILENCE
;
1129 if (hz
[HZ_400
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1130 newstate
= DSP_TONE_STATE_HUNGUP
;
1134 ast_log(LOG_WARNING
, "Can't process in unknown prog mode '%d'\n", dsp
->progmode
);
1136 if (newstate
== dsp
->tstate
) {
1138 if (dsp
->ringtimeout
)
1140 switch (dsp
->tstate
) {
1141 case DSP_TONE_STATE_RINGING
:
1142 if ((dsp
->features
& DSP_PROGRESS_RINGING
) &&
1143 (dsp
->tcount
==THRESH_RING
)) {
1144 res
= AST_CONTROL_RINGING
;
1145 dsp
->ringtimeout
= 1;
1148 case DSP_TONE_STATE_BUSY
:
1149 if ((dsp
->features
& DSP_PROGRESS_BUSY
) &&
1150 (dsp
->tcount
==THRESH_BUSY
)) {
1151 res
= AST_CONTROL_BUSY
;
1152 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1155 case DSP_TONE_STATE_TALKING
:
1156 if ((dsp
->features
& DSP_PROGRESS_TALK
) &&
1157 (dsp
->tcount
==THRESH_TALK
)) {
1158 res
= AST_CONTROL_ANSWER
;
1159 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1162 case DSP_TONE_STATE_SPECIAL3
:
1163 if ((dsp
->features
& DSP_PROGRESS_CONGESTION
) &&
1164 (dsp
->tcount
==THRESH_CONGESTION
)) {
1165 res
= AST_CONTROL_CONGESTION
;
1166 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1169 case DSP_TONE_STATE_HUNGUP
:
1170 if ((dsp
->features
& DSP_FEATURE_CALL_PROGRESS
) &&
1171 (dsp
->tcount
==THRESH_HANGUP
)) {
1172 res
= AST_CONTROL_HANGUP
;
1173 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1177 if (dsp
->ringtimeout
==THRESH_RING2ANSWER
) {
1179 ast_log(LOG_NOTICE
, "Consider call as answered because of timeout after last ring\n");
1181 res
= AST_CONTROL_ANSWER
;
1182 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1186 ast_log(LOG_NOTICE
, "Stop state %d with duration %d\n", dsp
->tstate
, dsp
->tcount
);
1187 ast_log(LOG_NOTICE
, "Start state %d\n", newstate
);
1189 dsp
->tstate
= newstate
;
1193 /* Reset goertzel */
1195 dsp
->freqs
[x
].v2
= dsp
->freqs
[x
].v3
= 0.0;
1202 printf("Returning %d\n", res
);
1207 int ast_dsp_call_progress(struct ast_dsp
*dsp
, struct ast_frame
*inf
)
1209 if (inf
->frametype
!= AST_FRAME_VOICE
) {
1210 ast_log(LOG_WARNING
, "Can't check call progress of non-voice frames\n");
1213 if (inf
->subclass
!= AST_FORMAT_SLINEAR
) {
1214 ast_log(LOG_WARNING
, "Can only check call progress in signed-linear frames\n");
1217 return __ast_dsp_call_progress(dsp
, inf
->data
, inf
->datalen
/ 2);
1220 static int __ast_dsp_silence(struct ast_dsp
*dsp
, short *s
, int len
, int *totalsilence
)
1229 for (x
=0;x
<len
; x
++)
1232 if (accum
< dsp
->threshold
) {
1234 dsp
->totalsilence
+= len
/8;
1235 if (dsp
->totalnoise
) {
1236 /* Move and save history */
1237 memmove(dsp
->historicnoise
+ DSP_HISTORY
- dsp
->busycount
, dsp
->historicnoise
+ DSP_HISTORY
- dsp
->busycount
+1, dsp
->busycount
*sizeof(dsp
->historicnoise
[0]));
1238 dsp
->historicnoise
[DSP_HISTORY
- 1] = dsp
->totalnoise
;
1239 /* we don't want to check for busydetect that frequently */
1244 dsp
->totalnoise
= 0;
1248 dsp
->totalnoise
+= len
/8;
1249 if (dsp
->totalsilence
) {
1250 int silence1
= dsp
->historicsilence
[DSP_HISTORY
- 1];
1251 int silence2
= dsp
->historicsilence
[DSP_HISTORY
- 2];
1252 /* Move and save history */
1253 memmove(dsp
->historicsilence
+ DSP_HISTORY
- dsp
->busycount
, dsp
->historicsilence
+ DSP_HISTORY
- dsp
->busycount
+ 1, dsp
->busycount
*sizeof(dsp
->historicsilence
[0]));
1254 dsp
->historicsilence
[DSP_HISTORY
- 1] = dsp
->totalsilence
;
1255 /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
1256 if (silence1
< silence2
) {
1257 if (silence1
+ silence1
*BUSY_PERCENT
/100 >= silence2
)
1262 if (silence1
- silence1
*BUSY_PERCENT
/100 <= silence2
)
1268 dsp
->totalsilence
= 0;
1271 *totalsilence
= dsp
->totalsilence
;
1275 #ifdef BUSYDETECT_MARTIN
1276 int ast_dsp_busydetect(struct ast_dsp
*dsp
)
1279 #ifndef BUSYDETECT_TONEONLY
1280 int avgsilence
= 0, hitsilence
= 0;
1282 int avgtone
= 0, hittone
= 0;
1283 if (!dsp
->busymaybe
)
1285 for (x
=DSP_HISTORY
- dsp
->busycount
;x
<DSP_HISTORY
;x
++) {
1286 #ifndef BUSYDETECT_TONEONLY
1287 avgsilence
+= dsp
->historicsilence
[x
];
1289 avgtone
+= dsp
->historicnoise
[x
];
1291 #ifndef BUSYDETECT_TONEONLY
1292 avgsilence
/= dsp
->busycount
;
1294 avgtone
/= dsp
->busycount
;
1295 for (x
=DSP_HISTORY
- dsp
->busycount
;x
<DSP_HISTORY
;x
++) {
1296 #ifndef BUSYDETECT_TONEONLY
1297 if (avgsilence
> dsp
->historicsilence
[x
]) {
1298 if (avgsilence
- (avgsilence
*BUSY_PERCENT
/100) <= dsp
->historicsilence
[x
])
1301 if (avgsilence
+ (avgsilence
*BUSY_PERCENT
/100) >= dsp
->historicsilence
[x
])
1305 if (avgtone
> dsp
->historicnoise
[x
]) {
1306 if (avgtone
- (avgtone
*BUSY_PERCENT
/100) <= dsp
->historicnoise
[x
])
1309 if (avgtone
+ (avgtone
*BUSY_PERCENT
/100) >= dsp
->historicnoise
[x
])
1313 #ifndef BUSYDETECT_TONEONLY
1314 if ((hittone
>= dsp
->busycount
- 1) && (hitsilence
>= dsp
->busycount
- 1) &&
1315 (avgtone
>= BUSY_MIN
&& avgtone
<= BUSY_MAX
) &&
1316 (avgsilence
>= BUSY_MIN
&& avgsilence
<= BUSY_MAX
)) {
1318 if ((hittone
>= dsp
->busycount
- 1) && (avgtone
>= BUSY_MIN
&& avgtone
<= BUSY_MAX
)) {
1320 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1321 #ifdef BUSYDETECT_TONEONLY
1322 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
1324 if (avgtone
> avgsilence
) {
1325 if (avgtone
- avgtone
*BUSY_PERCENT
/100 <= avgsilence
)
1328 if (avgtone
+ avgtone
*BUSY_PERCENT
/100 >= avgsilence
)
1335 /* If we know the expected busy tone length, check we are in the range */
1336 if (res
&& (dsp
->busy_tonelength
> 0)) {
1337 if (abs(avgtone
- dsp
->busy_tonelength
) > (dsp
->busy_tonelength
*BUSY_PAT_PERCENT
/100)) {
1339 ast_log(LOG_NOTICE
, "busy detector: avgtone of %d not close enough to desired %d\n",
1340 avgtone
, dsp
->busy_tonelength
);
1345 #ifndef BUSYDETECT_TONEONLY
1346 /* If we know the expected busy tone silent-period length, check we are in the range */
1347 if (res
&& (dsp
->busy_quietlength
> 0)) {
1348 if (abs(avgsilence
- dsp
->busy_quietlength
) > (dsp
->busy_quietlength
*BUSY_PAT_PERCENT
/100)) {
1350 ast_log(LOG_NOTICE
, "busy detector: avgsilence of %d not close enough to desired %d\n",
1351 avgsilence
, dsp
->busy_quietlength
);
1357 #ifndef BUSYDETECT_TONEONLY
1360 ast_log(LOG_DEBUG
, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone
, avgsilence
);
1368 int ast_dsp_busydetect(struct ast_dsp
*dsp
)
1375 if (dsp
->busy_hits
> 5);
1378 if (dsp
->busymaybe
) {
1380 printf("Maybe busy!\n");
1385 for (x
=DSP_HISTORY
- dsp
->busycount
;x
<DSP_HISTORY
;x
++) {
1387 printf("Silence: %d, Noise: %d\n", dsp
->historicsilence
[x
], dsp
->historicnoise
[x
]);
1389 if (dsp
->historicsilence
[x
] < min
)
1390 min
= dsp
->historicsilence
[x
];
1391 if (dsp
->historicnoise
[x
] < min
)
1392 min
= dsp
->historicnoise
[x
];
1393 if (dsp
->historicsilence
[x
] > max
)
1394 max
= dsp
->historicsilence
[x
];
1395 if (dsp
->historicnoise
[x
] > max
)
1396 max
= dsp
->historicnoise
[x
];
1398 if ((max
- min
< BUSY_THRESHOLD
) && (max
< BUSY_MAX
) && (min
> BUSY_MIN
)) {
1405 printf("Min: %d, max: %d\n", min
, max
);
1412 int ast_dsp_silence(struct ast_dsp
*dsp
, struct ast_frame
*f
, int *totalsilence
)
1417 if (f
->frametype
!= AST_FRAME_VOICE
) {
1418 ast_log(LOG_WARNING
, "Can't calculate silence on a non-voice frame\n");
1421 if (f
->subclass
!= AST_FORMAT_SLINEAR
) {
1422 ast_log(LOG_WARNING
, "Can only calculate silence on signed-linear frames :(\n");
1427 return __ast_dsp_silence(dsp
, s
, len
, totalsilence
);
1430 struct ast_frame
*ast_dsp_process(struct ast_channel
*chan
, struct ast_dsp
*dsp
, struct ast_frame
*af
)
1437 unsigned char *odata
;
1441 #define FIX_INF(inf) do { \
1443 switch(inf->subclass) { \
1444 case AST_FORMAT_SLINEAR: \
1446 case AST_FORMAT_ULAW: \
1447 for (x=0;x<len;x++) \
1448 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
1450 case AST_FORMAT_ALAW: \
1451 for (x=0;x<len;x++) \
1452 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
1460 if (af
->frametype
!= AST_FRAME_VOICE
)
1464 /* Make sure we have short data */
1465 switch(af
->subclass
) {
1466 case AST_FORMAT_SLINEAR
:
1467 shortdata
= af
->data
;
1468 len
= af
->datalen
/ 2;
1470 case AST_FORMAT_ULAW
:
1471 shortdata
= alloca(af
->datalen
* 2);
1472 for (x
= 0;x
< len
; x
++)
1473 shortdata
[x
] = AST_MULAW(odata
[x
]);
1475 case AST_FORMAT_ALAW
:
1476 shortdata
= alloca(af
->datalen
* 2);
1477 for (x
= 0; x
< len
; x
++)
1478 shortdata
[x
] = AST_ALAW(odata
[x
]);
1481 ast_log(LOG_WARNING
, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af
->subclass
));
1484 silence
= __ast_dsp_silence(dsp
, shortdata
, len
, NULL
);
1485 if ((dsp
->features
& DSP_FEATURE_SILENCE_SUPPRESS
) && silence
) {
1486 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1487 dsp
->f
.frametype
= AST_FRAME_NULL
;
1491 if ((dsp
->features
& DSP_FEATURE_BUSY_DETECT
) && ast_dsp_busydetect(dsp
)) {
1492 chan
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1493 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1494 dsp
->f
.frametype
= AST_FRAME_CONTROL
;
1495 dsp
->f
.subclass
= AST_CONTROL_BUSY
;
1497 ast_log(LOG_DEBUG
, "Requesting Hangup because the busy tone was detected on channel %s\n", chan
->name
);
1500 if ((dsp
->features
& DSP_FEATURE_DTMF_DETECT
)) {
1501 digit
= __ast_dsp_digitdetect(dsp
, shortdata
, len
, &writeback
);
1504 printf("Performing digit detection returned %d, digitmode is %d\n", digit
, dsp
->digitmode
);
1506 if (dsp
->digitmode
& (DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
)) {
1507 if (!dsp
->thinkdigit
) {
1509 /* Looks like we might have something.
1510 * Request a conference mute for the moment */
1511 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1512 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1513 dsp
->f
.subclass
= 'm';
1514 dsp
->thinkdigit
= 'x';
1517 ast_queue_frame(chan
, af
);
1523 /* Thought we saw one last time. Pretty sure we really have now */
1524 if ((dsp
->thinkdigit
!= 'x') && (dsp
->thinkdigit
!= digit
)) {
1525 /* If we found a digit, and we're changing digits, go
1526 ahead and send this one, but DON'T stop confmute because
1527 we're detecting something else, too... */
1528 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1529 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1530 dsp
->f
.subclass
= dsp
->thinkdigit
;
1533 ast_queue_frame(chan
, af
);
1536 dsp
->thinkdigit
= digit
;
1537 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1538 dsp
->f
.frametype
= AST_FRAME_DTMF_BEGIN
;
1539 dsp
->f
.subclass
= dsp
->thinkdigit
;
1542 ast_queue_frame(chan
, af
);
1547 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1548 if (dsp
->thinkdigit
!= 'x') {
1549 /* If we found a digit, send it now */
1550 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1551 dsp
->f
.subclass
= dsp
->thinkdigit
;
1552 dsp
->thinkdigit
= 0;
1554 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1555 dsp
->f
.subclass
= 'u';
1556 dsp
->thinkdigit
= 0;
1560 ast_queue_frame(chan
, af
);
1565 } else if (!digit
) {
1566 /* Only check when there is *not* a hit... */
1567 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1568 if (dsp
->td
.mf
.current_digits
) {
1569 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1570 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1571 dsp
->f
.subclass
= dsp
->td
.mf
.digits
[0];
1572 memmove(dsp
->td
.mf
.digits
, dsp
->td
.mf
.digits
+ 1, dsp
->td
.mf
.current_digits
);
1573 dsp
->td
.mf
.current_digits
--;
1576 ast_queue_frame(chan
, af
);
1581 if (dsp
->td
.dtmf
.current_digits
) {
1582 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1583 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1584 dsp
->f
.subclass
= dsp
->td
.dtmf
.digits
[0];
1585 memmove(dsp
->td
.dtmf
.digits
, dsp
->td
.dtmf
.digits
+ 1, dsp
->td
.dtmf
.current_digits
);
1586 dsp
->td
.dtmf
.current_digits
--;
1589 ast_queue_frame(chan
, af
);
1596 if ((dsp
->features
& DSP_FEATURE_CALL_PROGRESS
)) {
1597 res
= __ast_dsp_call_progress(dsp
, shortdata
, len
);
1600 case AST_CONTROL_ANSWER
:
1601 case AST_CONTROL_BUSY
:
1602 case AST_CONTROL_RINGING
:
1603 case AST_CONTROL_CONGESTION
:
1604 case AST_CONTROL_HANGUP
:
1605 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1606 dsp
->f
.frametype
= AST_FRAME_CONTROL
;
1607 dsp
->f
.subclass
= res
;
1608 dsp
->f
.src
= "dsp_progress";
1610 ast_queue_frame(chan
, &dsp
->f
);
1613 ast_log(LOG_WARNING
, "Don't know how to represent call progress message %d\n", res
);
1621 static void ast_dsp_prog_reset(struct ast_dsp
*dsp
)
1626 dsp
->gsamp_size
= modes
[dsp
->progmode
].size
;
1628 for (x
=0;x
<sizeof(modes
[dsp
->progmode
].freqs
) / sizeof(modes
[dsp
->progmode
].freqs
[0]);x
++) {
1629 if (modes
[dsp
->progmode
].freqs
[x
]) {
1630 goertzel_init(&dsp
->freqs
[x
], (float)modes
[dsp
->progmode
].freqs
[x
], dsp
->gsamp_size
);
1634 dsp
->freqcount
= max
;
1635 dsp
->ringtimeout
= 0;
1638 struct ast_dsp
*ast_dsp_new(void)
1640 struct ast_dsp
*dsp
;
1642 if ((dsp
= ast_calloc(1, sizeof(*dsp
)))) {
1643 dsp
->threshold
= DEFAULT_THRESHOLD
;
1644 dsp
->features
= DSP_FEATURE_SILENCE_SUPPRESS
;
1645 dsp
->busycount
= DSP_HISTORY
;
1646 /* Initialize DTMF detector */
1647 ast_dtmf_detect_init(&dsp
->td
.dtmf
);
1648 /* Initialize initial DSP progress detect parameters */
1649 ast_dsp_prog_reset(dsp
);
1654 void ast_dsp_set_features(struct ast_dsp
*dsp
, int features
)
1656 dsp
->features
= features
;
1659 void ast_dsp_free(struct ast_dsp
*dsp
)
1664 void ast_dsp_set_threshold(struct ast_dsp
*dsp
, int threshold
)
1666 dsp
->threshold
= threshold
;
1669 void ast_dsp_set_busy_count(struct ast_dsp
*dsp
, int cadences
)
1673 if (cadences
> DSP_HISTORY
)
1674 cadences
= DSP_HISTORY
;
1675 dsp
->busycount
= cadences
;
1678 void ast_dsp_set_busy_pattern(struct ast_dsp
*dsp
, int tonelength
, int quietlength
)
1680 dsp
->busy_tonelength
= tonelength
;
1681 dsp
->busy_quietlength
= quietlength
;
1682 ast_log(LOG_DEBUG
, "dsp busy pattern set to %d,%d\n", tonelength
, quietlength
);
1685 void ast_dsp_digitreset(struct ast_dsp
*dsp
)
1689 dsp
->thinkdigit
= 0;
1690 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1691 memset(dsp
->td
.mf
.digits
, 0, sizeof(dsp
->td
.mf
.digits
));
1692 dsp
->td
.mf
.current_digits
= 0;
1693 /* Reinitialise the detector for the next block */
1694 for (i
= 0; i
< 6; i
++) {
1695 goertzel_reset(&dsp
->td
.mf
.tone_out
[i
]);
1696 #ifdef OLD_DSP_ROUTINES
1697 goertzel_reset(&dsp
->td
.mf
.tone_out2nd
[i
]);
1700 #ifdef OLD_DSP_ROUTINES
1701 dsp
->td
.mf
.energy
= 0.0;
1702 dsp
->td
.mf
.hit1
= dsp
->td
.mf
.hit2
= dsp
->td
.mf
.hit3
= dsp
->td
.mf
.hit4
= dsp
->td
.mf
.mhit
= 0;
1704 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;
1706 dsp
->td
.mf
.current_sample
= 0;
1708 memset(dsp
->td
.dtmf
.digits
, 0, sizeof(dsp
->td
.dtmf
.digits
));
1709 dsp
->td
.dtmf
.current_digits
= 0;
1710 /* Reinitialise the detector for the next block */
1711 for (i
= 0; i
< 4; i
++) {
1712 goertzel_reset(&dsp
->td
.dtmf
.row_out
[i
]);
1713 goertzel_reset(&dsp
->td
.dtmf
.col_out
[i
]);
1714 #ifdef OLD_DSP_ROUTINES
1715 goertzel_reset(&dsp
->td
.dtmf
.row_out2nd
[i
]);
1716 goertzel_reset(&dsp
->td
.dtmf
.col_out2nd
[i
]);
1720 goertzel_reset (&dsp
->td
.dtmf
.fax_tone
);
1722 #ifdef OLD_DSP_ROUTINES
1724 goertzel_reset (&dsp
->td
.dtmf
.fax_tone2nd
);
1726 dsp
->td
.dtmf
.hit1
= dsp
->td
.dtmf
.hit2
= dsp
->td
.dtmf
.hit3
= dsp
->td
.dtmf
.hit4
= dsp
->td
.dtmf
.mhit
= 0;
1728 dsp
->td
.dtmf
.lasthit
= dsp
->td
.dtmf
.mhit
= 0;
1730 dsp
->td
.dtmf
.energy
= 0.0;
1731 dsp
->td
.dtmf
.current_sample
= 0;
1735 void ast_dsp_reset(struct ast_dsp
*dsp
)
1739 dsp
->totalsilence
= 0;
1742 dsp
->freqs
[x
].v2
= dsp
->freqs
[x
].v3
= 0.0;
1743 memset(dsp
->historicsilence
, 0, sizeof(dsp
->historicsilence
));
1744 memset(dsp
->historicnoise
, 0, sizeof(dsp
->historicnoise
));
1745 dsp
->ringtimeout
= 0;
1748 int ast_dsp_digitmode(struct ast_dsp
*dsp
, int digitmode
)
1753 old
= dsp
->digitmode
& (DSP_DIGITMODE_DTMF
| DSP_DIGITMODE_MF
| DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
);
1754 new = digitmode
& (DSP_DIGITMODE_DTMF
| DSP_DIGITMODE_MF
| DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
);
1756 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1757 if (new & DSP_DIGITMODE_MF
)
1758 ast_mf_detect_init(&dsp
->td
.mf
);
1760 ast_dtmf_detect_init(&dsp
->td
.dtmf
);
1762 dsp
->digitmode
= digitmode
;
1766 int ast_dsp_set_call_progress_zone(struct ast_dsp
*dsp
, char *zone
)
1770 for (x
=0;x
<sizeof(aliases
) / sizeof(aliases
[0]);x
++) {
1771 if (!strcasecmp(aliases
[x
].name
, zone
)) {
1772 dsp
->progmode
= aliases
[x
].mode
;
1773 ast_dsp_prog_reset(dsp
);
1780 int ast_dsp_get_tstate(struct ast_dsp
*dsp
)
1785 int ast_dsp_get_tcount(struct ast_dsp
*dsp
)