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 = 8,
00122 BUSY_THRESHOLD = 100,
00123 BUSY_MIN = 150,
00124 BUSY_MAX = 600
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 busytoneonly;
00382 int busycompare;
00383 int busy_tonelength;
00384 int busy_quietlength;
00385 int busy_pattern_fuzzy;
00386 int historicnoise[DSP_HISTORY];
00387 int historicsilence[DSP_HISTORY];
00388 goertzel_state_t freqs[7];
00389 int freqcount;
00390 int gsamps;
00391 enum gsamp_size gsamp_size;
00392 enum prog_mode progmode;
00393 int tstate;
00394 int tcount;
00395 int digitmode;
00396 int faxmode;
00397 int dtmf_began;
00398 int display_inband_dtmf_warning;
00399 float genergy;
00400 int mute_fragments;
00401 fragment_t mute_data[5];
00402 digit_detect_state_t digit_state;
00403 tone_detect_state_t cng_tone_state;
00404 tone_detect_state_t ced_tone_state;
00405 };
00406
00407 static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
00408 {
00409 if (dsp->mute_fragments >= ARRAY_LEN(dsp->mute_data)) {
00410 ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
00411 return;
00412 }
00413
00414 dsp->mute_data[dsp->mute_fragments++] = *fragment;
00415 }
00416
00417 static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
00418 {
00419 int duration_samples;
00420 float x;
00421 int periods_in_block;
00422
00423 s->freq = freq;
00424
00425
00426 duration_samples = duration * SAMPLE_RATE / 1000;
00427
00428 duration_samples = duration_samples * 9 / 10;
00429
00430
00431
00432
00433 s->block_size = SAMPLES_IN_FRAME;
00434
00435 periods_in_block = s->block_size * freq / SAMPLE_RATE;
00436
00437
00438
00439
00440 if (periods_in_block < 5)
00441 periods_in_block = 5;
00442
00443
00444 s->block_size = periods_in_block * SAMPLE_RATE / freq;
00445
00446
00447
00448 s->squelch = 0;
00449
00450
00451
00452 s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
00453
00454 goertzel_init(&s->tone, freq, s->block_size);
00455
00456 s->samples_pending = s->block_size;
00457 s->hit_count = 0;
00458 s->last_hit = 0;
00459 s->energy = 0.0;
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 x = pow(10.0, amp / 10.0);
00472 s->threshold = x / (x + 1);
00473
00474 ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
00475 }
00476
00477 static void ast_fax_detect_init(struct ast_dsp *s)
00478 {
00479 ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
00480 ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
00481 }
00482
00483 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00484 {
00485 int i;
00486
00487 s->lasthit = 0;
00488 s->current_hit = 0;
00489 for (i = 0; i < 4; i++) {
00490 goertzel_init(&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
00491 goertzel_init(&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
00492 s->energy = 0.0;
00493 }
00494 s->current_sample = 0;
00495 s->hits = 0;
00496 s->misses = 0;
00497
00498 s->hits_to_begin = DTMF_HITS_TO_BEGIN;
00499 s->misses_to_end = DTMF_MISSES_TO_END;
00500 }
00501
00502 static void ast_mf_detect_init (mf_detect_state_t *s)
00503 {
00504 int i;
00505 s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
00506 for (i = 0; i < 6; i++) {
00507 goertzel_init (&s->tone_out[i], mf_tones[i], 160);
00508 }
00509 s->current_sample = 0;
00510 s->current_hit = 0;
00511 }
00512
00513 static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
00514 {
00515 s->current_digits = 0;
00516 s->detected_digits = 0;
00517 s->lost_digits = 0;
00518 s->digits[0] = '\0';
00519
00520 if (mf) {
00521 ast_mf_detect_init(&s->td.mf);
00522 } else {
00523 ast_dtmf_detect_init(&s->td.dtmf);
00524 }
00525 }
00526
00527 static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
00528 {
00529 float tone_energy;
00530 int i;
00531 int hit = 0;
00532 int limit;
00533 int res = 0;
00534 int16_t *ptr;
00535 int start, end;
00536 fragment_t mute = {0, 0};
00537
00538 if (s->squelch && s->mute_samples > 0) {
00539 mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
00540 s->mute_samples -= mute.end;
00541 }
00542
00543 for (start = 0; start < samples; start = end) {
00544
00545 limit = samples - start;
00546 if (limit > s->samples_pending) {
00547 limit = s->samples_pending;
00548 }
00549 end = start + limit;
00550
00551 for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
00552
00553 s->energy += (int32_t) *ptr * (int32_t) *ptr;
00554
00555 goertzel_sample(&s->tone, *ptr);
00556 }
00557
00558 s->samples_pending -= limit;
00559
00560 if (s->samples_pending) {
00561
00562 break;
00563 }
00564
00565 tone_energy = goertzel_result(&s->tone);
00566
00567
00568 tone_energy *= 2.0;
00569 s->energy *= s->block_size;
00570
00571 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));
00572 hit = 0;
00573 if (tone_energy > s->energy * s->threshold) {
00574 ast_debug(10, "Hit! count=%d\n", s->hit_count);
00575 hit = 1;
00576 }
00577
00578 if (s->hit_count) {
00579 s->hit_count++;
00580 }
00581
00582 if (hit == s->last_hit) {
00583 if (!hit) {
00584
00585 s->hit_count = 0;
00586 } else if (!s->hit_count) {
00587 s->hit_count++;
00588 }
00589
00590 }
00591
00592 if (s->hit_count == s->hits_required) {
00593 ast_debug(1, "%d Hz done detected\n", s->freq);
00594 res = 1;
00595 }
00596
00597 s->last_hit = hit;
00598
00599
00600 if (s->squelch && hit) {
00601 if (mute.end < start - s->block_size) {
00602
00603 mute_fragment(dsp, &mute);
00604 mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
00605 }
00606 mute.end = end + s->block_size;
00607 }
00608
00609
00610
00611 goertzel_reset(&s->tone);
00612
00613
00614 s->energy = 0.0;
00615 s->samples_pending = s->block_size;
00616
00617 amp += limit;
00618 }
00619
00620 if (s->squelch && mute.end) {
00621 if (mute.end > samples) {
00622 s->mute_samples = mute.end - samples;
00623 mute.end = samples;
00624 }
00625 mute_fragment(dsp, &mute);
00626 }
00627
00628 return res;
00629 }
00630
00631 static void store_digit(digit_detect_state_t *s, char digit)
00632 {
00633 s->detected_digits++;
00634 if (s->current_digits < MAX_DTMF_DIGITS) {
00635 s->digitlen[s->current_digits] = 0;
00636 s->digits[s->current_digits++] = digit;
00637 s->digits[s->current_digits] = '\0';
00638 } else {
00639 ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
00640 s->lost_digits++;
00641 }
00642 }
00643
00644 static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
00645 {
00646 float row_energy[4];
00647 float col_energy[4];
00648 float famp;
00649 int i;
00650 int j;
00651 int sample;
00652 int best_row;
00653 int best_col;
00654 int hit;
00655 int limit;
00656 fragment_t mute = {0, 0};
00657
00658 if (squelch && s->td.dtmf.mute_samples > 0) {
00659 mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
00660 s->td.dtmf.mute_samples -= mute.end;
00661 }
00662
00663 hit = 0;
00664 for (sample = 0; sample < samples; sample = limit) {
00665
00666 if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
00667 limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
00668 } else {
00669 limit = samples;
00670 }
00671
00672
00673 for (j = sample; j < limit; j++) {
00674 famp = amp[j];
00675 s->td.dtmf.energy += famp*famp;
00676
00677
00678 goertzel_sample(s->td.dtmf.row_out, amp[j]);
00679 goertzel_sample(s->td.dtmf.col_out, amp[j]);
00680 goertzel_sample(s->td.dtmf.row_out + 1, amp[j]);
00681 goertzel_sample(s->td.dtmf.col_out + 1, amp[j]);
00682 goertzel_sample(s->td.dtmf.row_out + 2, amp[j]);
00683 goertzel_sample(s->td.dtmf.col_out + 2, amp[j]);
00684 goertzel_sample(s->td.dtmf.row_out + 3, amp[j]);
00685 goertzel_sample(s->td.dtmf.col_out + 3, amp[j]);
00686 }
00687 s->td.dtmf.current_sample += (limit - sample);
00688 if (s->td.dtmf.current_sample < DTMF_GSIZE) {
00689 continue;
00690 }
00691
00692
00693 row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
00694 col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
00695
00696 for (best_row = best_col = 0, i = 1; i < 4; i++) {
00697 row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
00698 if (row_energy[i] > row_energy[best_row]) {
00699 best_row = i;
00700 }
00701 col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
00702 if (col_energy[i] > col_energy[best_col]) {
00703 best_col = i;
00704 }
00705 }
00706 hit = 0;
00707
00708 if (row_energy[best_row] >= DTMF_THRESHOLD &&
00709 col_energy[best_col] >= DTMF_THRESHOLD &&
00710 col_energy[best_col] < row_energy[best_row] * DTMF_REVERSE_TWIST &&
00711 col_energy[best_col] * DTMF_NORMAL_TWIST > row_energy[best_row]) {
00712
00713 for (i = 0; i < 4; i++) {
00714 if ((i != best_col &&
00715 col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
00716 (i != best_row
00717 && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
00718 break;
00719 }
00720 }
00721
00722 if (i >= 4 &&
00723 (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
00724
00725 hit = dtmf_positions[(best_row << 2) + best_col];
00726 }
00727 }
00728
00729 if (s->td.dtmf.current_hit) {
00730
00731 if (hit != s->td.dtmf.current_hit) {
00732 s->td.dtmf.misses++;
00733 if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) {
00734
00735 s->td.dtmf.current_hit = 0;
00736 }
00737 } else {
00738 s->td.dtmf.misses = 0;
00739
00740 s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
00741 }
00742 }
00743
00744
00745
00746
00747 if (hit) {
00748 if (hit == s->td.dtmf.lasthit) {
00749 s->td.dtmf.hits++;
00750 } else {
00751 s->td.dtmf.hits = 1;
00752 }
00753
00754 if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin && hit != s->td.dtmf.current_hit) {
00755 store_digit(s, hit);
00756 s->td.dtmf.current_hit = hit;
00757 s->td.dtmf.misses = 0;
00758 }
00759 } else {
00760 s->td.dtmf.hits = 0;
00761 }
00762
00763 s->td.dtmf.lasthit = hit;
00764
00765
00766 if (squelch && hit) {
00767 if (mute.end < sample - DTMF_GSIZE) {
00768
00769 mute_fragment(dsp, &mute);
00770 mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
00771 }
00772 mute.end = limit + DTMF_GSIZE;
00773 }
00774
00775
00776 for (i = 0; i < 4; i++) {
00777 goertzel_reset(&s->td.dtmf.row_out[i]);
00778 goertzel_reset(&s->td.dtmf.col_out[i]);
00779 }
00780 s->td.dtmf.energy = 0.0;
00781 s->td.dtmf.current_sample = 0;
00782 }
00783
00784 if (squelch && mute.end) {
00785 if (mute.end > samples) {
00786 s->td.dtmf.mute_samples = mute.end - samples;
00787 mute.end = samples;
00788 }
00789 mute_fragment(dsp, &mute);
00790 }
00791
00792 return (s->td.dtmf.current_hit);
00793 }
00794
00795 static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
00796 int samples, int squelch, int relax)
00797 {
00798 float energy[6];
00799 int best;
00800 int second_best;
00801 float famp;
00802 int i;
00803 int j;
00804 int sample;
00805 int hit;
00806 int limit;
00807 fragment_t mute = {0, 0};
00808
00809 if (squelch && s->td.mf.mute_samples > 0) {
00810 mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
00811 s->td.mf.mute_samples -= mute.end;
00812 }
00813
00814 hit = 0;
00815 for (sample = 0; sample < samples; sample = limit) {
00816
00817
00818 if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
00819 limit = sample + (MF_GSIZE - s->td.mf.current_sample);
00820 } else {
00821 limit = samples;
00822 }
00823
00824
00825 for (j = sample; j < limit; j++) {
00826 famp = amp[j];
00827
00828
00829 goertzel_sample(s->td.mf.tone_out, amp[j]);
00830 goertzel_sample(s->td.mf.tone_out + 1, amp[j]);
00831 goertzel_sample(s->td.mf.tone_out + 2, amp[j]);
00832 goertzel_sample(s->td.mf.tone_out + 3, amp[j]);
00833 goertzel_sample(s->td.mf.tone_out + 4, amp[j]);
00834 goertzel_sample(s->td.mf.tone_out + 5, amp[j]);
00835 }
00836 s->td.mf.current_sample += (limit - sample);
00837 if (s->td.mf.current_sample < MF_GSIZE) {
00838 continue;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847 energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
00848 energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
00849 if (energy[0] > energy[1]) {
00850 best = 0;
00851 second_best = 1;
00852 } else {
00853 best = 1;
00854 second_best = 0;
00855 }
00856
00857 for (i = 2; i < 6; i++) {
00858 energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
00859 if (energy[i] >= energy[best]) {
00860 second_best = best;
00861 best = i;
00862 } else if (energy[i] >= energy[second_best]) {
00863 second_best = i;
00864 }
00865 }
00866
00867 hit = 0;
00868 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
00869 && energy[best] < energy[second_best]*BELL_MF_TWIST
00870 && energy[best] * BELL_MF_TWIST > energy[second_best]) {
00871
00872 hit = -1;
00873 for (i = 0; i < 6; i++) {
00874 if (i != best && i != second_best) {
00875 if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
00876
00877 hit = 0;
00878 break;
00879 }
00880 }
00881 }
00882 }
00883 if (hit) {
00884
00885 if (second_best < best) {
00886 i = best;
00887 best = second_best;
00888 second_best = i;
00889 }
00890 best = best * 5 + second_best - 1;
00891 hit = bell_mf_positions[best];
00892
00893
00894
00895
00896
00897
00898 if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
00899 ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
00900 (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
00901 hit != s->td.mf.hits[0]))) {
00902 store_digit(s, hit);
00903 }
00904 }
00905
00906
00907 if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
00908
00909 s->td.mf.current_hit = 0;
00910 }
00911
00912 s->td.mf.hits[0] = s->td.mf.hits[1];
00913 s->td.mf.hits[1] = s->td.mf.hits[2];
00914 s->td.mf.hits[2] = s->td.mf.hits[3];
00915 s->td.mf.hits[3] = s->td.mf.hits[4];
00916 s->td.mf.hits[4] = hit;
00917
00918
00919 if (squelch && hit) {
00920 if (mute.end < sample - MF_GSIZE) {
00921
00922 mute_fragment(dsp, &mute);
00923 mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
00924 }
00925 mute.end = limit + DTMF_GSIZE;
00926 }
00927
00928
00929 for (i = 0; i < 6; i++)
00930 goertzel_reset(&s->td.mf.tone_out[i]);
00931 s->td.mf.current_sample = 0;
00932 }
00933
00934 if (squelch && mute.end) {
00935 if (mute.end > samples) {
00936 s->td.mf.mute_samples = mute.end - samples;
00937 mute.end = samples;
00938 }
00939 mute_fragment(dsp, &mute);
00940 }
00941
00942 return (s->td.mf.current_hit);
00943 }
00944
00945 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
00946 {
00947
00948
00949 if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
00950 return 0;
00951 }
00952
00953 i2 *= TONE_THRESH;
00954 i1 *= TONE_THRESH;
00955 e *= TONE_THRESH;
00956
00957 if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
00958 return 0;
00959 }
00960
00961 if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
00962 return 0;
00963 }
00964
00965 return 1;
00966 }
00967
00968 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
00969 {
00970 int x;
00971 int y;
00972 int pass;
00973 int newstate = DSP_TONE_STATE_SILENCE;
00974 int res = 0;
00975 while (len) {
00976
00977 pass = len;
00978 if (pass > dsp->gsamp_size - dsp->gsamps) {
00979 pass = dsp->gsamp_size - dsp->gsamps;
00980 }
00981 for (x = 0; x < pass; x++) {
00982 for (y = 0; y < dsp->freqcount; y++) {
00983 goertzel_sample(&dsp->freqs[y], s[x]);
00984 }
00985 dsp->genergy += s[x] * s[x];
00986 }
00987 s += pass;
00988 dsp->gsamps += pass;
00989 len -= pass;
00990 if (dsp->gsamps == dsp->gsamp_size) {
00991 float hz[7];
00992 for (y = 0; y < 7; y++) {
00993 hz[y] = goertzel_result(&dsp->freqs[y]);
00994 }
00995 switch (dsp->progmode) {
00996 case PROG_MODE_NA:
00997 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
00998 newstate = DSP_TONE_STATE_BUSY;
00999 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01000 newstate = DSP_TONE_STATE_RINGING;
01001 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01002 newstate = DSP_TONE_STATE_DIALTONE;
01003 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01004 newstate = DSP_TONE_STATE_SPECIAL1;
01005 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01006
01007 if (dsp->tstate == DSP_TONE_STATE_SPECIAL1 || dsp->tstate == DSP_TONE_STATE_SPECIAL2) {
01008 newstate = DSP_TONE_STATE_SPECIAL2;
01009 }
01010 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01011
01012 if (dsp->tstate == DSP_TONE_STATE_SPECIAL2 || dsp->tstate == DSP_TONE_STATE_SPECIAL3) {
01013 newstate = DSP_TONE_STATE_SPECIAL3;
01014 }
01015 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01016 newstate = DSP_TONE_STATE_TALKING;
01017 } else {
01018 newstate = DSP_TONE_STATE_SILENCE;
01019 }
01020 break;
01021 case PROG_MODE_CR:
01022 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01023 newstate = DSP_TONE_STATE_RINGING;
01024 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01025 newstate = DSP_TONE_STATE_TALKING;
01026 } else {
01027 newstate = DSP_TONE_STATE_SILENCE;
01028 }
01029 break;
01030 case PROG_MODE_UK:
01031 if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
01032 newstate = DSP_TONE_STATE_HUNGUP;
01033 } else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
01034 newstate = DSP_TONE_STATE_DIALTONE;
01035 }
01036 break;
01037 default:
01038 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01039 }
01040 if (newstate == dsp->tstate) {
01041 dsp->tcount++;
01042 if (dsp->ringtimeout) {
01043 dsp->ringtimeout++;
01044 }
01045 switch (dsp->tstate) {
01046 case DSP_TONE_STATE_RINGING:
01047 if ((dsp->features & DSP_PROGRESS_RINGING) &&
01048 (dsp->tcount == THRESH_RING)) {
01049 res = AST_CONTROL_RINGING;
01050 dsp->ringtimeout = 1;
01051 }
01052 break;
01053 case DSP_TONE_STATE_BUSY:
01054 if ((dsp->features & DSP_PROGRESS_BUSY) &&
01055 (dsp->tcount == THRESH_BUSY)) {
01056 res = AST_CONTROL_BUSY;
01057 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01058 }
01059 break;
01060 case DSP_TONE_STATE_TALKING:
01061 if ((dsp->features & DSP_PROGRESS_TALK) &&
01062 (dsp->tcount == THRESH_TALK)) {
01063 res = AST_CONTROL_ANSWER;
01064 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01065 }
01066 break;
01067 case DSP_TONE_STATE_SPECIAL3:
01068 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
01069 (dsp->tcount == THRESH_CONGESTION)) {
01070 res = AST_CONTROL_CONGESTION;
01071 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01072 }
01073 break;
01074 case DSP_TONE_STATE_HUNGUP:
01075 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
01076 (dsp->tcount == THRESH_HANGUP)) {
01077 res = AST_CONTROL_HANGUP;
01078 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01079 }
01080 break;
01081 }
01082 if (dsp->ringtimeout == THRESH_RING2ANSWER) {
01083 ast_debug(1, "Consider call as answered because of timeout after last ring\n");
01084 res = AST_CONTROL_ANSWER;
01085 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01086 }
01087 } else {
01088 ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
01089 ast_debug(5, "Start state %d\n", newstate);
01090 dsp->tstate = newstate;
01091 dsp->tcount = 1;
01092 }
01093
01094
01095 for (x = 0; x < 7; x++) {
01096 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01097 }
01098 dsp->gsamps = 0;
01099 dsp->genergy = 0.0;
01100 }
01101 }
01102
01103 return res;
01104 }
01105
01106 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01107 {
01108 if (inf->frametype != AST_FRAME_VOICE) {
01109 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01110 return 0;
01111 }
01112 if (inf->subclass.codec != AST_FORMAT_SLINEAR) {
01113 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01114 return 0;
01115 }
01116 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
01117 }
01118
01119 static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
01120 {
01121 int accum;
01122 int x;
01123 int res = 0;
01124
01125 if (!len) {
01126 return 0;
01127 }
01128 accum = 0;
01129 for (x = 0; x < len; x++) {
01130 accum += abs(s[x]);
01131 }
01132 accum /= len;
01133 if (accum < dsp->threshold) {
01134
01135 dsp->totalsilence += len / 8;
01136 #ifdef DEBUG_DSP_BUSYDETECT
01137 fprintf(stderr, "SILENCE: len = %d, level = %d\n", dsp->totalsilence, accum);
01138 #endif
01139 if (dsp->totalnoise) {
01140
01141 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1) * sizeof(dsp->historicnoise[0]));
01142 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01143
01144 int tone1 = dsp->historicnoise[DSP_HISTORY - 1];
01145 int tone2 = dsp->historicnoise[DSP_HISTORY - 2];
01146 if (tone1 < tone2) {
01147 if ((tone1 + tone1*BUSY_PERCENT/100) >= tone2)
01148 dsp->busymaybe = 1;
01149 else
01150 dsp->busymaybe = 0;
01151 } else {
01152 if ((tone1 - tone1*BUSY_PERCENT/100) <= tone2)
01153 dsp->busymaybe = 1;
01154 else
01155 dsp->busymaybe = 0;
01156 }
01157 }
01158 dsp->totalnoise = 0;
01159 res = 1;
01160 } else {
01161
01162 dsp->totalnoise += len / 8;
01163 #ifdef DEBUG_DSP_BUSYDETECT
01164 fprintf(stderr, "NOISE: len = %d, level = %d\n", dsp->totalnoise, accum);
01165 #endif
01166 if (dsp->totalsilence) {
01167
01168 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1) * sizeof(dsp->historicsilence[0]));
01169 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01170 }
01171 dsp->totalsilence = 0;
01172 }
01173 if (totalsilence) {
01174 *totalsilence = dsp->totalsilence;
01175 }
01176 if (totalnoise) {
01177 *totalnoise = dsp->totalnoise;
01178 }
01179 return res;
01180 }
01181
01182 int ast_dsp_busydetect(struct ast_dsp *dsp)
01183 {
01184 int res = 0, x;
01185 int avgsilence = 0, hitsilence = 0;
01186 int avgtone = 0, hittone = 0;
01187 #ifdef DEBUG_DSP_BUSYDETECT
01188 char buf[16];
01189 char silence_list[64]="", tone_list[64]="";
01190 #endif
01191
01192 if (!dsp->busymaybe) {
01193 return res;
01194 }
01195 dsp->busymaybe = 0;
01196
01197 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01198 avgsilence += dsp->historicsilence[x];
01199 avgtone += dsp->historicnoise[x];
01200 }
01201 avgsilence /= dsp->busycount;
01202 avgtone /= dsp->busycount;
01203 #ifdef DEBUG_DSP_BUSYDETECT
01204 sprintf(silence_list,"Silences: ");
01205 sprintf(tone_list,"Tones: ");
01206 #endif
01207 for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) {
01208 #ifdef DEBUG_DSP_BUSYDETECT
01209 snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]);
01210 strcat(silence_list, buf);
01211 snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]);
01212 strcat(tone_list, buf);
01213 #endif
01214 if (!dsp->busytoneonly) {
01215 if (avgsilence > dsp->historicsilence[x]) {
01216 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01217 hitsilence++;
01218 } else {
01219 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01220 hitsilence++;
01221 }
01222 }
01223 if (avgtone > dsp->historicnoise[x]) {
01224 if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
01225 hittone++;
01226 }
01227 } else {
01228 if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
01229 hittone++;
01230 }
01231 }
01232 }
01233 #ifdef DEBUG_DSP_BUSYDETECT
01234 fprintf(stderr, "BUSY DETECTOR\n");
01235 fprintf(stderr, "%s\n", tone_list);
01236 fprintf(stderr, "%s\n", silence_list)
01237 #endif
01238 if ((dsp->busytoneonly ||
01239 (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) &&
01240 (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01241 if (dsp->busycompare) {
01242 if (dsp->busytoneonly) {
01243 res = 1;
01244 ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare");
01245 } else {
01246 if (avgtone > avgsilence) {
01247 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01248 res = 1;
01249 } else {
01250 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01251 res = 1;
01252 }
01253 }
01254 } else {
01255 res = 1;
01256 }
01257 }
01258
01259 if (res && (dsp->busy_tonelength > 0)) {
01260 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100)) {
01261 #ifdef BUSYDETECT_DEBUG
01262 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01263 avgtone, dsp->busy_tonelength);
01264 #endif
01265 res = 0;
01266 }
01267 }
01268
01269 if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) {
01270 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100)) {
01271 #ifdef BUSYDETECT_DEBUG
01272 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01273 avgsilence, dsp->busy_quietlength);
01274 #endif
01275 res = 0;
01276 }
01277 }
01278 if (res) {
01279 if (option_debug)
01280 ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01281 } else {
01282 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01283 }
01284 return res;
01285 }
01286
01287 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01288 {
01289 short *s;
01290 int len;
01291
01292 if (f->frametype != AST_FRAME_VOICE) {
01293 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01294 return 0;
01295 }
01296 if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01297 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01298 return 0;
01299 }
01300 s = f->data.ptr;
01301 len = f->datalen/2;
01302 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
01303 }
01304
01305 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
01306 {
01307 short *s;
01308 int len;
01309
01310 if (f->frametype != AST_FRAME_VOICE) {
01311 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
01312 return 0;
01313 }
01314 if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01315 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
01316 return 0;
01317 }
01318 s = f->data.ptr;
01319 len = f->datalen/2;
01320 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
01321 }
01322
01323
01324 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01325 {
01326 int silence;
01327 int res;
01328 int digit = 0, fax_digit = 0;
01329 int x;
01330 short *shortdata;
01331 unsigned char *odata;
01332 int len;
01333 struct ast_frame *outf = NULL;
01334
01335 if (!af) {
01336 return NULL;
01337 }
01338 if (af->frametype != AST_FRAME_VOICE) {
01339 return af;
01340 }
01341
01342 odata = af->data.ptr;
01343 len = af->datalen;
01344
01345 switch (af->subclass.codec) {
01346 case AST_FORMAT_SLINEAR:
01347 shortdata = af->data.ptr;
01348 len = af->datalen / 2;
01349 break;
01350 case AST_FORMAT_ULAW:
01351 case AST_FORMAT_TESTLAW:
01352 shortdata = alloca(af->datalen * 2);
01353 for (x = 0;x < len; x++) {
01354 shortdata[x] = AST_MULAW(odata[x]);
01355 }
01356 break;
01357 case AST_FORMAT_ALAW:
01358 shortdata = alloca(af->datalen * 2);
01359 for (x = 0; x < len; x++) {
01360 shortdata[x] = AST_ALAW(odata[x]);
01361 }
01362 break;
01363 default:
01364
01365 if (dsp->display_inband_dtmf_warning)
01366 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
01367 dsp->display_inband_dtmf_warning = 0;
01368 return af;
01369 }
01370
01371
01372 dsp->mute_fragments = 0;
01373
01374
01375 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01376 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
01377 }
01378
01379 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01380 memset(&dsp->f, 0, sizeof(dsp->f));
01381 dsp->f.frametype = AST_FRAME_NULL;
01382 ast_frfree(af);
01383 return ast_frisolate(&dsp->f);
01384 }
01385 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01386 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01387 memset(&dsp->f, 0, sizeof(dsp->f));
01388 dsp->f.frametype = AST_FRAME_CONTROL;
01389
01390 dsp->f.subclass.integer = AST_CONTROL_HANGUP;
01391 ast_frfree(af);
01392 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01393 return ast_frisolate(&dsp->f);
01394 }
01395
01396 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01397 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01398 fax_digit = 'f';
01399 }
01400
01401 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01402 fax_digit = 'e';
01403 }
01404 }
01405
01406 if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
01407 if (dsp->digitmode & DSP_DIGITMODE_MF)
01408 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01409 else
01410 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01411
01412 if (dsp->digit_state.current_digits) {
01413 int event = 0, event_len = 0;
01414 char event_digit = 0;
01415
01416 if (!dsp->dtmf_began) {
01417
01418
01419 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01420 event = AST_FRAME_DTMF_BEGIN;
01421 event_digit = dsp->digit_state.digits[0];
01422 }
01423 dsp->dtmf_began = 1;
01424
01425 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01426
01427 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01428 event = AST_FRAME_DTMF_END;
01429 event_digit = dsp->digit_state.digits[0];
01430 event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
01431 }
01432 memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
01433 memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
01434 dsp->digit_state.current_digits--;
01435 dsp->dtmf_began = 0;
01436
01437 if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
01438
01439 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01440 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01441 ast_debug(1, "DTMF Detected - Reset busydetector\n");
01442 }
01443 }
01444
01445 if (event) {
01446 memset(&dsp->f, 0, sizeof(dsp->f));
01447 dsp->f.frametype = event;
01448 dsp->f.subclass.integer = event_digit;
01449 dsp->f.len = event_len;
01450 outf = &dsp->f;
01451 goto done;
01452 }
01453 }
01454 }
01455
01456 if (fax_digit) {
01457
01458
01459 memset(&dsp->f, 0, sizeof(dsp->f));
01460 dsp->f.frametype = AST_FRAME_DTMF;
01461 dsp->f.subclass.integer = fax_digit;
01462 outf = &dsp->f;
01463 goto done;
01464 }
01465
01466 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01467 res = __ast_dsp_call_progress(dsp, shortdata, len);
01468 if (res) {
01469 switch (res) {
01470 case AST_CONTROL_ANSWER:
01471 case AST_CONTROL_BUSY:
01472 case AST_CONTROL_RINGING:
01473 case AST_CONTROL_CONGESTION:
01474 case AST_CONTROL_HANGUP:
01475 memset(&dsp->f, 0, sizeof(dsp->f));
01476 dsp->f.frametype = AST_FRAME_CONTROL;
01477 dsp->f.subclass.integer = res;
01478 dsp->f.src = "dsp_progress";
01479 if (chan)
01480 ast_queue_frame(chan, &dsp->f);
01481 break;
01482 default:
01483 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01484 }
01485 }
01486 } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
01487 res = __ast_dsp_call_progress(dsp, shortdata, len);
01488 }
01489
01490 done:
01491
01492 for (x = 0; x < dsp->mute_fragments; x++) {
01493 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01494 }
01495
01496 switch (af->subclass.codec) {
01497 case AST_FORMAT_SLINEAR:
01498 break;
01499 case AST_FORMAT_ULAW:
01500 for (x = 0; x < len; x++) {
01501 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01502 }
01503 break;
01504 case AST_FORMAT_ALAW:
01505 for (x = 0; x < len; x++) {
01506 odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01507 }
01508 break;
01509 }
01510
01511 if (outf) {
01512 if (chan) {
01513 ast_queue_frame(chan, af);
01514 }
01515 ast_frfree(af);
01516 return ast_frisolate(outf);
01517 } else {
01518 return af;
01519 }
01520 }
01521
01522 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01523 {
01524 int max = 0;
01525 int x;
01526
01527 dsp->gsamp_size = modes[dsp->progmode].size;
01528 dsp->gsamps = 0;
01529 for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
01530 if (modes[dsp->progmode].freqs[x]) {
01531 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01532 max = x + 1;
01533 }
01534 }
01535 dsp->freqcount = max;
01536 dsp->ringtimeout= 0;
01537 }
01538
01539 struct ast_dsp *ast_dsp_new(void)
01540 {
01541 struct ast_dsp *dsp;
01542
01543 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
01544 dsp->threshold = DEFAULT_THRESHOLD;
01545 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01546 dsp->busycount = DSP_HISTORY;
01547 dsp->digitmode = DSP_DIGITMODE_DTMF;
01548 dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01549 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT;
01550 #ifdef BUSYDETECT_TONEONLY
01551 dsp->busytoneonly = 1;
01552 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01553 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
01554 #endif
01555 #else
01556 dsp->busytoneonly = 0;
01557 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01558 dsp->busycompare = 1;
01559 #else
01560 dsp->busycompare = 0;
01561 #endif
01562 #endif
01563
01564 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01565 dsp->display_inband_dtmf_warning = 1;
01566
01567 ast_dsp_prog_reset(dsp);
01568
01569 ast_fax_detect_init(dsp);
01570 }
01571 return dsp;
01572 }
01573
01574 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01575 {
01576 dsp->features = features;
01577 }
01578
01579 void ast_dsp_free(struct ast_dsp *dsp)
01580 {
01581 ast_free(dsp);
01582 }
01583
01584 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01585 {
01586 if (threshold < 256)
01587 dsp->threshold = 256;
01588 else
01589 dsp->threshold = threshold;
01590 }
01591
01592 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01593 {
01594 if (cadences < 4) {
01595 cadences = 4;
01596 }
01597 if (cadences > DSP_HISTORY) {
01598 cadences = DSP_HISTORY;
01599 }
01600 dsp->busycount = cadences;
01601 }
01602
01603 void ast_dsp_set_busy_compare(struct ast_dsp *dsp, int compare)
01604 {
01605 if (compare > 0)
01606 dsp->busycompare = 1;
01607 else
01608 dsp->busycompare = 0;
01609 }
01610
01611 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength, int fuzzy)
01612 {
01613 dsp->busy_tonelength = tonelength;
01614 if (quietlength > 0)
01615 dsp->busy_quietlength = quietlength;
01616 else
01617 dsp->busytoneonly = 1;
01618 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01619 if( fuzzy > 0 && fuzzy < 50 )
01620 dsp->busy_pattern_fuzzy = fuzzy;
01621 }
01622
01623 void ast_dsp_digitreset(struct ast_dsp *dsp)
01624 {
01625 int i;
01626
01627 dsp->dtmf_began = 0;
01628 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01629 mf_detect_state_t *s = &dsp->digit_state.td.mf;
01630
01631 for (i = 0; i < 6; i++) {
01632 goertzel_reset(&s->tone_out[i]);
01633 }
01634 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01635 s->current_sample = 0;
01636 } else {
01637 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01638
01639 for (i = 0; i < 4; i++) {
01640 goertzel_reset(&s->row_out[i]);
01641 goertzel_reset(&s->col_out[i]);
01642 }
01643 s->lasthit = s->current_hit = 0;
01644 s->energy = 0.0;
01645 s->current_sample = 0;
01646 s->hits = 0;
01647 s->misses = 0;
01648 }
01649
01650 dsp->digit_state.digits[0] = '\0';
01651 dsp->digit_state.current_digits = 0;
01652 }
01653
01654 void ast_dsp_reset(struct ast_dsp *dsp)
01655 {
01656 int x;
01657
01658 dsp->totalsilence = 0;
01659 dsp->gsamps = 0;
01660 for (x = 0; x < 4; x++) {
01661 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01662 }
01663 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01664 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01665 dsp->ringtimeout= 0;
01666 }
01667
01668 int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
01669 {
01670 int new;
01671 int old;
01672
01673 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01674 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01675 if (old != new) {
01676
01677 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01678 }
01679 dsp->digitmode = digitmode;
01680 return 0;
01681 }
01682
01683 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
01684 {
01685 if (dsp->faxmode != faxmode) {
01686 ast_fax_detect_init(dsp);
01687 }
01688 dsp->faxmode = faxmode;
01689 return 0;
01690 }
01691
01692 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01693 {
01694 int x;
01695
01696 for (x = 0; x < ARRAY_LEN(aliases); x++) {
01697 if (!strcasecmp(aliases[x].name, zone)) {
01698 dsp->progmode = aliases[x].mode;
01699 ast_dsp_prog_reset(dsp);
01700 return 0;
01701 }
01702 }
01703 return -1;
01704 }
01705
01706 int ast_dsp_was_muted(struct ast_dsp *dsp)
01707 {
01708 return (dsp->mute_fragments > 0);
01709 }
01710
01711 int ast_dsp_get_tstate(struct ast_dsp *dsp)
01712 {
01713 return dsp->tstate;
01714 }
01715
01716 int ast_dsp_get_tcount(struct ast_dsp *dsp)
01717 {
01718 return dsp->tcount;
01719 }
01720
01721 static int _dsp_init(int reload)
01722 {
01723 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01724 struct ast_config *cfg;
01725
01726 cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags);
01727 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
01728 ast_verb(5, "Can't find dsp config file %s. Assuming default silencethreshold of %d.\n", CONFIG_FILE_NAME, DEFAULT_SILENCE_THRESHOLD);
01729 thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
01730 return 0;
01731 }
01732
01733 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
01734 return 0;
01735 }
01736
01737 if (cfg) {
01738 const char *value;
01739
01740 value = ast_variable_retrieve(cfg, "default", "silencethreshold");
01741 if (value && sscanf(value, "%30d", &thresholds[THRESHOLD_SILENCE]) != 1) {
01742 ast_verb(5, "%s: '%s' is not a valid silencethreshold value\n", CONFIG_FILE_NAME, value);
01743 thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
01744 } else if (!value) {
01745 thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
01746 }
01747
01748 ast_config_destroy(cfg);
01749 }
01750 return 0;
01751 }
01752
01753 int ast_dsp_get_threshold_from_settings(enum threshold which)
01754 {
01755 return thresholds[which];
01756 }
01757
01758 int ast_dsp_init(void)
01759 {
01760 return _dsp_init(0);
01761 }
01762
01763 int ast_dsp_reload(void)
01764 {
01765 return _dsp_init(1);
01766 }
01767