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
;
1489 ast_set_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
);
1492 if ((dsp
->features
& DSP_FEATURE_BUSY_DETECT
) && ast_dsp_busydetect(dsp
)) {
1493 chan
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1494 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1495 dsp
->f
.frametype
= AST_FRAME_CONTROL
;
1496 dsp
->f
.subclass
= AST_CONTROL_BUSY
;
1498 ast_set_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
);
1501 if ((dsp
->features
& DSP_FEATURE_DTMF_DETECT
)) {
1502 digit
= __ast_dsp_digitdetect(dsp
, shortdata
, len
, &writeback
);
1505 printf("Performing digit detection returned %d, digitmode is %d\n", digit
, dsp
->digitmode
);
1507 if (dsp
->digitmode
& (DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
)) {
1508 if (!dsp
->thinkdigit
) {
1510 /* Looks like we might have something.
1511 * Request a conference mute for the moment */
1512 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1513 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1514 dsp
->f
.subclass
= 'm';
1515 dsp
->thinkdigit
= 'x';
1518 ast_queue_frame(chan
, af
);
1520 ast_set_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
);
1525 /* Thought we saw one last time. Pretty sure we really have now */
1526 if ((dsp
->thinkdigit
!= 'x') && (dsp
->thinkdigit
!= digit
)) {
1527 /* If we found a digit, and we're changing digits, go
1528 ahead and send this one, but DON'T stop confmute because
1529 we're detecting something else, too... */
1530 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1531 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1532 dsp
->f
.subclass
= dsp
->thinkdigit
;
1535 ast_queue_frame(chan
, af
);
1538 dsp
->thinkdigit
= digit
;
1539 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1540 dsp
->f
.frametype
= AST_FRAME_DTMF_BEGIN
;
1541 dsp
->f
.subclass
= dsp
->thinkdigit
;
1544 ast_queue_frame(chan
, af
);
1547 ast_set_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
);
1550 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1551 if (dsp
->thinkdigit
!= 'x') {
1552 /* If we found a digit, send it now */
1553 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1554 dsp
->f
.subclass
= dsp
->thinkdigit
;
1555 dsp
->thinkdigit
= 0;
1557 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1558 dsp
->f
.subclass
= 'u';
1559 dsp
->thinkdigit
= 0;
1563 ast_queue_frame(chan
, af
);
1565 ast_set_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
);
1569 } else if (!digit
) {
1570 /* Only check when there is *not* a hit... */
1571 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1572 if (dsp
->td
.mf
.current_digits
) {
1573 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1574 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1575 dsp
->f
.subclass
= dsp
->td
.mf
.digits
[0];
1576 memmove(dsp
->td
.mf
.digits
, dsp
->td
.mf
.digits
+ 1, dsp
->td
.mf
.current_digits
);
1577 dsp
->td
.mf
.current_digits
--;
1580 ast_queue_frame(chan
, af
);
1582 ast_set_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
);
1586 if (dsp
->td
.dtmf
.current_digits
) {
1587 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1588 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1589 dsp
->f
.subclass
= dsp
->td
.dtmf
.digits
[0];
1590 memmove(dsp
->td
.dtmf
.digits
, dsp
->td
.dtmf
.digits
+ 1, dsp
->td
.dtmf
.current_digits
);
1591 dsp
->td
.dtmf
.current_digits
--;
1594 ast_queue_frame(chan
, af
);
1596 ast_set_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
);
1602 if ((dsp
->features
& DSP_FEATURE_CALL_PROGRESS
)) {
1603 res
= __ast_dsp_call_progress(dsp
, shortdata
, len
);
1606 case AST_CONTROL_ANSWER
:
1607 case AST_CONTROL_BUSY
:
1608 case AST_CONTROL_RINGING
:
1609 case AST_CONTROL_CONGESTION
:
1610 case AST_CONTROL_HANGUP
:
1611 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1612 dsp
->f
.frametype
= AST_FRAME_CONTROL
;
1613 dsp
->f
.subclass
= res
;
1614 dsp
->f
.src
= "dsp_progress";
1616 ast_queue_frame(chan
, &dsp
->f
);
1619 ast_log(LOG_WARNING
, "Don't know how to represent call progress message %d\n", res
);
1627 static void ast_dsp_prog_reset(struct ast_dsp
*dsp
)
1632 dsp
->gsamp_size
= modes
[dsp
->progmode
].size
;
1634 for (x
=0;x
<sizeof(modes
[dsp
->progmode
].freqs
) / sizeof(modes
[dsp
->progmode
].freqs
[0]);x
++) {
1635 if (modes
[dsp
->progmode
].freqs
[x
]) {
1636 goertzel_init(&dsp
->freqs
[x
], (float)modes
[dsp
->progmode
].freqs
[x
], dsp
->gsamp_size
);
1640 dsp
->freqcount
= max
;
1641 dsp
->ringtimeout
= 0;
1644 struct ast_dsp
*ast_dsp_new(void)
1646 struct ast_dsp
*dsp
;
1648 if ((dsp
= ast_calloc(1, sizeof(*dsp
)))) {
1649 dsp
->threshold
= DEFAULT_THRESHOLD
;
1650 dsp
->features
= DSP_FEATURE_SILENCE_SUPPRESS
;
1651 dsp
->busycount
= DSP_HISTORY
;
1652 /* Initialize DTMF detector */
1653 ast_dtmf_detect_init(&dsp
->td
.dtmf
);
1654 /* Initialize initial DSP progress detect parameters */
1655 ast_dsp_prog_reset(dsp
);
1660 void ast_dsp_set_features(struct ast_dsp
*dsp
, int features
)
1662 dsp
->features
= features
;
1665 void ast_dsp_free(struct ast_dsp
*dsp
)
1667 if (ast_test_flag(&dsp
->f
, AST_FRFLAG_FROM_DSP
)) {
1668 /* If this flag is still set, that means that the dsp's destruction
1669 * been torn down, while we still have a frame out there being used.
1670 * When ast_frfree() gets called on that frame, this ast_trans_pvt
1671 * will get destroyed, too. */
1673 /* Set the magic hint that this has been requested to be destroyed. */
1674 dsp
->freqcount
= -1;
1681 void ast_dsp_set_threshold(struct ast_dsp
*dsp
, int threshold
)
1683 dsp
->threshold
= threshold
;
1686 void ast_dsp_set_busy_count(struct ast_dsp
*dsp
, int cadences
)
1690 if (cadences
> DSP_HISTORY
)
1691 cadences
= DSP_HISTORY
;
1692 dsp
->busycount
= cadences
;
1695 void ast_dsp_set_busy_pattern(struct ast_dsp
*dsp
, int tonelength
, int quietlength
)
1697 dsp
->busy_tonelength
= tonelength
;
1698 dsp
->busy_quietlength
= quietlength
;
1699 ast_log(LOG_DEBUG
, "dsp busy pattern set to %d,%d\n", tonelength
, quietlength
);
1702 void ast_dsp_digitreset(struct ast_dsp
*dsp
)
1706 dsp
->thinkdigit
= 0;
1707 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1708 memset(dsp
->td
.mf
.digits
, 0, sizeof(dsp
->td
.mf
.digits
));
1709 dsp
->td
.mf
.current_digits
= 0;
1710 /* Reinitialise the detector for the next block */
1711 for (i
= 0; i
< 6; i
++) {
1712 goertzel_reset(&dsp
->td
.mf
.tone_out
[i
]);
1713 #ifdef OLD_DSP_ROUTINES
1714 goertzel_reset(&dsp
->td
.mf
.tone_out2nd
[i
]);
1717 #ifdef OLD_DSP_ROUTINES
1718 dsp
->td
.mf
.energy
= 0.0;
1719 dsp
->td
.mf
.hit1
= dsp
->td
.mf
.hit2
= dsp
->td
.mf
.hit3
= dsp
->td
.mf
.hit4
= dsp
->td
.mf
.mhit
= 0;
1721 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;
1723 dsp
->td
.mf
.current_sample
= 0;
1725 memset(dsp
->td
.dtmf
.digits
, 0, sizeof(dsp
->td
.dtmf
.digits
));
1726 dsp
->td
.dtmf
.current_digits
= 0;
1727 /* Reinitialise the detector for the next block */
1728 for (i
= 0; i
< 4; i
++) {
1729 goertzel_reset(&dsp
->td
.dtmf
.row_out
[i
]);
1730 goertzel_reset(&dsp
->td
.dtmf
.col_out
[i
]);
1731 #ifdef OLD_DSP_ROUTINES
1732 goertzel_reset(&dsp
->td
.dtmf
.row_out2nd
[i
]);
1733 goertzel_reset(&dsp
->td
.dtmf
.col_out2nd
[i
]);
1737 goertzel_reset (&dsp
->td
.dtmf
.fax_tone
);
1739 #ifdef OLD_DSP_ROUTINES
1741 goertzel_reset (&dsp
->td
.dtmf
.fax_tone2nd
);
1743 dsp
->td
.dtmf
.hit1
= dsp
->td
.dtmf
.hit2
= dsp
->td
.dtmf
.hit3
= dsp
->td
.dtmf
.hit4
= dsp
->td
.dtmf
.mhit
= 0;
1745 dsp
->td
.dtmf
.lasthit
= dsp
->td
.dtmf
.mhit
= 0;
1747 dsp
->td
.dtmf
.energy
= 0.0;
1748 dsp
->td
.dtmf
.current_sample
= 0;
1752 void ast_dsp_reset(struct ast_dsp
*dsp
)
1756 dsp
->totalsilence
= 0;
1759 dsp
->freqs
[x
].v2
= dsp
->freqs
[x
].v3
= 0.0;
1760 memset(dsp
->historicsilence
, 0, sizeof(dsp
->historicsilence
));
1761 memset(dsp
->historicnoise
, 0, sizeof(dsp
->historicnoise
));
1762 dsp
->ringtimeout
= 0;
1765 int ast_dsp_digitmode(struct ast_dsp
*dsp
, int digitmode
)
1770 old
= dsp
->digitmode
& (DSP_DIGITMODE_DTMF
| DSP_DIGITMODE_MF
| DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
);
1771 new = digitmode
& (DSP_DIGITMODE_DTMF
| DSP_DIGITMODE_MF
| DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
);
1773 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1774 if (new & DSP_DIGITMODE_MF
)
1775 ast_mf_detect_init(&dsp
->td
.mf
);
1777 ast_dtmf_detect_init(&dsp
->td
.dtmf
);
1779 dsp
->digitmode
= digitmode
;
1783 int ast_dsp_set_call_progress_zone(struct ast_dsp
*dsp
, char *zone
)
1787 for (x
=0;x
<sizeof(aliases
) / sizeof(aliases
[0]);x
++) {
1788 if (!strcasecmp(aliases
[x
].name
, zone
)) {
1789 dsp
->progmode
= aliases
[x
].mode
;
1790 ast_dsp_prog_reset(dsp
);
1797 int ast_dsp_get_tstate(struct ast_dsp
*dsp
)
1802 int ast_dsp_get_tcount(struct ast_dsp
*dsp
)
1807 void ast_dsp_frame_freed(struct ast_frame
*fr
)
1809 struct ast_dsp
*dsp
;
1811 ast_clear_flag(fr
, AST_FRFLAG_FROM_DSP
);
1813 dsp
= (struct ast_dsp
*) (((char *) fr
) - offsetof(struct ast_dsp
, f
));
1815 if (dsp
->freqcount
!= -1)