115#define FREQ_ARRAY_SIZE 7
140#define DEFAULT_THRESHOLD 512
151#define DSP_HISTORY 15
153#define TONE_THRESH 10.0
154#define TONE_MIN_THRESH 1e8
166#define MAX_DTMF_DIGITS 128
168#define DTMF_MATRIX_SIZE 4
182#define DTMF_THRESHOLD 8.0e7
183#define TONE_THRESHOLD 7.8e7
185#define DEF_DTMF_NORMAL_TWIST 6.31
186#define DEF_RELAX_DTMF_NORMAL_TWIST 6.31
189#define DEF_DTMF_REVERSE_TWIST 2.51
190#define DEF_RELAX_DTMF_REVERSE_TWIST 6.61
192#define DEF_DTMF_REVERSE_TWIST 2.51
193#define DEF_RELAX_DTMF_REVERSE_TWIST 3.98
196#define DTMF_RELATIVE_PEAK_ROW 6.3
197#define DTMF_RELATIVE_PEAK_COL 6.3
198#define DTMF_TO_TOTAL_ENERGY 42.0
200#define BELL_MF_THRESHOLD 1.6e9
201#define BELL_MF_TWIST 4.0
202#define BELL_MF_RELATIVE_PEAK 12.6
204#define R2_MF_THRESHOLD 5.0e8f
205#define R2_MF_TWIST 5.0f
206#define R2_MF_RELATIVE_PEAK 12.6f
208#if defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
209#error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
215#define FAX_TONE_CNG_FREQ 1100
216#define FAX_TONE_CNG_DURATION 500
217#define FAX_TONE_CNG_DB 16
223#define FAX_TONE_CED_FREQ 2100
224#define FAX_TONE_CED_DURATION 2600
225#define FAX_TONE_CED_DB 16
227#define DEFAULT_SAMPLE_RATE 8000
233#define DTMF_GSIZE 102
241#define DEF_DTMF_HITS_TO_BEGIN 2
246#define DEF_DTMF_MISSES_TO_END 3
254#define CONFIG_FILE_NAME "dsp.conf"
327 697.0, 770.0, 852.0, 941.0
330 1209.0, 1336.0, 1477.0, 1633.0
333 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
336 1380.0, 1500.0, 1620.0, 1740.0, 1860.0, 1980.0
339 1140.0, 1020.0, 900.0, 780.0, 660.0, 540.0
366 s->
v3 = (s->
fac * s->
v2) >> 15;
370 if (
abs(s->
v3) > (1 << 15)) {
389 return (
float)r.
value * (float)(1 << r.
power);
395 s->
fac = (int)(32768.0 * 2.0 *
cos(2.0 *
M_PI * freq / sample_rate));
468 int duration_samples;
470 int periods_in_block;
475 duration_samples = duration * sample_rate / 1000;
477 duration_samples = duration_samples * 9 / 10;
484 periods_in_block = s->
block_size * freq / sample_rate;
489 if (periods_in_block < 5) {
490 periods_in_block = 5;
494 s->
block_size = periods_in_block * sample_rate / freq;
521 x = pow(10.0, amp / 10.0);
567 for (i = 0; i < 6; i++) {
579 for (i = 0; i < 6; i++) {
622 for (start = 0; start < samples; start =
end) {
624 limit = samples - start;
630 for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
633 s->
energy += (int32_t) samp * (int32_t) samp;
706 if (mute.
end > samples) {
749 for (sample = 0; sample < samples; sample = limit) {
758 for (j = sample; j < limit; j++) {
784 if (row_energy[i] > row_energy[best_row]) {
788 if (col_energy[i] > col_energy[best_col]) {
792 ast_debug(10,
"DTMF best '%c' Erow=%.4E Ecol=%.4E Erc=%.4E Et=%.4E\n",
794 row_energy[best_row], col_energy[best_col],
795 row_energy[best_row] + col_energy[best_col], s->
td.
dtmf.
energy);
804 if ((i != best_col &&
908 if (squelch && hit) {
926 if (squelch && mute.
end) {
927 if (mute.
end > samples) {
938 int samples,
int squelch,
int relax)
957 for (sample = 0; sample < samples; sample = limit) {
967 for (j = sample; j < limit; j++) {
991 if (energy[0] > energy[1]) {
999 for (i = 2; i < 6; i++) {
1001 if (energy[i] >= energy[best]) {
1004 }
else if (energy[i] >= energy[second_best]) {
1015 for (i = 0; i < 6; i++) {
1016 if (i != best && i != second_best) {
1027 if (second_best < best) {
1032 best = best * 5 + second_best - 1;
1061 if (squelch && hit) {
1071 for (i = 0; i < 6; i++) {
1077 if (squelch && mute.
end) {
1078 if (mute.
end > samples) {
1089 int samples,
int squelch,
int relax,
const char *r2_positions)
1108 for (sample = 0; sample < samples; sample = limit) {
1116 for (j = sample; j < limit; j++) {
1140 if (energy[0] > energy[1]) {
1148 for (i = 2; i < 6; i++) {
1150 if (energy[i] >= energy[best]) {
1153 }
else if (energy[i] >= energy[second_best]) {
1161 && energy[best] *
R2_MF_TWIST > energy[second_best]) {
1164 for (i = 0; i < 6; i++) {
1165 if (i != best && i != second_best) {
1176 if (second_best < best) {
1181 best = best * 5 + second_best - 1;
1182 hit = r2_positions[best];
1211 if (squelch && hit) {
1221 for (i = 0; i < 6; i++) {
1227 if (squelch && mute.
end) {
1228 if (mute.
end > samples) {
1238static inline int pair_there(
float p1,
float p2,
float i1,
float i2,
float e)
1250 if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
1254 if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
1277 for (x = 0; x <
pass; x++) {
1279 dsp->
genergy += (int32_t) samp * (int32_t) samp;
1280 for (y = 0; y < freqcount; y++) {
1337 if (newstate == dsp->
tstate) {
1354 dsp->
features &= ~DSP_FEATURE_CALL_PROGRESS;
1361 dsp->
features &= ~DSP_FEATURE_CALL_PROGRESS;
1368 dsp->
features &= ~DSP_FEATURE_CALL_PROGRESS;
1375 dsp->
features &= ~DSP_FEATURE_CALL_PROGRESS;
1380 ast_debug(1,
"Consider call as answered because of timeout after last ring\n");
1382 dsp->
features &= ~DSP_FEATURE_CALL_PROGRESS;
1386 ast_debug(5,
"Start state %d\n", newstate);
1392 for (x = 0; x < 7; x++) {
1410 ast_log(
LOG_WARNING,
"Can only check call progress in signed-linear frames, %s not supported\n",
1427 for (x = 0; x <
len; x++) {
1455 if (silence1 < silence2) {
1456 if (silence1 + silence1 *
BUSY_PERCENT / 100 >= silence2) {
1462 if (silence1 - silence1 *
BUSY_PERCENT / 100 <= silence2) {
1477 if (frames_energy) {
1478 *frames_energy = accum;
1486#ifndef BUSYDETECT_TONEONLY
1487 int avgsilence = 0, hitsilence = 0;
1489 int avgtone = 0, hittone = 0;
1499#ifndef BUSYDETECT_TONEONLY
1504#ifndef BUSYDETECT_TONEONLY
1509#ifndef BUSYDETECT_TONEONLY
1530#ifndef BUSYDETECT_TONEONLY
1538#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1539 if (avgtone > avgsilence) {
1540 if (avgtone - avgtone*
BUSY_PERCENT/100 <= avgsilence) {
1544 if (avgtone + avgtone*
BUSY_PERCENT/100 >= avgsilence) {
1582 ast_debug(5,
"errors = %d max = %d\n", errors, errors_max);
1584 if (errors <= errors_max) {
1592#ifdef BUSYDETECT_DEBUG
1593 ast_debug(5,
"busy detector: avgtone of %d not close enough to desired %d\n",
1599#ifndef BUSYDETECT_TONEONLY
1603#ifdef BUSYDETECT_DEBUG
1604 ast_debug(5,
"busy detector: avgsilence of %d not close enough to desired %d\n",
1611#if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
1613 ast_debug(5,
"ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1615 ast_debug(5,
"busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1626 unsigned char *odata;
1645 for (x = 0; x <
len; x++) {
1650 for (x = 0; x <
len; x++) {
1654 ast_log(
LOG_WARNING,
"Can only calculate silence on signed-linear, alaw or ulaw frames, %s not supported\n",
1687 int digit = 0, fax_digit = 0, custom_freq_digit = 0;
1690 unsigned char *odata;
1709 for (x = 0; x <
len; x++) {
1714 for (x = 0; x <
len; x++) {
1726 ast_log(
LOG_WARNING,
"Can only do DSP on signed-linear, alaw or ulaw frames (%s not supported)\n",
1743 memset(&dsp->
f, 0,
sizeof(dsp->
f));
1750 memset(&dsp->
f, 0,
sizeof(dsp->
f));
1770 custom_freq_digit =
'q';
1784 int event = 0, event_len = 0;
1785 char event_digit = 0;
1811 ast_debug(1,
"DTMF Detected - Reset busydetector\n");
1816 memset(&dsp->
f, 0,
sizeof(dsp->
f));
1819 dsp->
f.
len = event_len;
1829 memset(&dsp->
f, 0,
sizeof(dsp->
f));
1836 if (custom_freq_digit) {
1839 memset(&dsp->
f, 0,
sizeof(dsp->
f));
1855 memset(&dsp->
f, 0,
sizeof(dsp->
f));
1858 dsp->
f.
src =
"dsp_progress";
1878 for (x = 0; x <
len; x++) {
1879 odata[x] =
AST_LIN2MU((
unsigned short) shortdata[x]);
1882 for (x = 0; x <
len; x++) {
1883 odata[x] =
AST_LIN2A((
unsigned short) shortdata[x]);
2003 for (i = 0; i < 6; i++) {
2012 for (i = 0; i < 4; i++) {
2034 for (x = 0; x < 4; x++) {
2042#define DSP_DIGITMODES (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_R2_FORWARD | DSP_DIGITMODE_R2_BACKWARD)
2133 if (!strcasecmp(v->
name,
"silencethreshold")) {
2134 if (sscanf(v->
value,
"%30d", &cfg_threshold) < 1) {
2136 }
else if (cfg_threshold < 0) {
2137 ast_log(
LOG_WARNING,
"Invalid silence threshold '%d' specified, using default\n", cfg_threshold);
2141 }
else if (!strcasecmp(v->
name,
"dtmf_normal_twist")) {
2142 if (sscanf(v->
value,
"%30f", &cfg_twist) < 1) {
2144 }
else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {
2149 }
else if (!strcasecmp(v->
name,
"dtmf_reverse_twist")) {
2150 if (sscanf(v->
value,
"%30f", &cfg_twist) < 1) {
2152 }
else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {
2157 }
else if (!strcasecmp(v->
name,
"relax_dtmf_normal_twist")) {
2158 if (sscanf(v->
value,
"%30f", &cfg_twist) < 1) {
2160 }
else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {
2165 }
else if (!strcasecmp(v->
name,
"relax_dtmf_reverse_twist")) {
2166 if (sscanf(v->
value,
"%30f", &cfg_twist) < 1) {
2168 }
else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {
2173 }
else if (!strcasecmp(v->
name,
"dtmf_hits_to_begin")) {
2174 if (sscanf(v->
value,
"%30d", &cfg_threshold) < 1) {
2176 }
else if (cfg_threshold < 1) {
2181 }
else if (!strcasecmp(v->
name,
"dtmf_misses_to_end")) {
2182 if (sscanf(v->
value,
"%30d", &cfg_threshold) < 1) {
2184 }
else if (cfg_threshold < 1) {
2201#ifdef TEST_FRAMEWORK
2202static void test_tone_sample_gen(
short *slin_buf,
int samples,
int rate,
int freq,
short amplitude)
2205 double sample_step = 2.0 *
M_PI * freq / rate;
2207 for (idx = 0; idx < samples; ++idx) {
2208 slin_buf[idx] = amplitude * sin(sample_step * idx);
2213#ifdef TEST_FRAMEWORK
2214static void test_tone_sample_gen_add(
short *slin_buf,
int samples,
int rate,
int freq,
short amplitude)
2217 double sample_step = 2.0 *
M_PI * freq / rate;
2219 for (idx = 0; idx < samples; ++idx) {
2220 slin_buf[idx] += amplitude * sin(sample_step * idx);
2225#ifdef TEST_FRAMEWORK
2226static void test_dual_sample_gen(
short *slin_buf,
int samples,
int rate,
int f1,
short a1,
int f2,
short a2)
2228 test_tone_sample_gen(slin_buf, samples, rate, f1, a1);
2229 test_tone_sample_gen_add(slin_buf, samples, rate, f2, a2);
2233#ifdef TEST_FRAMEWORK
2234#define TONE_AMPLITUDE_MAX 0x7fff
2235#define TONE_AMPLITUDE_MIN 80
2246 { .amp_val = TONE_AMPLITUDE_MAX, .detect = 1, },
2247 { .amp_val = 10000, .detect = 1, },
2248 { .amp_val = 1000, .detect = 1, },
2249 { .amp_val = 100, .detect = 1, },
2250 { .amp_val = TONE_AMPLITUDE_MIN, .detect = 1, },
2251 { .amp_val = 75, .detect = 0, },
2252 { .amp_val = 10, .detect = 0, },
2253 { .amp_val = 1, .detect = 0, },
2258 for (idx = 0; idx <
ARRAY_LEN(amp_tests); ++idx) {
2262 ast_debug(1,
"Test %d Hz at amplitude %d\n",
2263 tone_state->
freq, amp_tests[idx].amp_val);
2265 tone_state->
freq, amp_tests[idx].amp_val);
2268 for (duration = 0; !detected && duration < tone_state->
hits_required + 3; ++duration) {
2271 if (amp_tests[idx].detect != detected) {
2279 "Test %d Hz at amplitude %d failed. Detected: %s\n",
2280 tone_state->
freq, amp_tests[idx].amp_val,
2281 detected ?
"yes" :
"no");
2283 "Test %d Hz at amplitude %d failed. Detected: %s\n",
2284 tone_state->
freq, amp_tests[idx].amp_val,
2285 detected ?
"yes" :
"no");
2295#ifdef TEST_FRAMEWORK
2296static int test_dtmf_amplitude_sweep(
struct ast_test *
test,
struct ast_dsp *dsp,
int digit_index)
2311 { .amp_val = TONE_AMPLITUDE_MAX/2, .digit =
dtmf_positions[digit_index], },
2319 { .amp_val = 170, .digit = 0, },
2320 { .amp_val = 100, .digit = 0, },
2325 { .amp_val = TONE_AMPLITUDE_MIN, .digit = 0, },
2326 { .amp_val = 75, .digit = 0, },
2327 { .amp_val = 10, .digit = 0, },
2328 { .amp_val = 1, .digit = 0, },
2331 row = (digit_index >> 2) & 0x03;
2332 column = digit_index & 0x03;
2336 for (idx = 0; idx <
ARRAY_LEN(amp_tests); ++idx) {
2340 ast_debug(1,
"Test '%c' at amplitude %d\n",
2343 (
int)
dtmf_row[row], amp_tests[idx].amp_val,
2344 (
int)
dtmf_col[column], amp_tests[idx].amp_val);
2347 for (duration = 0; !
digit && duration < 3; ++duration) {
2359 "Test '%c' at amplitude %d failed. Detected Digit: '%c'\n",
2363 "Test '%c' at amplitude %d failed. Detected Digit: '%c'\n",
2375#ifdef TEST_FRAMEWORK
2376static int test_dtmf_twist_sweep(
struct ast_test *
test,
struct ast_dsp *dsp,
int digit_index)
2395 { .amp_row = 1000 + 1800, .amp_col = 1000 + 0, .digit = 0, },
2396 { .amp_row = 1000 + 1700, .amp_col = 1000 + 0, .digit = 0, },
2398 { .amp_row = 1000 + 1400, .amp_col = 1000 + 0, .digit =
dtmf_positions[digit_index], },
2399 { .amp_row = 1000 + 1300, .amp_col = 1000 + 0, .digit =
dtmf_positions[digit_index], },
2400 { .amp_row = 1000 + 1200, .amp_col = 1000 + 0, .digit =
dtmf_positions[digit_index], },
2401 { .amp_row = 1000 + 1100, .amp_col = 1000 + 0, .digit =
dtmf_positions[digit_index], },
2402 { .amp_row = 1000 + 1000, .amp_col = 1000 + 0, .digit =
dtmf_positions[digit_index], },
2403 { .amp_row = 1000 + 100, .amp_col = 1000 + 0, .digit =
dtmf_positions[digit_index], },
2404 { .amp_row = 1000 + 0, .amp_col = 1000 + 100, .digit =
dtmf_positions[digit_index], },
2405 { .amp_row = 1000 + 0, .amp_col = 1000 + 200, .digit =
dtmf_positions[digit_index], },
2406 { .amp_row = 1000 + 0, .amp_col = 1000 + 300, .digit =
dtmf_positions[digit_index], },
2407 { .amp_row = 1000 + 0, .amp_col = 1000 + 400, .digit =
dtmf_positions[digit_index], },
2408 { .amp_row = 1000 + 0, .amp_col = 1000 + 500, .digit =
dtmf_positions[digit_index], },
2409 { .amp_row = 1000 + 0, .amp_col = 1000 + 550, .digit =
dtmf_positions[digit_index], },
2411 { .amp_row = 1000 + 0, .amp_col = 1000 + 650, .digit = 0, },
2412 { .amp_row = 1000 + 0, .amp_col = 1000 + 700, .digit = 0, },
2413 { .amp_row = 1000 + 0, .amp_col = 1000 + 800, .digit = 0, },
2415 float save_normal_twist;
2416 float save_reverse_twist;
2423 row = (digit_index >> 2) & 0x03;
2424 column = digit_index & 0x03;
2428 for (idx = 0; idx <
ARRAY_LEN(twist_tests); ++idx) {
2432 ast_debug(1,
"Test '%c' twist row %d col %d amplitudes\n",
2434 twist_tests[idx].amp_row, twist_tests[idx].amp_col);
2436 (
int)
dtmf_row[row], twist_tests[idx].amp_row,
2437 (
int)
dtmf_col[column], twist_tests[idx].amp_col);
2440 for (duration = 0; !
digit && duration < 3; ++duration) {
2452 "Test '%c' twist row %d col %d amplitudes failed. Detected Digit: '%c'\n",
2454 twist_tests[idx].amp_row, twist_tests[idx].amp_col,
2457 "Test '%c' twist row %d col %d amplitudes failed. Detected Digit: '%c'\n",
2459 twist_tests[idx].amp_row, twist_tests[idx].amp_col,
2473#ifdef TEST_FRAMEWORK
2483 lower_freq = tone_state->
freq - 4;
2484 upper_freq = tone_state->
freq + 4;
2489 for (freq = 100; freq <= 3500; freq += 1) {
2492 int expect_detection;
2494 if (freq == tone_state->
freq) {
2499 expect_detection = (lower_freq <= freq && freq <= upper_freq) ? 1 : 0;
2501 ast_debug(1,
"Test %d Hz detection given %d Hz tone at amplitude %d. Range:%d-%d Expect detect: %s\n",
2502 tone_state->
freq, freq, amplitude, lower_freq, upper_freq,
2503 expect_detection ?
"yes" :
"no");
2508 for (duration = 0; !detected && duration < tone_state->
hits_required + 3; ++duration) {
2511 if (expect_detection != detected) {
2519 "Test %d Hz detection given %d Hz tone at amplitude %d failed. Range:%d-%d Detected: %s\n",
2520 tone_state->
freq, freq, amplitude, lower_freq, upper_freq,
2521 detected ?
"yes" :
"no");
2523 "Test %d Hz detection given %d Hz tone at amplitude %d failed. Range:%d-%d Detected: %s\n",
2524 tone_state->
freq, freq, amplitude, lower_freq, upper_freq,
2525 detected ?
"yes" :
"no");
2535#ifdef TEST_FRAMEWORK
2544 info->category =
"/main/dsp/";
2545 info->summary =
"DSP fax tone detect unit test";
2547 "Tests fax tone detection code.";
2591#ifdef TEST_FRAMEWORK
2600 info->name =
"dtmf";
2601 info->category =
"/main/dsp/";
2602 info->summary =
"DSP DTMF detect unit test";
2604 "Tests DTMF detection code.";
2618 if (test_dtmf_amplitude_sweep(
test, dsp, idx)) {
2624 if (test_dtmf_twist_sweep(
test, dsp, idx)) {
2665 .
requires =
"extconfig",
A-Law to Signed linear conversion.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_calloc(num, len)
A wrapper for calloc()
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
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.
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
static void ast_mf_detect_init(mf_detect_state_t *s, unsigned int sample_rate)
static int thresholds[THRESHOLD_MAX]
#define DEF_DTMF_HITS_TO_BEGIN
void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
Set the minimum average magnitude threshold to determine talking by the DSP.
#define BELL_MF_THRESHOLD
void ast_dsp_free(struct ast_dsp *dsp)
int ast_dsp_get_tcount(struct ast_dsp *dsp)
Get tcount (Threshold counter)
#define DEFAULT_THRESHOLD
Default minimum average magnitude threshold to determine talking/noise by the DSP.
#define DEF_DTMF_REVERSE_TWIST
static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp, unsigned int sample_rate)
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,...
#define DTMF_TO_TOTAL_ENERGY
#define BELL_MF_RELATIVE_PEAK
#define DEF_DTMF_MISSES_TO_END
static const int DEFAULT_SILENCE_THRESHOLD
The default silence threshold we will use if an alternate configured value is not present or is inval...
static const char dtmf_positions[]
static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
static void goertzel_init(goertzel_state_t *s, float freq, unsigned int sample_rate)
static struct progalias aliases[]
static int _dsp_init(int reload)
static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
static const float r2_forward_tones[]
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
#define FAX_TONE_CNG_FREQ
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
#define DEF_RELAX_DTMF_NORMAL_TWIST
static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
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.
#define FAX_TONE_CED_DURATION
static const char bell_mf_positions[]
static void ast_fax_detect_init(struct ast_dsp *s)
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.
#define DEF_DTMF_NORMAL_TWIST
static float goertzel_result(goertzel_state_t *s)
int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
Scans for progress indication in audio.
void ast_dsp_reset(struct ast_dsp *dsp)
Reset total silence count.
static void ast_freq_detect_init(struct ast_dsp *s, int freq, int dur, int db, int squelch)
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence)
Set expected lengths of the busy tone.
unsigned int ast_dsp_get_sample_rate(const struct ast_dsp *dsp)
Retrieve the sample rate this DSP structure was created with.
#define FAX_TONE_CED_FREQ
static int reload_module(void)
#define DTMF_RELATIVE_PEAK_COL
static struct progress modes[]
static void ast_digit_detect_init(digit_detect_state_t *s, int digitmode, unsigned int sample_rate)
static const float dtmf_row[]
static void goertzel_sample(goertzel_state_t *s, short sample)
#define DEF_RELAX_DTMF_REVERSE_TWIST
static int pair_there(float p1, float p2, float i1, float i2, float e)
static int r2_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax, const char *r2_positions)
static const float mf_tones[]
static float dtmf_reverse_twist
int ast_dsp_get_features(struct ast_dsp *dsp)
Get features.
#define R2_MF_RELATIVE_PEAK
static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
static void goertzel_reset(goertzel_state_t *s)
static int ast_dsp_silence_noise_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *total, int *frames_energy, int noise)
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
static void ast_dtmf_detect_init(dtmf_detect_state_t *s, unsigned int sample_rate)
static void ast_r2_detect_init(mf_detect_state_t *s, unsigned int sample_rate, int backward)
static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
#define DTMF_RELATIVE_PEAK_ROW
static int dtmf_misses_to_end
static int dtmf_hits_to_begin
#define DEFAULT_SAMPLE_RATE
static int load_module(void)
int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
Process the audio frame for noise.
static const float r2_backward_tones[]
int ast_dsp_get_tstate(struct ast_dsp *dsp)
Get tstate (Tone State)
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...
static int unload_module(void)
static float relax_dtmf_normal_twist
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 ...
static void store_digit(digit_detect_state_t *s, char digit)
int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
Set fax mode.
static const float dtmf_col[]
#define FAX_TONE_CNG_DURATION
int ast_dsp_set_freqmode(struct ast_dsp *dsp, int freq, int dur, int db, int squelch)
Set arbitrary frequency detection mode.
static struct ast_dsp * __ast_dsp_new(unsigned int sample_rate)
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
Set number of required cadences for busy.
static const char r2_mf_positions[]
static float dtmf_normal_twist
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
static float relax_dtmf_reverse_twist
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise, int *frames_energy)
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
Set zone for doing progress detection.
static void ast_dsp_prog_reset(struct ast_dsp *dsp)
Convenient Signal Processing routines.
#define DSP_PROGRESS_RINGING
#define DSP_TONE_STATE_SPECIAL3
#define DSP_FEATURE_WAITDIALTONE
#define DSP_TONE_STATE_SPECIAL2
#define DSP_FEATURE_BUSY_DETECT
#define DSP_TONE_STATE_DIALTONE
#define DSP_PROGRESS_TALK
#define DSP_TONE_STATE_SILENCE
#define DSP_DIGITMODE_NOQUELCH
#define DSP_TONE_STATE_BUSY
#define DSP_DIGITMODE_MUTEMAX
#define DSP_FEATURE_DIGIT_DETECT
#define DSP_PROGRESS_BUSY
#define DSP_FEATURE_FAX_DETECT
#define DSP_TONE_STATE_SPECIAL1
#define DSP_FAXMODE_DETECT_SQUELCH
#define DSP_FAXMODE_DETECT_CED
#define DSP_PROGRESS_CONGESTION
#define DSP_FEATURE_CALL_PROGRESS
#define DSP_DIGITMODE_MUTECONF
#define DSP_FAXMODE_DETECT_CNG
#define DSP_FEATURE_SILENCE_SUPPRESS
#define DSP_TONE_STATE_HUNGUP
#define DSP_FEATURE_FREQ_DETECT
#define DSP_TONE_STATE_TALKING
#define DSP_DIGITMODE_R2_BACKWARD
#define DSP_TONE_STATE_RINGING
#define DSP_DIGITMODE_DTMF
#define DSP_DIGITMODE_RELAXDTMF
#define DSP_DIGITMODE_R2_FORWARD
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
@ CONFIG_FLAG_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Asterisk internal frame definitions.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
@ AST_MODULE_LOAD_SUCCESS
Options provided by main asterisk program.
Main Channel structure associated with a channel.
int historicnoise[DSP_HISTORY]
goertzel_state_t freqs[FREQ_ARRAY_SIZE]
digit_detect_state_t digit_state
tone_detect_state_t ced_tone_state
int historicsilence[DSP_HISTORY]
enum gsamp_size gsamp_size
int display_inband_dtmf_warning
struct ast_dsp_busy_pattern busy_cadence
tone_detect_state_t cng_tone_state
Structure used to handle boolean flags.
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::@235 data
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
int digitlen[MAX_DTMF_DIGITS+1]
char digits[MAX_DTMF_DIGITS+1]
union digit_detect_state_t::@368 td
goertzel_state_t row_out[DTMF_MATRIX_SIZE]
goertzel_state_t col_out[DTMF_MATRIX_SIZE]
goertzel_state_t tone_out[6]
int freqs[FREQ_ARRAY_SIZE]
#define AST_TEST_REGISTER(cb)
#define ast_test_status_update(a, b, c...)
#define AST_TEST_UNREGISTER(cb)
#define AST_TEST_DEFINE(hdr)
u-Law to Signed linear conversion