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 */
159 #define DTMF_NORMAL_TWIST 6.3 /* 8dB */
161 #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5) /* 4dB normal */
163 #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5) /* 4dB normal */
165 #define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
166 #define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
167 #define DTMF_2ND_HARMONIC_ROW ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5) /* 4dB normal */
168 #define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
169 #define DTMF_TO_TOTAL_ENERGY 42.0
171 #ifdef OLD_DSP_ROUTINES
172 #define MF_THRESHOLD 8.0e7
173 #define MF_NORMAL_TWIST 5.3 /* 8dB */
174 #define MF_REVERSE_TWIST 4.0 /* was 2.5 */
175 #define MF_RELATIVE_PEAK 5.3 /* 8dB */
176 #define MF_2ND_HARMONIC 1.7 /* was 2.5 */
178 #define BELL_MF_THRESHOLD 1.6e9
179 #define BELL_MF_TWIST 4.0 /* 6dB */
180 #define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */
183 #if !defined(BUSYDETECT_MARTIN) && !defined(BUSYDETECT) && !defined(BUSYDETECT_TONEONLY) && !defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
184 #define BUSYDETECT_MARTIN
191 #ifndef OLD_DSP_ROUTINES
198 goertzel_state_t row_out
[4];
199 goertzel_state_t col_out
[4];
201 goertzel_state_t fax_tone
;
203 #ifdef OLD_DSP_ROUTINES
204 goertzel_state_t row_out2nd
[4];
205 goertzel_state_t col_out2nd
[4];
207 goertzel_state_t fax_tone2nd
;
220 char digits
[MAX_DTMF_DIGITS
+ 1];
229 } dtmf_detect_state_t
;
233 goertzel_state_t tone_out
[6];
235 #ifdef OLD_DSP_ROUTINES
240 goertzel_state_t tone_out2nd
[6];
247 char digits
[MAX_DTMF_DIGITS
+ 1];
257 static float dtmf_row
[] =
259 697.0, 770.0, 852.0, 941.0
261 static float dtmf_col
[] =
263 1209.0, 1336.0, 1477.0, 1633.0
266 static float mf_tones
[] =
268 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
272 static float fax_freq
= 1100.0;
275 static char dtmf_positions
[] = "123A" "456B" "789C" "*0#D";
277 #ifdef OLD_DSP_ROUTINES
278 static char mf_hit
[6][6] = {
279 /* 700 + */ { 0, '1', '2', '4', '7', 'C' },
280 /* 900 + */ { '1', 0, '3', '5', '8', 'A' },
281 /* 1100 + */ { '2', '3', 0, '6', '9', '*' },
282 /* 1300 + */ { '4', '5', '6', 0, '0', 'B' },
283 /* 1500 + */ { '7', '8', '9', '0', 0, '#' },
284 /* 1700 + */ { 'C', 'A', '*', 'B', '#', 0 },
287 static char bell_mf_positions
[] = "1247C-358A--69*---0B----#";
290 static inline void goertzel_sample(goertzel_state_t
*s
, short sample
)
293 float fsamp
= sample
;
297 s
->v3
= s
->fac
* s
->v2
- v1
+ fsamp
;
300 static inline void goertzel_update(goertzel_state_t
*s
, short *samps
, int count
)
304 for (i
=0;i
<count
;i
++)
305 goertzel_sample(s
, samps
[i
]);
309 static inline float goertzel_result(goertzel_state_t
*s
)
311 return s
->v3
* s
->v3
+ s
->v2
* s
->v2
- s
->v2
* s
->v3
* s
->fac
;
314 static inline void goertzel_init(goertzel_state_t
*s
, float freq
, int samples
)
317 s
->fac
= 2.0 * cos(2.0 * M_PI
* (freq
/ 8000.0));
318 #ifndef OLD_DSP_ROUTINES
319 s
->samples
= samples
;
323 static inline void goertzel_reset(goertzel_state_t
*s
)
338 int busy_quietlength
;
339 int historicnoise
[DSP_HISTORY
];
340 int historicsilence
[DSP_HISTORY
];
341 goertzel_state_t freqs
[7];
344 enum gsamp_size gsamp_size
;
345 enum prog_mode progmode
;
352 dtmf_detect_state_t dtmf
;
353 mf_detect_state_t mf
;
357 static void ast_dtmf_detect_init (dtmf_detect_state_t
*s
)
361 #ifdef OLD_DSP_ROUTINES
368 s
->hits
[0] = s
->hits
[1] = s
->hits
[2] = 0;
370 for (i
= 0; i
< 4; i
++) {
371 goertzel_init (&s
->row_out
[i
], dtmf_row
[i
], 102);
372 goertzel_init (&s
->col_out
[i
], dtmf_col
[i
], 102);
373 #ifdef OLD_DSP_ROUTINES
374 goertzel_init (&s
->row_out2nd
[i
], dtmf_row
[i
] * 2.0, 102);
375 goertzel_init (&s
->col_out2nd
[i
], dtmf_col
[i
] * 2.0, 102);
380 /* Same for the fax dector */
381 goertzel_init (&s
->fax_tone
, fax_freq
, 102);
383 #ifdef OLD_DSP_ROUTINES
384 /* Same for the fax dector 2nd harmonic */
385 goertzel_init (&s
->fax_tone2nd
, fax_freq
* 2.0, 102);
387 #endif /* FAX_DETECT */
388 s
->current_sample
= 0;
389 s
->detected_digits
= 0;
390 s
->current_digits
= 0;
391 memset(&s
->digits
, 0, sizeof(s
->digits
));
396 static void ast_mf_detect_init (mf_detect_state_t
*s
)
399 #ifdef OLD_DSP_ROUTINES
403 s
->hits
[0] = s
->hits
[1] = s
->hits
[2] = s
->hits
[3] = s
->hits
[4] = 0;
405 for (i
= 0; i
< 6; i
++) {
406 goertzel_init (&s
->tone_out
[i
], mf_tones
[i
], 160);
407 #ifdef OLD_DSP_ROUTINES
408 goertzel_init (&s
->tone_out2nd
[i
], mf_tones
[i
] * 2.0, 160);
412 s
->current_digits
= 0;
413 memset(&s
->digits
, 0, sizeof(s
->digits
));
414 s
->current_sample
= 0;
415 s
->detected_digits
= 0;
421 static int dtmf_detect (dtmf_detect_state_t
*s
, int16_t amp
[], int samples
,
422 int digitmode
, int *writeback
, int faxdetect
)
428 #ifdef OLD_DSP_ROUTINES
429 float fax_energy_2nd
;
431 #endif /* FAX_DETECT */
443 for (sample
= 0; sample
< samples
; sample
= limit
) {
444 /* 102 is optimised to meet the DTMF specs. */
445 if ((samples
- sample
) >= (102 - s
->current_sample
))
446 limit
= sample
+ (102 - s
->current_sample
);
449 #if defined(USE_3DNOW)
450 _dtmf_goertzel_update (s
->row_out
, amp
+ sample
, limit
- sample
);
451 _dtmf_goertzel_update (s
->col_out
, amp
+ sample
, limit
- sample
);
452 #ifdef OLD_DSP_ROUTINES
453 _dtmf_goertzel_update (s
->row_out2nd
, amp
+ sample
, limit2
- sample
);
454 _dtmf_goertzel_update (s
->col_out2nd
, amp
+ sample
, limit2
- sample
);
456 /* XXX Need to fax detect for 3dnow too XXX */
457 #warning "Fax Support Broken"
459 /* The following unrolled loop takes only 35% (rough estimate) of the
460 time of a rolled loop on the machine on which it was developed */
461 for (j
=sample
;j
<limit
;j
++) {
463 s
->energy
+= famp
*famp
;
464 /* With GCC 2.95, the following unrolled code seems to take about 35%
465 (rough estimate) as long as a neat little 0-3 loop */
466 v1
= s
->row_out
[0].v2
;
467 s
->row_out
[0].v2
= s
->row_out
[0].v3
;
468 s
->row_out
[0].v3
= s
->row_out
[0].fac
*s
->row_out
[0].v2
- v1
+ famp
;
469 v1
= s
->col_out
[0].v2
;
470 s
->col_out
[0].v2
= s
->col_out
[0].v3
;
471 s
->col_out
[0].v3
= s
->col_out
[0].fac
*s
->col_out
[0].v2
- v1
+ famp
;
472 v1
= s
->row_out
[1].v2
;
473 s
->row_out
[1].v2
= s
->row_out
[1].v3
;
474 s
->row_out
[1].v3
= s
->row_out
[1].fac
*s
->row_out
[1].v2
- v1
+ famp
;
475 v1
= s
->col_out
[1].v2
;
476 s
->col_out
[1].v2
= s
->col_out
[1].v3
;
477 s
->col_out
[1].v3
= s
->col_out
[1].fac
*s
->col_out
[1].v2
- v1
+ famp
;
478 v1
= s
->row_out
[2].v2
;
479 s
->row_out
[2].v2
= s
->row_out
[2].v3
;
480 s
->row_out
[2].v3
= s
->row_out
[2].fac
*s
->row_out
[2].v2
- v1
+ famp
;
481 v1
= s
->col_out
[2].v2
;
482 s
->col_out
[2].v2
= s
->col_out
[2].v3
;
483 s
->col_out
[2].v3
= s
->col_out
[2].fac
*s
->col_out
[2].v2
- v1
+ famp
;
484 v1
= s
->row_out
[3].v2
;
485 s
->row_out
[3].v2
= s
->row_out
[3].v3
;
486 s
->row_out
[3].v3
= s
->row_out
[3].fac
*s
->row_out
[3].v2
- v1
+ famp
;
487 v1
= s
->col_out
[3].v2
;
488 s
->col_out
[3].v2
= s
->col_out
[3].v3
;
489 s
->col_out
[3].v3
= s
->col_out
[3].fac
*s
->col_out
[3].v2
- v1
+ famp
;
491 /* Update fax tone */
493 s
->fax_tone
.v2
= s
->fax_tone
.v3
;
494 s
->fax_tone
.v3
= s
->fax_tone
.fac
*s
->fax_tone
.v2
- v1
+ famp
;
495 #endif /* FAX_DETECT */
496 #ifdef OLD_DSP_ROUTINES
497 v1
= s
->col_out2nd
[0].v2
;
498 s
->col_out2nd
[0].v2
= s
->col_out2nd
[0].v3
;
499 s
->col_out2nd
[0].v3
= s
->col_out2nd
[0].fac
*s
->col_out2nd
[0].v2
- v1
+ famp
;
500 v1
= s
->row_out2nd
[0].v2
;
501 s
->row_out2nd
[0].v2
= s
->row_out2nd
[0].v3
;
502 s
->row_out2nd
[0].v3
= s
->row_out2nd
[0].fac
*s
->row_out2nd
[0].v2
- v1
+ famp
;
503 v1
= s
->col_out2nd
[1].v2
;
504 s
->col_out2nd
[1].v2
= s
->col_out2nd
[1].v3
;
505 s
->col_out2nd
[1].v3
= s
->col_out2nd
[1].fac
*s
->col_out2nd
[1].v2
- v1
+ famp
;
506 v1
= s
->row_out2nd
[1].v2
;
507 s
->row_out2nd
[1].v2
= s
->row_out2nd
[1].v3
;
508 s
->row_out2nd
[1].v3
= s
->row_out2nd
[1].fac
*s
->row_out2nd
[1].v2
- v1
+ famp
;
509 v1
= s
->col_out2nd
[2].v2
;
510 s
->col_out2nd
[2].v2
= s
->col_out2nd
[2].v3
;
511 s
->col_out2nd
[2].v3
= s
->col_out2nd
[2].fac
*s
->col_out2nd
[2].v2
- v1
+ famp
;
512 v1
= s
->row_out2nd
[2].v2
;
513 s
->row_out2nd
[2].v2
= s
->row_out2nd
[2].v3
;
514 s
->row_out2nd
[2].v3
= s
->row_out2nd
[2].fac
*s
->row_out2nd
[2].v2
- v1
+ famp
;
515 v1
= s
->col_out2nd
[3].v2
;
516 s
->col_out2nd
[3].v2
= s
->col_out2nd
[3].v3
;
517 s
->col_out2nd
[3].v3
= s
->col_out2nd
[3].fac
*s
->col_out2nd
[3].v2
- v1
+ famp
;
518 v1
= s
->row_out2nd
[3].v2
;
519 s
->row_out2nd
[3].v2
= s
->row_out2nd
[3].v3
;
520 s
->row_out2nd
[3].v3
= s
->row_out2nd
[3].fac
*s
->row_out2nd
[3].v2
- v1
+ famp
;
522 /* Update fax tone */
524 s
->fax_tone2nd
.v2
= s
->fax_tone2nd
.v3
;
525 s
->fax_tone2nd
.v3
= s
->fax_tone2nd
.fac
*s
->fax_tone2nd
.v2
- v1
+ famp
;
526 #endif /* FAX_DETECT */
530 s
->current_sample
+= (limit
- sample
);
531 if (s
->current_sample
< 102) {
532 if (hit
&& !((digitmode
& DSP_DIGITMODE_NOQUELCH
))) {
533 /* If we had a hit last time, go ahead and clear this out since likely it
534 will be another hit */
535 for (i
=sample
;i
<limit
;i
++)
542 /* Detect the fax energy, too */
543 fax_energy
= goertzel_result(&s
->fax_tone
);
545 /* We are at the end of a DTMF detection block */
546 /* Find the peak row and the peak column */
547 row_energy
[0] = goertzel_result (&s
->row_out
[0]);
548 col_energy
[0] = goertzel_result (&s
->col_out
[0]);
550 for (best_row
= best_col
= 0, i
= 1; i
< 4; i
++) {
551 row_energy
[i
] = goertzel_result (&s
->row_out
[i
]);
552 if (row_energy
[i
] > row_energy
[best_row
])
554 col_energy
[i
] = goertzel_result (&s
->col_out
[i
]);
555 if (col_energy
[i
] > col_energy
[best_col
])
559 /* Basic signal level test and the twist test */
560 if (row_energy
[best_row
] >= DTMF_THRESHOLD
&&
561 col_energy
[best_col
] >= DTMF_THRESHOLD
&&
562 col_energy
[best_col
] < row_energy
[best_row
]*DTMF_REVERSE_TWIST
&&
563 col_energy
[best_col
]*DTMF_NORMAL_TWIST
> row_energy
[best_row
]) {
564 /* Relative peak test */
565 for (i
= 0; i
< 4; i
++) {
566 if ((i
!= best_col
&&
567 col_energy
[i
]*DTMF_RELATIVE_PEAK_COL
> col_energy
[best_col
]) ||
569 && row_energy
[i
]*DTMF_RELATIVE_PEAK_ROW
> row_energy
[best_row
])) {
573 #ifdef OLD_DSP_ROUTINES
574 /* ... and second harmonic test */
576 (row_energy
[best_row
] + col_energy
[best_col
]) > 42.0*s
->energy
&&
577 goertzel_result(&s
->col_out2nd
[best_col
])*DTMF_2ND_HARMONIC_COL
< col_energy
[best_col
]
578 && goertzel_result(&s
->row_out2nd
[best_row
])*DTMF_2ND_HARMONIC_ROW
< row_energy
[best_row
]) {
580 /* ... and fraction of total energy test */
582 (row_energy
[best_row
] + col_energy
[best_col
]) > DTMF_TO_TOTAL_ENERGY
*s
->energy
) {
585 hit
= dtmf_positions
[(best_row
<< 2) + best_col
];
586 if (!(digitmode
& DSP_DIGITMODE_NOQUELCH
)) {
587 /* Zero out frame data if this is part DTMF */
588 for (i
=sample
;i
<limit
;i
++)
592 /* Look for two successive similar results */
593 /* The logic in the next test is:
594 We need two successive identical clean detects, with
595 something different preceeding it. This can work with
596 back to back differing digits. More importantly, it
597 can work with nasty phones that give a very wobbly start
599 #ifdef OLD_DSP_ROUTINES
600 if (hit
== s
->hit3
&& s
->hit3
!= s
->hit2
) {
602 s
->digit_hits
[(best_row
<< 2) + best_col
]++;
603 s
->detected_digits
++;
604 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
605 s
->digits
[s
->current_digits
++] = hit
;
606 s
->digits
[s
->current_digits
] = '\0';
612 if (hit
== s
->hits
[2] && hit
!= s
->hits
[1] && hit
!= s
->hits
[0]) {
614 s
->digit_hits
[(best_row
<< 2) + best_col
]++;
615 s
->detected_digits
++;
616 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
617 s
->digits
[s
->current_digits
++] = hit
;
618 s
->digits
[s
->current_digits
] = '\0';
627 if (!hit
&& (fax_energy
>= FAX_THRESHOLD
) &&
628 (fax_energy
>= DTMF_TO_TOTAL_ENERGY
*s
->energy
) &&
631 printf("Fax energy/Second Harmonic: %f\n", fax_energy
);
633 /* XXX Probably need better checking than just this the energy XXX */
637 if (s
->fax_hits
> 5) {
640 s
->detected_digits
++;
641 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
642 s
->digits
[s
->current_digits
++] = hit
;
643 s
->digits
[s
->current_digits
] = '\0';
650 #endif /* FAX_DETECT */
651 #ifdef OLD_DSP_ROUTINES
656 s
->hits
[0] = s
->hits
[1];
657 s
->hits
[1] = s
->hits
[2];
660 /* Reinitialise the detector for the next block */
661 for (i
= 0; i
< 4; i
++) {
662 goertzel_reset(&s
->row_out
[i
]);
663 goertzel_reset(&s
->col_out
[i
]);
664 #ifdef OLD_DSP_ROUTINES
665 goertzel_reset(&s
->row_out2nd
[i
]);
666 goertzel_reset(&s
->col_out2nd
[i
]);
670 goertzel_reset (&s
->fax_tone
);
671 #ifdef OLD_DSP_ROUTINES
672 goertzel_reset (&s
->fax_tone2nd
);
676 s
->current_sample
= 0;
678 if ((!s
->mhit
) || (s
->mhit
!= hit
)) {
685 /* MF goertzel size */
686 #ifdef OLD_DSP_ROUTINES
692 static int mf_detect (mf_detect_state_t
*s
, int16_t amp
[],
693 int samples
, int digitmode
, int *writeback
)
695 #ifdef OLD_DSP_ROUTINES
696 float tone_energy
[6];
715 for (sample
= 0; sample
< samples
; sample
= limit
) {
716 /* 80 is optimised to meet the MF specs. */
717 if ((samples
- sample
) >= (MF_GSIZE
- s
->current_sample
))
718 limit
= sample
+ (MF_GSIZE
- s
->current_sample
);
721 #if defined(USE_3DNOW)
722 _dtmf_goertzel_update (s
->row_out
, amp
+ sample
, limit
- sample
);
723 _dtmf_goertzel_update (s
->col_out
, amp
+ sample
, limit
- sample
);
724 #ifdef OLD_DSP_ROUTINES
725 _dtmf_goertzel_update (s
->row_out2nd
, amp
+ sample
, limit2
- sample
);
726 _dtmf_goertzel_update (s
->col_out2nd
, amp
+ sample
, limit2
- sample
);
728 /* XXX Need to fax detect for 3dnow too XXX */
729 #warning "Fax Support Broken"
731 /* The following unrolled loop takes only 35% (rough estimate) of the
732 time of a rolled loop on the machine on which it was developed */
733 for (j
= sample
; j
< limit
; j
++) {
735 #ifdef OLD_DSP_ROUTINES
736 s
->energy
+= famp
*famp
;
738 /* With GCC 2.95, the following unrolled code seems to take about 35%
739 (rough estimate) as long as a neat little 0-3 loop */
740 v1
= s
->tone_out
[0].v2
;
741 s
->tone_out
[0].v2
= s
->tone_out
[0].v3
;
742 s
->tone_out
[0].v3
= s
->tone_out
[0].fac
*s
->tone_out
[0].v2
- v1
+ famp
;
743 v1
= s
->tone_out
[1].v2
;
744 s
->tone_out
[1].v2
= s
->tone_out
[1].v3
;
745 s
->tone_out
[1].v3
= s
->tone_out
[1].fac
*s
->tone_out
[1].v2
- v1
+ famp
;
746 v1
= s
->tone_out
[2].v2
;
747 s
->tone_out
[2].v2
= s
->tone_out
[2].v3
;
748 s
->tone_out
[2].v3
= s
->tone_out
[2].fac
*s
->tone_out
[2].v2
- v1
+ famp
;
749 v1
= s
->tone_out
[3].v2
;
750 s
->tone_out
[3].v2
= s
->tone_out
[3].v3
;
751 s
->tone_out
[3].v3
= s
->tone_out
[3].fac
*s
->tone_out
[3].v2
- v1
+ famp
;
752 v1
= s
->tone_out
[4].v2
;
753 s
->tone_out
[4].v2
= s
->tone_out
[4].v3
;
754 s
->tone_out
[4].v3
= s
->tone_out
[4].fac
*s
->tone_out
[4].v2
- v1
+ famp
;
755 v1
= s
->tone_out
[5].v2
;
756 s
->tone_out
[5].v2
= s
->tone_out
[5].v3
;
757 s
->tone_out
[5].v3
= s
->tone_out
[5].fac
*s
->tone_out
[5].v2
- v1
+ famp
;
758 #ifdef OLD_DSP_ROUTINES
759 v1
= s
->tone_out2nd
[0].v2
;
760 s
->tone_out2nd
[0].v2
= s
->tone_out2nd
[0].v3
;
761 s
->tone_out2nd
[0].v3
= s
->tone_out2nd
[0].fac
*s
->tone_out2nd
[0].v2
- v1
+ famp
;
762 v1
= s
->tone_out2nd
[1].v2
;
763 s
->tone_out2nd
[1].v2
= s
->tone_out2nd
[1].v3
;
764 s
->tone_out2nd
[1].v3
= s
->tone_out2nd
[1].fac
*s
->tone_out2nd
[1].v2
- v1
+ famp
;
765 v1
= s
->tone_out2nd
[2].v2
;
766 s
->tone_out2nd
[2].v2
= s
->tone_out2nd
[2].v3
;
767 s
->tone_out2nd
[2].v3
= s
->tone_out2nd
[2].fac
*s
->tone_out2nd
[2].v2
- v1
+ famp
;
768 v1
= s
->tone_out2nd
[3].v2
;
769 s
->tone_out2nd
[3].v2
= s
->tone_out2nd
[3].v3
;
770 s
->tone_out2nd
[3].v3
= s
->tone_out2nd
[3].fac
*s
->tone_out2nd
[3].v2
- v1
+ famp
;
771 v1
= s
->tone_out2nd
[4].v2
;
772 s
->tone_out2nd
[4].v2
= s
->tone_out2nd
[4].v3
;
773 s
->tone_out2nd
[4].v3
= s
->tone_out2nd
[4].fac
*s
->tone_out2nd
[2].v2
- v1
+ famp
;
774 v1
= s
->tone_out2nd
[3].v2
;
775 s
->tone_out2nd
[5].v2
= s
->tone_out2nd
[6].v3
;
776 s
->tone_out2nd
[5].v3
= s
->tone_out2nd
[6].fac
*s
->tone_out2nd
[3].v2
- v1
+ famp
;
780 s
->current_sample
+= (limit
- sample
);
781 if (s
->current_sample
< MF_GSIZE
) {
782 if (hit
&& !((digitmode
& DSP_DIGITMODE_NOQUELCH
))) {
783 /* If we had a hit last time, go ahead and clear this out since likely it
784 will be another hit */
785 for (i
=sample
;i
<limit
;i
++)
791 #ifdef OLD_DSP_ROUTINES
792 /* We're at the end of an MF detection block. Go ahead and calculate
795 tone_energy
[i
] = goertzel_result(&s
->tone_out
[i
]);
799 max
= tone_energy
[0];
801 if (tone_energy
[i
] > max
) {
802 max
= tone_energy
[i
];
807 /* Find 2nd highest */
809 max
= tone_energy
[0];
812 max
= tone_energy
[1];
817 if (i
== best1
) continue;
818 if (tone_energy
[i
] > max
) {
819 max
= tone_energy
[i
];
828 /* Check for relative energies */
834 if (tone_energy
[best1
] < tone_energy
[i
] * MF_RELATIVE_PEAK
) {
838 if (tone_energy
[best2
] < tone_energy
[i
] * MF_RELATIVE_PEAK
) {
845 /* Check for 2nd harmonic */
846 if (goertzel_result(&s
->tone_out2nd
[best1
]) * MF_2ND_HARMONIC
> tone_energy
[best1
])
848 else if (goertzel_result(&s
->tone_out2nd
[best2
]) * MF_2ND_HARMONIC
> tone_energy
[best2
])
852 hit
= mf_hit
[best1
][best2
];
853 if (!(digitmode
& DSP_DIGITMODE_NOQUELCH
)) {
854 /* Zero out frame data if this is part DTMF */
855 for (i
=sample
;i
<limit
;i
++)
859 /* Look for two consecutive clean hits */
860 if ((hit
== s
->hit3
) && (s
->hit3
!= s
->hit2
)) {
862 s
->detected_digits
++;
863 if (s
->current_digits
< MAX_DTMF_DIGITS
- 2) {
864 s
->digits
[s
->current_digits
++] = hit
;
865 s
->digits
[s
->current_digits
] = '\0';
875 /* Reinitialise the detector for the next block */
876 for (i
= 0; i
< 6; i
++) {
877 goertzel_reset(&s
->tone_out
[i
]);
878 goertzel_reset(&s
->tone_out2nd
[i
]);
881 s
->current_sample
= 0;
884 /* We're at the end of an MF detection block. */
885 /* Find the two highest energies. The spec says to look for
886 two tones and two tones only. Taking this literally -ie
887 only two tones pass the minimum threshold - doesn't work
888 well. The sinc function mess, due to rectangular windowing
889 ensure that! Find the two highest energies and ensure they
890 are considerably stronger than any of the others. */
891 energy
[0] = goertzel_result(&s
->tone_out
[0]);
892 energy
[1] = goertzel_result(&s
->tone_out
[1]);
893 if (energy
[0] > energy
[1]) {
902 energy
[i
] = goertzel_result(&s
->tone_out
[i
]);
903 if (energy
[i
] >= energy
[best
]) {
906 } else if (energy
[i
] >= energy
[second_best
]) {
910 /* Basic signal level and twist tests */
912 if (energy
[best
] >= BELL_MF_THRESHOLD
&& energy
[second_best
] >= BELL_MF_THRESHOLD
913 && energy
[best
] < energy
[second_best
]*BELL_MF_TWIST
914 && energy
[best
]*BELL_MF_TWIST
> energy
[second_best
]) {
915 /* Relative peak test */
918 if (i
!= best
&& i
!= second_best
) {
919 if (energy
[i
]*BELL_MF_RELATIVE_PEAK
>= energy
[second_best
]) {
920 /* The best two are not clearly the best */
928 /* Get the values into ascending order */
929 if (second_best
< best
) {
934 best
= best
*5 + second_best
- 1;
935 hit
= bell_mf_positions
[best
];
936 /* Look for two successive similar results */
937 /* The logic in the next test is:
938 For KP we need 4 successive identical clean detects, with
939 two blocks of something different preceeding it. For anything
940 else we need two successive identical clean detects, with
941 two blocks of something different preceeding it. */
942 if (hit
== s
->hits
[4] && hit
== s
->hits
[3] &&
943 ((hit
!= '*' && hit
!= s
->hits
[2] && hit
!= s
->hits
[1])||
944 (hit
== '*' && hit
== s
->hits
[2] && hit
!= s
->hits
[1] &&
945 hit
!= s
->hits
[0]))) {
946 s
->detected_digits
++;
947 if (s
->current_digits
< MAX_DTMF_DIGITS
) {
948 s
->digits
[s
->current_digits
++] = hit
;
949 s
->digits
[s
->current_digits
] = '\0';
957 s
->hits
[0] = s
->hits
[1];
958 s
->hits
[1] = s
->hits
[2];
959 s
->hits
[2] = s
->hits
[3];
960 s
->hits
[3] = s
->hits
[4];
962 /* Reinitialise the detector for the next block */
963 for (i
= 0; i
< 6; i
++)
964 goertzel_reset(&s
->tone_out
[i
]);
965 s
->current_sample
= 0;
968 if ((!s
->mhit
) || (s
->mhit
!= hit
)) {
975 static int __ast_dsp_digitdetect(struct ast_dsp
*dsp
, short *s
, int len
, int *writeback
)
979 if (dsp
->digitmode
& DSP_DIGITMODE_MF
)
980 res
= mf_detect(&dsp
->td
.mf
, s
, len
, dsp
->digitmode
& DSP_DIGITMODE_RELAXDTMF
, writeback
);
982 res
= dtmf_detect(&dsp
->td
.dtmf
, s
, len
, dsp
->digitmode
& DSP_DIGITMODE_RELAXDTMF
, writeback
, dsp
->features
& DSP_FEATURE_FAX_DETECT
);
986 int ast_dsp_digitdetect(struct ast_dsp
*dsp
, struct ast_frame
*inf
)
992 if (inf
->frametype
!= AST_FRAME_VOICE
) {
993 ast_log(LOG_WARNING
, "Can't check call progress of non-voice frames\n");
996 if (inf
->subclass
!= AST_FORMAT_SLINEAR
) {
997 ast_log(LOG_WARNING
, "Can only check call progress in signed-linear frames\n");
1001 len
= inf
->datalen
/ 2;
1002 return __ast_dsp_digitdetect(dsp
, s
, len
, &ign
);
1005 static inline int pair_there(float p1
, float p2
, float i1
, float i2
, float e
)
1007 /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
1008 /* Make sure absolute levels are high enough */
1009 if ((p1
< TONE_MIN_THRESH
) || (p2
< TONE_MIN_THRESH
))
1011 /* Amplify ignored stuff */
1015 /* Check first tone */
1016 if ((p1
< i1
) || (p1
< i2
) || (p1
< e
))
1019 if ((p2
< i1
) || (p2
< i2
) || (p2
< e
))
1021 /* Guess it's there... */
1025 int ast_dsp_getdigits (struct ast_dsp
*dsp
, char *buf
, int max
)
1027 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1028 if (max
> dsp
->td
.mf
.current_digits
)
1029 max
= dsp
->td
.mf
.current_digits
;
1031 memcpy(buf
, dsp
->td
.mf
.digits
, max
);
1032 memmove(dsp
->td
.mf
.digits
, dsp
->td
.mf
.digits
+ max
, dsp
->td
.mf
.current_digits
- max
);
1033 dsp
->td
.mf
.current_digits
-= max
;
1038 if (max
> dsp
->td
.dtmf
.current_digits
)
1039 max
= dsp
->td
.dtmf
.current_digits
;
1041 memcpy (buf
, dsp
->td
.dtmf
.digits
, max
);
1042 memmove (dsp
->td
.dtmf
.digits
, dsp
->td
.dtmf
.digits
+ max
, dsp
->td
.dtmf
.current_digits
- max
);
1043 dsp
->td
.dtmf
.current_digits
-= max
;
1050 static int __ast_dsp_call_progress(struct ast_dsp
*dsp
, short *s
, int len
)
1055 int newstate
= DSP_TONE_STATE_SILENCE
;
1058 /* Take the lesser of the number of samples we need and what we have */
1060 if (pass
> dsp
->gsamp_size
- dsp
->gsamps
)
1061 pass
= dsp
->gsamp_size
- dsp
->gsamps
;
1062 for (x
=0;x
<pass
;x
++) {
1063 for (y
=0;y
<dsp
->freqcount
;y
++)
1064 goertzel_sample(&dsp
->freqs
[y
], s
[x
]);
1065 dsp
->genergy
+= s
[x
] * s
[x
];
1068 dsp
->gsamps
+= pass
;
1070 if (dsp
->gsamps
== dsp
->gsamp_size
) {
1073 hz
[y
] = goertzel_result(&dsp
->freqs
[y
]);
1075 printf("\n350: 425: 440: 480: 620: 950: 1400: 1800: Energy: \n");
1076 printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n",
1077 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
);
1079 switch(dsp
->progmode
) {
1081 if (pair_there(hz
[HZ_480
], hz
[HZ_620
], hz
[HZ_350
], hz
[HZ_440
], dsp
->genergy
)) {
1082 newstate
= DSP_TONE_STATE_BUSY
;
1083 } else if (pair_there(hz
[HZ_440
], hz
[HZ_480
], hz
[HZ_350
], hz
[HZ_620
], dsp
->genergy
)) {
1084 newstate
= DSP_TONE_STATE_RINGING
;
1085 } else if (pair_there(hz
[HZ_350
], hz
[HZ_440
], hz
[HZ_480
], hz
[HZ_620
], dsp
->genergy
)) {
1086 newstate
= DSP_TONE_STATE_DIALTONE
;
1087 } else if (hz
[HZ_950
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1088 newstate
= DSP_TONE_STATE_SPECIAL1
;
1089 } else if (hz
[HZ_1400
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1090 if (dsp
->tstate
== DSP_TONE_STATE_SPECIAL1
)
1091 newstate
= DSP_TONE_STATE_SPECIAL2
;
1092 } else if (hz
[HZ_1800
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1093 if (dsp
->tstate
== DSP_TONE_STATE_SPECIAL2
)
1094 newstate
= DSP_TONE_STATE_SPECIAL3
;
1095 } else if (dsp
->genergy
> TONE_MIN_THRESH
* TONE_THRESH
) {
1096 newstate
= DSP_TONE_STATE_TALKING
;
1098 newstate
= DSP_TONE_STATE_SILENCE
;
1101 if (hz
[HZ_425
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1102 newstate
= DSP_TONE_STATE_RINGING
;
1103 } else if (dsp
->genergy
> TONE_MIN_THRESH
* TONE_THRESH
) {
1104 newstate
= DSP_TONE_STATE_TALKING
;
1106 newstate
= DSP_TONE_STATE_SILENCE
;
1109 if (hz
[HZ_400
] > TONE_MIN_THRESH
* TONE_THRESH
) {
1110 newstate
= DSP_TONE_STATE_HUNGUP
;
1114 ast_log(LOG_WARNING
, "Can't process in unknown prog mode '%d'\n", dsp
->progmode
);
1116 if (newstate
== dsp
->tstate
) {
1118 if (dsp
->ringtimeout
)
1120 switch (dsp
->tstate
) {
1121 case DSP_TONE_STATE_RINGING
:
1122 if ((dsp
->features
& DSP_PROGRESS_RINGING
) &&
1123 (dsp
->tcount
==THRESH_RING
)) {
1124 res
= AST_CONTROL_RINGING
;
1125 dsp
->ringtimeout
= 1;
1128 case DSP_TONE_STATE_BUSY
:
1129 if ((dsp
->features
& DSP_PROGRESS_BUSY
) &&
1130 (dsp
->tcount
==THRESH_BUSY
)) {
1131 res
= AST_CONTROL_BUSY
;
1132 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1135 case DSP_TONE_STATE_TALKING
:
1136 if ((dsp
->features
& DSP_PROGRESS_TALK
) &&
1137 (dsp
->tcount
==THRESH_TALK
)) {
1138 res
= AST_CONTROL_ANSWER
;
1139 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1142 case DSP_TONE_STATE_SPECIAL3
:
1143 if ((dsp
->features
& DSP_PROGRESS_CONGESTION
) &&
1144 (dsp
->tcount
==THRESH_CONGESTION
)) {
1145 res
= AST_CONTROL_CONGESTION
;
1146 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1149 case DSP_TONE_STATE_HUNGUP
:
1150 if ((dsp
->features
& DSP_FEATURE_CALL_PROGRESS
) &&
1151 (dsp
->tcount
==THRESH_HANGUP
)) {
1152 res
= AST_CONTROL_HANGUP
;
1153 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1157 if (dsp
->ringtimeout
==THRESH_RING2ANSWER
) {
1159 ast_log(LOG_NOTICE
, "Consider call as answered because of timeout after last ring\n");
1161 res
= AST_CONTROL_ANSWER
;
1162 dsp
->features
&= ~DSP_FEATURE_CALL_PROGRESS
;
1166 ast_log(LOG_NOTICE
, "Stop state %d with duration %d\n", dsp
->tstate
, dsp
->tcount
);
1167 ast_log(LOG_NOTICE
, "Start state %d\n", newstate
);
1169 dsp
->tstate
= newstate
;
1173 /* Reset goertzel */
1175 dsp
->freqs
[x
].v2
= dsp
->freqs
[x
].v3
= 0.0;
1182 printf("Returning %d\n", res
);
1187 int ast_dsp_call_progress(struct ast_dsp
*dsp
, struct ast_frame
*inf
)
1189 if (inf
->frametype
!= AST_FRAME_VOICE
) {
1190 ast_log(LOG_WARNING
, "Can't check call progress of non-voice frames\n");
1193 if (inf
->subclass
!= AST_FORMAT_SLINEAR
) {
1194 ast_log(LOG_WARNING
, "Can only check call progress in signed-linear frames\n");
1197 return __ast_dsp_call_progress(dsp
, inf
->data
, inf
->datalen
/ 2);
1200 static int __ast_dsp_silence(struct ast_dsp
*dsp
, short *s
, int len
, int *totalsilence
)
1209 for (x
=0;x
<len
; x
++)
1212 if (accum
< dsp
->threshold
) {
1214 dsp
->totalsilence
+= len
/8;
1215 if (dsp
->totalnoise
) {
1216 /* Move and save history */
1217 memmove(dsp
->historicnoise
+ DSP_HISTORY
- dsp
->busycount
, dsp
->historicnoise
+ DSP_HISTORY
- dsp
->busycount
+1, dsp
->busycount
*sizeof(dsp
->historicnoise
[0]));
1218 dsp
->historicnoise
[DSP_HISTORY
- 1] = dsp
->totalnoise
;
1219 /* we don't want to check for busydetect that frequently */
1224 dsp
->totalnoise
= 0;
1228 dsp
->totalnoise
+= len
/8;
1229 if (dsp
->totalsilence
) {
1230 int silence1
= dsp
->historicsilence
[DSP_HISTORY
- 1];
1231 int silence2
= dsp
->historicsilence
[DSP_HISTORY
- 2];
1232 /* Move and save history */
1233 memmove(dsp
->historicsilence
+ DSP_HISTORY
- dsp
->busycount
, dsp
->historicsilence
+ DSP_HISTORY
- dsp
->busycount
+ 1, dsp
->busycount
*sizeof(dsp
->historicsilence
[0]));
1234 dsp
->historicsilence
[DSP_HISTORY
- 1] = dsp
->totalsilence
;
1235 /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
1236 if (silence1
< silence2
) {
1237 if (silence1
+ silence1
*BUSY_PERCENT
/100 >= silence2
)
1242 if (silence1
- silence1
*BUSY_PERCENT
/100 <= silence2
)
1248 dsp
->totalsilence
= 0;
1251 *totalsilence
= dsp
->totalsilence
;
1255 #ifdef BUSYDETECT_MARTIN
1256 int ast_dsp_busydetect(struct ast_dsp
*dsp
)
1259 #ifndef BUSYDETECT_TONEONLY
1260 int avgsilence
= 0, hitsilence
= 0;
1262 int avgtone
= 0, hittone
= 0;
1263 if (!dsp
->busymaybe
)
1265 for (x
=DSP_HISTORY
- dsp
->busycount
;x
<DSP_HISTORY
;x
++) {
1266 #ifndef BUSYDETECT_TONEONLY
1267 avgsilence
+= dsp
->historicsilence
[x
];
1269 avgtone
+= dsp
->historicnoise
[x
];
1271 #ifndef BUSYDETECT_TONEONLY
1272 avgsilence
/= dsp
->busycount
;
1274 avgtone
/= dsp
->busycount
;
1275 for (x
=DSP_HISTORY
- dsp
->busycount
;x
<DSP_HISTORY
;x
++) {
1276 #ifndef BUSYDETECT_TONEONLY
1277 if (avgsilence
> dsp
->historicsilence
[x
]) {
1278 if (avgsilence
- (avgsilence
*BUSY_PERCENT
/100) <= dsp
->historicsilence
[x
])
1281 if (avgsilence
+ (avgsilence
*BUSY_PERCENT
/100) >= dsp
->historicsilence
[x
])
1285 if (avgtone
> dsp
->historicnoise
[x
]) {
1286 if (avgtone
- (avgtone
*BUSY_PERCENT
/100) <= dsp
->historicnoise
[x
])
1289 if (avgtone
+ (avgtone
*BUSY_PERCENT
/100) >= dsp
->historicnoise
[x
])
1293 #ifndef BUSYDETECT_TONEONLY
1294 if ((hittone
>= dsp
->busycount
- 1) && (hitsilence
>= dsp
->busycount
- 1) &&
1295 (avgtone
>= BUSY_MIN
&& avgtone
<= BUSY_MAX
) &&
1296 (avgsilence
>= BUSY_MIN
&& avgsilence
<= BUSY_MAX
)) {
1298 if ((hittone
>= dsp
->busycount
- 1) && (avgtone
>= BUSY_MIN
&& avgtone
<= BUSY_MAX
)) {
1300 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1301 #ifdef BUSYDETECT_TONEONLY
1302 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
1304 if (avgtone
> avgsilence
) {
1305 if (avgtone
- avgtone
*BUSY_PERCENT
/100 <= avgsilence
)
1308 if (avgtone
+ avgtone
*BUSY_PERCENT
/100 >= avgsilence
)
1315 /* If we know the expected busy tone length, check we are in the range */
1316 if (res
&& (dsp
->busy_tonelength
> 0)) {
1317 if (abs(avgtone
- dsp
->busy_tonelength
) > (dsp
->busy_tonelength
*BUSY_PAT_PERCENT
/100)) {
1319 ast_log(LOG_NOTICE
, "busy detector: avgtone of %d not close enough to desired %d\n",
1320 avgtone
, dsp
->busy_tonelength
);
1325 #ifndef BUSYDETECT_TONEONLY
1326 /* If we know the expected busy tone silent-period length, check we are in the range */
1327 if (res
&& (dsp
->busy_quietlength
> 0)) {
1328 if (abs(avgsilence
- dsp
->busy_quietlength
) > (dsp
->busy_quietlength
*BUSY_PAT_PERCENT
/100)) {
1330 ast_log(LOG_NOTICE
, "busy detector: avgsilence of %d not close enough to desired %d\n",
1331 avgsilence
, dsp
->busy_quietlength
);
1339 ast_log(LOG_DEBUG
, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone
, avgsilence
);
1346 int ast_dsp_busydetect(struct ast_dsp
*dsp
)
1353 if (dsp
->busy_hits
> 5);
1356 if (dsp
->busymaybe
) {
1358 printf("Maybe busy!\n");
1363 for (x
=DSP_HISTORY
- dsp
->busycount
;x
<DSP_HISTORY
;x
++) {
1365 printf("Silence: %d, Noise: %d\n", dsp
->historicsilence
[x
], dsp
->historicnoise
[x
]);
1367 if (dsp
->historicsilence
[x
] < min
)
1368 min
= dsp
->historicsilence
[x
];
1369 if (dsp
->historicnoise
[x
] < min
)
1370 min
= dsp
->historicnoise
[x
];
1371 if (dsp
->historicsilence
[x
] > max
)
1372 max
= dsp
->historicsilence
[x
];
1373 if (dsp
->historicnoise
[x
] > max
)
1374 max
= dsp
->historicnoise
[x
];
1376 if ((max
- min
< BUSY_THRESHOLD
) && (max
< BUSY_MAX
) && (min
> BUSY_MIN
)) {
1383 printf("Min: %d, max: %d\n", min
, max
);
1390 int ast_dsp_silence(struct ast_dsp
*dsp
, struct ast_frame
*f
, int *totalsilence
)
1395 if (f
->frametype
!= AST_FRAME_VOICE
) {
1396 ast_log(LOG_WARNING
, "Can't calculate silence on a non-voice frame\n");
1399 if (f
->subclass
!= AST_FORMAT_SLINEAR
) {
1400 ast_log(LOG_WARNING
, "Can only calculate silence on signed-linear frames :(\n");
1405 return __ast_dsp_silence(dsp
, s
, len
, totalsilence
);
1408 struct ast_frame
*ast_dsp_process(struct ast_channel
*chan
, struct ast_dsp
*dsp
, struct ast_frame
*af
)
1415 unsigned char *odata
;
1419 #define FIX_INF(inf) do { \
1421 switch(inf->subclass) { \
1422 case AST_FORMAT_SLINEAR: \
1424 case AST_FORMAT_ULAW: \
1425 for (x=0;x<len;x++) \
1426 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
1428 case AST_FORMAT_ALAW: \
1429 for (x=0;x<len;x++) \
1430 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
1438 if (af
->frametype
!= AST_FRAME_VOICE
)
1442 /* Make sure we have short data */
1443 switch(af
->subclass
) {
1444 case AST_FORMAT_SLINEAR
:
1445 shortdata
= af
->data
;
1446 len
= af
->datalen
/ 2;
1448 case AST_FORMAT_ULAW
:
1449 shortdata
= alloca(af
->datalen
* 2);
1450 for (x
= 0;x
< len
; x
++)
1451 shortdata
[x
] = AST_MULAW(odata
[x
]);
1453 case AST_FORMAT_ALAW
:
1454 shortdata
= alloca(af
->datalen
* 2);
1455 for (x
= 0; x
< len
; x
++)
1456 shortdata
[x
] = AST_ALAW(odata
[x
]);
1459 ast_log(LOG_WARNING
, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af
->subclass
));
1462 silence
= __ast_dsp_silence(dsp
, shortdata
, len
, NULL
);
1463 if ((dsp
->features
& DSP_FEATURE_SILENCE_SUPPRESS
) && silence
) {
1464 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1465 dsp
->f
.frametype
= AST_FRAME_NULL
;
1468 if ((dsp
->features
& DSP_FEATURE_BUSY_DETECT
) && ast_dsp_busydetect(dsp
)) {
1469 chan
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1470 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1471 dsp
->f
.frametype
= AST_FRAME_CONTROL
;
1472 dsp
->f
.subclass
= AST_CONTROL_BUSY
;
1473 ast_log(LOG_DEBUG
, "Requesting Hangup because the busy tone was detected on channel %s\n", chan
->name
);
1476 if ((dsp
->features
& DSP_FEATURE_DTMF_DETECT
)) {
1477 digit
= __ast_dsp_digitdetect(dsp
, shortdata
, len
, &writeback
);
1480 printf("Performing digit detection returned %d, digitmode is %d\n", digit
, dsp
->digitmode
);
1482 if (dsp
->digitmode
& (DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
)) {
1483 if (!dsp
->thinkdigit
) {
1485 /* Looks like we might have something.
1486 * Request a conference mute for the moment */
1487 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1488 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1489 dsp
->f
.subclass
= 'm';
1490 dsp
->thinkdigit
= 'x';
1493 ast_queue_frame(chan
, af
);
1499 /* Thought we saw one last time. Pretty sure we really have now */
1500 if ((dsp
->thinkdigit
!= 'x') && (dsp
->thinkdigit
!= digit
)) {
1501 /* If we found a digit, and we're changing digits, go
1502 ahead and send this one, but DON'T stop confmute because
1503 we're detecting something else, too... */
1504 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1505 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1506 dsp
->f
.subclass
= dsp
->thinkdigit
;
1509 ast_queue_frame(chan
, af
);
1512 dsp
->thinkdigit
= digit
;
1513 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1514 dsp
->f
.frametype
= AST_FRAME_DTMF_BEGIN
;
1515 dsp
->f
.subclass
= dsp
->thinkdigit
;
1518 ast_queue_frame(chan
, af
);
1523 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1524 if (dsp
->thinkdigit
!= 'x') {
1525 /* If we found a digit, send it now */
1526 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1527 dsp
->f
.subclass
= dsp
->thinkdigit
;
1528 dsp
->thinkdigit
= 0;
1530 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1531 dsp
->f
.subclass
= 'u';
1532 dsp
->thinkdigit
= 0;
1536 ast_queue_frame(chan
, af
);
1541 } else if (!digit
) {
1542 /* Only check when there is *not* a hit... */
1543 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1544 if (dsp
->td
.mf
.current_digits
) {
1545 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1546 dsp
->f
.frametype
= AST_FRAME_DTMF
;
1547 dsp
->f
.subclass
= dsp
->td
.mf
.digits
[0];
1548 memmove(dsp
->td
.mf
.digits
, dsp
->td
.mf
.digits
+ 1, dsp
->td
.mf
.current_digits
);
1549 dsp
->td
.mf
.current_digits
--;
1552 ast_queue_frame(chan
, af
);
1557 if (dsp
->td
.dtmf
.current_digits
) {
1558 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1559 dsp
->f
.frametype
= AST_FRAME_DTMF_END
;
1560 dsp
->f
.subclass
= dsp
->td
.dtmf
.digits
[0];
1561 memmove(dsp
->td
.dtmf
.digits
, dsp
->td
.dtmf
.digits
+ 1, dsp
->td
.dtmf
.current_digits
);
1562 dsp
->td
.dtmf
.current_digits
--;
1565 ast_queue_frame(chan
, af
);
1572 if ((dsp
->features
& DSP_FEATURE_CALL_PROGRESS
)) {
1573 res
= __ast_dsp_call_progress(dsp
, shortdata
, len
);
1576 case AST_CONTROL_ANSWER
:
1577 case AST_CONTROL_BUSY
:
1578 case AST_CONTROL_RINGING
:
1579 case AST_CONTROL_CONGESTION
:
1580 case AST_CONTROL_HANGUP
:
1581 memset(&dsp
->f
, 0, sizeof(dsp
->f
));
1582 dsp
->f
.frametype
= AST_FRAME_CONTROL
;
1583 dsp
->f
.subclass
= res
;
1584 dsp
->f
.src
= "dsp_progress";
1586 ast_queue_frame(chan
, &dsp
->f
);
1589 ast_log(LOG_WARNING
, "Don't know how to represent call progress message %d\n", res
);
1597 static void ast_dsp_prog_reset(struct ast_dsp
*dsp
)
1602 dsp
->gsamp_size
= modes
[dsp
->progmode
].size
;
1604 for (x
=0;x
<sizeof(modes
[dsp
->progmode
].freqs
) / sizeof(modes
[dsp
->progmode
].freqs
[0]);x
++) {
1605 if (modes
[dsp
->progmode
].freqs
[x
]) {
1606 goertzel_init(&dsp
->freqs
[x
], (float)modes
[dsp
->progmode
].freqs
[x
], dsp
->gsamp_size
);
1610 dsp
->freqcount
= max
;
1611 dsp
->ringtimeout
= 0;
1614 struct ast_dsp
*ast_dsp_new(void)
1616 struct ast_dsp
*dsp
;
1618 if ((dsp
= ast_calloc(1, sizeof(*dsp
)))) {
1619 dsp
->threshold
= DEFAULT_THRESHOLD
;
1620 dsp
->features
= DSP_FEATURE_SILENCE_SUPPRESS
;
1621 dsp
->busycount
= DSP_HISTORY
;
1622 /* Initialize DTMF detector */
1623 ast_dtmf_detect_init(&dsp
->td
.dtmf
);
1624 /* Initialize initial DSP progress detect parameters */
1625 ast_dsp_prog_reset(dsp
);
1630 void ast_dsp_set_features(struct ast_dsp
*dsp
, int features
)
1632 dsp
->features
= features
;
1635 void ast_dsp_free(struct ast_dsp
*dsp
)
1640 void ast_dsp_set_threshold(struct ast_dsp
*dsp
, int threshold
)
1642 dsp
->threshold
= threshold
;
1645 void ast_dsp_set_busy_count(struct ast_dsp
*dsp
, int cadences
)
1649 if (cadences
> DSP_HISTORY
)
1650 cadences
= DSP_HISTORY
;
1651 dsp
->busycount
= cadences
;
1654 void ast_dsp_set_busy_pattern(struct ast_dsp
*dsp
, int tonelength
, int quietlength
)
1656 dsp
->busy_tonelength
= tonelength
;
1657 dsp
->busy_quietlength
= quietlength
;
1658 ast_log(LOG_DEBUG
, "dsp busy pattern set to %d,%d\n", tonelength
, quietlength
);
1661 void ast_dsp_digitreset(struct ast_dsp
*dsp
)
1665 dsp
->thinkdigit
= 0;
1666 if (dsp
->digitmode
& DSP_DIGITMODE_MF
) {
1667 memset(dsp
->td
.mf
.digits
, 0, sizeof(dsp
->td
.mf
.digits
));
1668 dsp
->td
.mf
.current_digits
= 0;
1669 /* Reinitialise the detector for the next block */
1670 for (i
= 0; i
< 6; i
++) {
1671 goertzel_reset(&dsp
->td
.mf
.tone_out
[i
]);
1672 #ifdef OLD_DSP_ROUTINES
1673 goertzel_reset(&dsp
->td
.mf
.tone_out2nd
[i
]);
1676 #ifdef OLD_DSP_ROUTINES
1677 dsp
->td
.mf
.energy
= 0.0;
1678 dsp
->td
.mf
.hit1
= dsp
->td
.mf
.hit2
= dsp
->td
.mf
.hit3
= dsp
->td
.mf
.hit4
= dsp
->td
.mf
.mhit
= 0;
1680 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;
1682 dsp
->td
.mf
.current_sample
= 0;
1684 memset(dsp
->td
.dtmf
.digits
, 0, sizeof(dsp
->td
.dtmf
.digits
));
1685 dsp
->td
.dtmf
.current_digits
= 0;
1686 /* Reinitialise the detector for the next block */
1687 for (i
= 0; i
< 4; i
++) {
1688 goertzel_reset(&dsp
->td
.dtmf
.row_out
[i
]);
1689 goertzel_reset(&dsp
->td
.dtmf
.col_out
[i
]);
1690 #ifdef OLD_DSP_ROUTINES
1691 goertzel_reset(&dsp
->td
.dtmf
.row_out2nd
[i
]);
1692 goertzel_reset(&dsp
->td
.dtmf
.col_out2nd
[i
]);
1696 goertzel_reset (&dsp
->td
.dtmf
.fax_tone
);
1698 #ifdef OLD_DSP_ROUTINES
1700 goertzel_reset (&dsp
->td
.dtmf
.fax_tone2nd
);
1702 dsp
->td
.dtmf
.hit1
= dsp
->td
.dtmf
.hit2
= dsp
->td
.dtmf
.hit3
= dsp
->td
.dtmf
.hit4
= dsp
->td
.dtmf
.mhit
= 0;
1704 dsp
->td
.dtmf
.hits
[2] = dsp
->td
.dtmf
.hits
[1] = dsp
->td
.dtmf
.hits
[0] = dsp
->td
.dtmf
.mhit
= 0;
1706 dsp
->td
.dtmf
.energy
= 0.0;
1707 dsp
->td
.dtmf
.current_sample
= 0;
1711 void ast_dsp_reset(struct ast_dsp
*dsp
)
1715 dsp
->totalsilence
= 0;
1718 dsp
->freqs
[x
].v2
= dsp
->freqs
[x
].v3
= 0.0;
1719 memset(dsp
->historicsilence
, 0, sizeof(dsp
->historicsilence
));
1720 memset(dsp
->historicnoise
, 0, sizeof(dsp
->historicnoise
));
1721 dsp
->ringtimeout
= 0;
1724 int ast_dsp_digitmode(struct ast_dsp
*dsp
, int digitmode
)
1729 old
= dsp
->digitmode
& (DSP_DIGITMODE_DTMF
| DSP_DIGITMODE_MF
| DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
);
1730 new = digitmode
& (DSP_DIGITMODE_DTMF
| DSP_DIGITMODE_MF
| DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
);
1732 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1733 if (new & DSP_DIGITMODE_MF
)
1734 ast_mf_detect_init(&dsp
->td
.mf
);
1736 ast_dtmf_detect_init(&dsp
->td
.dtmf
);
1738 dsp
->digitmode
= digitmode
;
1742 int ast_dsp_set_call_progress_zone(struct ast_dsp
*dsp
, char *zone
)
1746 for (x
=0;x
<sizeof(aliases
) / sizeof(aliases
[0]);x
++) {
1747 if (!strcasecmp(aliases
[x
].name
, zone
)) {
1748 dsp
->progmode
= aliases
[x
].mode
;
1749 ast_dsp_prog_reset(dsp
);
1756 int ast_dsp_get_tstate(struct ast_dsp
*dsp
)
1761 int ast_dsp_get_tcount(struct ast_dsp
*dsp
)