Asterisk - The Open Source Telephony Project GIT-master-a63eec2
Loading...
Searching...
No Matches
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
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
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, 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 if (s->hit_count) {
639 ast_debug(9, "Partial detect expired after %d/%d hits\n", s->hit_count, s->hits_required);
640 }
641 s->hit_count = 0;
642 } else if (!s->hit_count) {
643 s->hit_count++;
644 }
645 }
646
647 if (s->hit_count == s->hits_required) {
648 ast_debug(1, "%d Hz tone detected\n", s->freq);
649 res = 1;
650 }
651
652 s->last_hit = hit;
653
654 /* If we had a hit in this block, include it into mute fragment */
655 if (s->squelch && hit) {
656 if (mute.end < start - s->block_size) {
657 /* There is a gap between fragments */
658 mute_fragment(dsp, &mute);
659 mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
660 }
661 mute.end = end + s->block_size;
662 }
663
664 /* Reinitialise the detector for the next block */
665 /* Reset for the next block */
666 goertzel_reset(&s->tone);
667
668 /* Advance to the next block */
669 s->energy = 0.0;
671
672 amp += limit;
673 }
674
675 if (s->squelch && mute.end) {
676 if (mute.end > samples) {
677 s->mute_samples = mute.end - samples;
678 mute.end = samples;
679 }
680 mute_fragment(dsp, &mute);
681 }
682
683 return res;
684}
685
687{
688 s->detected_digits++;
690 s->digitlen[s->current_digits] = 0;
691 s->digits[s->current_digits++] = digit;
692 s->digits[s->current_digits] = '\0';
693 } else {
694 ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
695 s->lost_digits++;
696 }
697}
698
699static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
700{
701 float row_energy[DTMF_MATRIX_SIZE];
702 float col_energy[DTMF_MATRIX_SIZE];
703 int i;
704 int j;
705 int sample;
706 short samp;
707 int best_row;
708 int best_col;
709 int hit;
710 int limit;
711 fragment_t mute = {0, 0};
712
713 if (squelch && s->td.dtmf.mute_samples > 0) {
714 mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
715 s->td.dtmf.mute_samples -= mute.end;
716 }
717
718 hit = 0;
719 for (sample = 0; sample < samples; sample = limit) {
720 /* DTMF_GSIZE is optimised to meet the DTMF specs. */
721 if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
722 limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
723 } else {
724 limit = samples;
725 }
726 /* The following unrolled loop takes only 35% (rough estimate) of the
727 time of a rolled loop on the machine on which it was developed */
728 for (j = sample; j < limit; j++) {
729 samp = amp[j];
730 s->td.dtmf.energy += (int32_t) samp * (int32_t) samp;
731 /* With GCC 2.95, the following unrolled code seems to take about 35%
732 (rough estimate) as long as a neat little 0-3 loop */
733 goertzel_sample(s->td.dtmf.row_out, samp);
734 goertzel_sample(s->td.dtmf.col_out, samp);
735 goertzel_sample(s->td.dtmf.row_out + 1, samp);
736 goertzel_sample(s->td.dtmf.col_out + 1, samp);
737 goertzel_sample(s->td.dtmf.row_out + 2, samp);
738 goertzel_sample(s->td.dtmf.col_out + 2, samp);
739 goertzel_sample(s->td.dtmf.row_out + 3, samp);
740 goertzel_sample(s->td.dtmf.col_out + 3, samp);
741 /* go up to DTMF_MATRIX_SIZE - 1 */
742 }
743 s->td.dtmf.current_sample += (limit - sample);
744 if (s->td.dtmf.current_sample < DTMF_GSIZE) {
745 continue;
746 }
747 /* We are at the end of a DTMF detection block */
748 /* Find the peak row and the peak column */
749 row_energy[0] = goertzel_result(&s->td.dtmf.row_out[0]);
750 col_energy[0] = goertzel_result(&s->td.dtmf.col_out[0]);
751
752 for (best_row = best_col = 0, i = 1; i < DTMF_MATRIX_SIZE; i++) {
753 row_energy[i] = goertzel_result(&s->td.dtmf.row_out[i]);
754 if (row_energy[i] > row_energy[best_row]) {
755 best_row = i;
756 }
757 col_energy[i] = goertzel_result(&s->td.dtmf.col_out[i]);
758 if (col_energy[i] > col_energy[best_col]) {
759 best_col = i;
760 }
761 }
762 ast_debug(10, "DTMF best '%c' Erow=%.4E Ecol=%.4E Erc=%.4E Et=%.4E\n",
763 dtmf_positions[(best_row << 2) + best_col],
764 row_energy[best_row], col_energy[best_col],
765 row_energy[best_row] + col_energy[best_col], s->td.dtmf.energy);
766 hit = 0;
767 /* Basic signal level test and the twist test */
768 if (row_energy[best_row] >= DTMF_THRESHOLD &&
769 col_energy[best_col] >= DTMF_THRESHOLD &&
770 col_energy[best_col] < row_energy[best_row] * (relax ? relax_dtmf_reverse_twist : dtmf_reverse_twist) &&
771 row_energy[best_row] < col_energy[best_col] * (relax ? relax_dtmf_normal_twist : dtmf_normal_twist)) {
772 /* Relative peak test */
773 for (i = 0; i < DTMF_MATRIX_SIZE; i++) {
774 if ((i != best_col &&
775 col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
776 (i != best_row
777 && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
778 break;
779 }
780 }
781 /* ... and fraction of total energy test */
782 if (i >= DTMF_MATRIX_SIZE &&
783 (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
784 /* Got a hit */
785 hit = dtmf_positions[(best_row << 2) + best_col];
786 ast_debug(10, "DTMF hit '%c'\n", hit);
787 }
788 }
789
790/*
791 * Adapted from ETSI ES 201 235-3 V1.3.1 (2006-03)
792 * (40ms reference is tunable with hits_to_begin and misses_to_end)
793 * each hit/miss is 12.75ms with DTMF_GSIZE at 102
794 *
795 * Character recognition: When not DRC *(1) and then
796 * Shall exist VSC > 40 ms (hits_to_begin)
797 * May exist 20 ms <= VSC <= 40 ms
798 * Shall not exist VSC < 20 ms
799 *
800 * Character recognition: When DRC and then
801 * Shall cease Not VSC > 40 ms (misses_to_end)
802 * May cease 20 ms >= Not VSC >= 40 ms
803 * Shall not cease Not VSC < 20 ms
804 *
805 * *(1) or optionally a different digit recognition condition
806 *
807 * Legend: VSC The continuous existence of a valid signal condition.
808 * Not VSC The continuous non-existence of valid signal condition.
809 * DRC The existence of digit recognition condition.
810 * Not DRC The non-existence of digit recognition condition.
811 */
812
813/*
814 * Example: hits_to_begin=2 misses_to_end=3
815 * -------A last_hit=A hits=0&1
816 * ------AA hits=2 current_hit=A misses=0 BEGIN A
817 * -----AA- misses=1 last_hit=' ' hits=0
818 * ----AA-- misses=2
819 * ---AA--- misses=3 current_hit=' ' END A
820 * --AA---B last_hit=B hits=0&1
821 * -AA---BC last_hit=C hits=0&1
822 * AA---BCC hits=2 current_hit=C misses=0 BEGIN C
823 * A---BCC- misses=1 last_hit=' ' hits=0
824 * ---BCC-C misses=0 last_hit=C hits=0&1
825 * --BCC-CC misses=0
826 *
827 * Example: hits_to_begin=3 misses_to_end=2
828 * -------A last_hit=A hits=0&1
829 * ------AA hits=2
830 * -----AAA hits=3 current_hit=A misses=0 BEGIN A
831 * ----AAAB misses=1 last_hit=B hits=0&1
832 * ---AAABB misses=2 current_hit=' ' hits=2 END A
833 * --AAABBB hits=3 current_hit=B misses=0 BEGIN B
834 * -AAABBBB misses=0
835 *
836 * Example: hits_to_begin=2 misses_to_end=2
837 * -------A last_hit=A hits=0&1
838 * ------AA hits=2 current_hit=A misses=0 BEGIN A
839 * -----AAB misses=1 hits=0&1
840 * ----AABB misses=2 current_hit=' ' hits=2 current_hit=B misses=0 BEGIN B
841 * ---AABBB misses=0
842 */
843
844 if (s->td.dtmf.current_hit) {
845 /* We are in the middle of a digit already */
846 if (hit != s->td.dtmf.current_hit) {
847 s->td.dtmf.misses++;
848 if (s->td.dtmf.misses == dtmf_misses_to_end) {
849 /* There were enough misses to consider digit ended */
850 s->td.dtmf.current_hit = 0;
851 }
852 } else {
853 s->td.dtmf.misses = 0;
854 /* Current hit was same as last, so increment digit duration (of last digit) */
855 s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
856 }
857 }
858
859 /* Look for a start of a new digit no matter if we are already in the middle of some
860 digit or not. This is because hits_to_begin may be smaller than misses_to_end
861 and we may find begin of new digit before we consider last one ended. */
862
863 if (hit != s->td.dtmf.lasthit) {
864 s->td.dtmf.lasthit = hit;
865 s->td.dtmf.hits = 0;
866 }
867 if (hit && hit != s->td.dtmf.current_hit) {
868 s->td.dtmf.hits++;
869 if (s->td.dtmf.hits == dtmf_hits_to_begin) {
870 store_digit(s, hit);
872 s->td.dtmf.current_hit = hit;
873 s->td.dtmf.misses = 0;
874 }
875 }
876
877 /* If we had a hit in this block, include it into mute fragment */
878 if (squelch && hit) {
879 if (mute.end < sample - DTMF_GSIZE) {
880 /* There is a gap between fragments */
881 mute_fragment(dsp, &mute);
882 mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
883 }
884 mute.end = limit + DTMF_GSIZE;
885 }
886
887 /* Reinitialise the detector for the next block */
888 for (i = 0; i < DTMF_MATRIX_SIZE; i++) {
891 }
892 s->td.dtmf.energy = 0.0;
893 s->td.dtmf.current_sample = 0;
894 }
895
896 if (squelch && mute.end) {
897 if (mute.end > samples) {
898 s->td.dtmf.mute_samples = mute.end - samples;
899 mute.end = samples;
900 }
901 mute_fragment(dsp, &mute);
902 }
903
904 return (s->td.dtmf.current_hit); /* return the debounced hit */
905}
906
907static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
908 int samples, int squelch, int relax)
909{
910 float energy[6];
911 int best;
912 int second_best;
913 int i;
914 int j;
915 int sample;
916 short samp;
917 int hit;
918 int limit;
919 fragment_t mute = {0, 0};
920
921 if (squelch && s->td.mf.mute_samples > 0) {
922 mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
923 s->td.mf.mute_samples -= mute.end;
924 }
925
926 hit = 0;
927 for (sample = 0; sample < samples; sample = limit) {
928 /* 80 is optimised to meet the MF specs. */
929 /* XXX So then why is MF_GSIZE defined as 120? */
930 if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
931 limit = sample + (MF_GSIZE - s->td.mf.current_sample);
932 } else {
933 limit = samples;
934 }
935 /* The following unrolled loop takes only 35% (rough estimate) of the
936 time of a rolled loop on the machine on which it was developed */
937 for (j = sample; j < limit; j++) {
938 /* With GCC 2.95, the following unrolled code seems to take about 35%
939 (rough estimate) as long as a neat little 0-3 loop */
940 samp = amp[j];
941 goertzel_sample(s->td.mf.tone_out, samp);
942 goertzel_sample(s->td.mf.tone_out + 1, samp);
943 goertzel_sample(s->td.mf.tone_out + 2, samp);
944 goertzel_sample(s->td.mf.tone_out + 3, samp);
945 goertzel_sample(s->td.mf.tone_out + 4, samp);
946 goertzel_sample(s->td.mf.tone_out + 5, samp);
947 }
948 s->td.mf.current_sample += (limit - sample);
949 if (s->td.mf.current_sample < MF_GSIZE) {
950 continue;
951 }
952 /* We're at the end of an MF detection block. */
953 /* Find the two highest energies. The spec says to look for
954 two tones and two tones only. Taking this literally -ie
955 only two tones pass the minimum threshold - doesn't work
956 well. The sinc function mess, due to rectangular windowing
957 ensure that! Find the two highest energies and ensure they
958 are considerably stronger than any of the others. */
959 energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
960 energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
961 if (energy[0] > energy[1]) {
962 best = 0;
963 second_best = 1;
964 } else {
965 best = 1;
966 second_best = 0;
967 }
968 /*endif*/
969 for (i = 2; i < 6; i++) {
970 energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
971 if (energy[i] >= energy[best]) {
972 second_best = best;
973 best = i;
974 } else if (energy[i] >= energy[second_best]) {
975 second_best = i;
976 }
977 }
978 /* Basic signal level and twist tests */
979 hit = 0;
980 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
981 && energy[best] < energy[second_best]*BELL_MF_TWIST
982 && energy[best] * BELL_MF_TWIST > energy[second_best]) {
983 /* Relative peak test */
984 hit = -1;
985 for (i = 0; i < 6; i++) {
986 if (i != best && i != second_best) {
987 if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
988 /* The best two are not clearly the best */
989 hit = 0;
990 break;
991 }
992 }
993 }
994 }
995 if (hit) {
996 /* Get the values into ascending order */
997 if (second_best < best) {
998 i = best;
999 best = second_best;
1000 second_best = i;
1001 }
1002 best = best * 5 + second_best - 1;
1003 hit = bell_mf_positions[best];
1004 /* Look for two successive similar results */
1005 /* The logic in the next test is:
1006 For KP we need 4 successive identical clean detects, with
1007 two blocks of something different preceeding it. For anything
1008 else we need two successive identical clean detects, with
1009 two blocks of something different preceeding it. */
1010 if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
1011 ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
1012 (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
1013 hit != s->td.mf.hits[0]))) {
1014 store_digit(s, hit);
1015 }
1016 }
1017
1018
1019 if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
1020 /* Two successive block without a hit terminate current digit */
1021 s->td.mf.current_hit = 0;
1022 }
1023
1024 s->td.mf.hits[0] = s->td.mf.hits[1];
1025 s->td.mf.hits[1] = s->td.mf.hits[2];
1026 s->td.mf.hits[2] = s->td.mf.hits[3];
1027 s->td.mf.hits[3] = s->td.mf.hits[4];
1028 s->td.mf.hits[4] = hit;
1029
1030 /* If we had a hit in this block, include it into mute fragment */
1031 if (squelch && hit) {
1032 if (mute.end < sample - MF_GSIZE) {
1033 /* There is a gap between fragments */
1034 mute_fragment(dsp, &mute);
1035 mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
1036 }
1037 mute.end = limit + MF_GSIZE;
1038 }
1039
1040 /* Reinitialise the detector for the next block */
1041 for (i = 0; i < 6; i++) {
1042 goertzel_reset(&s->td.mf.tone_out[i]);
1043 }
1044 s->td.mf.current_sample = 0;
1045 }
1046
1047 if (squelch && mute.end) {
1048 if (mute.end > samples) {
1049 s->td.mf.mute_samples = mute.end - samples;
1050 mute.end = samples;
1051 }
1052 mute_fragment(dsp, &mute);
1053 }
1054
1055 return (s->td.mf.current_hit); /* return the debounced hit */
1056}
1057
1058static inline int pair_there(float p1, float p2, float i1, float i2, float e)
1059{
1060 /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
1061 /* Make sure absolute levels are high enough */
1062 if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
1063 return 0;
1064 }
1065 /* Amplify ignored stuff */
1066 i2 *= TONE_THRESH;
1067 i1 *= TONE_THRESH;
1068 e *= TONE_THRESH;
1069 /* Check first tone */
1070 if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
1071 return 0;
1072 }
1073 /* And second */
1074 if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
1075 return 0;
1076 }
1077 /* Guess it's there... */
1078 return 1;
1079}
1080
1081static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
1082{
1083 short samp;
1084 int x;
1085 int y;
1086 int pass;
1087 int newstate = DSP_TONE_STATE_SILENCE;
1088 int res = 0;
1089 int freqcount = dsp->freqcount > FREQ_ARRAY_SIZE ? FREQ_ARRAY_SIZE : dsp->freqcount;
1090
1091 while (len) {
1092 /* Take the lesser of the number of samples we need and what we have */
1093 pass = len;
1094 if (pass > dsp->gsamp_size - dsp->gsamps) {
1095 pass = dsp->gsamp_size - dsp->gsamps;
1096 }
1097 for (x = 0; x < pass; x++) {
1098 samp = s[x];
1099 dsp->genergy += (int32_t) samp * (int32_t) samp;
1100 for (y = 0; y < freqcount; y++) {
1101 goertzel_sample(&dsp->freqs[y], samp);
1102 }
1103 }
1104 s += pass;
1105 dsp->gsamps += pass;
1106 len -= pass;
1107 if (dsp->gsamps == dsp->gsamp_size) {
1108 float hz[FREQ_ARRAY_SIZE];
1109 for (y = 0; y < FREQ_ARRAY_SIZE; y++) {
1110 hz[y] = goertzel_result(&dsp->freqs[y]);
1111 }
1112 switch (dsp->progmode) {
1113 case PROG_MODE_NA:
1114 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
1115 newstate = DSP_TONE_STATE_BUSY;
1116 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
1117 newstate = DSP_TONE_STATE_RINGING;
1118 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
1119 newstate = DSP_TONE_STATE_DIALTONE;
1120 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
1121 newstate = DSP_TONE_STATE_SPECIAL1;
1122 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
1123 /* End of SPECIAL1 or middle of SPECIAL2 */
1125 newstate = DSP_TONE_STATE_SPECIAL2;
1126 }
1127 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
1128 /* End of SPECIAL2 or middle of SPECIAL3 */
1130 newstate = DSP_TONE_STATE_SPECIAL3;
1131 }
1132 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1133 newstate = DSP_TONE_STATE_TALKING;
1134 } else {
1135 newstate = DSP_TONE_STATE_SILENCE;
1136 }
1137 break;
1138 case PROG_MODE_CR:
1139 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
1140 newstate = DSP_TONE_STATE_RINGING;
1141 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1142 newstate = DSP_TONE_STATE_TALKING;
1143 } else {
1144 newstate = DSP_TONE_STATE_SILENCE;
1145 }
1146 break;
1147 case PROG_MODE_UK:
1148 if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
1149 newstate = DSP_TONE_STATE_HUNGUP;
1150 } else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
1151 newstate = DSP_TONE_STATE_DIALTONE;
1152 }
1153 break;
1154 default:
1155 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%u'\n", dsp->progmode);
1156 }
1157 if (newstate == dsp->tstate) {
1158 dsp->tcount++;
1159 if (dsp->ringtimeout) {
1160 dsp->ringtimeout++;
1161 }
1162 switch (dsp->tstate) {
1164 if ((dsp->features & DSP_PROGRESS_RINGING) &&
1165 (dsp->tcount == THRESH_RING)) {
1166 res = AST_CONTROL_RINGING;
1167 dsp->ringtimeout = 1;
1168 }
1169 break;
1171 if ((dsp->features & DSP_PROGRESS_BUSY) &&
1172 (dsp->tcount == THRESH_BUSY)) {
1173 res = AST_CONTROL_BUSY;
1174 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1175 }
1176 break;
1178 if ((dsp->features & DSP_PROGRESS_TALK) &&
1179 (dsp->tcount == THRESH_TALK)) {
1180 res = AST_CONTROL_ANSWER;
1181 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1182 }
1183 break;
1185 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
1186 (dsp->tcount == THRESH_CONGESTION)) {
1188 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1189 }
1190 break;
1192 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
1193 (dsp->tcount == THRESH_HANGUP)) {
1194 res = AST_CONTROL_HANGUP;
1195 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1196 }
1197 break;
1198 }
1199 if (dsp->ringtimeout == THRESH_RING2ANSWER) {
1200 ast_debug(1, "Consider call as answered because of timeout after last ring\n");
1201 res = AST_CONTROL_ANSWER;
1202 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1203 }
1204 } else {
1205 ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
1206 ast_debug(5, "Start state %d\n", newstate);
1207 dsp->tstate = newstate;
1208 dsp->tcount = 1;
1209 }
1210
1211 /* Reset goertzel */
1212 for (x = 0; x < 7; x++) {
1213 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1214 }
1215 dsp->gsamps = 0;
1216 dsp->genergy = 0.0;
1217 }
1218 }
1219
1220 return res;
1221}
1222
1223int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
1224{
1225 if (inf->frametype != AST_FRAME_VOICE) {
1226 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
1227 return 0;
1228 }
1230 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames, %s not supported\n",
1232 return 0;
1233 }
1234 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
1235}
1236
1237static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise, int *frames_energy)
1238{
1239 int accum;
1240 int x;
1241 int res = 0;
1242
1243 if (!len) {
1244 return 0;
1245 }
1246 accum = 0;
1247 for (x = 0; x < len; x++) {
1248 accum += abs(s[x]);
1249 }
1250 accum /= len;
1251 if (accum < dsp->threshold) {
1252 /* Silent */
1253 dsp->totalsilence += len / (dsp->sample_rate / 1000);
1254 if (dsp->totalnoise) {
1255 /* Move and save history */
1256 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicnoise[0]));
1257 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
1258/* we don't want to check for busydetect that frequently */
1259#if 0
1260 dsp->busymaybe = 1;
1261#endif
1262 }
1263 dsp->totalnoise = 0;
1264 res = 1;
1265 } else {
1266 /* Not silent */
1267 dsp->totalnoise += len / (dsp->sample_rate / 1000);
1268 if (dsp->totalsilence) {
1269 int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
1270 int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
1271 /* Move and save history */
1272 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicsilence[0]));
1273 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
1274 /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
1275 if (silence1 < silence2) {
1276 if (silence1 + silence1 * BUSY_PERCENT / 100 >= silence2) {
1277 dsp->busymaybe = 1;
1278 } else {
1279 dsp->busymaybe = 0;
1280 }
1281 } else {
1282 if (silence1 - silence1 * BUSY_PERCENT / 100 <= silence2) {
1283 dsp->busymaybe = 1;
1284 } else {
1285 dsp->busymaybe = 0;
1286 }
1287 }
1288 }
1289 dsp->totalsilence = 0;
1290 }
1291 if (totalsilence) {
1292 *totalsilence = dsp->totalsilence;
1293 }
1294 if (totalnoise) {
1295 *totalnoise = dsp->totalnoise;
1296 }
1297 if (frames_energy) {
1298 *frames_energy = accum;
1299 }
1300 return res;
1301}
1302
1304{
1305 int res = 0, x;
1306#ifndef BUSYDETECT_TONEONLY
1307 int avgsilence = 0, hitsilence = 0;
1308#endif
1309 int avgtone = 0, hittone = 0;
1310
1311 /* if we have a 4 length pattern, the way busymaybe is set doesn't help us. */
1312 if (dsp->busy_cadence.length != 4) {
1313 if (!dsp->busymaybe) {
1314 return res;
1315 }
1316 }
1317
1318 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
1319#ifndef BUSYDETECT_TONEONLY
1320 avgsilence += dsp->historicsilence[x];
1321#endif
1322 avgtone += dsp->historicnoise[x];
1323 }
1324#ifndef BUSYDETECT_TONEONLY
1325 avgsilence /= dsp->busycount;
1326#endif
1327 avgtone /= dsp->busycount;
1328 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
1329#ifndef BUSYDETECT_TONEONLY
1330 if (avgsilence > dsp->historicsilence[x]) {
1331 if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
1332 hitsilence++;
1333 }
1334 } else {
1335 if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
1336 hitsilence++;
1337 }
1338 }
1339#endif
1340 if (avgtone > dsp->historicnoise[x]) {
1341 if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
1342 hittone++;
1343 }
1344 } else {
1345 if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
1346 hittone++;
1347 }
1348 }
1349 }
1350#ifndef BUSYDETECT_TONEONLY
1351 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
1352 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
1353 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX))
1354#else
1355 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX))
1356#endif
1357 {
1358#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1359 if (avgtone > avgsilence) {
1360 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
1361 res = 1;
1362 }
1363 } else {
1364 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
1365 res = 1;
1366 }
1367 }
1368#else
1369 res = 1;
1370#endif
1371 }
1372
1373 /* If we have a 4-length pattern, we can go ahead and just check it in a different way. */
1374 if (dsp->busy_cadence.length == 4) {
1375 int x;
1376 int errors = 0;
1377 int errors_max = ((4 * dsp->busycount) / 100.0) * BUSY_PAT_PERCENT;
1378
1379 for (x = DSP_HISTORY - (dsp->busycount); x < DSP_HISTORY; x += 2) {
1380 int temp_error;
1381 temp_error = abs(dsp->historicnoise[x] - dsp->busy_cadence.pattern[0]);
1382 if ((temp_error * 100) / dsp->busy_cadence.pattern[0] > BUSY_PERCENT) {
1383 errors++;
1384 }
1385
1386 temp_error = abs(dsp->historicnoise[x + 1] - dsp->busy_cadence.pattern[2]);
1387 if ((temp_error * 100) / dsp->busy_cadence.pattern[2] > BUSY_PERCENT) {
1388 errors++;
1389 }
1390
1391 temp_error = abs(dsp->historicsilence[x] - dsp->busy_cadence.pattern[1]);
1392 if ((temp_error * 100) / dsp->busy_cadence.pattern[1] > BUSY_PERCENT) {
1393 errors++;
1394 }
1395
1396 temp_error = abs(dsp->historicsilence[x + 1] - dsp->busy_cadence.pattern[3]);
1397 if ((temp_error * 100) / dsp->busy_cadence.pattern[3] > BUSY_PERCENT) {
1398 errors++;
1399 }
1400 }
1401
1402 ast_debug(5, "errors = %d max = %d\n", errors, errors_max);
1403
1404 if (errors <= errors_max) {
1405 return 1;
1406 }
1407 }
1408
1409 /* If we know the expected busy tone length, check we are in the range */
1410 if (res && (dsp->busy_cadence.pattern[0] > 0)) {
1411 if (abs(avgtone - dsp->busy_cadence.pattern[0]) > MAX(dsp->busy_cadence.pattern[0]*BUSY_PAT_PERCENT/100, 20)) {
1412#ifdef BUSYDETECT_DEBUG
1413 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
1414 avgtone, dsp->busy_cadence.pattern[0]);
1415#endif
1416 res = 0;
1417 }
1418 }
1419#ifndef BUSYDETECT_TONEONLY
1420 /* If we know the expected busy tone silent-period length, check we are in the range */
1421 if (res && (dsp->busy_cadence.pattern[1] > 0)) {
1422 if (abs(avgsilence - dsp->busy_cadence.pattern[1]) > MAX(dsp->busy_cadence.pattern[1]*BUSY_PAT_PERCENT/100, 20)) {
1423#ifdef BUSYDETECT_DEBUG
1424 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
1425 avgsilence, dsp->busy_cadence.pattern[1]);
1426#endif
1427 res = 0;
1428 }
1429 }
1430#endif
1431#if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
1432 if (res) {
1433 ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1434 } else {
1435 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1436 }
1437#endif
1438 return res;
1439}
1440
1441static int ast_dsp_silence_noise_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *total, int *frames_energy, int noise)
1442{
1443 short *s;
1444 int len;
1445 int x;
1446 unsigned char *odata;
1447
1448 if (!f) {
1449 return 0;
1450 }
1451
1452 if (f->frametype != AST_FRAME_VOICE) {
1453 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
1454 return 0;
1455 }
1456
1458 s = f->data.ptr;
1459 len = f->datalen/2;
1460 } else {
1461 odata = f->data.ptr;
1462 len = f->datalen;
1464 s = ast_alloca(len * 2);
1465 for (x = 0; x < len; x++) {
1466 s[x] = AST_MULAW(odata[x]);
1467 }
1469 s = ast_alloca(len * 2);
1470 for (x = 0; x < len; x++) {
1471 s[x] = AST_ALAW(odata[x]);
1472 }
1473 } else {
1474 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear, alaw or ulaw frames, %s not supported\n",
1476 return 0;
1477 }
1478 }
1479
1480 if (noise) {
1481 return __ast_dsp_silence_noise(dsp, s, len, NULL, total, frames_energy);
1482 } else {
1483 return __ast_dsp_silence_noise(dsp, s, len, total, NULL, frames_energy);
1484 }
1485}
1486
1487int ast_dsp_silence_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence, int *frames_energy)
1488{
1489 return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, frames_energy, 0);
1490}
1491
1492int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
1493{
1494 return ast_dsp_silence_noise_with_energy(dsp, f, totalsilence, NULL, 0);
1495}
1496
1497int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
1498{
1499 return ast_dsp_silence_noise_with_energy(dsp, f, totalnoise, NULL, 1);
1500}
1501
1502
1503struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
1504{
1505 int silence;
1506 int res;
1507 int digit = 0, fax_digit = 0, custom_freq_digit = 0;
1508 int x;
1509 short *shortdata;
1510 unsigned char *odata;
1511 int len;
1512 struct ast_frame *outf = NULL;
1513
1514 if (!af) {
1515 return NULL;
1516 }
1517 if (af->frametype != AST_FRAME_VOICE) {
1518 return af;
1519 }
1520
1521 odata = af->data.ptr;
1522 len = af->datalen;
1523 /* Make sure we have short data */
1525 shortdata = af->data.ptr;
1526 len = af->datalen / 2;
1528 shortdata = ast_alloca(af->datalen * 2);
1529 for (x = 0; x < len; x++) {
1530 shortdata[x] = AST_MULAW(odata[x]);
1531 }
1533 shortdata = ast_alloca(af->datalen * 2);
1534 for (x = 0; x < len; x++) {
1535 shortdata[x] = AST_ALAW(odata[x]);
1536 }
1537 } else {
1538 /* Display warning only once. Otherwise you would get hundreds of warnings every second */
1539 if (dsp->display_inband_dtmf_warning) {
1540 /* If DTMF is enabled for the DSP, try to be helpful and warn about that specifically,
1541 * otherwise emit a more generic message that covers all other cases. */
1543 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n",
1545 } else {
1546 ast_log(LOG_WARNING, "Can only do DSP on signed-linear, alaw or ulaw frames (%s not supported)\n",
1548 }
1549 }
1551 return af;
1552 }
1553
1554 /* Initially we do not want to mute anything */
1555 dsp->mute_fragments = 0;
1556
1557 /* Need to run the silence detection stuff for silence suppression and busy detection */
1559 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL, NULL);
1560 }
1561
1562 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
1563 memset(&dsp->f, 0, sizeof(dsp->f));
1564 dsp->f.frametype = AST_FRAME_NULL;
1565 ast_frfree(af);
1566 return ast_frisolate(&dsp->f);
1567 }
1570 memset(&dsp->f, 0, sizeof(dsp->f));
1573 ast_frfree(af);
1574 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", ast_channel_name(chan));
1575 return ast_frisolate(&dsp->f);
1576 }
1577
1578 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
1579 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
1580 fax_digit = 'f';
1581 }
1582
1583 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
1584 fax_digit = 'e';
1585 }
1586 }
1587
1588 if ((dsp->features & DSP_FEATURE_FREQ_DETECT)) {
1589 if ((dsp->freqmode) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
1590 custom_freq_digit = 'q';
1591 }
1592 }
1593
1595 if (dsp->digitmode & DSP_DIGITMODE_MF) {
1596 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1597 } else {
1598 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1599 }
1600
1601 if (dsp->digit_state.current_digits) {
1602 int event = 0, event_len = 0;
1603 char event_digit = 0;
1604
1605 if (!dsp->dtmf_began) {
1606 /* We have not reported DTMF_BEGIN for anything yet */
1607
1609 event = AST_FRAME_DTMF_BEGIN;
1610 event_digit = dsp->digit_state.digits[0];
1611 }
1612 dsp->dtmf_began = 1;
1613
1614 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
1615 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
1617 event = AST_FRAME_DTMF_END;
1618 event_digit = dsp->digit_state.digits[0];
1619 event_len = dsp->digit_state.digitlen[0] * 1000 / dsp->sample_rate;
1620 }
1621 memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
1622 memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
1624 dsp->dtmf_began = 0;
1625
1626 if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
1627 /* Reset Busy Detector as we have some confirmed activity */
1628 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1629 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
1630 ast_debug(1, "DTMF Detected - Reset busydetector\n");
1631 }
1632 }
1633
1634 if (event) {
1635 memset(&dsp->f, 0, sizeof(dsp->f));
1636 dsp->f.frametype = event;
1637 dsp->f.subclass.integer = event_digit;
1638 dsp->f.len = event_len;
1639 outf = &dsp->f;
1640 goto done;
1641 }
1642 }
1643 }
1644
1645 if (fax_digit) {
1646 /* Fax was detected - digit is either 'f' or 'e' */
1647
1648 memset(&dsp->f, 0, sizeof(dsp->f));
1649 dsp->f.frametype = AST_FRAME_DTMF;
1650 dsp->f.subclass.integer = fax_digit;
1651 outf = &dsp->f;
1652 goto done;
1653 }
1654
1655 if (custom_freq_digit) {
1656 /* Custom frequency was detected - digit is 'q' */
1657
1658 memset(&dsp->f, 0, sizeof(dsp->f));
1659 dsp->f.frametype = AST_FRAME_DTMF;
1660 dsp->f.subclass.integer = custom_freq_digit;
1661 outf = &dsp->f;
1662 goto done;
1663 }
1664
1665 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
1666 res = __ast_dsp_call_progress(dsp, shortdata, len);
1667 if (res) {
1668 switch (res) {
1669 case AST_CONTROL_ANSWER:
1670 case AST_CONTROL_BUSY:
1673 case AST_CONTROL_HANGUP:
1674 memset(&dsp->f, 0, sizeof(dsp->f));
1676 dsp->f.subclass.integer = res;
1677 dsp->f.src = "dsp_progress";
1678 if (chan) {
1679 ast_queue_frame(chan, &dsp->f);
1680 }
1681 break;
1682 default:
1683 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
1684 }
1685 }
1686 } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
1687 res = __ast_dsp_call_progress(dsp, shortdata, len);
1688 }
1689
1690done:
1691 /* Mute fragment of the frame */
1692 for (x = 0; x < dsp->mute_fragments; x++) {
1693 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
1694 }
1695
1697 for (x = 0; x < len; x++) {
1698 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
1699 }
1701 for (x = 0; x < len; x++) {
1702 odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
1703 }
1704 }
1705
1706 if (outf) {
1707 if (chan) {
1708 ast_queue_frame(chan, af);
1709 }
1710 ast_frfree(af);
1711 return ast_frisolate(outf);
1712 } else {
1713 return af;
1714 }
1715}
1716
1717static void ast_dsp_prog_reset(struct ast_dsp *dsp)
1718{
1719 int max = 0;
1720 int x;
1721
1722 dsp->gsamp_size = modes[dsp->progmode].size;
1723 dsp->gsamps = 0;
1724 for (x = 0; x < FREQ_ARRAY_SIZE; x++) {
1725 if (modes[dsp->progmode].freqs[x]) {
1726 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->sample_rate);
1727 max = x + 1;
1728 }
1729 }
1730 dsp->freqcount = max;
1731 dsp->ringtimeout = 0;
1732}
1733
1734unsigned int ast_dsp_get_sample_rate(const struct ast_dsp *dsp)
1735{
1736 return dsp->sample_rate;
1737}
1738
1739static struct ast_dsp *__ast_dsp_new(unsigned int sample_rate)
1740{
1741 struct ast_dsp *dsp;
1742
1743 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
1746 dsp->busycount = DSP_HISTORY;
1749 dsp->sample_rate = sample_rate;
1750 dsp->freqcount = 0;
1751 /* Initialize digit detector */
1754 /* Initialize initial DSP progress detect parameters */
1755 ast_dsp_prog_reset(dsp);
1756 /* Initialize fax detector */
1758 }
1759 return dsp;
1760}
1761
1763{
1765}
1766
1768{
1769 return __ast_dsp_new(sample_rate);
1770}
1771
1773{
1774 dsp->features = features;
1777 }
1778}
1779
1780
1782{
1783 return (dsp->features);
1784}
1785
1786
1787void ast_dsp_free(struct ast_dsp *dsp)
1788{
1789 ast_free(dsp);
1790}
1791
1793{
1794 dsp->threshold = threshold;
1795}
1796
1798{
1799 if (cadences < 4) {
1800 cadences = 4;
1801 }
1802 if (cadences > DSP_HISTORY) {
1804 }
1805 dsp->busycount = cadences;
1806}
1807
1808void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence)
1809{
1810 dsp->busy_cadence = *cadence;
1811 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);
1812}
1813
1815{
1816 int i;
1817
1818 dsp->dtmf_began = 0;
1819 if (dsp->digitmode & DSP_DIGITMODE_MF) {
1821 /* Reinitialise the detector for the next block */
1822 for (i = 0; i < 6; i++) {
1823 goertzel_reset(&s->tone_out[i]);
1824 }
1825 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = 0;
1826 s->current_hit = 0;
1827 s->current_sample = 0;
1828 } else {
1830 /* Reinitialise the detector for the next block */
1831 for (i = 0; i < 4; i++) {
1832 goertzel_reset(&s->row_out[i]);
1833 goertzel_reset(&s->col_out[i]);
1834 }
1835 s->lasthit = 0;
1836 s->current_hit = 0;
1837 s->energy = 0.0;
1838 s->current_sample = 0;
1839 s->hits = 0;
1840 s->misses = 0;
1841 }
1842
1843 dsp->digit_state.digits[0] = '\0';
1844 dsp->digit_state.current_digits = 0;
1845}
1846
1847void ast_dsp_reset(struct ast_dsp *dsp)
1848{
1849 int x;
1850
1851 dsp->totalsilence = 0;
1852 dsp->gsamps = 0;
1853 for (x = 0; x < 4; x++) {
1854 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1855 }
1856 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1857 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
1858 dsp->ringtimeout = 0;
1859}
1860
1862{
1863 int new;
1864 int old;
1865
1868 if (old != new) {
1869 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1871 }
1872 dsp->digitmode = digitmode;
1873 return 0;
1874}
1875
1876int ast_dsp_set_freqmode(struct ast_dsp *dsp, int freq, int dur, int db, int squelch)
1877{
1878 if (freq > 0) {
1879 dsp->freqmode = 1;
1880 ast_freq_detect_init(dsp, freq, dur, db, squelch);
1881 } else {
1882 dsp->freqmode = 0;
1883 }
1884 return 0;
1885}
1886
1888{
1889 if (dsp->faxmode != faxmode) {
1890 dsp->faxmode = faxmode;
1892 }
1893 return 0;
1894}
1895
1896int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
1897{
1898 int x;
1899
1900 for (x = 0; x < ARRAY_LEN(aliases); x++) {
1901 if (!strcasecmp(aliases[x].name, zone)) {
1902 dsp->progmode = aliases[x].mode;
1903 ast_dsp_prog_reset(dsp);
1904 return 0;
1905 }
1906 }
1907 return -1;
1908}
1909
1911{
1912 return (dsp->mute_fragments > 0);
1913}
1914
1916{
1917 return dsp->tstate;
1918}
1919
1921{
1922 return dsp->tcount;
1923}
1924
1925static int _dsp_init(int reload)
1926{
1927 struct ast_config *cfg;
1928 struct ast_variable *v;
1929 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1930 int cfg_threshold;
1931 float cfg_twist;
1932
1933 if ((cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
1934 return 0;
1935 }
1936
1944
1946 return 0;
1947 }
1948
1949 for (v = ast_variable_browse(cfg, "default"); v; v = v->next) {
1950 if (!strcasecmp(v->name, "silencethreshold")) {
1951 if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1952 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1953 } else if (cfg_threshold < 0) {
1954 ast_log(LOG_WARNING, "Invalid silence threshold '%d' specified, using default\n", cfg_threshold);
1955 } else {
1956 thresholds[THRESHOLD_SILENCE] = cfg_threshold;
1957 }
1958 } else if (!strcasecmp(v->name, "dtmf_normal_twist")) {
1959 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1960 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1961 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1962 ast_log(LOG_WARNING, "Invalid dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_normal_twist);
1963 } else {
1964 dtmf_normal_twist = cfg_twist;
1965 }
1966 } else if (!strcasecmp(v->name, "dtmf_reverse_twist")) {
1967 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1968 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1969 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1970 ast_log(LOG_WARNING, "Invalid dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_reverse_twist);
1971 } else {
1972 dtmf_reverse_twist = cfg_twist;
1973 }
1974 } else if (!strcasecmp(v->name, "relax_dtmf_normal_twist")) {
1975 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1976 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1977 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1978 ast_log(LOG_WARNING, "Invalid relax_dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_normal_twist);
1979 } else {
1980 relax_dtmf_normal_twist = cfg_twist;
1981 }
1982 } else if (!strcasecmp(v->name, "relax_dtmf_reverse_twist")) {
1983 if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1984 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1985 } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1986 ast_log(LOG_WARNING, "Invalid relax_dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_reverse_twist);
1987 } else {
1988 relax_dtmf_reverse_twist = cfg_twist;
1989 }
1990 } else if (!strcasecmp(v->name, "dtmf_hits_to_begin")) {
1991 if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1992 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1993 } else if (cfg_threshold < 1) { /* must be 1 or greater */
1994 ast_log(LOG_WARNING, "Invalid dtmf_hits_to_begin value '%d' specified, using default of %d\n", cfg_threshold, dtmf_hits_to_begin);
1995 } else {
1996 dtmf_hits_to_begin = cfg_threshold;
1997 }
1998 } else if (!strcasecmp(v->name, "dtmf_misses_to_end")) {
1999 if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
2000 ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
2001 } else if (cfg_threshold < 1) { /* must be 1 or greater */
2002 ast_log(LOG_WARNING, "Invalid dtmf_misses_to_end value '%d' specified, using default of %d\n", cfg_threshold, dtmf_misses_to_end);
2003 } else {
2004 dtmf_misses_to_end = cfg_threshold;
2005 }
2006 }
2007 }
2008 ast_config_destroy(cfg);
2009
2010 return 0;
2011}
2012
2014{
2015 return thresholds[which];
2016}
2017
2018#ifdef TEST_FRAMEWORK
2019static void test_tone_sample_gen(short *slin_buf, int samples, int rate, int freq, short amplitude)
2020{
2021 int idx;
2022 double sample_step = 2.0 * M_PI * freq / rate;/* radians per step */
2023
2024 for (idx = 0; idx < samples; ++idx) {
2025 slin_buf[idx] = amplitude * sin(sample_step * idx);
2026 }
2027}
2028#endif
2029
2030#ifdef TEST_FRAMEWORK
2031static void test_tone_sample_gen_add(short *slin_buf, int samples, int rate, int freq, short amplitude)
2032{
2033 int idx;
2034 double sample_step = 2.0 * M_PI * freq / rate;/* radians per step */
2035
2036 for (idx = 0; idx < samples; ++idx) {
2037 slin_buf[idx] += amplitude * sin(sample_step * idx);
2038 }
2039}
2040#endif
2041
2042#ifdef TEST_FRAMEWORK
2043static void test_dual_sample_gen(short *slin_buf, int samples, int rate, int f1, short a1, int f2, short a2)
2044{
2045 test_tone_sample_gen(slin_buf, samples, rate, f1, a1);
2046 test_tone_sample_gen_add(slin_buf, samples, rate, f2, a2);
2047}
2048#endif
2049
2050#ifdef TEST_FRAMEWORK
2051#define TONE_AMPLITUDE_MAX 0x7fff /* Max signed linear amplitude */
2052#define TONE_AMPLITUDE_MIN 80 /* Min signed linear amplitude detectable */
2053
2054static int test_tone_amplitude_sweep(struct ast_test *test, struct ast_dsp *dsp, tone_detect_state_t *tone_state)
2055{
2056 short slin_buf[tone_state->block_size];
2057 int result;
2058 int idx;
2059 struct {
2060 short amp_val;
2061 int detect;
2062 } amp_tests[] = {
2063 { .amp_val = TONE_AMPLITUDE_MAX, .detect = 1, },
2064 { .amp_val = 10000, .detect = 1, },
2065 { .amp_val = 1000, .detect = 1, },
2066 { .amp_val = 100, .detect = 1, },
2067 { .amp_val = TONE_AMPLITUDE_MIN, .detect = 1, },
2068 { .amp_val = 75, .detect = 0, },
2069 { .amp_val = 10, .detect = 0, },
2070 { .amp_val = 1, .detect = 0, },
2071 };
2072
2073 result = 0;
2074
2075 for (idx = 0; idx < ARRAY_LEN(amp_tests); ++idx) {
2076 int detected;
2077 int duration;
2078
2079 ast_debug(1, "Test %d Hz at amplitude %d\n",
2080 tone_state->freq, amp_tests[idx].amp_val);
2081 test_tone_sample_gen(slin_buf, tone_state->block_size, DEFAULT_SAMPLE_RATE,
2082 tone_state->freq, amp_tests[idx].amp_val);
2083
2084 detected = 0;
2085 for (duration = 0; !detected && duration < tone_state->hits_required + 3; ++duration) {
2086 detected = tone_detect(dsp, tone_state, slin_buf, tone_state->block_size) ? 1 : 0;
2087 }
2088 if (amp_tests[idx].detect != detected) {
2089 /*
2090 * Both messages are needed. ast_debug for when figuring out
2091 * what went wrong and the test update for normal output before
2092 * you start debugging. The different logging methods are not
2093 * synchronized.
2094 */
2095 ast_debug(1,
2096 "Test %d Hz at amplitude %d failed. Detected: %s\n",
2097 tone_state->freq, amp_tests[idx].amp_val,
2098 detected ? "yes" : "no");
2100 "Test %d Hz at amplitude %d failed. Detected: %s\n",
2101 tone_state->freq, amp_tests[idx].amp_val,
2102 detected ? "yes" : "no");
2103 result = -1;
2104 }
2105 tone_state->hit_count = 0;
2106 }
2107
2108 return result;
2109}
2110#endif
2111
2112#ifdef TEST_FRAMEWORK
2113static int test_dtmf_amplitude_sweep(struct ast_test *test, struct ast_dsp *dsp, int digit_index)
2114{
2115 short slin_buf[DTMF_GSIZE];
2116 int result;
2117 int row;
2118 int column;
2119 int idx;
2120 struct {
2121 short amp_val;
2122 int digit;
2123 } amp_tests[] = {
2124 /*
2125 * XXX Since there is no current DTMF level detection issue. This test
2126 * just checks the current detection levels.
2127 */
2128 { .amp_val = TONE_AMPLITUDE_MAX/2, .digit = dtmf_positions[digit_index], },
2129 { .amp_val = 10000, .digit = dtmf_positions[digit_index], },
2130 { .amp_val = 1000, .digit = dtmf_positions[digit_index], },
2131 { .amp_val = 500, .digit = dtmf_positions[digit_index], },
2132 { .amp_val = 250, .digit = dtmf_positions[digit_index], },
2133 { .amp_val = 200, .digit = dtmf_positions[digit_index], },
2134 { .amp_val = 180, .digit = dtmf_positions[digit_index], },
2135 /* Various digits detect and not detect in this range */
2136 { .amp_val = 170, .digit = 0, },
2137 { .amp_val = 100, .digit = 0, },
2138 /*
2139 * Amplitudes below TONE_AMPLITUDE_MIN start having questionable detection
2140 * over quantization and background noise.
2141 */
2142 { .amp_val = TONE_AMPLITUDE_MIN, .digit = 0, },
2143 { .amp_val = 75, .digit = 0, },
2144 { .amp_val = 10, .digit = 0, },
2145 { .amp_val = 1, .digit = 0, },
2146 };
2147
2148 row = (digit_index >> 2) & 0x03;
2149 column = digit_index & 0x03;
2150
2151 result = 0;
2152
2153 for (idx = 0; idx < ARRAY_LEN(amp_tests); ++idx) {
2154 int digit;
2155 int duration;
2156
2157 ast_debug(1, "Test '%c' at amplitude %d\n",
2158 dtmf_positions[digit_index], amp_tests[idx].amp_val);
2159 test_dual_sample_gen(slin_buf, ARRAY_LEN(slin_buf), DEFAULT_SAMPLE_RATE,
2160 (int) dtmf_row[row], amp_tests[idx].amp_val,
2161 (int) dtmf_col[column], amp_tests[idx].amp_val);
2162
2163 digit = 0;
2164 for (duration = 0; !digit && duration < 3; ++duration) {
2165 digit = dtmf_detect(dsp, &dsp->digit_state, slin_buf, ARRAY_LEN(slin_buf),
2166 0, 0);
2167 }
2168 if (amp_tests[idx].digit != digit) {
2169 /*
2170 * Both messages are needed. ast_debug for when figuring out
2171 * what went wrong and the test update for normal output before
2172 * you start debugging. The different logging methods are not
2173 * synchronized.
2174 */
2175 ast_debug(1,
2176 "Test '%c' at amplitude %d failed. Detected Digit: '%c'\n",
2177 dtmf_positions[digit_index], amp_tests[idx].amp_val,
2178 digit ?: ' ');
2180 "Test '%c' at amplitude %d failed. Detected Digit: '%c'\n",
2181 dtmf_positions[digit_index], amp_tests[idx].amp_val,
2182 digit ?: ' ');
2183 result = -1;
2184 }
2185 ast_dsp_digitreset(dsp);
2186 }
2187
2188 return result;
2189}
2190#endif
2191
2192#ifdef TEST_FRAMEWORK
2193static int test_dtmf_twist_sweep(struct ast_test *test, struct ast_dsp *dsp, int digit_index)
2194{
2195 short slin_buf[DTMF_GSIZE];
2196 int result;
2197 int row;
2198 int column;
2199 int idx;
2200 struct {
2201 short amp_row;
2202 short amp_col;
2203 int digit;
2204 } twist_tests[] = {
2205 /*
2206 * XXX Since there is no current DTMF twist detection issue. This test
2207 * just checks the current detection levels.
2208 *
2209 * Normal twist has the column higher than the row amplitude.
2210 * Reverse twist is the other way.
2211 */
2212 { .amp_row = 1000 + 1800, .amp_col = 1000 + 0, .digit = 0, },
2213 { .amp_row = 1000 + 1700, .amp_col = 1000 + 0, .digit = 0, },
2214 /* Various digits detect and not detect in this range */
2215 { .amp_row = 1000 + 1400, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2216 { .amp_row = 1000 + 1300, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2217 { .amp_row = 1000 + 1200, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2218 { .amp_row = 1000 + 1100, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2219 { .amp_row = 1000 + 1000, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2220 { .amp_row = 1000 + 100, .amp_col = 1000 + 0, .digit = dtmf_positions[digit_index], },
2221 { .amp_row = 1000 + 0, .amp_col = 1000 + 100, .digit = dtmf_positions[digit_index], },
2222 { .amp_row = 1000 + 0, .amp_col = 1000 + 200, .digit = dtmf_positions[digit_index], },
2223 { .amp_row = 1000 + 0, .amp_col = 1000 + 300, .digit = dtmf_positions[digit_index], },
2224 { .amp_row = 1000 + 0, .amp_col = 1000 + 400, .digit = dtmf_positions[digit_index], },
2225 { .amp_row = 1000 + 0, .amp_col = 1000 + 500, .digit = dtmf_positions[digit_index], },
2226 { .amp_row = 1000 + 0, .amp_col = 1000 + 550, .digit = dtmf_positions[digit_index], },
2227 /* Various digits detect and not detect in this range */
2228 { .amp_row = 1000 + 0, .amp_col = 1000 + 650, .digit = 0, },
2229 { .amp_row = 1000 + 0, .amp_col = 1000 + 700, .digit = 0, },
2230 { .amp_row = 1000 + 0, .amp_col = 1000 + 800, .digit = 0, },
2231 };
2232 float save_normal_twist;
2233 float save_reverse_twist;
2234
2235 save_normal_twist = dtmf_normal_twist;
2236 save_reverse_twist = dtmf_reverse_twist;
2239
2240 row = (digit_index >> 2) & 0x03;
2241 column = digit_index & 0x03;
2242
2243 result = 0;
2244
2245 for (idx = 0; idx < ARRAY_LEN(twist_tests); ++idx) {
2246 int digit;
2247 int duration;
2248
2249 ast_debug(1, "Test '%c' twist row %d col %d amplitudes\n",
2250 dtmf_positions[digit_index],
2251 twist_tests[idx].amp_row, twist_tests[idx].amp_col);
2252 test_dual_sample_gen(slin_buf, ARRAY_LEN(slin_buf), DEFAULT_SAMPLE_RATE,
2253 (int) dtmf_row[row], twist_tests[idx].amp_row,
2254 (int) dtmf_col[column], twist_tests[idx].amp_col);
2255
2256 digit = 0;
2257 for (duration = 0; !digit && duration < 3; ++duration) {
2258 digit = dtmf_detect(dsp, &dsp->digit_state, slin_buf, ARRAY_LEN(slin_buf),
2259 0, 0);
2260 }
2261 if (twist_tests[idx].digit != digit) {
2262 /*
2263 * Both messages are needed. ast_debug for when figuring out
2264 * what went wrong and the test update for normal output before
2265 * you start debugging. The different logging methods are not
2266 * synchronized.
2267 */
2268 ast_debug(1,
2269 "Test '%c' twist row %d col %d amplitudes failed. Detected Digit: '%c'\n",
2270 dtmf_positions[digit_index],
2271 twist_tests[idx].amp_row, twist_tests[idx].amp_col,
2272 digit ?: ' ');
2274 "Test '%c' twist row %d col %d amplitudes failed. Detected Digit: '%c'\n",
2275 dtmf_positions[digit_index],
2276 twist_tests[idx].amp_row, twist_tests[idx].amp_col,
2277 digit ?: ' ');
2278 result = -1;
2279 }
2280 ast_dsp_digitreset(dsp);
2281 }
2282
2283 dtmf_normal_twist = save_normal_twist;
2284 dtmf_reverse_twist = save_reverse_twist;
2285
2286 return result;
2287}
2288#endif
2289
2290#ifdef TEST_FRAMEWORK
2291static int test_tone_freq_sweep(struct ast_test *test, struct ast_dsp *dsp, tone_detect_state_t *tone_state, short amplitude)
2292{
2293 short slin_buf[tone_state->block_size];
2294 int result;
2295 int freq;
2296 int lower_freq;
2297 int upper_freq;
2298
2299 /* Calculate detection frequency range */
2300 lower_freq = tone_state->freq - 4;
2301 upper_freq = tone_state->freq + 4;
2302
2303 result = 0;
2304
2305 /* Sweep frequencies loop. */
2306 for (freq = 100; freq <= 3500; freq += 1) {
2307 int detected;
2308 int duration;
2309 int expect_detection;
2310
2311 if (freq == tone_state->freq) {
2312 /* This case is done by the amplitude sweep. */
2313 continue;
2314 }
2315
2316 expect_detection = (lower_freq <= freq && freq <= upper_freq) ? 1 : 0;
2317
2318 ast_debug(1, "Test %d Hz detection given %d Hz tone at amplitude %d. Range:%d-%d Expect detect: %s\n",
2319 tone_state->freq, freq, amplitude, lower_freq, upper_freq,
2320 expect_detection ? "yes" : "no");
2321 test_tone_sample_gen(slin_buf, tone_state->block_size, DEFAULT_SAMPLE_RATE, freq,
2322 amplitude);
2323
2324 detected = 0;
2325 for (duration = 0; !detected && duration < tone_state->hits_required + 3; ++duration) {
2326 detected = tone_detect(dsp, tone_state, slin_buf, tone_state->block_size) ? 1 : 0;
2327 }
2328 if (expect_detection != detected) {
2329 /*
2330 * Both messages are needed. ast_debug for when figuring out
2331 * what went wrong and the test update for normal output before
2332 * you start debugging. The different logging methods are not
2333 * synchronized.
2334 */
2335 ast_debug(1,
2336 "Test %d Hz detection given %d Hz tone at amplitude %d failed. Range:%d-%d Detected: %s\n",
2337 tone_state->freq, freq, amplitude, lower_freq, upper_freq,
2338 detected ? "yes" : "no");
2340 "Test %d Hz detection given %d Hz tone at amplitude %d failed. Range:%d-%d Detected: %s\n",
2341 tone_state->freq, freq, amplitude, lower_freq, upper_freq,
2342 detected ? "yes" : "no");
2343 result = -1;
2344 }
2345 tone_state->hit_count = 0;
2346 }
2347
2348 return result;
2349}
2350#endif
2351
2352#ifdef TEST_FRAMEWORK
2353AST_TEST_DEFINE(test_dsp_fax_detect)
2354{
2355 struct ast_dsp *dsp;
2357
2358 switch (cmd) {
2359 case TEST_INIT:
2360 info->name = "fax";
2361 info->category = "/main/dsp/";
2362 info->summary = "DSP fax tone detect unit test";
2363 info->description =
2364 "Tests fax tone detection code.";
2365 return AST_TEST_NOT_RUN;
2366 case TEST_EXECUTE:
2367 break;
2368 }
2369
2370 dsp = ast_dsp_new();
2371 if (!dsp) {
2372 return AST_TEST_FAIL;
2373 }
2374
2376
2377 /* Test CNG tone amplitude detection */
2378 if (test_tone_amplitude_sweep(test, dsp, &dsp->cng_tone_state)) {
2380 }
2381
2382 /* Test CED tone amplitude detection */
2383 if (test_tone_amplitude_sweep(test, dsp, &dsp->ced_tone_state)) {
2385 }
2386
2387 /* Test CNG tone frequency detection */
2388 if (test_tone_freq_sweep(test, dsp, &dsp->cng_tone_state, TONE_AMPLITUDE_MAX)) {
2390 }
2391 if (test_tone_freq_sweep(test, dsp, &dsp->cng_tone_state, TONE_AMPLITUDE_MIN)) {
2393 }
2394
2395 /* Test CED tone frequency detection */
2396 if (test_tone_freq_sweep(test, dsp, &dsp->ced_tone_state, TONE_AMPLITUDE_MAX)) {
2398 }
2399 if (test_tone_freq_sweep(test, dsp, &dsp->ced_tone_state, TONE_AMPLITUDE_MIN)) {
2401 }
2402
2403 ast_dsp_free(dsp);
2404 return result;
2405}
2406#endif
2407
2408#ifdef TEST_FRAMEWORK
2409AST_TEST_DEFINE(test_dsp_dtmf_detect)
2410{
2411 int idx;
2412 struct ast_dsp *dsp;
2414
2415 switch (cmd) {
2416 case TEST_INIT:
2417 info->name = "dtmf";
2418 info->category = "/main/dsp/";
2419 info->summary = "DSP DTMF detect unit test";
2420 info->description =
2421 "Tests DTMF detection code.";
2422 return AST_TEST_NOT_RUN;
2423 case TEST_EXECUTE:
2424 break;
2425 }
2426
2427 dsp = ast_dsp_new();
2428 if (!dsp) {
2429 return AST_TEST_FAIL;
2430 }
2431
2433
2434 for (idx = 0; dtmf_positions[idx]; ++idx) {
2435 if (test_dtmf_amplitude_sweep(test, dsp, idx)) {
2437 }
2438 }
2439
2440 for (idx = 0; dtmf_positions[idx]; ++idx) {
2441 if (test_dtmf_twist_sweep(test, dsp, idx)) {
2443 }
2444 }
2445
2446 ast_dsp_free(dsp);
2447 return result;
2448}
2449#endif
2450
2451static int unload_module(void)
2452{
2453 AST_TEST_UNREGISTER(test_dsp_fax_detect);
2454 AST_TEST_UNREGISTER(test_dsp_dtmf_detect);
2455
2456 return 0;
2457}
2458
2459static int load_module(void)
2460{
2461 if (_dsp_init(0)) {
2463 }
2464
2465 AST_TEST_REGISTER(test_dsp_fax_detect);
2466 AST_TEST_REGISTER(test_dsp_dtmf_detect);
2467
2469}
2470
2471static int reload_module(void)
2472{
2473 return _dsp_init(1);
2474}
2475
2477 .support_level = AST_MODULE_SUPPORT_CORE,
2478 .load = load_module,
2479 .unload = unload_module,
2481 .load_pri = AST_MODPRI_CORE,
2482 .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:820
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
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
@ AST_SOFTHANGUP_DEV
Definition channel.h:1141
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:1792
#define BELL_MF_THRESHOLD
Definition dsp.c:200
void ast_dsp_free(struct ast_dsp *dsp)
Definition dsp.c:1787
int ast_dsp_get_tcount(struct ast_dsp *dsp)
Get tcount (Threshold counter)
Definition dsp.c:1920
#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:1503
#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:1081
#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:1925
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:1492
#define FAX_TONE_CNG_FREQ
Definition dsp.c:211
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
Definition dsp.c:1814
#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:907
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:1767
#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:1487
#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:1223
void ast_dsp_reset(struct ast_dsp *dsp)
Reset total silence count.
Definition dsp.c:1847
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:1808
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:1734
#define FAX_TONE_CED_FREQ
Definition dsp.c:219
static int reload_module(void)
Definition dsp.c:2471
#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:1058
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:1781
#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:699
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition dsp.c:1861
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:1441
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:2013
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:2459
int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
Process the audio frame for noise.
Definition dsp.c:1497
int ast_dsp_get_tstate(struct ast_dsp *dsp)
Get tstate (Tone State)
Definition dsp.c:1915
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:1910
static int unload_module(void)
Definition dsp.c:2451
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:1303
static void store_digit(digit_detect_state_t *s, char digit)
Definition dsp.c:686
int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
Set fax mode.
Definition dsp.c:1887
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:1876
static struct ast_dsp * __ast_dsp_new(unsigned int sample_rate)
Definition dsp.c:1739
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
Set number of required cadences for busy.
Definition dsp.c:1797
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:1772
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:1762
static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise, int *frames_energy)
Definition dsp.c:1237
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
Set zone for doing progress detection.
Definition dsp.c:1896
#define TONE_THRESH
Definition dsp.c:153
static void ast_dsp_prog_reset(struct ast_dsp *dsp)
Definition dsp.c:1717
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.
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
struct ast_format * ast_format_alaw
Built-in cached alaw format.
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.
#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_DTMF_END
@ AST_FRAME_DTMF_BEGIN
@ AST_FRAME_CONTROL
@ 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
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::@239 data
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
mf_detect_state_t mf
Definition dsp.c:315
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
union digit_detect_state_t::@372 td
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 start
Definition dsp.c:390
int end
Definition dsp.c:391
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
char * name
Definition dsp.c:105
enum prog_mode mode
Definition dsp.c:106
enum gsamp_size size
Definition dsp.c:118
int freqs[FREQ_ARRAY_SIZE]
Definition dsp.c:119
float threshold
Definition dsp.c:276
goertzel_state_t tone
Definition dsp.c:270
int samples_pending
Definition dsp.c:272
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
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