2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
11 * See http://www.asterisk.org for more information about
12 * the Asterisk project. Please do not directly contact
13 * any of the maintainers of this project for assistance;
14 * the project provides a web site, mailing lists and IRC
15 * channels for your use.
17 * This program is free software, distributed under the terms of
18 * the GNU General Public License Version 2. See the LICENSE file
19 * at the top of the source tree.
24 * \brief Convenience Signal Processing routines
26 * \author Mark Spencer <markster@digium.com>
27 * \author Steve Underwood <steveu@coppice.org>
30 /* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
32 tone_detect.c - General telephony tone detection, and specific
35 Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
37 Despite my general liking of the GPL, I place this code in the
38 public domain for the benefit of all mankind - even the slimy
39 ones who might try to proprietize my work and use it to my
45 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
49 #include "asterisk/frame.h"
50 #include "asterisk/channel.h"
51 #include "asterisk/dsp.h"
52 #include "asterisk/ulaw.h"
53 #include "asterisk/alaw.h"
54 #include "asterisk/utils.h"
55 #include "asterisk/options.h"
56 #include "asterisk/config.h"
58 /*! Number of goertzels for progress detect */
60 GSAMP_SIZE_NA = 183, /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
61 GSAMP_SIZE_CR = 188, /*!< Costa Rica, Brazil - Only care about 425 Hz */
62 GSAMP_SIZE_UK = 160 /*!< UK disconnect goertzel feed - should trigger 400hz */
81 /*! For CR/BR modes */
88 static struct progalias {
92 { "us", PROG_MODE_NA },
93 { "ca", PROG_MODE_NA },
94 { "cr", PROG_MODE_CR },
95 { "br", PROG_MODE_CR },
96 { "uk", PROG_MODE_UK },
99 static struct progress {
100 enum gsamp_size size;
103 { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
104 { GSAMP_SIZE_CR, { 425 } }, /*!< Costa Rica, Brazil */
105 { GSAMP_SIZE_UK, { 400 } }, /*!< UK */
108 #define DEFAULT_THRESHOLD 512
111 BUSY_PERCENT = 10, /*!< The percentage difference between the two last silence periods */
112 BUSY_PAT_PERCENT = 7, /*!< The percentage difference between measured and actual pattern */
113 BUSY_THRESHOLD = 100, /*!< Max number of ms difference between max and min times in busy */
114 BUSY_MIN = 75, /*!< Busy must be at least 80 ms in half-cadence */
115 BUSY_MAX =3100 /*!< Busy can't be longer than 3100 ms in half-cadence */
118 /*! Remember last 15 units */
119 #define DSP_HISTORY 15
121 #define TONE_THRESH 10.0 /*!< How much louder the tone should be than channel energy */
122 #define TONE_MIN_THRESH 1e8 /*!< How much tone there should be at least to attempt */
124 /*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
126 THRESH_RING = 8, /*!< Need at least 150ms ring to accept */
127 THRESH_TALK = 2, /*!< Talk detection does not work continuously */
128 THRESH_BUSY = 4, /*!< Need at least 80ms to accept */
129 THRESH_CONGESTION = 4, /*!< Need at least 80ms to accept */
130 THRESH_HANGUP = 60, /*!< Need at least 1300ms to accept hangup */
131 THRESH_RING2ANSWER = 300 /*!< Timeout from start of ring to answer (about 6600 ms) */
134 #define MAX_DTMF_DIGITS 128
138 * Minimum tone on = 40ms
139 * Minimum tone off = 50ms
140 * Maximum digit rate = 10 per second
141 * Normal twist <= 8dB accepted
142 * Reverse twist <= 4dB accepted
143 * S/N >= 15dB will detect OK
144 * Attenuation <= 26dB will detect OK
145 * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
148 #define DTMF_THRESHOLD 8.0e7
149 #define FAX_THRESHOLD 8.0e7
150 #define FAX_2ND_HARMONIC 2.0 /* 4dB */
151 #define DTMF_NORMAL_TWIST 6.3 /* 8dB */
153 #define DTMF_REVERSE_TWIST (relax ? 6.5 : 2.5) /* 4dB normal */
155 #define DTMF_REVERSE_TWIST (relax ? 4.0 : 2.5) /* 4dB normal */
157 #define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
158 #define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
159 #define DTMF_2ND_HARMONIC_ROW (relax ? 1.7 : 2.5) /* 4dB normal */
160 #define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
161 #define DTMF_TO_TOTAL_ENERGY 42.0
163 #define BELL_MF_THRESHOLD 1.6e9
164 #define BELL_MF_TWIST 4.0 /* 6dB */
165 #define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */
167 #if defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
168 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
171 /* The CNG signal consists of the transmission of 1100 Hz for 1/2 second,
172 * followed by a 3 second silent (2100 Hz OFF) period.
174 #define FAX_TONE_CNG_FREQ 1100
175 #define FAX_TONE_CNG_DURATION 500
176 #define FAX_TONE_CNG_DB 16
178 /* This signal may be sent by the Terminating FAX machine anywhere between
179 * 1.8 to 2.5 seconds AFTER answering the call. The CED signal consists
180 * of a 2100 Hz tone that is from 2.6 to 4 seconds in duration.
182 #define FAX_TONE_CED_FREQ 2100
183 #define FAX_TONE_CED_DURATION 2600
184 #define FAX_TONE_CED_DB 16
186 #define SAMPLE_RATE 8000
188 /* How many samples a frame has. This constant is used when calculating
189 * Goertzel block size for tone_detect. It is only important if we want to
190 * remove (squelch) the tone. In this case it is important to have block
191 * size not to exceed size of voice frame. Otherwise by the moment the tone
192 * is detected it is too late to squelch it from previous frames.
194 #define SAMPLES_IN_FRAME 160
196 /* MF goertzel size */
199 /* DTMF goertzel size */
200 #define DTMF_GSIZE 102
202 /* How many successive hits needed to consider begin of a digit */
203 #define DTMF_HITS_TO_BEGIN 2
204 /* How many successive misses needed to consider end of a digit */
205 #define DTMF_MISSES_TO_END 3
207 #define CONFIG_FILE_NAME "dsp.conf"
226 int squelch; /* Remove (squelch) tone */
227 goertzel_state_t tone;
228 float energy; /* Accumulated energy of the current block */
229 int samples_pending; /* Samples remain to complete the current block */
230 int mute_samples; /* How many additional samples needs to be muted to suppress already detected tone */
232 int hits_required; /* How many successive blocks with tone we are looking for */
233 float threshold; /* Energy of the tone relative to energy from all other signals to consider a hit */
235 int hit_count; /* How many successive blocks we consider tone present */
236 int last_hit; /* Indicates if the last processed block was a hit */
238 } tone_detect_state_t;
242 goertzel_state_t row_out[4];
243 goertzel_state_t col_out[4];
244 int hits_to_begin; /* How many successive hits needed to consider begin of a digit */
245 int misses_to_end; /* How many successive misses needed to consider end of a digit */
246 int hits; /* How many successive hits we have seen already */
247 int misses; /* How many successive misses we have seen already */
253 } dtmf_detect_state_t;
257 goertzel_state_t tone_out[6];
266 char digits[MAX_DTMF_DIGITS + 1];
272 dtmf_detect_state_t dtmf;
273 mf_detect_state_t mf;
275 } digit_detect_state_t;
277 static float dtmf_row[] =
279 697.0, 770.0, 852.0, 941.0
281 static float dtmf_col[] =
283 1209.0, 1336.0, 1477.0, 1633.0
286 static float mf_tones[] =
288 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
291 static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
293 static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
295 static int thresholds[THRESHOLD_MAX];
297 static inline void goertzel_sample(goertzel_state_t *s, short sample)
304 s->v3 = (s->fac * s->v2) >> 15;
305 s->v3 = s->v3 - v1 + (sample >> s->chunky);
306 if (abs(s->v3) > 32768) {
314 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
318 for (i=0;i<count;i++)
319 goertzel_sample(s, samps[i]);
323 static inline float goertzel_result(goertzel_state_t *s)
326 r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
327 r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
328 r.power = s->chunky * 2;
329 return (float)r.value * (float)(1 << r.power);
332 static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
334 s->v2 = s->v3 = s->chunky = 0.0;
335 s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
336 s->samples = samples;
339 static inline void goertzel_reset(goertzel_state_t *s)
341 s->v2 = s->v3 = s->chunky = 0.0;
349 /* Note on tone suppression (squelching). Individual detectors (DTMF/MF/generic tone)
350 * report fragmens of the frame in which detected tone resides and which needs
351 * to be "muted" in order to suppress the tone. To mark fragment for muting,
352 * detectors call mute_fragment passing fragment_t there. Multiple fragments
353 * can be marked and ast_dsp_process later will mute all of them.
355 * Note: When tone starts in the middle of a Goertzel block, it won't be properly
356 * detected in that block, only in the next. If we only mute the next block
357 * where tone is actually detected, the user will still hear beginning
358 * of the tone in preceeding block. This is why we usually want to mute some amount
359 * of samples preceeding and following the block where tone was detected.
372 int busy_quietlength;
373 int historicnoise[DSP_HISTORY];
374 int historicsilence[DSP_HISTORY];
375 goertzel_state_t freqs[7];
378 enum gsamp_size gsamp_size;
379 enum prog_mode progmode;
387 fragment_t mute_data[5];
388 digit_detect_state_t digit_state;
389 tone_detect_state_t cng_tone_state;
390 tone_detect_state_t ced_tone_state;
393 static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
395 if (dsp->mute_fragments >= sizeof(dsp->mute_data) / sizeof(dsp->mute_data[0])) {
396 ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
400 dsp->mute_data[dsp->mute_fragments++] = *fragment;
403 static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
405 int duration_samples;
407 int periods_in_block;
411 /* Desired tone duration in samples */
412 duration_samples = duration * SAMPLE_RATE / 1000;
413 /* We want to allow 10% deviation of tone duration */
414 duration_samples = duration_samples * 9 / 10;
416 /* If we want to remove tone, it is important to have block size not
417 to exceed frame size. Otherwise by the moment tone is detected it is too late
418 to squelch it from previous frames */
419 s->block_size = SAMPLES_IN_FRAME;
421 periods_in_block = s->block_size * freq / SAMPLE_RATE;
423 /* Make sure we will have at least 5 periods at target frequency for analisys.
424 This may make block larger than expected packet and will make squelching impossible
425 but at least we will be detecting the tone */
426 if (periods_in_block < 5)
427 periods_in_block = 5;
429 /* Now calculate final block size. It will contain integer number of periods */
430 s->block_size = periods_in_block * SAMPLE_RATE / freq;
432 /* tone_detect is currently only used to detect fax tones and we
433 do not need suqlching the fax tones */
436 /* Account for the first and the last block to be incomplete
437 and thus no tone will be detected in them */
438 s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
440 goertzel_init(&s->tone, freq, s->block_size);
442 s->samples_pending = s->block_size;
447 /* We want tone energy to be amp decibels above the rest of the signal (the noise).
448 According to Parseval's theorem the energy computed in time domain equals to energy
449 computed in frequency domain. So subtracting energy in the frequency domain (Goertzel result)
450 from the energy in the time domain we will get energy of the remaining signal (without the tone
451 we are detecting). We will be checking that
452 10*log(Ew / (Et - Ew)) > amp
453 Calculate threshold so that we will be actually checking
457 x = pow(10.0, amp / 10.0);
458 s->threshold = x / (x + 1);
460 ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
463 static void ast_fax_detect_init(struct ast_dsp *s)
465 ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
466 ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
469 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
475 for (i = 0; i < 4; i++) {
476 goertzel_init (&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
477 goertzel_init (&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
480 s->current_sample = 0;
484 s->hits_to_begin = DTMF_HITS_TO_BEGIN;
485 s->misses_to_end = DTMF_MISSES_TO_END;
488 static void ast_mf_detect_init (mf_detect_state_t *s)
491 s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
492 for (i = 0; i < 6; i++) {
493 goertzel_init (&s->tone_out[i], mf_tones[i], 160);
495 s->current_sample = 0;
499 static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
501 s->current_digits = 0;
502 s->detected_digits = 0;
507 ast_mf_detect_init(&s->td.mf);
509 ast_dtmf_detect_init(&s->td.dtmf);
512 static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
521 fragment_t mute = {0, 0};
523 if (s->squelch && s->mute_samples > 0) {
524 mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
525 s->mute_samples -= mute.end;
528 for (start = 0; start < samples; start = end) {
529 /* Process in blocks. */
530 limit = samples - start;
531 if (limit > s->samples_pending)
532 limit = s->samples_pending;
535 for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
536 /* signed 32 bit int should be enough to suqare any possible signed 16 bit value */
537 s->energy += (int32_t) *ptr * (int32_t) *ptr;
539 goertzel_sample(&s->tone, *ptr);
542 s->samples_pending -= limit;
544 if (s->samples_pending) {
545 /* Finished incomplete (last) block */
549 tone_energy = goertzel_result(&s->tone);
551 /* Scale to make comparable */
553 s->energy *= s->block_size;
555 ast_debug(10, "tone %d, Ew=%.2E, Et=%.2E, s/n=%10.2f\n", s->freq, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
557 if (tone_energy > s->energy * s->threshold) {
559 ast_debug(10, "Hit! count=%d\n", s->hit_count);
566 if (hit == s->last_hit) {
568 /* Two successive misses. Tone ended */
570 } else if (!s->hit_count) {
576 if (s->hit_count == s->hits_required) {
577 ast_debug(1, "%d Hz done detected\n", s->freq);
583 /* If we had a hit in this block, include it into mute fragment */
584 if (s->squelch && hit) {
585 if (mute.end < start - s->block_size) {
586 /* There is a gap between fragments */
587 mute_fragment(dsp, &mute);
588 mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
590 mute.end = end + s->block_size;
593 /* Reinitialise the detector for the next block */
594 /* Reset for the next block */
595 goertzel_reset(&s->tone);
597 /* Advance to the next block */
599 s->samples_pending = s->block_size;
604 if (s->squelch && mute.end) {
605 if (mute.end > samples) {
606 s->mute_samples = mute.end - samples;
609 mute_fragment(dsp, &mute);
615 static void store_digit(digit_detect_state_t *s, char digit)
617 s->detected_digits++;
618 if (s->current_digits < MAX_DTMF_DIGITS) {
619 s->digits[s->current_digits++] = digit;
620 s->digits[s->current_digits] = '\0';
622 ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
627 static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
639 fragment_t mute = {0, 0};
641 if (squelch && s->td.dtmf.mute_samples > 0) {
642 mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
643 s->td.dtmf.mute_samples -= mute.end;
647 for (sample = 0; sample < samples; sample = limit) {
648 /* DTMF_GSIZE is optimised to meet the DTMF specs. */
649 if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample))
650 limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
653 /* The following unrolled loop takes only 35% (rough estimate) of the
654 time of a rolled loop on the machine on which it was developed */
655 for (j = sample; j < limit; j++) {
657 s->td.dtmf.energy += famp*famp;
658 /* With GCC 2.95, the following unrolled code seems to take about 35%
659 (rough estimate) as long as a neat little 0-3 loop */
660 goertzel_sample(s->td.dtmf.row_out, amp[j]);
661 goertzel_sample(s->td.dtmf.col_out, amp[j]);
662 goertzel_sample(s->td.dtmf.row_out + 1, amp[j]);
663 goertzel_sample(s->td.dtmf.col_out + 1, amp[j]);
664 goertzel_sample(s->td.dtmf.row_out + 2, amp[j]);
665 goertzel_sample(s->td.dtmf.col_out + 2, amp[j]);
666 goertzel_sample(s->td.dtmf.row_out + 3, amp[j]);
667 goertzel_sample(s->td.dtmf.col_out + 3, amp[j]);
669 s->td.dtmf.current_sample += (limit - sample);
670 if (s->td.dtmf.current_sample < DTMF_GSIZE) {
673 /* We are at the end of a DTMF detection block */
674 /* Find the peak row and the peak column */
675 row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
676 col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
678 for (best_row = best_col = 0, i = 1; i < 4; i++) {
679 row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
680 if (row_energy[i] > row_energy[best_row])
682 col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
683 if (col_energy[i] > col_energy[best_col])
687 /* Basic signal level test and the twist test */
688 if (row_energy[best_row] >= DTMF_THRESHOLD &&
689 col_energy[best_col] >= DTMF_THRESHOLD &&
690 col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
691 col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
692 /* Relative peak test */
693 for (i = 0; i < 4; i++) {
694 if ((i != best_col &&
695 col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
697 && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
701 /* ... and fraction of total energy test */
703 (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->td.dtmf.energy) {
705 hit = dtmf_positions[(best_row << 2) + best_col];
709 if (s->td.dtmf.current_hit) {
710 /* We are in the middle of a digit already */
711 if (hit != s->td.dtmf.current_hit) {
713 if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) {
714 /* There were enough misses to consider digit ended */
715 s->td.dtmf.current_hit = 0;
718 s->td.dtmf.misses = 0;
722 /* Look for a start of a new digit no matter if we are already in the middle of some
723 digit or not. This is because hits_to_begin may be smaller than misses_to_end
724 and we may find begin of new digit before we consider last one ended. */
726 if (hit == s->td.dtmf.lasthit) {
732 if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin && hit != s->td.dtmf.current_hit) {
734 s->td.dtmf.current_hit = hit;
735 s->td.dtmf.misses = 0;
741 s->td.dtmf.lasthit = hit;
743 /* If we had a hit in this block, include it into mute fragment */
744 if (squelch && hit) {
745 if (mute.end < sample - DTMF_GSIZE) {
746 /* There is a gap between fragments */
747 mute_fragment(dsp, &mute);
748 mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
750 mute.end = limit + DTMF_GSIZE;
753 /* Reinitialise the detector for the next block */
754 for (i = 0; i < 4; i++) {
755 goertzel_reset(&s->td.dtmf.row_out[i]);
756 goertzel_reset(&s->td.dtmf.col_out[i]);
758 s->td.dtmf.energy = 0.0;
759 s->td.dtmf.current_sample = 0;
762 if (squelch && mute.end) {
763 if (mute.end > samples) {
764 s->td.dtmf.mute_samples = mute.end - samples;
767 mute_fragment(dsp, &mute);
770 return (s->td.dtmf.current_hit); /* return the debounced hit */
773 static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
774 int samples, int squelch, int relax)
785 fragment_t mute = {0, 0};
787 if (squelch && s->td.mf.mute_samples > 0) {
788 mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
789 s->td.mf.mute_samples -= mute.end;
793 for (sample = 0; sample < samples; sample = limit) {
794 /* 80 is optimised to meet the MF specs. */
795 /* XXX So then why is MF_GSIZE defined as 120? */
796 if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample))
797 limit = sample + (MF_GSIZE - s->td.mf.current_sample);
800 /* The following unrolled loop takes only 35% (rough estimate) of the
801 time of a rolled loop on the machine on which it was developed */
802 for (j = sample; j < limit; j++) {
804 /* With GCC 2.95, the following unrolled code seems to take about 35%
805 (rough estimate) as long as a neat little 0-3 loop */
806 goertzel_sample(s->td.mf.tone_out, amp[j]);
807 goertzel_sample(s->td.mf.tone_out + 1, amp[j]);
808 goertzel_sample(s->td.mf.tone_out + 2, amp[j]);
809 goertzel_sample(s->td.mf.tone_out + 3, amp[j]);
810 goertzel_sample(s->td.mf.tone_out + 4, amp[j]);
811 goertzel_sample(s->td.mf.tone_out + 5, amp[j]);
813 s->td.mf.current_sample += (limit - sample);
814 if (s->td.mf.current_sample < MF_GSIZE) {
817 /* We're at the end of an MF detection block. */
818 /* Find the two highest energies. The spec says to look for
819 two tones and two tones only. Taking this literally -ie
820 only two tones pass the minimum threshold - doesn't work
821 well. The sinc function mess, due to rectangular windowing
822 ensure that! Find the two highest energies and ensure they
823 are considerably stronger than any of the others. */
824 energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
825 energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
826 if (energy[0] > energy[1]) {
835 energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
836 if (energy[i] >= energy[best]) {
839 } else if (energy[i] >= energy[second_best]) {
843 /* Basic signal level and twist tests */
845 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
846 && energy[best] < energy[second_best]*BELL_MF_TWIST
847 && energy[best]*BELL_MF_TWIST > energy[second_best]) {
848 /* Relative peak test */
851 if (i != best && i != second_best) {
852 if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
853 /* The best two are not clearly the best */
861 /* Get the values into ascending order */
862 if (second_best < best) {
867 best = best*5 + second_best - 1;
868 hit = bell_mf_positions[best];
869 /* Look for two successive similar results */
870 /* The logic in the next test is:
871 For KP we need 4 successive identical clean detects, with
872 two blocks of something different preceeding it. For anything
873 else we need two successive identical clean detects, with
874 two blocks of something different preceeding it. */
875 if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
876 ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
877 (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
878 hit != s->td.mf.hits[0]))) {
884 if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
885 /* Two successive block without a hit terminate current digit */
886 s->td.mf.current_hit = 0;
889 s->td.mf.hits[0] = s->td.mf.hits[1];
890 s->td.mf.hits[1] = s->td.mf.hits[2];
891 s->td.mf.hits[2] = s->td.mf.hits[3];
892 s->td.mf.hits[3] = s->td.mf.hits[4];
893 s->td.mf.hits[4] = hit;
895 /* If we had a hit in this block, include it into mute fragment */
896 if (squelch && hit) {
897 if (mute.end < sample - MF_GSIZE) {
898 /* There is a gap between fragments */
899 mute_fragment(dsp, &mute);
900 mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
902 mute.end = limit + DTMF_GSIZE;
905 /* Reinitialise the detector for the next block */
906 for (i = 0; i < 6; i++)
907 goertzel_reset(&s->td.mf.tone_out[i]);
908 s->td.mf.current_sample = 0;
911 if (squelch && mute.end) {
912 if (mute.end > samples) {
913 s->td.mf.mute_samples = mute.end - samples;
916 mute_fragment(dsp, &mute);
919 return (s->td.mf.current_hit); /* return the debounced hit */
922 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
924 /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
925 /* Make sure absolute levels are high enough */
926 if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
928 /* Amplify ignored stuff */
932 /* Check first tone */
933 if ((p1 < i1) || (p1 < i2) || (p1 < e))
936 if ((p2 < i1) || (p2 < i2) || (p2 < e))
938 /* Guess it's there... */
942 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
947 int newstate = DSP_TONE_STATE_SILENCE;
950 /* Take the lesser of the number of samples we need and what we have */
952 if (pass > dsp->gsamp_size - dsp->gsamps)
953 pass = dsp->gsamp_size - dsp->gsamps;
954 for (x=0;x<pass;x++) {
955 for (y=0;y<dsp->freqcount;y++)
956 goertzel_sample(&dsp->freqs[y], s[x]);
957 dsp->genergy += s[x] * s[x];
962 if (dsp->gsamps == dsp->gsamp_size) {
965 hz[y] = goertzel_result(&dsp->freqs[y]);
966 switch (dsp->progmode) {
968 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
969 newstate = DSP_TONE_STATE_BUSY;
970 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
971 newstate = DSP_TONE_STATE_RINGING;
972 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
973 newstate = DSP_TONE_STATE_DIALTONE;
974 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
975 newstate = DSP_TONE_STATE_SPECIAL1;
976 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
977 if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
978 newstate = DSP_TONE_STATE_SPECIAL2;
979 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
980 if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
981 newstate = DSP_TONE_STATE_SPECIAL3;
982 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
983 newstate = DSP_TONE_STATE_TALKING;
985 newstate = DSP_TONE_STATE_SILENCE;
988 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
989 newstate = DSP_TONE_STATE_RINGING;
990 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
991 newstate = DSP_TONE_STATE_TALKING;
993 newstate = DSP_TONE_STATE_SILENCE;
996 if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
997 newstate = DSP_TONE_STATE_HUNGUP;
1001 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
1003 if (newstate == dsp->tstate) {
1005 if (dsp->ringtimeout)
1007 switch (dsp->tstate) {
1008 case DSP_TONE_STATE_RINGING:
1009 if ((dsp->features & DSP_PROGRESS_RINGING) &&
1010 (dsp->tcount==THRESH_RING)) {
1011 res = AST_CONTROL_RINGING;
1012 dsp->ringtimeout= 1;
1015 case DSP_TONE_STATE_BUSY:
1016 if ((dsp->features & DSP_PROGRESS_BUSY) &&
1017 (dsp->tcount==THRESH_BUSY)) {
1018 res = AST_CONTROL_BUSY;
1019 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1022 case DSP_TONE_STATE_TALKING:
1023 if ((dsp->features & DSP_PROGRESS_TALK) &&
1024 (dsp->tcount==THRESH_TALK)) {
1025 res = AST_CONTROL_ANSWER;
1026 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1029 case DSP_TONE_STATE_SPECIAL3:
1030 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
1031 (dsp->tcount==THRESH_CONGESTION)) {
1032 res = AST_CONTROL_CONGESTION;
1033 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1036 case DSP_TONE_STATE_HUNGUP:
1037 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
1038 (dsp->tcount==THRESH_HANGUP)) {
1039 res = AST_CONTROL_HANGUP;
1040 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1044 if (dsp->ringtimeout==THRESH_RING2ANSWER) {
1045 ast_debug(1, "Consider call as answered because of timeout after last ring\n");
1046 res = AST_CONTROL_ANSWER;
1047 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
1050 ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
1051 ast_debug(5, "Start state %d\n", newstate);
1052 dsp->tstate = newstate;
1056 /* Reset goertzel */
1058 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1067 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
1069 if (inf->frametype != AST_FRAME_VOICE) {
1070 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
1073 if (inf->subclass != AST_FORMAT_SLINEAR) {
1074 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
1077 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
1080 static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
1089 for (x=0;x<len; x++)
1092 if (accum < dsp->threshold) {
1094 dsp->totalsilence += len/8;
1095 if (dsp->totalnoise) {
1096 /* Move and save history */
1097 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
1098 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
1099 /* we don't want to check for busydetect that frequently */
1104 dsp->totalnoise = 0;
1108 dsp->totalnoise += len/8;
1109 if (dsp->totalsilence) {
1110 int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
1111 int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
1112 /* Move and save history */
1113 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
1114 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
1115 /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
1116 if (silence1 < silence2) {
1117 if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
1122 if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
1128 dsp->totalsilence = 0;
1131 *totalsilence = dsp->totalsilence;
1133 *totalnoise = dsp->totalnoise;
1137 int ast_dsp_busydetect(struct ast_dsp *dsp)
1140 #ifndef BUSYDETECT_TONEONLY
1141 int avgsilence = 0, hitsilence = 0;
1143 int avgtone = 0, hittone = 0;
1144 if (!dsp->busymaybe)
1146 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
1147 #ifndef BUSYDETECT_TONEONLY
1148 avgsilence += dsp->historicsilence[x];
1150 avgtone += dsp->historicnoise[x];
1152 #ifndef BUSYDETECT_TONEONLY
1153 avgsilence /= dsp->busycount;
1155 avgtone /= dsp->busycount;
1156 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
1157 #ifndef BUSYDETECT_TONEONLY
1158 if (avgsilence > dsp->historicsilence[x]) {
1159 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
1162 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
1166 if (avgtone > dsp->historicnoise[x]) {
1167 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
1170 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
1174 #ifndef BUSYDETECT_TONEONLY
1175 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
1176 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
1177 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
1179 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
1181 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1182 if (avgtone > avgsilence) {
1183 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
1186 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
1193 /* If we know the expected busy tone length, check we are in the range */
1194 if (res && (dsp->busy_tonelength > 0)) {
1195 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
1196 #ifdef BUSYDETECT_DEBUG
1197 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
1198 avgtone, dsp->busy_tonelength);
1203 #ifndef BUSYDETECT_TONEONLY
1204 /* If we know the expected busy tone silent-period length, check we are in the range */
1205 if (res && (dsp->busy_quietlength > 0)) {
1206 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
1207 #ifdef BUSYDETECT_DEBUG
1208 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
1209 avgsilence, dsp->busy_quietlength);
1215 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
1217 ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1219 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1225 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
1230 if (f->frametype != AST_FRAME_VOICE) {
1231 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
1234 if (f->subclass != AST_FORMAT_SLINEAR) {
1235 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
1240 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
1243 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
1248 if (f->frametype != AST_FRAME_VOICE) {
1249 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
1252 if (f->subclass != AST_FORMAT_SLINEAR) {
1253 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
1258 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
1262 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
1266 int digit = 0, fax_digit = 0;
1269 unsigned char *odata;
1271 struct ast_frame *outf = NULL;
1275 if (af->frametype != AST_FRAME_VOICE)
1280 /* Make sure we have short data */
1281 switch (af->subclass) {
1282 case AST_FORMAT_SLINEAR:
1283 shortdata = af->data;
1284 len = af->datalen / 2;
1286 case AST_FORMAT_ULAW:
1287 shortdata = alloca(af->datalen * 2);
1288 for (x = 0;x < len; x++)
1289 shortdata[x] = AST_MULAW(odata[x]);
1291 case AST_FORMAT_ALAW:
1292 shortdata = alloca(af->datalen * 2);
1293 for (x = 0; x < len; x++)
1294 shortdata[x] = AST_ALAW(odata[x]);
1297 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
1301 /* Initially we do not want to mute anything */
1302 dsp->mute_fragments = 0;
1304 /* Need to run the silence detection stuff for silence suppression and busy detection */
1305 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
1306 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
1309 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
1310 memset(&dsp->f, 0, sizeof(dsp->f));
1311 dsp->f.frametype = AST_FRAME_NULL;
1315 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
1316 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1317 memset(&dsp->f, 0, sizeof(dsp->f));
1318 dsp->f.frametype = AST_FRAME_CONTROL;
1319 dsp->f.subclass = AST_CONTROL_BUSY;
1321 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
1325 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
1326 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
1330 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
1335 if ((dsp->features & DSP_FEATURE_DIGIT_DETECT)) {
1336 if ((dsp->digitmode & DSP_DIGITMODE_MF))
1337 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1339 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1341 if (dsp->digit_state.current_digits) {
1343 char event_digit = 0;
1345 if (!dsp->dtmf_began) {
1346 /* We have not reported DTMF_BEGIN for anything yet */
1348 event = AST_FRAME_DTMF_BEGIN;
1349 event_digit = dsp->digit_state.digits[0];
1350 dsp->dtmf_began = 1;
1352 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
1353 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
1355 event = AST_FRAME_DTMF_END;
1356 event_digit = dsp->digit_state.digits[0];
1357 memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits);
1358 dsp->digit_state.current_digits--;
1359 dsp->dtmf_began = 0;
1363 memset(&dsp->f, 0, sizeof(dsp->f));
1364 dsp->f.frametype = event;
1365 dsp->f.subclass = event_digit;
1373 /* Fax was detected - digit is either 'f' or 'e' */
1375 memset(&dsp->f, 0, sizeof(dsp->f));
1376 dsp->f.frametype = AST_FRAME_DTMF;
1377 dsp->f.subclass = fax_digit;
1382 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
1383 res = __ast_dsp_call_progress(dsp, shortdata, len);
1386 case AST_CONTROL_ANSWER:
1387 case AST_CONTROL_BUSY:
1388 case AST_CONTROL_RINGING:
1389 case AST_CONTROL_CONGESTION:
1390 case AST_CONTROL_HANGUP:
1391 memset(&dsp->f, 0, sizeof(dsp->f));
1392 dsp->f.frametype = AST_FRAME_CONTROL;
1393 dsp->f.subclass = res;
1394 dsp->f.src = "dsp_progress";
1396 ast_queue_frame(chan, &dsp->f);
1399 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
1405 /* Mute fragment of the frame */
1406 for (x = 0; x < dsp->mute_fragments; x++) {
1407 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
1410 switch (af->subclass) {
1411 case AST_FORMAT_SLINEAR:
1413 case AST_FORMAT_ULAW:
1414 for (x = 0; x < len; x++)
1415 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
1417 case AST_FORMAT_ALAW:
1418 for (x = 0; x < len; x++)
1419 odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
1425 ast_queue_frame(chan, af);
1433 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
1438 dsp->gsamp_size = modes[dsp->progmode].size;
1440 for (x = 0; x < sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]); x++) {
1441 if (modes[dsp->progmode].freqs[x]) {
1442 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
1446 dsp->freqcount = max;
1447 dsp->ringtimeout= 0;
1450 struct ast_dsp *ast_dsp_new(void)
1452 struct ast_dsp *dsp;
1454 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
1455 dsp->threshold = DEFAULT_THRESHOLD;
1456 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
1457 dsp->busycount = DSP_HISTORY;
1458 dsp->digitmode = DSP_DIGITMODE_DTMF;
1459 dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
1460 /* Initialize digit detector */
1461 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
1462 /* Initialize initial DSP progress detect parameters */
1463 ast_dsp_prog_reset(dsp);
1464 /* Initialize fax detector */
1465 ast_fax_detect_init(dsp);
1470 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
1472 dsp->features = features;
1475 void ast_dsp_free(struct ast_dsp *dsp)
1480 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
1482 dsp->threshold = threshold;
1485 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
1489 if (cadences > DSP_HISTORY)
1490 cadences = DSP_HISTORY;
1491 dsp->busycount = cadences;
1494 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
1496 dsp->busy_tonelength = tonelength;
1497 dsp->busy_quietlength = quietlength;
1498 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
1501 void ast_dsp_digitreset(struct ast_dsp *dsp)
1505 dsp->dtmf_began = 0;
1506 if (dsp->digitmode & DSP_DIGITMODE_MF) {
1507 mf_detect_state_t *s = &dsp->digit_state.td.mf;
1508 /* Reinitialise the detector for the next block */
1509 for (i = 0; i < 6; i++) {
1510 goertzel_reset(&s->tone_out[i]);
1512 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
1513 s->current_sample = 0;
1515 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
1516 /* Reinitialise the detector for the next block */
1517 for (i = 0; i < 4; i++) {
1518 goertzel_reset(&s->row_out[i]);
1519 goertzel_reset(&s->col_out[i]);
1521 s->lasthit = s->current_hit = 0;
1523 s->current_sample = 0;
1528 dsp->digit_state.digits[0] = '\0';
1529 dsp->digit_state.current_digits = 0;
1532 void ast_dsp_reset(struct ast_dsp *dsp)
1536 dsp->totalsilence = 0;
1539 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1540 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1541 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
1542 dsp->ringtimeout= 0;
1545 int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
1550 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
1551 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
1553 /* Must initialize structures if switching from MF to DTMF or vice-versa */
1554 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
1556 dsp->digitmode = digitmode;
1560 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
1562 if (dsp->faxmode != faxmode) {
1563 ast_fax_detect_init(dsp);
1565 dsp->faxmode = faxmode;
1569 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
1573 for (x = 0; x < ARRAY_LEN(aliases); x++) {
1574 if (!strcasecmp(aliases[x].name, zone)) {
1575 dsp->progmode = aliases[x].mode;
1576 ast_dsp_prog_reset(dsp);
1583 int ast_dsp_was_muted(struct ast_dsp *dsp)
1585 return (dsp->mute_fragments > 0);
1588 int ast_dsp_get_tstate(struct ast_dsp *dsp)
1593 int ast_dsp_get_tcount(struct ast_dsp *dsp)
1598 static int _dsp_init(int reload)
1600 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1601 struct ast_config *cfg;
1603 cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags);
1605 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED) {
1608 value = ast_variable_retrieve(cfg, "default", "silencethreshold");
1609 if (value && sscanf(value, "%d", &thresholds[THRESHOLD_SILENCE]) != 1) {
1610 ast_log(LOG_WARNING, "%s: '%s' is not a valid silencethreshold value\n", CONFIG_FILE_NAME, value);
1611 thresholds[THRESHOLD_SILENCE] = 256;
1613 thresholds[THRESHOLD_SILENCE] = 256;
1615 ast_config_destroy(cfg);
1620 int ast_dsp_get_threshold_from_settings(enum threshold which)
1622 return thresholds[which];
1625 int ast_dsp_init(void)
1627 return _dsp_init(0);
1630 int ast_dsp_reload(void)
1632 return _dsp_init(1);