00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "asterisk.h"
00044
00045 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 268690 $")
00046
00047 #include <math.h>
00048
00049 #include "asterisk/frame.h"
00050 #include "asterisk/channel.h"
00051 #include "asterisk/dsp.h"
00052 #include "asterisk/ulaw.h"
00053 #include "asterisk/alaw.h"
00054 #include "asterisk/utils.h"
00055 #include "asterisk/options.h"
00056 #include "asterisk/config.h"
00057
00058
00059 enum gsamp_size {
00060 GSAMP_SIZE_NA = 183,
00061 GSAMP_SIZE_CR = 188,
00062 GSAMP_SIZE_UK = 160
00063 };
00064
00065 enum prog_mode {
00066 PROG_MODE_NA = 0,
00067 PROG_MODE_CR,
00068 PROG_MODE_UK
00069 };
00070
00071 enum freq_index {
00072
00073 HZ_350 = 0,
00074 HZ_440,
00075 HZ_480,
00076 HZ_620,
00077 HZ_950,
00078 HZ_1400,
00079 HZ_1800,
00080
00081
00082 HZ_425 = 0,
00083
00084
00085 HZ_350UK = 0,
00086 HZ_400UK,
00087 HZ_440UK
00088 };
00089
00090 static struct progalias {
00091 char *name;
00092 enum prog_mode mode;
00093 } aliases[] = {
00094 { "us", PROG_MODE_NA },
00095 { "ca", PROG_MODE_NA },
00096 { "cr", PROG_MODE_CR },
00097 { "br", PROG_MODE_CR },
00098 { "uk", PROG_MODE_UK },
00099 };
00100
00101 static struct progress {
00102 enum gsamp_size size;
00103 int freqs[7];
00104 } modes[] = {
00105 { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } },
00106 { GSAMP_SIZE_CR, { 425 } },
00107 { GSAMP_SIZE_UK, { 350, 400, 440 } },
00108 };
00109
00110
00111
00112
00113
00114
00115
00116
00117 #define DEFAULT_THRESHOLD 512
00118
00119 enum busy_detect {
00120 BUSY_PERCENT = 10,
00121 BUSY_PAT_PERCENT = 7,
00122 BUSY_THRESHOLD = 100,
00123 BUSY_MIN = 75,
00124 BUSY_MAX =3100
00125 };
00126
00127
00128 #define DSP_HISTORY 15
00129
00130 #define TONE_THRESH 10.0
00131 #define TONE_MIN_THRESH 1e8
00132
00133
00134 enum gsamp_thresh {
00135 THRESH_RING = 8,
00136 THRESH_TALK = 2,
00137 THRESH_BUSY = 4,
00138 THRESH_CONGESTION = 4,
00139 THRESH_HANGUP = 60,
00140 THRESH_RING2ANSWER = 300
00141 };
00142
00143 #define MAX_DTMF_DIGITS 128
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 #define DTMF_THRESHOLD 8.0e7
00158 #define FAX_THRESHOLD 8.0e7
00159 #define FAX_2ND_HARMONIC 2.0
00160 #define DTMF_NORMAL_TWIST 6.3
00161 #ifdef RADIO_RELAX
00162 #define DTMF_REVERSE_TWIST (relax ? 6.5 : 2.5)
00163 #else
00164 #define DTMF_REVERSE_TWIST (relax ? 4.0 : 2.5)
00165 #endif
00166 #define DTMF_RELATIVE_PEAK_ROW 6.3
00167 #define DTMF_RELATIVE_PEAK_COL 6.3
00168 #define DTMF_2ND_HARMONIC_ROW (relax ? 1.7 : 2.5)
00169 #define DTMF_2ND_HARMONIC_COL 63.1
00170 #define DTMF_TO_TOTAL_ENERGY 42.0
00171
00172 #define BELL_MF_THRESHOLD 1.6e9
00173 #define BELL_MF_TWIST 4.0
00174 #define BELL_MF_RELATIVE_PEAK 12.6
00175
00176 #if defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
00177 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
00178 #endif
00179
00180
00181
00182
00183 #define FAX_TONE_CNG_FREQ 1100
00184 #define FAX_TONE_CNG_DURATION 500
00185 #define FAX_TONE_CNG_DB 16
00186
00187
00188
00189
00190
00191 #define FAX_TONE_CED_FREQ 2100
00192 #define FAX_TONE_CED_DURATION 2600
00193 #define FAX_TONE_CED_DB 16
00194
00195 #define SAMPLE_RATE 8000
00196
00197
00198
00199
00200
00201
00202
00203 #define SAMPLES_IN_FRAME 160
00204
00205
00206 #define MF_GSIZE 120
00207
00208
00209 #define DTMF_GSIZE 102
00210
00211
00212 #define DTMF_HITS_TO_BEGIN 2
00213
00214 #define DTMF_MISSES_TO_END 3
00215
00216
00217
00218
00219
00220 static const int DEFAULT_SILENCE_THRESHOLD = 256;
00221
00222 #define CONFIG_FILE_NAME "dsp.conf"
00223
00224 typedef struct {
00225 int v2;
00226 int v3;
00227 int chunky;
00228 int fac;
00229 int samples;
00230 } goertzel_state_t;
00231
00232 typedef struct {
00233 int value;
00234 int power;
00235 } goertzel_result_t;
00236
00237 typedef struct
00238 {
00239 int freq;
00240 int block_size;
00241 int squelch;
00242 goertzel_state_t tone;
00243 float energy;
00244 int samples_pending;
00245 int mute_samples;
00246
00247 int hits_required;
00248 float threshold;
00249
00250 int hit_count;
00251 int last_hit;
00252
00253 } tone_detect_state_t;
00254
00255 typedef struct
00256 {
00257 goertzel_state_t row_out[4];
00258 goertzel_state_t col_out[4];
00259 int hits_to_begin;
00260 int misses_to_end;
00261 int hits;
00262 int misses;
00263 int lasthit;
00264 int current_hit;
00265 float energy;
00266 int current_sample;
00267 int mute_samples;
00268 } dtmf_detect_state_t;
00269
00270 typedef struct
00271 {
00272 goertzel_state_t tone_out[6];
00273 int current_hit;
00274 int hits[5];
00275 int current_sample;
00276 int mute_samples;
00277 } mf_detect_state_t;
00278
00279 typedef struct
00280 {
00281 char digits[MAX_DTMF_DIGITS + 1];
00282 int digitlen[MAX_DTMF_DIGITS + 1];
00283 int current_digits;
00284 int detected_digits;
00285 int lost_digits;
00286
00287 union {
00288 dtmf_detect_state_t dtmf;
00289 mf_detect_state_t mf;
00290 } td;
00291 } digit_detect_state_t;
00292
00293 static const float dtmf_row[] = {
00294 697.0, 770.0, 852.0, 941.0
00295 };
00296 static const float dtmf_col[] = {
00297 1209.0, 1336.0, 1477.0, 1633.0
00298 };
00299 static const float mf_tones[] = {
00300 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
00301 };
00302 static const char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
00303 static const char bell_mf_positions[] = "1247C-358A--69*---0B----#";
00304 static int thresholds[THRESHOLD_MAX];
00305
00306 static inline void goertzel_sample(goertzel_state_t *s, short sample)
00307 {
00308 int v1;
00309
00310 v1 = s->v2;
00311 s->v2 = s->v3;
00312
00313 s->v3 = (s->fac * s->v2) >> 15;
00314 s->v3 = s->v3 - v1 + (sample >> s->chunky);
00315 if (abs(s->v3) > 32768) {
00316 s->chunky++;
00317 s->v3 = s->v3 >> 1;
00318 s->v2 = s->v2 >> 1;
00319 v1 = v1 >> 1;
00320 }
00321 }
00322
00323 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
00324 {
00325 int i;
00326
00327 for (i = 0; i < count; i++) {
00328 goertzel_sample(s, samps[i]);
00329 }
00330 }
00331
00332
00333 static inline float goertzel_result(goertzel_state_t *s)
00334 {
00335 goertzel_result_t r;
00336 r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
00337 r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
00338 r.power = s->chunky * 2;
00339 return (float)r.value * (float)(1 << r.power);
00340 }
00341
00342 static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
00343 {
00344 s->v2 = s->v3 = s->chunky = 0.0;
00345 s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
00346 s->samples = samples;
00347 }
00348
00349 static inline void goertzel_reset(goertzel_state_t *s)
00350 {
00351 s->v2 = s->v3 = s->chunky = 0.0;
00352 }
00353
00354 typedef struct {
00355 int start;
00356 int end;
00357 } fragment_t;
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 struct ast_dsp {
00373 struct ast_frame f;
00374 int threshold;
00375 int totalsilence;
00376 int totalnoise;
00377 int features;
00378 int ringtimeout;
00379 int busymaybe;
00380 int busycount;
00381 int busy_tonelength;
00382 int busy_quietlength;
00383 int historicnoise[DSP_HISTORY];
00384 int historicsilence[DSP_HISTORY];
00385 goertzel_state_t freqs[7];
00386 int freqcount;
00387 int gsamps;
00388 enum gsamp_size gsamp_size;
00389 enum prog_mode progmode;
00390 int tstate;
00391 int tcount;
00392 int digitmode;
00393 int faxmode;
00394 int dtmf_began;
00395 int display_inband_dtmf_warning;
00396 float genergy;
00397 int mute_fragments;
00398 fragment_t mute_data[5];
00399 digit_detect_state_t digit_state;
00400 tone_detect_state_t cng_tone_state;
00401 tone_detect_state_t ced_tone_state;
00402 };
00403
00404 static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
00405 {
00406 if (dsp->mute_fragments >= ARRAY_LEN(dsp->mute_data)) {
00407 ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
00408 return;
00409 }
00410
00411 dsp->mute_data[dsp->mute_fragments++] = *fragment;
00412 }
00413
00414 static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
00415 {
00416 int duration_samples;
00417 float x;
00418 int periods_in_block;
00419
00420 s->freq = freq;
00421
00422
00423 duration_samples = duration * SAMPLE_RATE / 1000;
00424
00425 duration_samples = duration_samples * 9 / 10;
00426
00427
00428
00429
00430 s->block_size = SAMPLES_IN_FRAME;
00431
00432 periods_in_block = s->block_size * freq / SAMPLE_RATE;
00433
00434
00435
00436
00437 if (periods_in_block < 5)
00438 periods_in_block = 5;
00439
00440
00441 s->block_size = periods_in_block * SAMPLE_RATE / freq;
00442
00443
00444
00445 s->squelch = 0;
00446
00447
00448
00449 s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
00450
00451 goertzel_init(&s->tone, freq, s->block_size);
00452
00453 s->samples_pending = s->block_size;
00454 s->hit_count = 0;
00455 s->last_hit = 0;
00456 s->energy = 0.0;
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 x = pow(10.0, amp / 10.0);
00469 s->threshold = x / (x + 1);
00470
00471 ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
00472 }
00473
00474 static void ast_fax_detect_init(struct ast_dsp *s)
00475 {
00476 ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
00477 ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
00478 }
00479
00480 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00481 {
00482 int i;
00483
00484 s->lasthit = 0;
00485 s->current_hit = 0;
00486 for (i = 0; i < 4; i++) {
00487 goertzel_init(&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
00488 goertzel_init(&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
00489 s->energy = 0.0;
00490 }
00491 s->current_sample = 0;
00492 s->hits = 0;
00493 s->misses = 0;
00494
00495 s->hits_to_begin = DTMF_HITS_TO_BEGIN;
00496 s->misses_to_end = DTMF_MISSES_TO_END;
00497 }
00498
00499 static void ast_mf_detect_init (mf_detect_state_t *s)
00500 {
00501 int i;
00502 s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
00503 for (i = 0; i < 6; i++) {
00504 goertzel_init (&s->tone_out[i], mf_tones[i], 160);
00505 }
00506 s->current_sample = 0;
00507 s->current_hit = 0;
00508 }
00509
00510 static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
00511 {
00512 s->current_digits = 0;
00513 s->detected_digits = 0;
00514 s->lost_digits = 0;
00515 s->digits[0] = '\0';
00516
00517 if (mf) {
00518 ast_mf_detect_init(&s->td.mf);
00519 } else {
00520 ast_dtmf_detect_init(&s->td.dtmf);
00521 }
00522 }
00523
00524 static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
00525 {
00526 float tone_energy;
00527 int i;
00528 int hit = 0;
00529 int limit;
00530 int res = 0;
00531 int16_t *ptr;
00532 int start, end;
00533 fragment_t mute = {0, 0};
00534
00535 if (s->squelch && s->mute_samples > 0) {
00536 mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
00537 s->mute_samples -= mute.end;
00538 }
00539
00540 for (start = 0; start < samples; start = end) {
00541
00542 limit = samples - start;
00543 if (limit > s->samples_pending) {
00544 limit = s->samples_pending;
00545 }
00546 end = start + limit;
00547
00548 for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
00549
00550 s->energy += (int32_t) *ptr * (int32_t) *ptr;
00551
00552 goertzel_sample(&s->tone, *ptr);
00553 }
00554
00555 s->samples_pending -= limit;
00556
00557 if (s->samples_pending) {
00558
00559 break;
00560 }
00561
00562 tone_energy = goertzel_result(&s->tone);
00563
00564
00565 tone_energy *= 2.0;
00566 s->energy *= s->block_size;
00567
00568 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));
00569 hit = 0;
00570 if (tone_energy > s->energy * s->threshold) {
00571 ast_debug(10, "Hit! count=%d\n", s->hit_count);
00572 hit = 1;
00573 }
00574
00575 if (s->hit_count) {
00576 s->hit_count++;
00577 }
00578
00579 if (hit == s->last_hit) {
00580 if (!hit) {
00581
00582 s->hit_count = 0;
00583 } else if (!s->hit_count) {
00584 s->hit_count++;
00585 }
00586
00587 }
00588
00589 if (s->hit_count == s->hits_required) {
00590 ast_debug(1, "%d Hz done detected\n", s->freq);
00591 res = 1;
00592 }
00593
00594 s->last_hit = hit;
00595
00596
00597 if (s->squelch && hit) {
00598 if (mute.end < start - s->block_size) {
00599
00600 mute_fragment(dsp, &mute);
00601 mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
00602 }
00603 mute.end = end + s->block_size;
00604 }
00605
00606
00607
00608 goertzel_reset(&s->tone);
00609
00610
00611 s->energy = 0.0;
00612 s->samples_pending = s->block_size;
00613
00614 amp += limit;
00615 }
00616
00617 if (s->squelch && mute.end) {
00618 if (mute.end > samples) {
00619 s->mute_samples = mute.end - samples;
00620 mute.end = samples;
00621 }
00622 mute_fragment(dsp, &mute);
00623 }
00624
00625 return res;
00626 }
00627
00628 static void store_digit(digit_detect_state_t *s, char digit)
00629 {
00630 s->detected_digits++;
00631 if (s->current_digits < MAX_DTMF_DIGITS) {
00632 s->digitlen[s->current_digits] = 0;
00633 s->digits[s->current_digits++] = digit;
00634 s->digits[s->current_digits] = '\0';
00635 } else {
00636 ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
00637 s->lost_digits++;
00638 }
00639 }
00640
00641 static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
00642 {
00643 float row_energy[4];
00644 float col_energy[4];
00645 float famp;
00646 int i;
00647 int j;
00648 int sample;
00649 int best_row;
00650 int best_col;
00651 int hit;
00652 int limit;
00653 fragment_t mute = {0, 0};
00654
00655 if (squelch && s->td.dtmf.mute_samples > 0) {
00656 mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
00657 s->td.dtmf.mute_samples -= mute.end;
00658 }
00659
00660 hit = 0;
00661 for (sample = 0; sample < samples; sample = limit) {
00662
00663 if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
00664 limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
00665 } else {
00666 limit = samples;
00667 }
00668
00669
00670 for (j = sample; j < limit; j++) {
00671 famp = amp[j];
00672 s->td.dtmf.energy += famp*famp;
00673
00674
00675 goertzel_sample(s->td.dtmf.row_out, amp[j]);
00676 goertzel_sample(s->td.dtmf.col_out, amp[j]);
00677 goertzel_sample(s->td.dtmf.row_out + 1, amp[j]);
00678 goertzel_sample(s->td.dtmf.col_out + 1, amp[j]);
00679 goertzel_sample(s->td.dtmf.row_out + 2, amp[j]);
00680 goertzel_sample(s->td.dtmf.col_out + 2, amp[j]);
00681 goertzel_sample(s->td.dtmf.row_out + 3, amp[j]);
00682 goertzel_sample(s->td.dtmf.col_out + 3, amp[j]);
00683 }
00684 s->td.dtmf.current_sample += (limit - sample);
00685 if (s->td.dtmf.current_sample < DTMF_GSIZE) {
00686 continue;
00687 }
00688
00689
00690 row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
00691 col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
00692
00693 for (best_row = best_col = 0, i = 1; i < 4; i++) {
00694 row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
00695 if (row_energy[i] > row_energy[best_row]) {
00696 best_row = i;
00697 }
00698 col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
00699 if (col_energy[i] > col_energy[best_col]) {
00700 best_col = i;
00701 }
00702 }
00703 hit = 0;
00704
00705 if (row_energy[best_row] >= DTMF_THRESHOLD &&
00706 col_energy[best_col] >= DTMF_THRESHOLD &&
00707 col_energy[best_col] < row_energy[best_row] * DTMF_REVERSE_TWIST &&
00708 col_energy[best_col] * DTMF_NORMAL_TWIST > row_energy[best_row]) {
00709
00710 for (i = 0; i < 4; i++) {
00711 if ((i != best_col &&
00712 col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
00713 (i != best_row
00714 && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
00715 break;
00716 }
00717 }
00718
00719 if (i >= 4 &&
00720 (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
00721
00722 hit = dtmf_positions[(best_row << 2) + best_col];
00723 }
00724 }
00725
00726 if (s->td.dtmf.current_hit) {
00727
00728 if (hit != s->td.dtmf.current_hit) {
00729 s->td.dtmf.misses++;
00730 if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) {
00731
00732 s->td.dtmf.current_hit = 0;
00733 }
00734 } else {
00735 s->td.dtmf.misses = 0;
00736
00737 s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
00738 }
00739 }
00740
00741
00742
00743
00744 if (hit) {
00745 if (hit == s->td.dtmf.lasthit) {
00746 s->td.dtmf.hits++;
00747 } else {
00748 s->td.dtmf.hits = 1;
00749 }
00750
00751 if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin && hit != s->td.dtmf.current_hit) {
00752 store_digit(s, hit);
00753 s->td.dtmf.current_hit = hit;
00754 s->td.dtmf.misses = 0;
00755 }
00756 } else {
00757 s->td.dtmf.hits = 0;
00758 }
00759
00760 s->td.dtmf.lasthit = hit;
00761
00762
00763 if (squelch && hit) {
00764 if (mute.end < sample - DTMF_GSIZE) {
00765
00766 mute_fragment(dsp, &mute);
00767 mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
00768 }
00769 mute.end = limit + DTMF_GSIZE;
00770 }
00771
00772
00773 for (i = 0; i < 4; i++) {
00774 goertzel_reset(&s->td.dtmf.row_out[i]);
00775 goertzel_reset(&s->td.dtmf.col_out[i]);
00776 }
00777 s->td.dtmf.energy = 0.0;
00778 s->td.dtmf.current_sample = 0;
00779 }
00780
00781 if (squelch && mute.end) {
00782 if (mute.end > samples) {
00783 s->td.dtmf.mute_samples = mute.end - samples;
00784 mute.end = samples;
00785 }
00786 mute_fragment(dsp, &mute);
00787 }
00788
00789 return (s->td.dtmf.current_hit);
00790 }
00791
00792 static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
00793 int samples, int squelch, int relax)
00794 {
00795 float energy[6];
00796 int best;
00797 int second_best;
00798 float famp;
00799 int i;
00800 int j;
00801 int sample;
00802 int hit;
00803 int limit;
00804 fragment_t mute = {0, 0};
00805
00806 if (squelch && s->td.mf.mute_samples > 0) {
00807 mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
00808 s->td.mf.mute_samples -= mute.end;
00809 }
00810
00811 hit = 0;
00812 for (sample = 0; sample < samples; sample = limit) {
00813
00814
00815 if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
00816 limit = sample + (MF_GSIZE - s->td.mf.current_sample);
00817 } else {
00818 limit = samples;
00819 }
00820
00821
00822 for (j = sample; j < limit; j++) {
00823 famp = amp[j];
00824
00825
00826 goertzel_sample(s->td.mf.tone_out, amp[j]);
00827 goertzel_sample(s->td.mf.tone_out + 1, amp[j]);
00828 goertzel_sample(s->td.mf.tone_out + 2, amp[j]);
00829 goertzel_sample(s->td.mf.tone_out + 3, amp[j]);
00830 goertzel_sample(s->td.mf.tone_out + 4, amp[j]);
00831 goertzel_sample(s->td.mf.tone_out + 5, amp[j]);
00832 }
00833 s->td.mf.current_sample += (limit - sample);
00834 if (s->td.mf.current_sample < MF_GSIZE) {
00835 continue;
00836 }
00837
00838
00839
00840
00841
00842
00843
00844 energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
00845 energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
00846 if (energy[0] > energy[1]) {
00847 best = 0;
00848 second_best = 1;
00849 } else {
00850 best = 1;
00851 second_best = 0;
00852 }
00853
00854 for (i = 2; i < 6; i++) {
00855 energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
00856 if (energy[i] >= energy[best]) {
00857 second_best = best;
00858 best = i;
00859 } else if (energy[i] >= energy[second_best]) {
00860 second_best = i;
00861 }
00862 }
00863
00864 hit = 0;
00865 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
00866 && energy[best] < energy[second_best]*BELL_MF_TWIST
00867 && energy[best] * BELL_MF_TWIST > energy[second_best]) {
00868
00869 hit = -1;
00870 for (i = 0; i < 6; i++) {
00871 if (i != best && i != second_best) {
00872 if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
00873
00874 hit = 0;
00875 break;
00876 }
00877 }
00878 }
00879 }
00880 if (hit) {
00881
00882 if (second_best < best) {
00883 i = best;
00884 best = second_best;
00885 second_best = i;
00886 }
00887 best = best * 5 + second_best - 1;
00888 hit = bell_mf_positions[best];
00889
00890
00891
00892
00893
00894
00895 if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
00896 ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
00897 (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
00898 hit != s->td.mf.hits[0]))) {
00899 store_digit(s, hit);
00900 }
00901 }
00902
00903
00904 if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
00905
00906 s->td.mf.current_hit = 0;
00907 }
00908
00909 s->td.mf.hits[0] = s->td.mf.hits[1];
00910 s->td.mf.hits[1] = s->td.mf.hits[2];
00911 s->td.mf.hits[2] = s->td.mf.hits[3];
00912 s->td.mf.hits[3] = s->td.mf.hits[4];
00913 s->td.mf.hits[4] = hit;
00914
00915
00916 if (squelch && hit) {
00917 if (mute.end < sample - MF_GSIZE) {
00918
00919 mute_fragment(dsp, &mute);
00920 mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
00921 }
00922 mute.end = limit + DTMF_GSIZE;
00923 }
00924
00925
00926 for (i = 0; i < 6; i++)
00927 goertzel_reset(&s->td.mf.tone_out[i]);
00928 s->td.mf.current_sample = 0;
00929 }
00930
00931 if (squelch && mute.end) {
00932 if (mute.end > samples) {
00933 s->td.mf.mute_samples = mute.end - samples;
00934 mute.end = samples;
00935 }
00936 mute_fragment(dsp, &mute);
00937 }
00938
00939 return (s->td.mf.current_hit);
00940 }
00941
00942 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
00943 {
00944
00945
00946 if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
00947 return 0;
00948 }
00949
00950 i2 *= TONE_THRESH;
00951 i1 *= TONE_THRESH;
00952 e *= TONE_THRESH;
00953
00954 if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
00955 return 0;
00956 }
00957
00958 if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
00959 return 0;
00960 }
00961
00962 return 1;
00963 }
00964
00965 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
00966 {
00967 int x;
00968 int y;
00969 int pass;
00970 int newstate = DSP_TONE_STATE_SILENCE;
00971 int res = 0;
00972 while (len) {
00973
00974 pass = len;
00975 if (pass > dsp->gsamp_size - dsp->gsamps) {
00976 pass = dsp->gsamp_size - dsp->gsamps;
00977 }
00978 for (x = 0; x < pass; x++) {
00979 for (y = 0; y < dsp->freqcount; y++) {
00980 goertzel_sample(&dsp->freqs[y], s[x]);
00981 }
00982 dsp->genergy += s[x] * s[x];
00983 }
00984 s += pass;
00985 dsp->gsamps += pass;
00986 len -= pass;
00987 if (dsp->gsamps == dsp->gsamp_size) {
00988 float hz[7];
00989 for (y = 0; y < 7; y++) {
00990 hz[y] = goertzel_result(&dsp->freqs[y]);
00991 }
00992 switch (dsp->progmode) {
00993 case PROG_MODE_NA:
00994 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
00995 newstate = DSP_TONE_STATE_BUSY;
00996 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
00997 newstate = DSP_TONE_STATE_RINGING;
00998 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
00999 newstate = DSP_TONE_STATE_DIALTONE;
01000 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01001 newstate = DSP_TONE_STATE_SPECIAL1;
01002 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01003
01004 if (dsp->tstate == DSP_TONE_STATE_SPECIAL1 || dsp->tstate == DSP_TONE_STATE_SPECIAL2) {
01005 newstate = DSP_TONE_STATE_SPECIAL2;
01006 }
01007 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01008
01009 if (dsp->tstate == DSP_TONE_STATE_SPECIAL2 || dsp->tstate == DSP_TONE_STATE_SPECIAL3) {
01010 newstate = DSP_TONE_STATE_SPECIAL3;
01011 }
01012 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01013 newstate = DSP_TONE_STATE_TALKING;
01014 } else {
01015 newstate = DSP_TONE_STATE_SILENCE;
01016 }
01017 break;
01018 case PROG_MODE_CR:
01019 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01020 newstate = DSP_TONE_STATE_RINGING;
01021 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01022 newstate = DSP_TONE_STATE_TALKING;
01023 } else {
01024 newstate = DSP_TONE_STATE_SILENCE;
01025 }
01026 break;
01027 case PROG_MODE_UK:
01028 if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
01029 newstate = DSP_TONE_STATE_HUNGUP;
01030 } else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
01031 newstate = DSP_TONE_STATE_DIALTONE;
01032 }
01033 break;
01034 default:
01035 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01036 }
01037 if (newstate == dsp->tstate) {
01038 dsp->tcount++;
01039 if (dsp->ringtimeout) {
01040 dsp->ringtimeout++;
01041 }
01042 switch (dsp->tstate) {
01043 case DSP_TONE_STATE_RINGING:
01044 if ((dsp->features & DSP_PROGRESS_RINGING) &&
01045 (dsp->tcount == THRESH_RING)) {
01046 res = AST_CONTROL_RINGING;
01047 dsp->ringtimeout = 1;
01048 }
01049 break;
01050 case DSP_TONE_STATE_BUSY:
01051 if ((dsp->features & DSP_PROGRESS_BUSY) &&
01052 (dsp->tcount == THRESH_BUSY)) {
01053 res = AST_CONTROL_BUSY;
01054 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01055 }
01056 break;
01057 case DSP_TONE_STATE_TALKING:
01058 if ((dsp->features & DSP_PROGRESS_TALK) &&
01059 (dsp->tcount == THRESH_TALK)) {
01060 res = AST_CONTROL_ANSWER;
01061 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01062 }
01063 break;
01064 case DSP_TONE_STATE_SPECIAL3:
01065 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
01066 (dsp->tcount == THRESH_CONGESTION)) {
01067 res = AST_CONTROL_CONGESTION;
01068 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01069 }
01070 break;
01071 case DSP_TONE_STATE_HUNGUP:
01072 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
01073 (dsp->tcount == THRESH_HANGUP)) {
01074 res = AST_CONTROL_HANGUP;
01075 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01076 }
01077 break;
01078 }
01079 if (dsp->ringtimeout == THRESH_RING2ANSWER) {
01080 ast_debug(1, "Consider call as answered because of timeout after last ring\n");
01081 res = AST_CONTROL_ANSWER;
01082 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01083 }
01084 } else {
01085 ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
01086 ast_debug(5, "Start state %d\n", newstate);
01087 dsp->tstate = newstate;
01088 dsp->tcount = 1;
01089 }
01090
01091
01092 for (x = 0; x < 7; x++) {
01093 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01094 }
01095 dsp->gsamps = 0;
01096 dsp->genergy = 0.0;
01097 }
01098 }
01099
01100 return res;
01101 }
01102
01103 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01104 {
01105 if (inf->frametype != AST_FRAME_VOICE) {
01106 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01107 return 0;
01108 }
01109 if (inf->subclass.codec != AST_FORMAT_SLINEAR) {
01110 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01111 return 0;
01112 }
01113 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
01114 }
01115
01116 static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
01117 {
01118 int accum;
01119 int x;
01120 int res = 0;
01121
01122 if (!len) {
01123 return 0;
01124 }
01125 accum = 0;
01126 for (x = 0; x < len; x++) {
01127 accum += abs(s[x]);
01128 }
01129 accum /= len;
01130 if (accum < dsp->threshold) {
01131
01132 dsp->totalsilence += len / 8;
01133 if (dsp->totalnoise) {
01134
01135 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicnoise[0]));
01136 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01137
01138 #if 0
01139 dsp->busymaybe = 1;
01140 #endif
01141 }
01142 dsp->totalnoise = 0;
01143 res = 1;
01144 } else {
01145
01146 dsp->totalnoise += len / 8;
01147 if (dsp->totalsilence) {
01148 int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01149 int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01150
01151 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicsilence[0]));
01152 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01153
01154 if (silence1 < silence2) {
01155 if (silence1 + silence1 * BUSY_PERCENT / 100 >= silence2) {
01156 dsp->busymaybe = 1;
01157 } else {
01158 dsp->busymaybe = 0;
01159 }
01160 } else {
01161 if (silence1 - silence1 * BUSY_PERCENT / 100 <= silence2) {
01162 dsp->busymaybe = 1;
01163 } else {
01164 dsp->busymaybe = 0;
01165 }
01166 }
01167 }
01168 dsp->totalsilence = 0;
01169 }
01170 if (totalsilence) {
01171 *totalsilence = dsp->totalsilence;
01172 }
01173 if (totalnoise) {
01174 *totalnoise = dsp->totalnoise;
01175 }
01176 return res;
01177 }
01178
01179 int ast_dsp_busydetect(struct ast_dsp *dsp)
01180 {
01181 int res = 0, x;
01182 #ifndef BUSYDETECT_TONEONLY
01183 int avgsilence = 0, hitsilence = 0;
01184 #endif
01185 int avgtone = 0, hittone = 0;
01186 if (!dsp->busymaybe) {
01187 return res;
01188 }
01189 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01190 #ifndef BUSYDETECT_TONEONLY
01191 avgsilence += dsp->historicsilence[x];
01192 #endif
01193 avgtone += dsp->historicnoise[x];
01194 }
01195 #ifndef BUSYDETECT_TONEONLY
01196 avgsilence /= dsp->busycount;
01197 #endif
01198 avgtone /= dsp->busycount;
01199 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01200 #ifndef BUSYDETECT_TONEONLY
01201 if (avgsilence > dsp->historicsilence[x]) {
01202 if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
01203 hitsilence++;
01204 }
01205 } else {
01206 if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
01207 hitsilence++;
01208 }
01209 }
01210 #endif
01211 if (avgtone > dsp->historicnoise[x]) {
01212 if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
01213 hittone++;
01214 }
01215 } else {
01216 if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
01217 hittone++;
01218 }
01219 }
01220 }
01221 #ifndef BUSYDETECT_TONEONLY
01222 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
01223 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
01224 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01225 #else
01226 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01227 #endif
01228 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01229 if (avgtone > avgsilence) {
01230 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
01231 res = 1;
01232 }
01233 } else {
01234 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
01235 res = 1;
01236 }
01237 }
01238 #else
01239 res = 1;
01240 #endif
01241 }
01242
01243 if (res && (dsp->busy_tonelength > 0)) {
01244 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
01245 #ifdef BUSYDETECT_DEBUG
01246 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01247 avgtone, dsp->busy_tonelength);
01248 #endif
01249 res = 0;
01250 }
01251 }
01252 #ifndef BUSYDETECT_TONEONLY
01253
01254 if (res && (dsp->busy_quietlength > 0)) {
01255 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01256 #ifdef BUSYDETECT_DEBUG
01257 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01258 avgsilence, dsp->busy_quietlength);
01259 #endif
01260 res = 0;
01261 }
01262 }
01263 #endif
01264 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
01265 if (res) {
01266 ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01267 } else {
01268 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01269 }
01270 #endif
01271 return res;
01272 }
01273
01274 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01275 {
01276 short *s;
01277 int len;
01278
01279 if (f->frametype != AST_FRAME_VOICE) {
01280 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01281 return 0;
01282 }
01283 if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01284 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01285 return 0;
01286 }
01287 s = f->data.ptr;
01288 len = f->datalen/2;
01289 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
01290 }
01291
01292 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
01293 {
01294 short *s;
01295 int len;
01296
01297 if (f->frametype != AST_FRAME_VOICE) {
01298 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
01299 return 0;
01300 }
01301 if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01302 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
01303 return 0;
01304 }
01305 s = f->data.ptr;
01306 len = f->datalen/2;
01307 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
01308 }
01309
01310
01311 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01312 {
01313 int silence;
01314 int res;
01315 int digit = 0, fax_digit = 0;
01316 int x;
01317 short *shortdata;
01318 unsigned char *odata;
01319 int len;
01320 struct ast_frame *outf = NULL;
01321
01322 if (!af) {
01323 return NULL;
01324 }
01325 if (af->frametype != AST_FRAME_VOICE) {
01326 return af;
01327 }
01328
01329 odata = af->data.ptr;
01330 len = af->datalen;
01331
01332 switch (af->subclass.codec) {
01333 case AST_FORMAT_SLINEAR:
01334 shortdata = af->data.ptr;
01335 len = af->datalen / 2;
01336 break;
01337 case AST_FORMAT_ULAW:
01338 case AST_FORMAT_TESTLAW:
01339 shortdata = alloca(af->datalen * 2);
01340 for (x = 0;x < len; x++) {
01341 shortdata[x] = AST_MULAW(odata[x]);
01342 }
01343 break;
01344 case AST_FORMAT_ALAW:
01345 shortdata = alloca(af->datalen * 2);
01346 for (x = 0; x < len; x++) {
01347 shortdata[x] = AST_ALAW(odata[x]);
01348 }
01349 break;
01350 default:
01351
01352 if (dsp->display_inband_dtmf_warning)
01353 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
01354 dsp->display_inband_dtmf_warning = 0;
01355 return af;
01356 }
01357
01358
01359 dsp->mute_fragments = 0;
01360
01361
01362 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01363 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
01364 }
01365
01366 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01367 memset(&dsp->f, 0, sizeof(dsp->f));
01368 dsp->f.frametype = AST_FRAME_NULL;
01369 ast_frfree(af);
01370 return ast_frisolate(&dsp->f);
01371 }
01372 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01373 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01374 memset(&dsp->f, 0, sizeof(dsp->f));
01375 dsp->f.frametype = AST_FRAME_CONTROL;
01376 dsp->f.subclass.integer = AST_CONTROL_BUSY;
01377 ast_frfree(af);
01378 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01379 return ast_frisolate(&dsp->f);
01380 }
01381
01382 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01383 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01384 fax_digit = 'f';
01385 }
01386
01387 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01388 fax_digit = 'e';
01389 }
01390 }
01391
01392 if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
01393 if (dsp->digitmode & DSP_DIGITMODE_MF)
01394 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01395 else
01396 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01397
01398 if (dsp->digit_state.current_digits) {
01399 int event = 0, event_len = 0;
01400 char event_digit = 0;
01401
01402 if (!dsp->dtmf_began) {
01403
01404
01405 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01406 event = AST_FRAME_DTMF_BEGIN;
01407 event_digit = dsp->digit_state.digits[0];
01408 }
01409 dsp->dtmf_began = 1;
01410
01411 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01412
01413 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01414 event = AST_FRAME_DTMF_END;
01415 event_digit = dsp->digit_state.digits[0];
01416 event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
01417 }
01418 memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
01419 memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
01420 dsp->digit_state.current_digits--;
01421 dsp->dtmf_began = 0;
01422
01423 if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
01424
01425 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01426 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01427 ast_debug(1, "DTMF Detected - Reset busydetector\n");
01428 }
01429 }
01430
01431 if (event) {
01432 memset(&dsp->f, 0, sizeof(dsp->f));
01433 dsp->f.frametype = event;
01434 dsp->f.subclass.integer = event_digit;
01435 dsp->f.len = event_len;
01436 outf = &dsp->f;
01437 goto done;
01438 }
01439 }
01440 }
01441
01442 if (fax_digit) {
01443
01444
01445 memset(&dsp->f, 0, sizeof(dsp->f));
01446 dsp->f.frametype = AST_FRAME_DTMF;
01447 dsp->f.subclass.integer = fax_digit;
01448 outf = &dsp->f;
01449 goto done;
01450 }
01451
01452 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01453 res = __ast_dsp_call_progress(dsp, shortdata, len);
01454 if (res) {
01455 switch (res) {
01456 case AST_CONTROL_ANSWER:
01457 case AST_CONTROL_BUSY:
01458 case AST_CONTROL_RINGING:
01459 case AST_CONTROL_CONGESTION:
01460 case AST_CONTROL_HANGUP:
01461 memset(&dsp->f, 0, sizeof(dsp->f));
01462 dsp->f.frametype = AST_FRAME_CONTROL;
01463 dsp->f.subclass.integer = res;
01464 dsp->f.src = "dsp_progress";
01465 if (chan)
01466 ast_queue_frame(chan, &dsp->f);
01467 break;
01468 default:
01469 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01470 }
01471 }
01472 } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
01473 res = __ast_dsp_call_progress(dsp, shortdata, len);
01474 }
01475
01476 done:
01477
01478 for (x = 0; x < dsp->mute_fragments; x++) {
01479 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01480 }
01481
01482 switch (af->subclass.codec) {
01483 case AST_FORMAT_SLINEAR:
01484 break;
01485 case AST_FORMAT_ULAW:
01486 for (x = 0; x < len; x++) {
01487 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01488 }
01489 break;
01490 case AST_FORMAT_ALAW:
01491 for (x = 0; x < len; x++) {
01492 odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01493 }
01494 break;
01495 }
01496
01497 if (outf) {
01498 if (chan) {
01499 ast_queue_frame(chan, af);
01500 }
01501 ast_frfree(af);
01502 return ast_frisolate(outf);
01503 } else {
01504 return af;
01505 }
01506 }
01507
01508 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01509 {
01510 int max = 0;
01511 int x;
01512
01513 dsp->gsamp_size = modes[dsp->progmode].size;
01514 dsp->gsamps = 0;
01515 for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
01516 if (modes[dsp->progmode].freqs[x]) {
01517 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01518 max = x + 1;
01519 }
01520 }
01521 dsp->freqcount = max;
01522 dsp->ringtimeout= 0;
01523 }
01524
01525 struct ast_dsp *ast_dsp_new(void)
01526 {
01527 struct ast_dsp *dsp;
01528
01529 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
01530 dsp->threshold = DEFAULT_THRESHOLD;
01531 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01532 dsp->busycount = DSP_HISTORY;
01533 dsp->digitmode = DSP_DIGITMODE_DTMF;
01534 dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01535
01536 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01537 dsp->display_inband_dtmf_warning = 1;
01538
01539 ast_dsp_prog_reset(dsp);
01540
01541 ast_fax_detect_init(dsp);
01542 }
01543 return dsp;
01544 }
01545
01546 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01547 {
01548 dsp->features = features;
01549 }
01550
01551 void ast_dsp_free(struct ast_dsp *dsp)
01552 {
01553 ast_free(dsp);
01554 }
01555
01556 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01557 {
01558 dsp->threshold = threshold;
01559 }
01560
01561 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01562 {
01563 if (cadences < 4) {
01564 cadences = 4;
01565 }
01566 if (cadences > DSP_HISTORY) {
01567 cadences = DSP_HISTORY;
01568 }
01569 dsp->busycount = cadences;
01570 }
01571
01572 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
01573 {
01574 dsp->busy_tonelength = tonelength;
01575 dsp->busy_quietlength = quietlength;
01576 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01577 }
01578
01579 void ast_dsp_digitreset(struct ast_dsp *dsp)
01580 {
01581 int i;
01582
01583 dsp->dtmf_began = 0;
01584 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01585 mf_detect_state_t *s = &dsp->digit_state.td.mf;
01586
01587 for (i = 0; i < 6; i++) {
01588 goertzel_reset(&s->tone_out[i]);
01589 }
01590 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01591 s->current_sample = 0;
01592 } else {
01593 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01594
01595 for (i = 0; i < 4; i++) {
01596 goertzel_reset(&s->row_out[i]);
01597 goertzel_reset(&s->col_out[i]);
01598 }
01599 s->lasthit = s->current_hit = 0;
01600 s->energy = 0.0;
01601 s->current_sample = 0;
01602 s->hits = 0;
01603 s->misses = 0;
01604 }
01605
01606 dsp->digit_state.digits[0] = '\0';
01607 dsp->digit_state.current_digits = 0;
01608 }
01609
01610 void ast_dsp_reset(struct ast_dsp *dsp)
01611 {
01612 int x;
01613
01614 dsp->totalsilence = 0;
01615 dsp->gsamps = 0;
01616 for (x = 0; x < 4; x++) {
01617 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01618 }
01619 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01620 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01621 dsp->ringtimeout= 0;
01622 }
01623
01624 int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
01625 {
01626 int new;
01627 int old;
01628
01629 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01630 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01631 if (old != new) {
01632
01633 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01634 }
01635 dsp->digitmode = digitmode;
01636 return 0;
01637 }
01638
01639 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
01640 {
01641 if (dsp->faxmode != faxmode) {
01642 ast_fax_detect_init(dsp);
01643 }
01644 dsp->faxmode = faxmode;
01645 return 0;
01646 }
01647
01648 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01649 {
01650 int x;
01651
01652 for (x = 0; x < ARRAY_LEN(aliases); x++) {
01653 if (!strcasecmp(aliases[x].name, zone)) {
01654 dsp->progmode = aliases[x].mode;
01655 ast_dsp_prog_reset(dsp);
01656 return 0;
01657 }
01658 }
01659 return -1;
01660 }
01661
01662 int ast_dsp_was_muted(struct ast_dsp *dsp)
01663 {
01664 return (dsp->mute_fragments > 0);
01665 }
01666
01667 int ast_dsp_get_tstate(struct ast_dsp *dsp)
01668 {
01669 return dsp->tstate;
01670 }
01671
01672 int ast_dsp_get_tcount(struct ast_dsp *dsp)
01673 {
01674 return dsp->tcount;
01675 }
01676
01677 static int _dsp_init(int reload)
01678 {
01679 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01680 struct ast_config *cfg;
01681
01682 cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags);
01683 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
01684 ast_verb(5, "Can't find dsp config file %s. Assuming default silencethreshold of %d.\n", CONFIG_FILE_NAME, DEFAULT_SILENCE_THRESHOLD);
01685 thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
01686 return 0;
01687 }
01688
01689 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
01690 return 0;
01691 }
01692
01693 if (cfg) {
01694 const char *value;
01695
01696 value = ast_variable_retrieve(cfg, "default", "silencethreshold");
01697 if (value && sscanf(value, "%30d", &thresholds[THRESHOLD_SILENCE]) != 1) {
01698 ast_verb(5, "%s: '%s' is not a valid silencethreshold value\n", CONFIG_FILE_NAME, value);
01699 thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
01700 } else if (!value) {
01701 thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
01702 }
01703
01704 ast_config_destroy(cfg);
01705 }
01706 return 0;
01707 }
01708
01709 int ast_dsp_get_threshold_from_settings(enum threshold which)
01710 {
01711 return thresholds[which];
01712 }
01713
01714 int ast_dsp_init(void)
01715 {
01716 return _dsp_init(0);
01717 }
01718
01719 int ast_dsp_reload(void)
01720 {
01721 return _dsp_init(1);
01722 }
01723