Asterisk - The Open Source Telephony Project GIT-master-77d630f
dsp.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
8 * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
9 * DTMF detector.
10 *
11 * See http://www.asterisk.org for more information about
12 * the Asterisk project. Please do not directly contact
13 * any of the maintainers of this project for assistance;
14 * the project provides a web site, mailing lists and IRC
15 * channels for your use.
16 *
17 * This program is free software, distributed under the terms of
18 * the GNU General Public License Version 2. See the LICENSE file
19 * at the top of the source tree.
20 */
21
22/*! \file
23 *
24 * \brief Convenience Signal Processing routines
25 *
26 * \author Mark Spencer <markster@digium.com>
27 * \author Steve Underwood <steveu@coppice.org>
28 */
29
30/*! \li \ref dsp.c uses the configuration file \ref dsp.conf
31 * \addtogroup configuration_file Configuration Files
32 */
33
34/*!
35 * \page dsp.conf dsp.conf
36 * \verbinclude dsp.conf.sample
37 */
38
39/* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
40/*
41 tone_detect.c - General telephony tone detection, and specific
42 detection of DTMF.
43
44 Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
45
46 Despite my general liking of the GPL, I place this code in the
47 public domain for the benefit of all mankind - even the slimy
48 ones who might try to proprietize my work and use it to my
49 detriment.
50*/
51
52/*** MODULEINFO
53 <support_level>core</support_level>
54 ***/
55
56#include "asterisk.h"
57
58#include <math.h>
59
60#include "asterisk/module.h"
61#include "asterisk/frame.h"
63#include "asterisk/channel.h"
64#include "asterisk/dsp.h"
65#include "asterisk/ulaw.h"
66#include "asterisk/alaw.h"
67#include "asterisk/utils.h"
68#include "asterisk/options.h"
69#include "asterisk/config.h"
70#include "asterisk/test.h"
71
72/*! Number of goertzels for progress detect */
74 GSAMP_SIZE_NA = 183, /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
75 GSAMP_SIZE_CR = 188, /*!< Costa Rica, Brazil - Only care about 425 Hz */
76 GSAMP_SIZE_UK = 160 /*!< UK disconnect goertzel feed - should trigger 400hz */
77};
78
83};
84
86 /*! For US modes { */
87 HZ_350 = 0,
93 HZ_1800, /*!< } */
94
95 /*! For CR/BR modes */
96 HZ_425 = 0,
97
98 /*! For UK mode */
103
104static struct progalias {
105 char *name;
107} aliases[] = {
108 { "us", PROG_MODE_NA },
109 { "ca", PROG_MODE_NA },
110 { "cr", PROG_MODE_CR },
111 { "br", PROG_MODE_CR },
112 { "uk", PROG_MODE_UK },
114
115#define FREQ_ARRAY_SIZE 7
116
117static struct progress {
120} modes[] = {
121 { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
122 { GSAMP_SIZE_CR, { 425 } }, /*!< Costa Rica, Brazil */
123 { GSAMP_SIZE_UK, { 350, 400, 440 } }, /*!< UK */
125
126/*!
127 * \brief Default minimum average magnitude threshold to determine talking/noise by the DSP.
128 *
129 * \details
130 * The magnitude calculated for this threshold is determined by
131 * averaging the absolute value of all samples within a frame.
132 *
133 * This value is the threshold for which a frame's average magnitude
134 * is determined to either be silence (below the threshold) or
135 * noise/talking (at or above the threshold). Please note that while
136 * the default threshold is an even exponent of 2, there is no
137 * requirement that it be so. The threshold will work for any value
138 * between 1 and 2^15.
139 */
140#define DEFAULT_THRESHOLD 512
141
143 BUSY_PERCENT = 10, /*!< The percentage difference between the two last silence periods */
144 BUSY_PAT_PERCENT = 7, /*!< The percentage difference between measured and actual pattern */
145 BUSY_THRESHOLD = 100, /*!< Max number of ms difference between max and min times in busy */
146 BUSY_MIN = 75, /*!< Busy must be at least 80 ms in half-cadence */
147 BUSY_MAX = 3100 /*!< Busy can't be longer than 3100 ms in half-cadence */
149
150/*! Remember last 15 units */
151#define DSP_HISTORY 15
152
153#define TONE_THRESH 10.0 /*!< How much louder the tone should be than channel energy */
154#define TONE_MIN_THRESH 1e8 /*!< How much tone there should be at least to attempt */
155
156/*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
158 THRESH_RING = 8, /*!< Need at least 150ms ring to accept */
159 THRESH_TALK = 2, /*!< Talk detection does not work continuously */
160 THRESH_BUSY = 4, /*!< Need at least 80ms to accept */
161 THRESH_CONGESTION = 4, /*!< Need at least 80ms to accept */
162 THRESH_HANGUP = 60, /*!< Need at least 1300ms to accept hangup */
163 THRESH_RING2ANSWER = 300 /*!< Timeout from start of ring to answer (about 6600 ms) */
165
166#define MAX_DTMF_DIGITS 128
167
168#define DTMF_MATRIX_SIZE 4
169
170/* Basic DTMF (AT&T) specs:
171 *
172 * Minimum tone on = 40ms
173 * Minimum tone off = 50ms
174 * Maximum digit rate = 10 per second
175 * Normal twist <= 8dB accepted
176 * Reverse twist <= 4dB accepted
177 * S/N >= 15dB will detect OK
178 * Attenuation <= 26dB will detect OK
179 * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
180 */
181
182#define DTMF_THRESHOLD 8.0e7
183#define TONE_THRESHOLD 7.8e7
184
185#define DEF_DTMF_NORMAL_TWIST 6.31 /* 8.0dB */
186#define DEF_RELAX_DTMF_NORMAL_TWIST 6.31 /* 8.0dB */
187
188#ifdef RADIO_RELAX
189#define DEF_DTMF_REVERSE_TWIST 2.51 /* 4.01dB */
190#define DEF_RELAX_DTMF_REVERSE_TWIST 6.61 /* 8.2dB */
191#else
192#define DEF_DTMF_REVERSE_TWIST 2.51 /* 4.01dB */
193#define DEF_RELAX_DTMF_REVERSE_TWIST 3.98 /* 6.0dB */
194#endif
195
196#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
197#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
198#define DTMF_TO_TOTAL_ENERGY 42.0
199
200#define BELL_MF_THRESHOLD 1.6e9
201#define BELL_MF_TWIST 4.0 /* 6dB */
202#define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */
203
204#if defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
205#error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
206#endif
207
208/* The CNG signal consists of the transmission of 1100 Hz for 1/2 second,
209 * followed by a 3 second silent (2100 Hz OFF) period.
210 */
211#define FAX_TONE_CNG_FREQ 1100
212#define FAX_TONE_CNG_DURATION 500 /* ms */
213#define FAX_TONE_CNG_DB 16
214
215/* This signal may be sent by the Terminating FAX machine anywhere between
216 * 1.8 to 2.5 seconds AFTER answering the call. The CED signal consists
217 * of a 2100 Hz tone that is from 2.6 to 4 seconds in duration.
218*/
219#define FAX_TONE_CED_FREQ 2100
220#define FAX_TONE_CED_DURATION 2600 /* ms */
221#define FAX_TONE_CED_DB 16
222
223#define DEFAULT_SAMPLE_RATE 8000
224
225/* MF goertzel size */
226#define MF_GSIZE 120
227
228/* DTMF goertzel size */
229#define DTMF_GSIZE 102
230
231/* How many successive hits needed to consider begin of a digit
232 * IE. Override with dtmf_hits_to_begin=4 in dsp.conf
233 */
234#define DEF_DTMF_HITS_TO_BEGIN 2
235
236/* How many successive misses needed to consider end of a digit
237 * IE. Override with dtmf_misses_to_end=4 in dsp.conf
238 */
239#define DEF_DTMF_MISSES_TO_END 3
240
241/*!
242 * \brief The default silence threshold we will use if an alternate
243 * configured value is not present or is invalid.
244 */
245static const int DEFAULT_SILENCE_THRESHOLD = 256;
246
247#define CONFIG_FILE_NAME "dsp.conf"
248
249typedef struct {
250 /*! The previous previous sample calculation (No binary point just plain int) */
251 int v2;
252 /*! The previous sample calculation (No binary point just plain int) */
253 int v3;
254 /*! v2 and v3 power of two exponent to keep value in int range */
256 /*! 15 bit fixed point goertzel coefficient = 2 * cos(2 * pi * freq / sample_rate) */
257 int fac;
259
260typedef struct {
261 int value;
262 int power;
264
265typedef struct
266{
267 int freq;
269 int squelch; /* Remove (squelch) tone */
271 float energy; /* Accumulated energy of the current block */
272 int samples_pending; /* Samples remain to complete the current block */
273 int mute_samples; /* How many additional samples needs to be muted to suppress already detected tone */
274
275 int hits_required; /* How many successive blocks with tone we are looking for */
276 float threshold; /* Energy of the tone relative to energy from all other signals to consider a hit */
277
278 int hit_count; /* How many successive blocks we consider tone present */
279 int last_hit; /* Indicates if the last processed block was a hit */
280
282
283typedef struct
284{
287 int hits; /* How many successive hits we have seen already */
288 int misses; /* How many successive misses we have seen already */
291 float energy;
295
296typedef struct
297{
298 goertzel_state_t tone_out[6];
300 int hits[5];
304
305typedef struct
306{
307 char digits[MAX_DTMF_DIGITS + 1];
308 int digitlen[MAX_DTMF_DIGITS + 1];
312
313 union {
316 } td;
318
319static const float dtmf_row[] = {
320 697.0, 770.0, 852.0, 941.0
321};
322static const float dtmf_col[] = {
323 1209.0, 1336.0, 1477.0, 1633.0
324};
325static const float mf_tones[] = {
326 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
327};
328static const char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
329static const char bell_mf_positions[] = "1247C-358A--69*---0B----#";
331static float dtmf_normal_twist; /* AT&T = 8dB */
332static float dtmf_reverse_twist; /* AT&T = 4dB */
333static float relax_dtmf_normal_twist; /* AT&T = 8dB */
334static float relax_dtmf_reverse_twist; /* AT&T = 6dB */
335static int dtmf_hits_to_begin; /* How many successive hits needed to consider begin of a digit */
336static int dtmf_misses_to_end; /* How many successive misses needed to consider end of a digit */
337
338static inline void goertzel_sample(goertzel_state_t *s, short sample)
339{
340 int v1;
341
342 /*
343 * Shift previous values so
344 * v1 is previous previous value
345 * v2 is previous value
346 * until the new v3 is calculated.
347 */
348 v1 = s->v2;
349 s->v2 = s->v3;
350
351 /* Discard the binary fraction introduced by s->fac */
352 s->v3 = (s->fac * s->v2) >> 15;
353 /* Scale sample to match previous values */
354 s->v3 = s->v3 - v1 + (sample >> s->chunky);
355
356 if (abs(s->v3) > (1 << 15)) {
357 /* The result is now too large so increase the chunky power. */
358 s->chunky++;
359 s->v3 = s->v3 >> 1;
360 s->v2 = s->v2 >> 1;
361 }
362}
363
364static inline float goertzel_result(goertzel_state_t *s)
365{
367
368 r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
369 r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
370 /*
371 * We have to double the exponent because we multiplied the
372 * previous sample calculation values together.
373 */
374 r.power = s->chunky * 2;
375 return (float)r.value * (float)(1 << r.power);
376}
377
378static inline void goertzel_init(goertzel_state_t *s, float freq, unsigned int sample_rate)
379{
380 s->v2 = s->v3 = s->chunky = 0;
381 s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / sample_rate));
382}
383
384static inline void goertzel_reset(goertzel_state_t *s)
385{
386 s->v2 = s->v3 = s->chunky = 0;
387}
388
389typedef struct {
390 int start;
391 int end;
392} fragment_t;
393
394/* Note on tone suppression (squelching). Individual detectors (DTMF/MF/generic tone)
395 * report fragments of the frame in which detected tone resides and which needs
396 * to be "muted" in order to suppress the tone. To mark fragment for muting,
397 * detectors call mute_fragment passing fragment_t there. Multiple fragments
398 * can be marked and ast_dsp_process later will mute all of them.
399 *
400 * Note: When tone starts in the middle of a Goertzel block, it won't be properly
401 * detected in that block, only in the next. If we only mute the next block
402 * where tone is actually detected, the user will still hear beginning
403 * of the tone in preceeding block. This is why we usually want to mute some amount
404 * of samples preceeding and following the block where tone was detected.
405*/
406
407struct ast_dsp {
408 struct ast_frame f;
410 /*! Accumulated total silence in ms since last talking/noise. */
412 /*! Accumulated total talking/noise in ms since last silence. */
416 int busymaybe; /* Boolean, could be a bitfield */
431 int dtmf_began; /* Boolean, could be a bitfield */
432 int display_inband_dtmf_warning; /* Boolean, could be a bitfield */
433 float genergy;
435 unsigned int sample_rate;
440};
441
442static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
443{
444 if (dsp->mute_fragments >= ARRAY_LEN(dsp->mute_data)) {
445 ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
446 return;
447 }
448
449 dsp->mute_data[dsp->mute_fragments++] = *fragment;
450}
451
452static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp, unsigned int sample_rate)
453{
454 int duration_samples;
455 float x;
456 int periods_in_block;
457
458 s->freq = freq;
459
460 /* Desired tone duration in samples */
461 duration_samples = duration * sample_rate / 1000;
462 /* We want to allow 10% deviation of tone duration */
463 duration_samples = duration_samples * 9 / 10;
464
465 /* If we want to remove tone, it is important to have block size not
466 to exceed frame size. Otherwise by the moment tone is detected it is too late
467 to squelch it from previous frames. Block size is 20ms at the given sample rate.*/
468 s->block_size = (20 * sample_rate) / 1000;
469
470 periods_in_block = s->block_size * freq / sample_rate;
471
472 /* Make sure we will have at least 5 periods at target frequency for analysis.
473 This may make block larger than expected packet and will make squelching impossible
474 but at least we will be detecting the tone */
475 if (periods_in_block < 5) {
476 periods_in_block = 5;
477 }
478
479 /* Now calculate final block size. It will contain integer number of periods */
480 s->block_size = periods_in_block * sample_rate / freq;
481
482 /* tone_detect is generally only used to detect fax tones and we
483 do not need squelching the fax tones */
484 s->squelch = 0;
485
486 /* Account for the first and the last block to be incomplete
487 and thus no tone will be detected in them */
488 s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
489
490 goertzel_init(&s->tone, freq, sample_rate);
491
493 s->hit_count = 0;
494 s->last_hit = 0;
495 s->energy = 0.0;
496
497 /* We want tone energy to be amp decibels above the rest of the signal (the noise).
498 According to Parseval's theorem the energy computed in time domain equals to energy
499 computed in frequency domain. So subtracting energy in the frequency domain (Goertzel result)
500 from the energy in the time domain we will get energy of the remaining signal (without the tone
501 we are detecting). We will be checking that
502 10*log(Ew / (Et - Ew)) > amp
503 Calculate threshold so that we will be actually checking
504 Ew > Et * threshold
505 */
506
507 x = pow(10.0, amp / 10.0);
508 s->threshold = x / (x + 1);
509
510 ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
511}
512
513static void ast_fax_detect_init(struct ast_dsp *s)
514{
518 s->cng_tone_state.squelch = 1;
519 s->ced_tone_state.squelch = 1;
520 }
521
522}
523
524static void ast_freq_detect_init(struct ast_dsp *s, int freq, int dur, int db, int squelch)
525{
526 /* we can conveniently just use one of the two fax tone states */
528 if (s->freqmode & squelch) {
529 s->cng_tone_state.squelch = 1;
530 }
531}
532
533static void ast_dtmf_detect_init(dtmf_detect_state_t *s, unsigned int sample_rate)
534{
535 int i;
536
537 for (i = 0; i < DTMF_MATRIX_SIZE; i++) {
538 goertzel_init(&s->row_out[i], dtmf_row[i], sample_rate);
539 goertzel_init(&s->col_out[i], dtmf_col[i], sample_rate);
540 }
541 s->lasthit = 0;
542 s->current_hit = 0;
543 s->energy = 0.0;
544 s->current_sample = 0;
545 s->hits = 0;
546 s->misses = 0;
547}
548
549static void ast_mf_detect_init(mf_detect_state_t *s, unsigned int sample_rate)
550{
551 int i;
552
553 for (i = 0; i < 6; i++) {
554 goertzel_init(&s->tone_out[i], mf_tones[i], sample_rate);
555 }
556 s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
557 s->current_sample = 0;
558 s->current_hit = 0;
559}
560
561static void ast_digit_detect_init(digit_detect_state_t *s, int mf, unsigned int sample_rate)
562{
563 s->current_digits = 0;
564 s->detected_digits = 0;
565 s->lost_digits = 0;
566 s->digits[0] = '\0';
567
568 if (mf) {
569 ast_mf_detect_init(&s->td.mf, sample_rate);
570 } else {
571 ast_dtmf_detect_init(&s->td.dtmf, sample_rate);
572 }
573}
574
575static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
576{
577 float tone_energy;
578 int i;
579 int hit = 0;
580 int limit;
581 int res = 0;
582 int16_t *ptr;
583 short samp;
584 int start, end;
585 fragment_t mute = {0, 0};
586
587 if (s->squelch && s->mute_samples > 0) {
588 mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
589 s->mute_samples -= mute.end;
590 }
591
592 for (start = 0; start < samples; start = end) {
593 /* Process in blocks. */
594 limit = samples - start;
595 if (limit > s->samples_pending) {
596 limit = s->samples_pending;
597 }
598 end = start + limit;
599
600 for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
601 samp = *ptr;
602 /* signed 32 bit int should be enough to square any possible signed 16 bit value */
603 s->energy += (int32_t) samp * (int32_t) samp;
604
605 goertzel_sample(&s->tone, samp);
606 }
607
608 s->samples_pending -= limit;
609
610 if (s->samples_pending) {
611 /* Finished incomplete (last) block */
612 break;
613 }
614
615 tone_energy = goertzel_result(&s->tone);
616
617 /* Scale to make comparable */
618 tone_energy *= 2.0;
619 s->energy *= s->block_size;
620
621 /* Add 1 to hit_count when logging, since it doesn't get incremented until later in the loop. */
622 if (TONE_THRESHOLD <= tone_energy
623 && tone_energy > s->energy * s->threshold) {
624 ast_debug(9, "%d Hz tone Hit! [%d/%d] Ew=%.4E, Et=%.4E, s/n=%10.2f\n", s->freq, s->hit_count + 1, s->hits_required, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
625 hit = 1;
626 } else {
627 ast_debug(10, "%d Hz tone [%d/%d] Ew=%.4E, Et=%.4E, s/n=%10.2f\n", s->freq, s->hit_count + 1, s->hits_required, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
628 hit = 0;
629 }
630
631 if (s->hit_count) {
632 s->hit_count++;
633 }
634
635 if (hit == s->last_hit) {
636 if (!hit) {
637 /* Two successive misses. Tone ended */
638 ast_debug(9, "Partial detect expired after %d/%d hits\n", s->hit_count, s->hits_required);
639 s->hit_count = 0;
640 } else if (!s->hit_count) {
641 s->hit_count++;
642 }
643 }
644
645 if (s->hit_count == s->hits_required) {
646 ast_debug(1, "%d Hz tone detected\n", s->freq);
647 res = 1;
648 }
649
650 s->last_hit = hit;
651
652 /* If we had a hit in this block, include it into mute fragment */
653 if (s->squelch && hit) {
654 if (mute.end < start - s->block_size) {
655 /* There is a gap between fragments */
656 mute_fragment(dsp, &mute);
657 mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
658 }
659 mute.end = end + s->block_size;
660 }
661
662 /* Reinitialise the detector for the next block */
663 /* Reset for the next block */
664 goertzel_reset(&s->tone);
665
666 /* Advance to the next block */
667 s->energy = 0.0;
669
670 amp += limit;
671 }
672
673 if (s->squelch && mute.end) {
674 if (mute.end > samples) {
675 s->mute_samples = mute.end - samples;
676 mute.end = samples;
677 }
678 mute_fragment(dsp, &mute);
679 }
680
681 return res;
682}
683
685{
686 s->detected_digits++;
688 s->digitlen[s->current_digits] = 0;
689 s->digits[s->current_digits++] = digit;
690 s->digits[s->current_digits] = '\0';
691 } else {
692 ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
693 s->lost_digits++;
694 }
695}
696
697static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
698{
699 float row_energy[DTMF_MATRIX_SIZE];
700 float col_energy[DTMF_MATRIX_SIZE];
701 int i;
702 int j;
703 int sample;
704 short samp;
705 int best_row;
706 int best_col;
707 int hit;
708 int limit;
709 fragment_t mute = {0, 0};
710
711 if (squelch && s->td.dtmf.mute_samples > 0) {
712 mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
713 s->td.dtmf.mute_samples -= mute.end;
714 }
715
716 hit = 0;
717 for (sample = 0; sample < samples; sample = limit) {
718 /* DTMF_GSIZE is optimised to meet the DTMF specs. */
719 if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
720 limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
721 } else {
722 limit = samples;
723 }
724 /* The following unrolled loop takes only 35% (rough estimate) of the
725 time of a rolled loop on the machine on which it was developed */
726 for (j = sample; j < limit; j++) {
727 samp = amp[j];
728 s->td.dtmf.energy += (int32_t) samp * (int32_t) samp;
729 /* With GCC 2.95, the following unrolled code seems to take about 35%
730 (rough estimate) as long as a neat little 0-3 loop */
731 goertzel_sample(s->td.dtmf.row_out, samp);
732 goertzel_sample(s->td.dtmf.col_out, samp);
733 goertzel_sample(s->td.dtmf.row_out + 1, samp);
734 goertzel_sample(s->td.dtmf.col_out + 1, samp);
735 goertzel_sample(s->td.dtmf.row_out + 2, samp);
736 goertzel_sample(s->td.dtmf.col_out + 2, samp);
737 goertzel_sample(s->td.dtmf.row_out + 3, samp);
738 goertzel_sample(s->td.dtmf.col_out + 3, samp);
739 /* go up to DTMF_MATRIX_SIZE - 1 */
740 }
741 s->td.dtmf.current_sample += (limit - sample);
742 if (s->td.dtmf.current_sample < DTMF_GSIZE) {
743 continue;
744 }
745 /* We are at the end of a DTMF detection block */
746 /* Find the peak row and the peak column */
747 row_energy[0] = goertzel_result(&s->td.dtmf.row_out[0]);
748 col_energy[0] = goertzel_result(&s->td.dtmf.col_out[0]);
749
750 for (best_row = best_col = 0, i = 1; i < DTMF_MATRIX_SIZE; i++) {
751 row_energy[i] = goertzel_result(&s->td.dtmf.row_out[i]);
752 if (row_energy[i] > row_energy[best_row]) {
753 best_row = i;
754 }
755 col_energy[i] = goertzel_result(&s->td.dtmf.col_out[i]);
756 if (col_energy[i] > col_energy[best_col]) {
757 best_col = i;
758 }
759 }
760 ast_debug(10, "DTMF best '%c' Erow=%.4E Ecol=%.4E Erc=%.4E Et=%.4E\n",
761 dtmf_positions[(best_row << 2) + best_col],
762 row_energy[best_row], col_energy[best_col],
763 row_energy[best_row] + col_energy[best_col], s->td.dtmf.energy);
764 hit = 0;
765 /* Basic signal level test and the twist test */
766 if (row_energy[best_row] >= DTMF_THRESHOLD &&
767 col_energy[best_col] >= DTMF_THRESHOLD &&
768 col_energy[best_col] < row_energy[best_row] * (relax ? relax_dtmf_reverse_twist : dtmf_reverse_twist) &&
769 row_energy[best_row] < col_energy[best_col] * (relax ? relax_dtmf_normal_twist : dtmf_normal_twist)) {
770 /* Relative peak test */
771 for (i = 0; i < DTMF_MATRIX_SIZE; i++) {
772 if ((i != best_col &&
773 col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
774 (i != best_row
775 && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
776 break;
777 }
778 }
779 /* ... and fraction of total energy test */
780 if (i >= DTMF_MATRIX_SIZE &&
781 (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
782 /* Got a hit */
783 hit = dtmf_positions[(best_row << 2) + best_col];
784 ast_debug(10, "DTMF hit '%c'\n", hit);
785 }
786 }
787
788/*
789 * Adapted from ETSI ES 201 235-3 V1.3.1 (2006-03)
790 * (40ms reference is tunable with hits_to_begin and misses_to_end)
791 * each hit/miss is 12.75ms with DTMF_GSIZE at 102
792 *
793 * Character recognition: When not DRC *(1) and then
794 * Shall exist VSC > 40 ms (hits_to_begin)
795 * May exist 20 ms <= VSC <= 40 ms
796 * Shall not exist VSC < 20 ms
797 *
798 * Character recognition: When DRC and then
799 * Shall cease Not VSC > 40 ms (misses_to_end)
800 * May cease 20 ms >= Not VSC >= 40 ms
801 * Shall not cease Not VSC < 20 ms
802 *
803 * *(1) or optionally a different digit recognition condition
804 *
805 * Legend: VSC The continuous existence of a valid signal condition.
806 * Not VSC The continuous non-existence of valid signal condition.
807 * DRC The existence of digit recognition condition.
808 * Not DRC The non-existence of digit recognition condition.
809 */
810
811/*
812 * Example: hits_to_begin=2 misses_to_end=3
813 * -------A last_hit=A hits=0&1
814 * ------AA hits=2 current_hit=A misses=0 BEGIN A
815 * -----AA- misses=1 last_hit=' ' hits=0
816 * ----AA-- misses=2
817 * ---AA--- misses=3 current_hit=' ' END A
818 * --AA---B last_hit=B hits=0&1
819 * -AA---BC last_hit=C hits=0&1
820 * AA---BCC hits=2 current_hit=C misses=0 BEGIN C
821 * A---BCC- misses=1 last_hit=' ' hits=0
822 * ---BCC-C misses=0 last_hit=C hits=0&1
823 * --BCC-CC misses=0
824 *
825 * Example: hits_to_begin=3 misses_to_end=2
826 * -------A last_hit=A hits=0&1
827 * ------AA hits=2
828 * -----AAA hits=3 current_hit=A misses=0 BEGIN A
829 * ----AAAB misses=1 last_hit=B hits=0&1
830 * ---AAABB misses=2 current_hit=' ' hits=2 END A
831 * --AAABBB hits=3 current_hit=B misses=0 BEGIN B
832 * -AAABBBB misses=0
833 *
834 * Example: hits_to_begin=2 misses_to_end=2
835 * -------A last_hit=A hits=0&1
836 * ------AA hits=2 current_hit=A misses=0 BEGIN A
837 * -----AAB misses=1 hits=0&1
838 * ----AABB misses=2 current_hit=' ' hits=2 current_hit=B misses=0 BEGIN B
839 * ---AABBB misses=0
840 */
841
842 if (s->td.dtmf.current_hit) {
843 /* We are in the middle of a digit already */
844 if (hit != s->td.dtmf.current_hit) {
845 s->td.dtmf.misses++;
846 if (s->td.dtmf.misses == dtmf_misses_to_end) {
847 /* There were enough misses to consider digit ended */
848 s->td.dtmf.current_hit = 0;
849 }
850 } else {
851 s->td.dtmf.misses = 0;
852 /* Current hit was same as last, so increment digit duration (of last digit) */
853 s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
854 }
855 }
856
857 /* Look for a start of a new digit no matter if we are already in the middle of some
858 digit or not. This is because hits_to_begin may be smaller than misses_to_end
859 and we may find begin of new digit before we consider last one ended. */
860
861 if (hit != s->td.dtmf.lasthit) {
862 s->td.dtmf.lasthit = hit;
863 s->td.dtmf.hits = 0;
864 }
865 if (hit && hit != s->td.dtmf.current_hit) {
866 s->td.dtmf.hits++;
867 if (s->td.dtmf.hits == dtmf_hits_to_begin) {
868 store_digit(s, hit);
870 s->td.dtmf.current_hit = hit;
871 s->td.dtmf.misses = 0;
872 }
873 }
874
875 /* If we had a hit in this block, include it into mute fragment */
876 if (squelch && hit) {
877 if (mute.end < sample - DTMF_GSIZE) {
878 /* There is a gap between fragments */
879 mute_fragment(dsp, &mute);
880 mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
881 }
882 mute.end = limit + DTMF_GSIZE;
883 }
884
885 /* Reinitialise the detector for the next block */
886 for (i = 0; i < DTMF_MATRIX_SIZE; i++) {
889 }
890 s->td.dtmf.energy = 0.0;
891 s->td.dtmf.current_sample = 0;
892 }
893
894 if (squelch && mute.end) {
895 if (mute.end > samples) {
896 s->td.dtmf.mute_samples = mute.end - samples;
897 mute.end = samples;
898 }
899 mute_fragment(dsp, &mute);
900 }
901
902 return (s->td.dtmf.current_hit); /* return the debounced hit */
903}
904
905static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
906 int samples, int squelch, int relax)
907{
908 float energy[6];
909 int best;
910 int second_best;
911 int i;
912 int j;
913 int sample;
914 short samp;
915 int hit;
916 int limit;
917 fragment_t mute = {0, 0};
918
919 if (squelch && s->td.mf.mute_samples > 0) {
920 mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
921 s->td.mf.mute_samples -= mute.end;
922 }
923
924 hit = 0;
925 for (sample = 0; sample < samples; sample = limit) {
926 /* 80 is optimised to meet the MF specs. */
927 /* XXX So then why is MF_GSIZE defined as 120? */
928 if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
929 limit = sample + (MF_GSIZE - s->td.mf.current_sample);
930 } else {
931 limit = samples;
932 }
933 /* The following unrolled loop takes only 35% (rough estimate) of the
934 time of a rolled loop on the machine on which it was developed */
935 for (j = sample; j < limit; j++) {
936 /* With GCC 2.95, the following unrolled code seems to take about 35%
937 (rough estimate) as long as a neat little 0-3 loop */
938 samp = amp[j];
939 goertzel_sample(s->td.mf.tone_out, samp);
940 goertzel_sample(s->td.mf.tone_out + 1, samp);
941 goertzel_sample(s->td.mf.tone_out + 2, samp);
942 goertzel_sample(s->td.mf.tone_out + 3, samp);
943 goertzel_sample(s->td.mf.tone_out + 4, samp);
944 goertzel_sample(s->td.mf.tone_out + 5, samp);
945 }
946 s->td.mf.current_sample += (limit - sample);
947 if (s->td.mf.current_sample < MF_GSIZE) {
948 continue;
949 }
950 /* We're at the end of an MF detection block. */
951 /* Find the two highest energies. The spec says to look for
952 two tones and two tones only. Taking this literally -ie
953 only two tones pass the minimum threshold - doesn't work
954 well. The sinc function mess, due to rectangular windowing
955 ensure that! Find the two highest energies and ensure they
956 are considerably stronger than any of the others. */
957 energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
958 energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
959 if (energy[0] > energy[1]) {
960 best = 0;
961 second_best = 1;
962 } else {
963 best = 1;
964 second_best = 0;
965 }
966 /*endif*/
967 for (i = 2; i < 6; i++) {
968 energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
969 if (energy[i] >= energy[best]) {
970 second_best = best;
971 best = i;
972 } else if (energy[i] >= energy[second_best]) {
973 second_best = i;
974 }
975 }
976 /* Basic signal level and twist tests */
977 hit = 0;
978 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
979 && energy[best] < energy[second_best]*BELL_MF_TWIST
980 && energy[best] * BELL_MF_TWIST > energy[second_best]) {
981 /* Relative peak test */
982 hit = -1;
983 for (i = 0; i < 6; i++) {
984 if (i != best && i != second_best) {
985 if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
986 /* The best two are not clearly the best */
987 hit = 0;
988 break;
989 }
990 }
991 }
992 }
993 if (hit) {
994 /* Get the values into ascending order */
995 if (second_best < best) {
996 i = best;
997 best = second_best;
998 second_best = i;
999 }
1000 best = best * 5 + second_best - 1;
1001 hit = bell_mf_positions[best];
1002 /* Look for two successive similar results */
1003 /* The logic in the next test is:
1004 For KP we need 4 successive identical clean detects, with
1005 two blocks of something different preceeding it. For anything
1006 else we need two successive identical clean detects, with
1007 two blocks of something different preceeding it. */
1008 if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
1009 ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
1010 (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
1011 hit != s->td.mf.hits[0]))) {
1012 store_digit(s, hit);
1013 }
1014 }
1015
1016
1017 if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
1018 /* Two successive block without a hit terminate current digit */
1019 s->td.mf.current_hit = 0;
1020 }
1021
1022 s->td.mf.hits[0] = s->td.mf.hits[1];
1023 s->td.mf.hits[1] = s->td.mf.hits[2];
1024 s->td.mf.hits[2] = s->td.mf.hits[3];
1025 s->td.mf.hits[3] = s->td.mf.hits[4];
1026 s->td.mf.hits[4] = hit;
1027
1028 /* If we had a hit in this block, include it into mute fragment */
1029 if (squelch && hit) {
1030 if (mute.end < sample - MF_GSIZE) {
1031 /* There is a gap between fragments */
1032 mute_fragment(dsp, &mute);
1033 mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
1034 }
1035 mute.end = limit + MF_GSIZE;
1036 }
1037
1038 /* Reinitialise the detector for the next block */
1039 for (i = 0; i < 6; i++) {
1040 goertzel_reset(&s->td.mf.tone_out[i]);
1041 }
1042 s->td.mf.current_sample = 0;
1043 }
1044
1045 if (squelch && mute.end) {
1046 if (mute.end > samples) {
1047 s->td.mf.mute_samples = mute.end - samples;
1048 mute.end = samples;
1049 }
1050 mute_fragment(dsp, &mute);
1051 }
1052
1053 return (s->td.mf.current_hit); /* return the debounced hit */
1054}
1055
1056static inline int pair_there(float p1, float p2, float i1, float i2, float e)
1057{
1058 /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
1059 /* Make sure absolute levels are high enough */
1060 if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
1061 return 0;
1062 }
1063 /* Amplify ignored stuff */
1064 i2 *= TONE_THRESH;
1065 i1 *= TONE_THRESH;
1066 e *= TONE_THRESH;
1067 /* Check first tone */
1068 if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
1069 return 0;
1070 }
1071 /* And second */
1072 if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
1073 return 0;
1074 }
1075 /* Guess it's there... */
1076 return 1;
1077}
1078
1079static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
1080{
1081 short samp;
1082 int x;
1083 int y;
1084 int pass;
1085 int newstate = DSP_TONE_STATE_SILENCE;
1086 int res = 0;
1087 int freqcount = dsp->freqcount > FREQ_ARRAY_SIZE ? FREQ_ARRAY_SIZE : dsp->freqcount;
1088
1089 while (len) {
1090 /* Take the lesser of the number of samples we need and what we have */
1091 pass = len;
1092 if (pass > dsp->gsamp_size - dsp->gsamps) {
1093 pass = dsp->gsamp_size - dsp->gsamps;
1094 }
1095 for (x = 0; x < pass; x++) {
1096 samp = s[x];
1097 dsp->genergy += (int32_t) samp * (int32_t) samp;
1098 for (y = 0; y < freqcount; y++) {
1099 goertzel_sample(&dsp->freqs[y], samp);
1100 }
1101 }
1102 s += pass;
1103 dsp->gsamps += pass;
1104 len -= pass;
1105 if (dsp->gsamps == dsp->gsamp_size) {
1106 float hz[FREQ_ARRAY_SIZE];
1107 for (y = 0; y < FREQ_ARRAY_SIZE; y++) {
1108 hz[y] = goertzel_result(&dsp->freqs[y]);
1109 }
1110 switch (dsp->progmode) {
1111 case PROG_MODE_NA:
1112 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
1113 newstate = DSP_TONE_STATE_BUSY;
1114 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
1115 newstate = DSP_TONE_STATE_RINGING;
1116 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
1117 newstate = DSP_TONE_STATE_DIALTONE;
1118 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
1119 newstate = DSP_TONE_STATE_SPECIAL1;
1120 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
1121 /* End of SPECIAL1 or middle of SPECIAL2 */
1123 newstate = DSP_TONE_STATE_SPECIAL2;
1124 }
1125 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
1126 /* End of SPECIAL2 or middle of SPECIAL3 */
1128 newstate = DSP_TONE_STATE_SPECIAL3;
1129 }
1130 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1131 newstate = DSP_TONE_STATE_TALKING;
1132 } else {
1133 newstate = DSP_TONE_STATE_SILENCE;
1134 }
1135 break;
1136 case PROG_MODE_CR:
1137 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
1138 newstate = DSP_TONE_STATE_RINGING;
1139 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1140 newstate = DSP_TONE_STATE_TALKING;
1141 } else {
1142 newstate = DSP_TONE_STATE_SILENCE;
1143 }
1144 break;
1145 case PROG_MODE_UK:
1146 if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
1147 newstate = DSP_TONE_STATE_HUNGUP;
1148 } else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
1149 newstate = DSP_TONE_STATE_DIALTONE;
1150 }
1151 break;
1152 default:
1153 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%u'\n", dsp->progmode);
1154 }
1155 if (newstate == dsp->tstate) {
1156 dsp->tcount++;
1157 if (dsp->ringtimeout) {
1158 dsp->ringtimeout++;
1159 }
1160 switch (dsp->tstate) {
1162 if ((dsp->features & DSP_PROGRESS_RINGING) &&
1163 (dsp->tcount == THRESH_RING)) {
1164 res = AST_CONTROL_RINGING;
1165 dsp->ringtimeout = 1;
1166 }
1167 break;
1169 if ((dsp->features & DSP_PROGRESS_BUSY) &&
1170 (dsp->tcount == THRESH_BUSY)) {
1171 res = AST_CONTROL_BUSY;
1172 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1173 }
1174 break;
1176 if ((dsp->features & DSP_PROGRESS_TALK) &&
1177 (dsp->tcount == THRESH_TALK)) {
1178 res = AST_CONTROL_ANSWER;
1179 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1180 }
1181 break;
1183 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
1184 (dsp->tcount == THRESH_CONGESTION)) {
1186 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1187 }
1188 break;
1190 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
1191 (dsp->tcount == THRESH_HANGUP)) {
1192 res = AST_CONTROL_HANGUP;
1193 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1194 }
1195 break;
1196 }
1197 if (dsp->ringtimeout == THRESH_RING2ANSWER) {
1198 ast_debug(1, "Consider call as answered because of timeout after last ring\n");
1199 res = AST_CONTROL_ANSWER;
1200 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1201 }
1202 } else {
1203 ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
1204 ast_debug(5, "Start state %d\n", newstate);
1205 dsp->tstate = newstate;
1206 dsp->tcount = 1;
1207 }
1208
1209 /* Reset goertzel */
1210 for (x = 0; x < 7; x++) {
1211 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1212 }
1213 dsp->gsamps = 0;
1214 dsp->genergy = 0.0;
1215 }
1216 }
1217
1218 return res;
1219}
1220
1221int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
1222{
1223 if (inf->frametype != AST_FRAME_VOICE) {
1224 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
1225 return 0;
1226 }
1228 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames, %s not supported\n",
1230 return 0;
1231 }
1232 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
1233}
1234
1235static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise, int *frames_energy)
1236{
1237 int accum;
1238 int x;
1239 int res = 0;
1240
1241 if (!len) {
1242 return 0;
1243 }
1244 accum = 0;
1245 for (x = 0; x < len; x++) {
1246 accum += abs(s[x]);
1247 }
1248 accum /= len;
1249 if (accum < dsp->threshold) {
1250 /* Silent */
1251 dsp->totalsilence += len / (dsp->sample_rate / 1000);
1252 if (dsp->totalnoise) {
1253 /* Move and save history */
1254 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicnoise[0]));
1255 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
1256/* we don't want to check for busydetect that frequently */
1257#if 0
1258 dsp->busymaybe = 1;
1259#endif
1260 }
1261 dsp->totalnoise = 0;
1262 res = 1;
1263 } else {
1264 /* Not silent */
1265 dsp->totalnoise += len / (dsp->sample_rate / 1000);
1266 if (dsp->totalsilence) {
1267 int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
1268 int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
1269 /* Move and save history */
1270 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicsilence[0]));
1271 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
1272 /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
1273 if (silence1 < silence2) {
1274 if (silence1 + silence1 * BUSY_PERCENT / 100 >= silence2) {
1275 dsp->busymaybe = 1;
1276 } else {
1277 dsp->busymaybe = 0;
1278 }
1279 } else {
1280 if (silence1 - silence1 * BUSY_PERCENT / 100 <= silence2) {
1281 dsp->busymaybe = 1;
1282 } else {
1283 dsp->busymaybe = 0;
1284 }
1285 }
1286 }
1287 dsp->totalsilence = 0;
1288 }
1289 if (totalsilence) {
1290 *totalsilence = dsp->totalsilence;
1291 }
1292 if (totalnoise) {
1293 *totalnoise = dsp->totalnoise;
1294 }
1295 if (frames_energy) {
1296 *frames_energy = accum;
1297 }
1298 return res;
1299}
1300
1302{
1303 int res = 0, x;
1304#ifndef BUSYDETECT_TONEONLY
1305 int avgsilence = 0, hitsilence = 0;
1306#endif
1307 int avgtone = 0, hittone = 0;
1308
1309 /* if we have a 4 length pattern, the way busymaybe is set doesn't help us. */
1310 if (dsp->busy_cadence.length != 4) {
1311 if (!dsp->busymaybe) {
1312 return res;
1313 }
1314 }
1315
1316 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
1317#ifndef BUSYDETECT_TONEONLY
1318 avgsilence += dsp->historicsilence[x];
1319#endif
1320 avgtone += dsp->historicnoise[x];
1321 }
1322#ifndef BUSYDETECT_TONEONLY
1323 avgsilence /= dsp->busycount;
1324#endif
1325 avgtone /= dsp->busycount;
1326 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
1327#ifndef BUSYDETECT_TONEONLY
1328 if (avgsilence > dsp->historicsilence[x]) {
1329 if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
1330 hitsilence++;
1331 }
1332 } else {
1333 if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
1334 hitsilence++;
1335 }
1336 }
1337#endif
1338 if (avgtone > dsp->historicnoise[x]) {
1339 if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
1340 hittone++;
1341 }
1342 } else {
1343 if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
1344 hittone++;
1345 }
1346 }
1347 }
1348#ifndef BUSYDETECT_TONEONLY
1349 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
1350 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
1351 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX))
1352#else
1353 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX))
1354#endif
1355 {
1356#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1357 if (avgtone > avgsilence) {
1358 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
1359 res = 1;
1360 }
1361 } else {
1362 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
1363 res = 1;
1364 }
1365 }
1366#else
1367 res = 1;
1368#endif
1369 }
1370
1371 /* If we have a 4-length pattern, we can go ahead and just check it in a different way. */
1372 if (dsp->busy_cadence.length == 4) {
1373 int x;
1374 int errors = 0;
1375 int errors_max = ((4 * dsp->busycount) / 100.0) * BUSY_PAT_PERCENT;
1376
1377 for (x = DSP_HISTORY - (dsp->busycount); x < DSP_HISTORY; x += 2) {
1378 int temp_error;
1379 temp_error = abs(dsp->historicnoise[x] - dsp->busy_cadence.pattern[0]);
1380 if ((temp_error * 100) / dsp->busy_cadence.pattern[0] > BUSY_PERCENT) {
1381 errors++;
1382 }
1383
1384 temp_error = abs(dsp->historicnoise[x + 1] - dsp->busy_cadence.pattern[2]);
1385 if ((temp_error * 100) / dsp->busy_cadence.pattern[2] > BUSY_PERCENT) {
1386 errors++;
1387 }
1388
1389 temp_error = abs(dsp->historicsilence[x] - dsp->busy_cadence.pattern[1]);
1390 if ((temp_error * 100) / dsp->busy_cadence.pattern[1] > BUSY_PERCENT) {
1391 errors++;
1392 }
1393
1394 temp_error = abs(dsp->historicsilence[x + 1] - dsp->busy_cadence.pattern[3]);
1395 if ((temp_error * 100) / dsp->busy_cadence.pattern[3] > BUSY_PERCENT) {
1396 errors++;
1397 }
1398 }
1399
1400 ast_debug(5, "errors = %d max = %d\n", errors, errors_max);
1401
1402 if (errors <= errors_max) {
1403 return 1;
1404 }
1405 }
1406
1407 /* If we know the expected busy tone length, check we are in the range */
1408 if (res && (dsp->busy_cadence.pattern[0] > 0)) {
1409 if (abs(avgtone - dsp->busy_cadence.pattern[0]) > MAX(dsp->busy_cadence.pattern[0]*BUSY_PAT_PERCENT/100, 20)) {
1410#ifdef BUSYDETECT_DEBUG
1411 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
1412 avgtone, dsp->busy_cadence.pattern[0]);
1413#endif
1414 res = 0;
1415 }
1416 }
1417#ifndef BUSYDETECT_TONEONLY
1418 /* If we know the expected busy tone silent-period length, check we are in the range */
1419 if (res && (dsp->busy_cadence.pattern[1] > 0)) {
1420 if (abs(avgsilence - dsp->busy_cadence.pattern[1]) > MAX(dsp->busy_cadence.pattern[1]*BUSY_PAT_PERCENT/100, 20)) {
1421#ifdef BUSYDETECT_DEBUG
1422 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
1423 avgsilence, dsp->busy_cadence.pattern[1]);
1424#endif
1425 res = 0;
1426 }
1427 }
1428#endif
1429#if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
1430 if (res) {
1431 ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1432 } else {
1433 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1434 }
1435#endif
1436 return res;
1437}
1438
1439static int ast_dsp_silence_noise_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *total, int *frames_energy, int noise)
1440{
1441 short *s;
1442 int len;
1443 int x;
1444 unsigned char *odata;
1445
1446 if (!f) {
1447 return 0;
1448 }
1449
1450 if (f->frametype != AST_FRAME_VOICE) {
1451 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
1452 return 0;
1453 }
1454
1456 s = f->data.ptr;
1457 len = f->datalen/2;
1458 } else {
1459 odata = f->data.ptr;
1460 len = f->datalen;
1462 s = ast_alloca(len * 2);
1463 for (x = 0; x < len; x++) {
1464 s[x] = AST_MULAW(odata[x]);
1465 }
1467 s = ast_alloca(len * 2);
1468 for (x = 0; x < len; x++) {
1469 s[x] = AST_ALAW(odata[x]);
1470 }
1471 } else {
1472 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear, alaw or ulaw frames, %s not supported\n",
1474 return 0;
1475 }
1476 }
1477
1478 if (noise) {
1479 return __ast_dsp_silence_noise(dsp, s, len, NULL, total, frames_energy);
1480 } else {
1481 return __ast_dsp_silence_noise(dsp, s, len, total, NULL, frames_energy);
1482 }
1483}
1484
1485int ast_dsp_silence_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence, int *frames_energy)
1486{
1487 return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, frames_energy, 0);
1488}
1489
1490int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
1491{
1492 return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, NULL, 0);
1493}
1494
1495int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
1496{
1497 return ast_dsp_silence_noise_with_energy(dsp, f, totalnoise, NULL, 1);
1498}
1499
1500
1501struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
1502{
1503 int silence;
1504 int res;
1505 int digit = 0, fax_digit = 0, custom_freq_digit = 0;
1506 int x;
1507 short *shortdata;
1508 unsigned char *odata;
1509 int len;
1510 struct ast_frame *outf = NULL;
1511
1512 if (!af) {
1513 return NULL;
1514 }
1515 if (af->frametype != AST_FRAME_VOICE) {
1516 return af;
1517 }
1518
1519 odata = af->data.ptr;
1520 len = af->datalen;
1521 /* Make sure we have short data */
1523 shortdata = af->data.ptr;
1524 len = af->datalen / 2;
1526 shortdata = ast_alloca(af->datalen * 2);
1527 for (x = 0; x < len; x++) {
1528 shortdata[x] = AST_MULAW(odata[x]);
1529 }
1531 shortdata = ast_alloca(af->datalen * 2);
1532 for (x = 0; x < len; x++) {
1533 shortdata[x] = AST_ALAW(odata[x]);
1534 }
1535 } else {
1536 /* Display warning only once. Otherwise you would get hundreds of warnings every second */
1537 if (dsp->display_inband_dtmf_warning) {
1538 /* If DTMF is enabled for the DSP, try to be helpful and warn about that specifically,
1539 * otherwise emit a more generic message that covers all other cases. */
1541 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n",
1543 } else {
1544 ast_log(LOG_WARNING, "Can only do DSP on signed-linear, alaw or ulaw frames (%s not supported)\n",
1546 }
1547 }
1549 return af;
1550 }
1551
1552 /* Initially we do not want to mute anything */
1553 dsp->mute_fragments = 0;
1554
1555 /* Need to run the silence detection stuff for silence suppression and busy detection */
1557 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL, NULL);
1558 }
1559
1560 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
1561 memset(&dsp->f, 0, sizeof(dsp->f));
1562 dsp->f.frametype = AST_FRAME_NULL;
1563 ast_frfree(af);
1564 return ast_frisolate(&dsp->f);
1565 }
1568 memset(&dsp->f, 0, sizeof(dsp->f));
1571 ast_frfree(af);
1572 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", ast_channel_name(chan));
1573 return ast_frisolate(&dsp->f);
1574 }
1575
1576 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
1577 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
1578 fax_digit = 'f';
1579 }
1580
1581 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
1582 fax_digit = 'e';
1583 }
1584 }
1585
1586 if ((dsp->features & DSP_FEATURE_FREQ_DETECT)) {
1587 if ((dsp->freqmode) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
1588 custom_freq_digit = 'q';
1589 }
1590 }
1591
1593 if (dsp->digitmode & DSP_DIGITMODE_MF) {
1594 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1595 } else {
1596 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1597 }
1598
1599 if (dsp->digit_state.current_digits) {
1600 int event = 0, event_len = 0;
1601 char event_digit = 0;
1602
1603 if (!dsp->dtmf_began) {
1604 /* We have not reported DTMF_BEGIN for anything yet */
1605
1607 event = AST_FRAME_DTMF_BEGIN;
1608 event_digit = dsp->digit_state.digits[0];
1609 }
1610 dsp->dtmf_began = 1;
1611
1612 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
1613 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
1615 event = AST_FRAME_DTMF_END;
1616 event_digit = dsp->digit_state.digits[0];
1617 event_len = dsp->digit_state.digitlen[0] * 1000 / dsp->sample_rate;
1618 }
1619 memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
1620 memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
1622 dsp->dtmf_began = 0;
1623
1624 if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
1625 /* Reset Busy Detector as we have some confirmed activity */
1626 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1627 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
1628 ast_debug(1, "DTMF Detected - Reset busydetector\n");
1629 }
1630 }
1631
1632 if (event) {
1633 memset(&dsp->f, 0, sizeof(dsp->f));
1634 dsp->f.frametype = event;
1635 dsp->f.subclass.integer = event_digit;
1636 dsp->f.len = event_len;
1637 outf = &dsp->f;
1638 goto done;
1639 }
1640 }
1641 }
1642
1643 if (fax_digit) {
1644 /* Fax was detected - digit is either 'f' or 'e' */
1645
1646 memset(&dsp->f, 0, sizeof(dsp->f));
1647 dsp->f.frametype = AST_FRAME_DTMF;
1648 dsp->f.subclass.integer = fax_digit;
1649 outf = &dsp->f;
1650 goto done;
1651 }
1652
1653 if (custom_freq_digit) {
1654 /* Custom frequency was detected - digit is 'q' */
1655
1656 memset(&dsp->f, 0, sizeof(dsp->f));
1657 dsp->f.frametype = AST_FRAME_DTMF;
1658 dsp->f.subclass.integer = custom_freq_digit;
1659 outf = &dsp->f;
1660 goto done;
1661 }
1662
1663 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
1664 res = __ast_dsp_call_progress(dsp, shortdata, len);
1665 if (res) {
1666 switch (res) {
1667 case AST_CONTROL_ANSWER:
1668 case AST_CONTROL_BUSY:
1671 case AST_CONTROL_HANGUP:
1672 memset(&dsp->f, 0, sizeof(dsp->f));
1674 dsp->f.subclass.integer = res;
1675 dsp->f.src = "dsp_progress";
1676 if (chan) {
1677 ast_queue_frame(chan, &dsp->f);
1678 }
1679 break;
1680 default:
1681 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
1682 }
1683 }
1684 } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
1685 res = __ast_dsp_call_progress(dsp, shortdata, len);
1686 }
1687
1688done:
1689 /* Mute fragment of the frame */
1690 for (x = 0; x < dsp->mute_fragments; x++) {
1691 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
1692 }
1693
1695 for (x = 0; x < len; x++) {
1696 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
1697 }
1699 for (x = 0; x < len; x++) {
1700 odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
1701 }
1702 }
1703
1704 if (outf) {
1705 if (chan) {
1706 ast_queue_frame(chan, af);
1707 }
1708 ast_frfree(af);
1709 return ast_frisolate(outf);
1710 } else {
1711 return af;
1712 }
1713}
1714
1715static void ast_dsp_prog_reset(struct ast_dsp *dsp)
1716{
1717 int max = 0;
1718 int x;
1719
1720 dsp->gsamp_size = modes[dsp->progmode].size;
1721 dsp->gsamps = 0;
1722 for (x = 0; x < FREQ_ARRAY_SIZE; x++) {
1723 if (modes[dsp->progmode].freqs[x]) {
1724 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->sample_rate);
1725 max = x + 1;
1726 }
1727 }
1728 dsp->freqcount = max;
1729 dsp->ringtimeout = 0;
1730}
1731
1732unsigned int ast_dsp_get_sample_rate(const struct ast_dsp *dsp)
1733{
1734 return dsp->sample_rate;
1735}
1736
1737static struct ast_dsp *__ast_dsp_new(unsigned int sample_rate)
1738{
1739 struct ast_dsp *dsp;
1740
1741 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
1744 dsp->busycount = DSP_HISTORY;
1747 dsp->sample_rate = sample_rate;
1748 dsp->freqcount = 0;
1749 /* Initialize digit detector */
1752 /* Initialize initial DSP progress detect parameters */
1753 ast_dsp_prog_reset(dsp);
1754 /* Initialize fax detector */
1756 }
1757 return dsp;
1758}
1759
1761{
1763}
1764
1766{
1767 return __ast_dsp_new(sample_rate);
1768}
1769
1771{
1772 dsp->features = features;
1775 }
1776}
1777
1778
1780{
1781 return (dsp->features);
1782}
1783
1784
1785void ast_dsp_free(struct ast_dsp *dsp)
1786{
1787 ast_free(dsp);
1788}
1789
1791{
1792 dsp->threshold = threshold;
1793}
1794
1796{
1797 if (cadences < 4) {
1798 cadences = 4;
1799 }
1800 if (cadences > DSP_HISTORY) {
1802 }
1803 dsp->busycount = cadences;
1804}
1805
1806void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence)
1807{
1808 dsp->busy_cadence = *cadence;
1809 ast_debug(1, "dsp busy pattern set to %d,%d,%d,%d\n", cadence->pattern[0], cadence->pattern[1], (cadence->length == 4) ? cadence->pattern[2] : 0, (cadence->length == 4) ? cadence->pattern[3] : 0);
1810}
1811
1813{
1814 int i;
1815
1816 dsp->dtmf_began = 0;
1817 if (dsp->digitmode & DSP_DIGITMODE_MF) {
1819 /* Reinitialise the detector for the next block */
1820 for (i = 0; i < 6; i++) {
1821 goertzel_reset(&s->tone_out[i]);
1822 }
1823 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = 0;
1824 s->current_hit = 0;
1825 s->current_sample = 0;
1826 } else {
1828 /* Reinitialise the detector for the next block */
1829 for (i = 0; i < 4; i++) {
1830 goertzel_reset(&s->row_out[i]);
1831 goertzel_reset(&s->col_out[i]);
1832 }
1833 s->lasthit = 0;
1834 s->current_hit = 0;
1835 s->energy = 0.0;
1836 s->current_sample = 0;
1837 s->hits = 0;
1838 s->misses = 0;
1839 }
1840
1841 dsp->digit_state.digits[0] = '\0';
1842 dsp->digit_state.current_digits = 0;
1843}
1844
1845void ast_dsp_reset(struct ast_dsp *dsp)
1846{
1847 int x;
1848
1849 dsp->totalsilence = 0;
1850 dsp->gsamps = 0;
1851 for (x = 0; x < 4; x++) {
1852 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1853 }
1854 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1855 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
1856 dsp->ringtimeout = 0;
1857}
1858
1860{
1861 int new;
1862 int old;
1863
1866 if (old != new) {
1867 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1869 }
1870 dsp->digitmode = digitmode;
1871 return 0;
1872}
1873
1874int ast_dsp_set_freqmode(struct ast_dsp *dsp, int freq, int dur, int db, int squelch)
1875{
1876 if (freq > 0) {
1877 dsp->freqmode = 1;
1878 ast_freq_detect_init(dsp, freq, dur, db, squelch);
1879 } else {
1880 dsp->freqmode = 0;
1881 }
1882 return 0;
1883}
1884
1886{
1887 if (dsp->faxmode != faxmode) {
1888 dsp->faxmode = faxmode;
1890 }
1891 return 0;
1892}
1893
1894int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
1895{
1896 int x;
1897
1898 for (x = 0; x < ARRAY_LEN(aliases); x++) {
1899 if (!strcasecmp(aliases[x].name, zone)) {
1900 dsp->progmode = aliases[x].mode;
1901 ast_dsp_prog_reset(dsp);
1902 return 0;
1903 }
1904 }
1905 return -1;
1906}
1907
1909{
1910 return (dsp->mute_fragments > 0);
1911}
1912
1914{
1915 return dsp->tstate;
1916}
1917
1919{
1920 return dsp->tcount;
1921}
1922
1923static int _dsp_init(int reload)
1924{
1925 struct ast_config *cfg;
1926 struct ast_variable *v;
1927 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1928 int cfg_threshold;
1929 float cfg_twist;
1930
1931 if ((cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
1932 return 0;
1933 }
1934
1942
1944 return 0;
1945 }
1946
1947 for (v = ast_variable_browse(cfg, "default"); v; v = v->next) {
1948 if (!strcasecmp(v->name, "silencethreshold")) {
1949 if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1950 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1951 } else if (cfg_threshold < 0) {
1952 ast_log(LOG_WARNING, "Invalid silence threshold '%d' specified, using default\n", cfg_threshold);
1953 } else {
1954 thresholds[THRESHOLD_SILENCE] = cfg_threshold;
1955 }
1956 } else if (!strcasecmp(v->name, "dtmf_normal_twist")) {
1957 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1958 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1959 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1960 ast_log(LOG_WARNING, "Invalid dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_normal_twist);
1961 } else {
1962 dtmf_normal_twist = cfg_twist;
1963 }
1964 } else if (!strcasecmp(v->name, "dtmf_reverse_twist")) {
1965 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1966 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1967 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1968 ast_log(LOG_WARNING, "Invalid dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_reverse_twist);
1969 } else {
1970 dtmf_reverse_twist = cfg_twist;
1971 }
1972 } else if (!strcasecmp(v->name, "relax_dtmf_normal_twist")) {
1973 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1974 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1975 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1976 ast_log(LOG_WARNING, "Invalid relax_dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_normal_twist);
1977 } else {
1978 relax_dtmf_normal_twist = cfg_twist;
1979 }
1980 } else if (!strcasecmp(v->name, "relax_dtmf_reverse_twist")) {
1981 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1982 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1983 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1984 ast_log(LOG_WARNING, "Invalid relax_dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_reverse_twist);
1985 } else {
1986 relax_dtmf_reverse_twist = cfg_twist;
1987 }
1988 } else if (!strcasecmp(v->name, "dtmf_hits_to_begin")) {
1989 if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1990 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1991 } else if (cfg_threshold < 1) { /* must be 1 or greater */
1992 ast_log(LOG_WARNING, "Invalid dtmf_hits_to_begin value '%d' specified, using default of %d\n", cfg_threshold, dtmf_hits_to_begin);
1993 } else {
1994 dtmf_hits_to_begin = cfg_threshold;
1995 }
1996 } else if (!strcasecmp(v->name, "dtmf_misses_to_end")) {
1997 if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1998 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1999 } else if (cfg_threshold < 1) { /* must be 1 or greater */
2000 ast_log(LOG_WARNING, "Invalid dtmf_misses_to_end value '%d' specified, using default of %d\n", cfg_threshold, dtmf_misses_to_end);
2001 } else {
2002 dtmf_misses_to_end = cfg_threshold;
2003 }
2004 }
2005 }
2006 ast_config_destroy(cfg);
2007
2008 return 0;
2009}
2010
2012{
2013 return thresholds[which];
2014}
2015
2016#ifdef TEST_FRAMEWORK
2017static void test_tone_sample_gen(short *slin_buf, int samples, int rate, int freq, short amplitude)
2018{
2019 int idx;
2020 double sample_step = 2.0 * M_PI * freq / rate;/* radians per step */
2021
2022 for (idx = 0; idx < samples; ++idx) {
2023 slin_buf[idx] = amplitude * sin(sample_step * idx);
2024 }
2025}
2026#endif
2027
2028#ifdef TEST_FRAMEWORK
2029static void test_tone_sample_gen_add(short *slin_buf, int samples, int rate, int freq, short amplitude)
2030{
2031 int idx;
2032 double sample_step = 2.0 * M_PI * freq / rate;/* radians per step */
2033
2034 for (idx = 0; idx < samples; ++idx) {
2035 slin_buf[idx] += amplitude * sin(sample_step * idx);
2036 }
2037}
2038#endif
2039
2040#ifdef TEST_FRAMEWORK
2041static void test_dual_sample_gen(short *slin_buf, int samples, int rate, int f1, short a1, int f2, short a2)
2042{
2043 test_tone_sample_gen(slin_buf, samples, rate, f1, a1);
2044 test_tone_sample_gen_add(slin_buf, samples, rate, f2, a2);
2045}
2046#endif
2047
2048#ifdef TEST_FRAMEWORK
2049#define TONE_AMPLITUDE_MAX 0x7fff /* Max signed linear amplitude */
2050#define TONE_AMPLITUDE_MIN 80 /* Min signed linear amplitude detectable */
2051
2052static int test_tone_amplitude_sweep(struct ast_test *test, struct ast_dsp *dsp, tone_detect_state_t *tone_state)
2053{
2054 short slin_buf[tone_state->block_size];
2055 int result;
2056 int idx;
2057 struct {
2058 short amp_val;
2059 int detect;
2060 } amp_tests[] = {
2061 { .amp_val = TONE_AMPLITUDE_MAX, .detect = 1, },
2062 { .amp_val = 10000, .detect = 1, },
2063 { .amp_val = 1000, .detect = 1, },
2064 { .amp_val = 100, .detect = 1, },
2065 { .amp_val = TONE_AMPLITUDE_MIN, .detect = 1, },
2066 { .amp_val = 75, .detect = 0, },
2067 { .amp_val = 10, .detect = 0, },
2068 { .amp_val = 1, .detect = 0, },
2069 };
2070
2071 result = 0;
2072
2073 for (idx = 0; idx < ARRAY_LEN(amp_tests); ++idx) {
2074 int detected;
2075 int duration;
2076
2077 ast_debug(1, "Test %d Hz at amplitude %d\n",
2078 tone_state->freq, amp_tests[idx].amp_val);
2079 test_tone_sample_gen(slin_buf, tone_state->block_size, DEFAULT_SAMPLE_RATE,
2080 tone_state->freq, amp_tests[idx].amp_val);
2081
2082 detected = 0;
2083 for (duration = 0; !detected && duration < tone_state->hits_required + 3; ++duration) {
2084 detected = tone_detect(dsp, tone_state, slin_buf, tone_state->block_size) ? 1 : 0;
2085 }
2086 if (amp_tests[idx].detect != detected) {
2087 /*
2088 * Both messages are needed. ast_debug for when figuring out
2089 * what went wrong and the test update for normal output before
2090 * you start debugging. The different logging methods are not
2091 * synchronized.
2092 */
2093 ast_debug(1,
2094 "Test %d Hz at amplitude %d failed. Detected: %s\n",
2095 tone_state->freq, amp_tests[idx].amp_val,
2096 detected ? "yes" : "no");
2098 "Test %d Hz at amplitude %d failed. Detected: %s\n",
2099 tone_state->freq, amp_tests[idx].amp_val,
2100 detected ? "yes" : "no");
2101 result = -1;
2102 }
2103 tone_state->hit_count = 0;
2104 }
2105
2106 return result;
2107}
2108#endif
2109
2110#ifdef TEST_FRAMEWORK
2111static int test_dtmf_amplitude_sweep(struct ast_test *test, struct ast_dsp *dsp, int digit_index)
2112{
2113 short slin_buf[DTMF_GSIZE];
2114 int result;
2115 int row;
2116 int column;
2117 int idx;
2118 struct {
2119 short amp_val;
2120 int digit;
2121 } amp_tests[] = {
2122 /*
2123 * XXX Since there is no current DTMF level detection issue. This test
2124 * just checks the current detection levels.
2125 */
2126 { .amp_val = TONE_AMPLITUDE_MAX/2, .digit = dtmf_positions[digit_index], },
2127 { .amp_val = 10000, .digit = dtmf_positions[digit_index], },
2128 { .amp_val = 1000, .digit = dtmf_positions[digit_index], },
2129 { .amp_val = 500, .digit = dtmf_positions[digit_index], },
2130 { .amp_val = 250, .digit = dtmf_positions[digit_index], },
2131 { .amp_val = 200, .digit = dtmf_positions[digit_index], },
2132 { .amp_val = 180, .digit = dtmf_positions[digit_index], },
2133 /* Various digits detect and not detect in this range */
2134 { .amp_val = 170, .digit = 0, },
2135 { .amp_val = 100, .digit = 0, },
2136 /*
2137 * Amplitudes below TONE_AMPLITUDE_MIN start having questionable detection
2138 * over quantization and background noise.
2139 */
2140 { .amp_val = TONE_AMPLITUDE_MIN, .digit = 0, },
2141 { .amp_val = 75, .digit = 0, },
2142 { .amp_val = 10, .digit = 0, },
2143 { .amp_val = 1, .digit = 0, },
2144 };
2145
2146 row = (digit_index >> 2) & 0x03;
2147 column = digit_index & 0x03;
2148
2149 result = 0;
2150
2151 for (idx = 0; idx < ARRAY_LEN(amp_tests); ++idx) {
2152 int digit;
2153 int duration;
2154
2155 ast_debug(1, "Test '%c' at amplitude %d\n",
2156 dtmf_positions[digit_index], amp_tests[idx].amp_val);
2157 test_dual_sample_gen(slin_buf, ARRAY_LEN(slin_buf), DEFAULT_SAMPLE_RATE,
2158 (int) dtmf_row[row], amp_tests[idx].amp_val,
2159 (int) dtmf_col[column], amp_tests[idx].amp_val);
2160
2161 digit = 0;
2162 for (duration = 0; !digit && duration < 3; ++duration) {
2163 digit = dtmf_detect(dsp, &dsp->digit_state, slin_buf, ARRAY_LEN(slin_buf),
2164 0, 0);
2165 }
2166 if (amp_tests[idx].digit != digit) {
2167 /*
2168 * Both messages are needed. ast_debug for when figuring out
2169 * what went wrong and the test update for normal output before
2170 * you start debugging. The different logging methods are not
2171 * synchronized.
2172 */
2173 ast_debug(1,
2174 "Test '%c' at amplitude %d failed. Detected Digit: '%c'\n",
2175 dtmf_positions[digit_index], amp_tests[idx].amp_val,
2176 digit ?: ' ');
2178 "Test '%c' at amplitude %d failed. Detected Digit: '%c'\n",
2179 dtmf_positions[digit_index], amp_tests[idx].amp_val,
2180 digit ?: ' ');
2181 result = -1;
2182 }
2183 ast_dsp_digitreset(dsp);
2184 }
2185
2186 return result;
2187}
2188#endif
2189
2190#ifdef TEST_FRAMEWORK
2191static int test_dtmf_twist_sweep(struct ast_test *test, struct ast_dsp *dsp, int digit_index)
2192{
2193 short slin_buf[DTMF_GSIZE];
2194 int result;
2195 int row;
2196 int column;
2197 int idx;
2198 struct {
2199 short amp_row;
2200 short amp_col;
2201 int digit;
2202 } twist_tests[] = {
2203 /*
2204 * XXX Since there is no current DTMF twist detection issue. This test
2205 * just checks the current detection levels.
2206 *
2207 * Normal twist has the column higher than the row amplitude.
2208 * Reverse twist is the other way.
2209 */
2210 { .amp_row = 1000 + 1800, .amp_col = 1000 + 0, .digit = 0, },
2211 { .amp_row = 1000 + 1700, .amp_col = 1000 + 0, .digit = 0, },
2212 /* Various digits detect and not detect in this range */
2213 { .amp_row = 1000 + 1400, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2214 { .amp_row = 1000 + 1300, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2215 { .amp_row = 1000 + 1200, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2216 { .amp_row = 1000 + 1100, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2217 { .amp_row = 1000 + 1000, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2218 { .amp_row = 1000 + 100, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2219 { .amp_row = 1000 + 0, .amp_col = 1000 + 100, .digit = dtmf_positions[digit_index], },
2220 { .amp_row = 1000 + 0, .amp_col = 1000 + 200, .digit = dtmf_positions[digit_index], },
2221 { .amp_row = 1000 + 0, .amp_col = 1000 + 300, .digit = dtmf_positions[digit_index], },
2222 { .amp_row = 1000 + 0, .amp_col = 1000 + 400, .digit = dtmf_positions[digit_index], },
2223 { .amp_row = 1000 + 0, .amp_col = 1000 + 500, .digit = dtmf_positions[digit_index], },
2224 { .amp_row = 1000 + 0, .amp_col = 1000 + 550, .digit = dtmf_positions[digit_index], },
2225 /* Various digits detect and not detect in this range */
2226 { .amp_row = 1000 + 0, .amp_col = 1000 + 650, .digit = 0, },
2227 { .amp_row = 1000 + 0, .amp_col = 1000 + 700, .digit = 0, },
2228 { .amp_row = 1000 + 0, .amp_col = 1000 + 800, .digit = 0, },
2229 };
2230 float save_normal_twist;
2231 float save_reverse_twist;
2232
2233 save_normal_twist = dtmf_normal_twist;
2234 save_reverse_twist = dtmf_reverse_twist;
2237
2238 row = (digit_index >> 2) & 0x03;
2239 column = digit_index & 0x03;
2240
2241 result = 0;
2242
2243 for (idx = 0; idx < ARRAY_LEN(twist_tests); ++idx) {
2244 int digit;
2245 int duration;
2246
2247 ast_debug(1, "Test '%c' twist row %d col %d amplitudes\n",
2248 dtmf_positions[digit_index],
2249 twist_tests[idx].amp_row, twist_tests[idx].amp_col);
2250 test_dual_sample_gen(slin_buf, ARRAY_LEN(slin_buf), DEFAULT_SAMPLE_RATE,
2251 (int) dtmf_row[row], twist_tests[idx].amp_row,
2252 (int) dtmf_col[column], twist_tests[idx].amp_col);
2253
2254 digit = 0;
2255 for (duration = 0; !digit && duration < 3; ++duration) {
2256 digit = dtmf_detect(dsp, &dsp->digit_state, slin_buf, ARRAY_LEN(slin_buf),
2257 0, 0);
2258 }
2259 if (twist_tests[idx].digit != digit) {
2260 /*
2261 * Both messages are needed. ast_debug for when figuring out
2262 * what went wrong and the test update for normal output before
2263 * you start debugging. The different logging methods are not
2264 * synchronized.
2265 */
2266 ast_debug(1,
2267 "Test '%c' twist row %d col %d amplitudes failed. Detected Digit: '%c'\n",
2268 dtmf_positions[digit_index],
2269 twist_tests[idx].amp_row, twist_tests[idx].amp_col,
2270 digit ?: ' ');
2272 "Test '%c' twist row %d col %d amplitudes failed. Detected Digit: '%c'\n",
2273 dtmf_positions[digit_index],
2274 twist_tests[idx].amp_row, twist_tests[idx].amp_col,
2275 digit ?: ' ');
2276 result = -1;
2277 }
2278 ast_dsp_digitreset(dsp);
2279 }
2280
2281 dtmf_normal_twist = save_normal_twist;
2282 dtmf_reverse_twist = save_reverse_twist;
2283
2284 return result;
2285}
2286#endif
2287
2288#ifdef TEST_FRAMEWORK
2289static int test_tone_freq_sweep(struct ast_test *test, struct ast_dsp *dsp, tone_detect_state_t *tone_state, short amplitude)
2290{
2291 short slin_buf[tone_state->block_size];
2292 int result;
2293 int freq;
2294 int lower_freq;
2295 int upper_freq;
2296
2297 /* Calculate detection frequency range */
2298 lower_freq = tone_state->freq - 4;
2299 upper_freq = tone_state->freq + 4;
2300
2301 result = 0;
2302
2303 /* Sweep frequencies loop. */
2304 for (freq = 100; freq <= 3500; freq += 1) {
2305 int detected;
2306 int duration;
2307 int expect_detection;
2308
2309 if (freq == tone_state->freq) {
2310 /* This case is done by the amplitude sweep. */
2311 continue;
2312 }
2313
2314 expect_detection = (lower_freq <= freq && freq <= upper_freq) ? 1 : 0;
2315
2316 ast_debug(1, "Test %d Hz detection given %d Hz tone at amplitude %d. Range:%d-%d Expect detect: %s\n",
2317 tone_state->freq, freq, amplitude, lower_freq, upper_freq,
2318 expect_detection ? "yes" : "no");
2319 test_tone_sample_gen(slin_buf, tone_state->block_size, DEFAULT_SAMPLE_RATE, freq,
2320 amplitude);
2321
2322 detected = 0;
2323 for (duration = 0; !detected && duration < tone_state->hits_required + 3; ++duration) {
2324 detected = tone_detect(dsp, tone_state, slin_buf, tone_state->block_size) ? 1 : 0;
2325 }
2326 if (expect_detection != detected) {
2327 /*
2328 * Both messages are needed. ast_debug for when figuring out
2329 * what went wrong and the test update for normal output before
2330 * you start debugging. The different logging methods are not
2331 * synchronized.
2332 */
2333 ast_debug(1,
2334 "Test %d Hz detection given %d Hz tone at amplitude %d failed. Range:%d-%d Detected: %s\n",
2335 tone_state->freq, freq, amplitude, lower_freq, upper_freq,
2336 detected ? "yes" : "no");
2338 "Test %d Hz detection given %d Hz tone at amplitude %d failed. Range:%d-%d Detected: %s\n",
2339 tone_state->freq, freq, amplitude, lower_freq, upper_freq,
2340 detected ? "yes" : "no");
2341 result = -1;
2342 }
2343 tone_state->hit_count = 0;
2344 }
2345
2346 return result;
2347}
2348#endif
2349
2350#ifdef TEST_FRAMEWORK
2351AST_TEST_DEFINE(test_dsp_fax_detect)
2352{
2353 struct ast_dsp *dsp;
2355
2356 switch (cmd) {
2357 case TEST_INIT:
2358 info->name = "fax";
2359 info->category = "/main/dsp/";
2360 info->summary = "DSP fax tone detect unit test";
2361 info->description =
2362 "Tests fax tone detection code.";
2363 return AST_TEST_NOT_RUN;
2364 case TEST_EXECUTE:
2365 break;
2366 }
2367
2368 dsp = ast_dsp_new();
2369 if (!dsp) {
2370 return AST_TEST_FAIL;
2371 }
2372
2374
2375 /* Test CNG tone amplitude detection */
2376 if (test_tone_amplitude_sweep(test, dsp, &dsp->cng_tone_state)) {
2378 }
2379
2380 /* Test CED tone amplitude detection */
2381 if (test_tone_amplitude_sweep(test, dsp, &dsp->ced_tone_state)) {
2383 }
2384
2385 /* Test CNG tone frequency detection */
2386 if (test_tone_freq_sweep(test, dsp, &dsp->cng_tone_state, TONE_AMPLITUDE_MAX)) {
2388 }
2389 if (test_tone_freq_sweep(test, dsp, &dsp->cng_tone_state, TONE_AMPLITUDE_MIN)) {
2391 }
2392
2393 /* Test CED tone frequency detection */
2394 if (test_tone_freq_sweep(test, dsp, &dsp->ced_tone_state, TONE_AMPLITUDE_MAX)) {
2396 }
2397 if (test_tone_freq_sweep(test, dsp, &dsp->ced_tone_state, TONE_AMPLITUDE_MIN)) {
2399 }
2400
2401 ast_dsp_free(dsp);
2402 return result;
2403}
2404#endif
2405
2406#ifdef TEST_FRAMEWORK
2407AST_TEST_DEFINE(test_dsp_dtmf_detect)
2408{
2409 int idx;
2410 struct ast_dsp *dsp;
2412
2413 switch (cmd) {
2414 case TEST_INIT:
2415 info->name = "dtmf";
2416 info->category = "/main/dsp/";
2417 info->summary = "DSP DTMF detect unit test";
2418 info->description =
2419 "Tests DTMF detection code.";
2420 return AST_TEST_NOT_RUN;
2421 case TEST_EXECUTE:
2422 break;
2423 }
2424
2425 dsp = ast_dsp_new();
2426 if (!dsp) {
2427 return AST_TEST_FAIL;
2428 }
2429
2431
2432 for (idx = 0; dtmf_positions[idx]; ++idx) {
2433 if (test_dtmf_amplitude_sweep(test, dsp, idx)) {
2435 }
2436 }
2437
2438 for (idx = 0; dtmf_positions[idx]; ++idx) {
2439 if (test_dtmf_twist_sweep(test, dsp, idx)) {
2441 }
2442 }
2443
2444 ast_dsp_free(dsp);
2445 return result;
2446}
2447#endif
2448
2449static int unload_module(void)
2450{
2451 AST_TEST_UNREGISTER(test_dsp_fax_detect);
2452 AST_TEST_UNREGISTER(test_dsp_dtmf_detect);
2453
2454 return 0;
2455}
2456
2457static int load_module(void)
2458{
2459 if (_dsp_init(0)) {
2461 }
2462
2463 AST_TEST_REGISTER(test_dsp_fax_detect);
2464 AST_TEST_REGISTER(test_dsp_dtmf_detect);
2465
2467}
2468
2469static int reload_module(void)
2470{
2471 return _dsp_init(1);
2472}
2473
2475 .support_level = AST_MODULE_SUPPORT_CORE,
2476 .load = load_module,
2477 .unload = unload_module,
2479 .load_pri = AST_MODPRI_CORE,
2480 .requires = "extconfig",
A-Law to Signed linear conversion.
#define AST_LIN2A(a)
Definition: alaw.h:50
#define AST_ALAW(a)
Definition: alaw.h:84
char digit
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
static sqlite3 * db
static PGresult * result
Definition: cel_pgsql.c:84
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
Definition: chan_dahdi.c:765
unsigned int cos
Definition: chan_iax2.c:380
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1170
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1141
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
static void ast_mf_detect_init(mf_detect_state_t *s, unsigned int sample_rate)
Definition: dsp.c:549
static int thresholds[THRESHOLD_MAX]
Definition: dsp.c:330
#define DEF_DTMF_HITS_TO_BEGIN
Definition: dsp.c:234
void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
Set the minimum average magnitude threshold to determine talking by the DSP.
Definition: dsp.c:1790
#define BELL_MF_THRESHOLD
Definition: dsp.c:200
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1785
int ast_dsp_get_tcount(struct ast_dsp *dsp)
Get tcount (Threshold counter)
Definition: dsp.c:1918
#define DEFAULT_THRESHOLD
Default minimum average magnitude threshold to determine talking/noise by the DSP.
Definition: dsp.c:140
#define DEF_DTMF_REVERSE_TWIST
Definition: dsp.c:192
static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp, unsigned int sample_rate)
Definition: dsp.c:452
gsamp_thresh
Definition: dsp.c:157
@ THRESH_RING
Definition: dsp.c:158
@ THRESH_CONGESTION
Definition: dsp.c:161
@ THRESH_RING2ANSWER
Definition: dsp.c:163
@ THRESH_TALK
Definition: dsp.c:159
@ THRESH_HANGUP
Definition: dsp.c:162
@ THRESH_BUSY
Definition: dsp.c:160
#define FAX_TONE_CED_DB
Definition: dsp.c:221
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress,...
Definition: dsp.c:1501
#define DTMF_TO_TOTAL_ENERGY
Definition: dsp.c:198
#define BELL_MF_RELATIVE_PEAK
Definition: dsp.c:202
#define DEF_DTMF_MISSES_TO_END
Definition: dsp.c:239
static const int DEFAULT_SILENCE_THRESHOLD
The default silence threshold we will use if an alternate configured value is not present or is inval...
Definition: dsp.c:245
static const char dtmf_positions[]
Definition: dsp.c:328
static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
Definition: dsp.c:1079
#define DTMF_MATRIX_SIZE
Definition: dsp.c:168
static void goertzel_init(goertzel_state_t *s, float freq, unsigned int sample_rate)
Definition: dsp.c:378
static struct progalias aliases[]
static int _dsp_init(int reload)
Definition: dsp.c:1923
static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
Definition: dsp.c:575
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
Definition: dsp.c:1490
#define FAX_TONE_CNG_FREQ
Definition: dsp.c:211
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
Definition: dsp.c:1812
#define DEF_RELAX_DTMF_NORMAL_TWIST
Definition: dsp.c:186
static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
Definition: dsp.c:905
struct ast_dsp * ast_dsp_new_with_rate(unsigned int sample_rate)
Allocates a new dsp with a specific internal sample rate used during processing.
Definition: dsp.c:1765
#define FAX_TONE_CED_DURATION
Definition: dsp.c:220
#define DTMF_THRESHOLD
Definition: dsp.c:182
#define TONE_MIN_THRESH
Definition: dsp.c:154
static const char bell_mf_positions[]
Definition: dsp.c:329
static void ast_fax_detect_init(struct ast_dsp *s)
Definition: dsp.c:513
#define MAX_DTMF_DIGITS
Definition: dsp.c:166
int ast_dsp_silence_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence, int *frames_energy)
Process the audio frame for silence.
Definition: dsp.c:1485
#define DEF_DTMF_NORMAL_TWIST
Definition: dsp.c:185
#define CONFIG_FILE_NAME
Definition: dsp.c:247
static float goertzel_result(goertzel_state_t *s)
Definition: dsp.c:364
#define FAX_TONE_CNG_DB
Definition: dsp.c:213
int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
Scans for progress indication in audio.
Definition: dsp.c:1221
void ast_dsp_reset(struct ast_dsp *dsp)
Reset total silence count.
Definition: dsp.c:1845
static void ast_freq_detect_init(struct ast_dsp *s, int freq, int dur, int db, int squelch)
Definition: dsp.c:524
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence)
Set expected lengths of the busy tone.
Definition: dsp.c:1806
unsigned int ast_dsp_get_sample_rate(const struct ast_dsp *dsp)
Retrieve the sample rate this DSP structure was created with.
Definition: dsp.c:1732
#define FAX_TONE_CED_FREQ
Definition: dsp.c:219
static int reload_module(void)
Definition: dsp.c:2469
#define DTMF_RELATIVE_PEAK_COL
Definition: dsp.c:197
static struct progress modes[]
#define DTMF_GSIZE
Definition: dsp.c:229
static const float dtmf_row[]
Definition: dsp.c:319
static void goertzel_sample(goertzel_state_t *s, short sample)
Definition: dsp.c:338
#define DEF_RELAX_DTMF_REVERSE_TWIST
Definition: dsp.c:193
static int pair_there(float p1, float p2, float i1, float i2, float e)
Definition: dsp.c:1056
static const float mf_tones[]
Definition: dsp.c:325
static float dtmf_reverse_twist
Definition: dsp.c:332
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
Definition: dsp.c:1779
#define TONE_THRESHOLD
Definition: dsp.c:183
busy_detect
Definition: dsp.c:142
@ BUSY_MAX
Definition: dsp.c:147
@ BUSY_PAT_PERCENT
Definition: dsp.c:144
@ BUSY_MIN
Definition: dsp.c:146
@ BUSY_PERCENT
Definition: dsp.c:143
@ BUSY_THRESHOLD
Definition: dsp.c:145
prog_mode
Definition: dsp.c:79
@ PROG_MODE_CR
Definition: dsp.c:81
@ PROG_MODE_UK
Definition: dsp.c:82
@ PROG_MODE_NA
Definition: dsp.c:80
static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
Definition: dsp.c:697
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1859
freq_index
Definition: dsp.c:85
@ HZ_425
Definition: dsp.c:96
@ HZ_950
Definition: dsp.c:91
@ HZ_350UK
Definition: dsp.c:99
@ HZ_620
Definition: dsp.c:90
@ HZ_440
Definition: dsp.c:88
@ HZ_440UK
Definition: dsp.c:101
@ HZ_480
Definition: dsp.c:89
@ HZ_350
Definition: dsp.c:87
@ HZ_1400
Definition: dsp.c:92
@ HZ_400UK
Definition: dsp.c:100
@ HZ_1800
Definition: dsp.c:93
static void goertzel_reset(goertzel_state_t *s)
Definition: dsp.c:384
static int ast_dsp_silence_noise_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *total, int *frames_energy, int noise)
Definition: dsp.c:1439
gsamp_size
Definition: dsp.c:73
@ GSAMP_SIZE_NA
Definition: dsp.c:74
@ GSAMP_SIZE_CR
Definition: dsp.c:75
@ GSAMP_SIZE_UK
Definition: dsp.c:76
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:2011
static void ast_dtmf_detect_init(dtmf_detect_state_t *s, unsigned int sample_rate)
Definition: dsp.c:533
#define FREQ_ARRAY_SIZE
Definition: dsp.c:115
static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
Definition: dsp.c:442
#define DTMF_RELATIVE_PEAK_ROW
Definition: dsp.c:196
#define DSP_HISTORY
Definition: dsp.c:151
static int dtmf_misses_to_end
Definition: dsp.c:336
static int dtmf_hits_to_begin
Definition: dsp.c:335
#define DEFAULT_SAMPLE_RATE
Definition: dsp.c:223
static int load_module(void)
Definition: dsp.c:2457
int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
Process the audio frame for noise.
Definition: dsp.c:1495
int ast_dsp_get_tstate(struct ast_dsp *dsp)
Get tstate (Tone State)
Definition: dsp.c:1913
int ast_dsp_was_muted(struct ast_dsp *dsp)
Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) hap...
Definition: dsp.c:1908
static int unload_module(void)
Definition: dsp.c:2449
static float relax_dtmf_normal_twist
Definition: dsp.c:333
int ast_dsp_busydetect(struct ast_dsp *dsp)
Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been ...
Definition: dsp.c:1301
static void store_digit(digit_detect_state_t *s, char digit)
Definition: dsp.c:684
int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
Set fax mode.
Definition: dsp.c:1885
static void ast_digit_detect_init(digit_detect_state_t *s, int mf, unsigned int sample_rate)
Definition: dsp.c:561
#define BELL_MF_TWIST
Definition: dsp.c:201
static const float dtmf_col[]
Definition: dsp.c:322
#define MF_GSIZE
Definition: dsp.c:226
#define FAX_TONE_CNG_DURATION
Definition: dsp.c:212
int ast_dsp_set_freqmode(struct ast_dsp *dsp, int freq, int dur, int db, int squelch)
Set arbitrary frequency detection mode.
Definition: dsp.c:1874
static struct ast_dsp * __ast_dsp_new(unsigned int sample_rate)
Definition: dsp.c:1737
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
Set number of required cadences for busy.
Definition: dsp.c:1795
static float dtmf_normal_twist
Definition: dsp.c:331
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1770
static float relax_dtmf_reverse_twist
Definition: dsp.c:334
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1760
static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise, int *frames_energy)
Definition: dsp.c:1235
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
Set zone for doing progress detection.
Definition: dsp.c:1894
#define TONE_THRESH
Definition: dsp.c:153
static void ast_dsp_prog_reset(struct ast_dsp *dsp)
Definition: dsp.c:1715
Convenient Signal Processing routines.
threshold
Definition: dsp.h:71
@ THRESHOLD_SILENCE
Definition: dsp.h:73
@ THRESHOLD_MAX
Definition: dsp.h:75
#define DSP_PROGRESS_RINGING
Definition: dsp.h:40
#define DSP_TONE_STATE_SPECIAL3
Definition: dsp.h:59
#define DSP_FEATURE_WAITDIALTONE
Definition: dsp.h:44
#define DSP_TONE_STATE_SPECIAL2
Definition: dsp.h:58
#define DSP_FEATURE_BUSY_DETECT
Definition: dsp.h:27
#define DSP_TONE_STATE_DIALTONE
Definition: dsp.h:54
#define DSP_PROGRESS_TALK
Definition: dsp.h:39
#define DSP_TONE_STATE_SILENCE
Definition: dsp.h:52
#define DSP_DIGITMODE_NOQUELCH
Definition: dsp.h:34
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
#define DSP_TONE_STATE_BUSY
Definition: dsp.h:56
#define DSP_DIGITMODE_MUTEMAX
Definition: dsp.h:36
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
#define DSP_PROGRESS_BUSY
Definition: dsp.h:41
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
#define DSP_TONE_STATE_SPECIAL1
Definition: dsp.h:57
#define DSP_FAXMODE_DETECT_SQUELCH
Definition: dsp.h:49
#define DSP_FAXMODE_DETECT_CED
Definition: dsp.h:48
#define DSP_PROGRESS_CONGESTION
Definition: dsp.h:42
#define DSP_FEATURE_CALL_PROGRESS
Definition: dsp.h:43
#define DSP_DIGITMODE_MUTECONF
Definition: dsp.h:35
#define DSP_FAXMODE_DETECT_CNG
Definition: dsp.h:47
#define DSP_FEATURE_SILENCE_SUPPRESS
Definition: dsp.h:26
#define DSP_TONE_STATE_HUNGUP
Definition: dsp.h:60
#define DSP_FEATURE_FREQ_DETECT
Definition: dsp.h:45
#define DSP_TONE_STATE_TALKING
Definition: dsp.h:55
#define DSP_TONE_STATE_RINGING
Definition: dsp.h:53
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
char * end
Definition: eagi_proxy.c:73
#define abs(x)
Definition: f2c.h:195
#define max(a, b)
Definition: f2c.h:198
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
Media Format Cache API.
int ast_format_cache_is_slinear(struct ast_format *format)
Determines if a format is one of the cached slin formats.
Definition: format_cache.c:534
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
static const char name[]
Definition: format_mp3.c:68
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Configuration File Parser.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3541
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1287
@ CONFIG_FLAG_FILEUNCHANGED
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1213
Asterisk internal frame definitions.
#define AST_FRAME_DTMF
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
#define ast_frfree(fr)
@ AST_FRAME_NULL
@ AST_FRAME_DTMF_END
@ AST_FRAME_DTMF_BEGIN
@ AST_FRAME_VOICE
@ AST_FRAME_CONTROL
@ AST_CONTROL_BUSY
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_WARNING
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:331
@ AST_MODFLAG_GLOBAL_SYMBOLS
Definition: module.h:330
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:557
@ AST_MODPRI_CORE
Definition: module.h:338
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
def info(msg)
Options provided by main asterisk program.
static int total
Definition: res_adsi.c:970
static char pass[512]
static int reload(void)
#define NULL
Definition: resample.c:96
#define M_PI
Definition: resample.c:83
Main Channel structure associated with a channel.
int pattern[4]
Definition: dsp.h:68
Definition: dsp.c:407
fragment_t mute_data[5]
Definition: dsp.c:436
int historicnoise[DSP_HISTORY]
Definition: dsp.c:419
int tcount
Definition: dsp.c:427
int faxmode
Definition: dsp.c:429
unsigned int sample_rate
Definition: dsp.c:435
int busymaybe
Definition: dsp.c:416
int mute_fragments
Definition: dsp.c:434
int busycount
Definition: dsp.c:417
int totalsilence
Definition: dsp.c:411
goertzel_state_t freqs[FREQ_ARRAY_SIZE]
Definition: dsp.c:421
int tstate
Definition: dsp.c:426
int threshold
Definition: dsp.c:409
struct ast_frame f
Definition: dsp.c:408
digit_detect_state_t digit_state
Definition: dsp.c:437
int totalnoise
Definition: dsp.c:413
tone_detect_state_t ced_tone_state
Definition: dsp.c:439
int historicsilence[DSP_HISTORY]
Definition: dsp.c:420
enum prog_mode progmode
Definition: dsp.c:425
int freqcount
Definition: dsp.c:422
int features
Definition: dsp.c:414
int digitmode
Definition: dsp.c:428
enum gsamp_size gsamp_size
Definition: dsp.c:424
int display_inband_dtmf_warning
Definition: dsp.c:432
int dtmf_began
Definition: dsp.c:431
float genergy
Definition: dsp.c:433
int freqmode
Definition: dsp.c:430
int gsamps
Definition: dsp.c:423
int ringtimeout
Definition: dsp.c:415
struct ast_dsp_busy_pattern busy_cadence
Definition: dsp.c:418
tone_detect_state_t cng_tone_state
Definition: dsp.c:438
Structure used to handle boolean flags.
Definition: utils.h:217
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
union ast_frame::@231 data
const char * src
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
int detected_digits
Definition: dsp.c:310
mf_detect_state_t mf
Definition: dsp.c:315
union digit_detect_state_t::@351 td
dtmf_detect_state_t dtmf
Definition: dsp.c:314
int digitlen[MAX_DTMF_DIGITS+1]
Definition: dsp.c:308
char digits[MAX_DTMF_DIGITS+1]
Definition: dsp.c:307
int current_digits
Definition: dsp.c:309
float energy
Definition: dsp.c:291
goertzel_state_t row_out[DTMF_MATRIX_SIZE]
Definition: dsp.c:285
goertzel_state_t col_out[DTMF_MATRIX_SIZE]
Definition: dsp.c:286
int mute_samples
Definition: dsp.c:293
int current_sample
Definition: dsp.c:292
Definition: astman.c:222
int start
Definition: dsp.c:390
int end
Definition: dsp.c:391
int chunky
Definition: dsp.c:255
int mute_samples
Definition: dsp.c:302
int hits[5]
Definition: dsp.c:300
goertzel_state_t tone_out[6]
Definition: dsp.c:298
int current_hit
Definition: dsp.c:299
int current_sample
Definition: dsp.c:301
Definition: dsp.c:104
char * name
Definition: dsp.c:105
enum prog_mode mode
Definition: dsp.c:106
Definition: dsp.c:117
enum gsamp_size size
Definition: dsp.c:118
int freqs[FREQ_ARRAY_SIZE]
Definition: dsp.c:119
float energy
Definition: dsp.c:271
float threshold
Definition: dsp.c:276
int mute_samples
Definition: dsp.c:273
goertzel_state_t tone
Definition: dsp.c:270
int samples_pending
Definition: dsp.c:272
int hits_required
Definition: dsp.c:275
Test Framework API.
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
#define AST_TEST_DEFINE(hdr)
Definition: test.h:126
ast_test_result_state
Definition: test.h:193
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
int done
Definition: test_amihooks.c:48
u-Law to Signed linear conversion
#define AST_MULAW(a)
Definition: ulaw.h:85
#define AST_LIN2MU(a)
Definition: ulaw.h:49
Utility functions.
#define ARRAY_LEN(a)
Definition: utils.h:703
#define MAX(a, b)
Definition: utils.h:251