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: 349728 $")
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 4
00213
00214 #define DTMF_MISSES_TO_END 4
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 (hit == s->td.dtmf.lasthit) {
00730 if (s->td.dtmf.current_hit) {
00731
00732 if (hit) {
00733 if (hit != s->td.dtmf.current_hit) {
00734
00735
00736
00737 s->td.dtmf.current_hit = 0;
00738 } else {
00739
00740 s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
00741 }
00742 } else {
00743
00744 s->td.dtmf.misses++;
00745 if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) {
00746
00747 s->td.dtmf.current_hit = 0;
00748 }
00749 }
00750 } else if (hit) {
00751
00752 s->td.dtmf.hits++;
00753 if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin) {
00754 store_digit(s, hit);
00755 s->td.dtmf.current_hit = hit;
00756 }
00757 }
00758 } else {
00759 s->td.dtmf.hits = 1;
00760 s->td.dtmf.misses = 1;
00761 s->td.dtmf.lasthit = hit;
00762 }
00763
00764
00765 if (squelch && hit) {
00766 if (mute.end < sample - DTMF_GSIZE) {
00767
00768 mute_fragment(dsp, &mute);
00769 mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
00770 }
00771 mute.end = limit + DTMF_GSIZE;
00772 }
00773
00774
00775 for (i = 0; i < 4; i++) {
00776 goertzel_reset(&s->td.dtmf.row_out[i]);
00777 goertzel_reset(&s->td.dtmf.col_out[i]);
00778 }
00779 s->td.dtmf.energy = 0.0;
00780 s->td.dtmf.current_sample = 0;
00781 }
00782
00783 if (squelch && mute.end) {
00784 if (mute.end > samples) {
00785 s->td.dtmf.mute_samples = mute.end - samples;
00786 mute.end = samples;
00787 }
00788 mute_fragment(dsp, &mute);
00789 }
00790
00791 return (s->td.dtmf.current_hit);
00792 }
00793
00794 static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
00795 int samples, int squelch, int relax)
00796 {
00797 float energy[6];
00798 int best;
00799 int second_best;
00800 int i;
00801 int j;
00802 int sample;
00803 int hit;
00804 int limit;
00805 fragment_t mute = {0, 0};
00806
00807 if (squelch && s->td.mf.mute_samples > 0) {
00808 mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
00809 s->td.mf.mute_samples -= mute.end;
00810 }
00811
00812 hit = 0;
00813 for (sample = 0; sample < samples; sample = limit) {
00814
00815
00816 if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
00817 limit = sample + (MF_GSIZE - s->td.mf.current_sample);
00818 } else {
00819 limit = samples;
00820 }
00821
00822
00823 for (j = sample; j < limit; 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 #ifdef DEBUG_DSP_BUSYDETECT
01134 fprintf(stderr, "SILENCE: len = %d, level = %d\n", dsp->totalsilence, accum);
01135 #endif
01136 if (dsp->totalnoise) {
01137
01138 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1) * sizeof(dsp->historicnoise[0]));
01139 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01140
01141 int tone1 = dsp->historicnoise[DSP_HISTORY - 1];
01142 int tone2 = dsp->historicnoise[DSP_HISTORY - 2];
01143 if (tone1 < tone2) {
01144 if ((tone1 + tone1*BUSY_PERCENT/100) >= tone2)
01145 dsp->busymaybe = 1;
01146 else
01147 dsp->busymaybe = 0;
01148 } else {
01149 if ((tone1 - tone1*BUSY_PERCENT/100) <= tone2)
01150 dsp->busymaybe = 1;
01151 else
01152 dsp->busymaybe = 0;
01153 }
01154 }
01155 dsp->totalnoise = 0;
01156 res = 1;
01157 } else {
01158
01159 dsp->totalnoise += len / 8;
01160 #ifdef DEBUG_DSP_BUSYDETECT
01161 fprintf(stderr, "NOISE: len = %d, level = %d\n", dsp->totalnoise, accum);
01162 #endif
01163 if (dsp->totalsilence) {
01164
01165 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1) * sizeof(dsp->historicsilence[0]));
01166 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
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 int avgsilence = 0, hitsilence = 0;
01183 int avgtone = 0, hittone = 0;
01184 #ifdef DEBUG_DSP_BUSYDETECT
01185 char buf[16];
01186 char silence_list[64]="", tone_list[64]="";
01187 #endif
01188
01189 if (!dsp->busymaybe) {
01190 return res;
01191 }
01192 dsp->busymaybe = 0;
01193
01194 for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01195 avgsilence += dsp->historicsilence[x];
01196 avgtone += dsp->historicnoise[x];
01197 }
01198 avgsilence /= dsp->busycount;
01199 avgtone /= dsp->busycount;
01200 #ifdef DEBUG_DSP_BUSYDETECT
01201 sprintf(silence_list,"Silences: ");
01202 sprintf(tone_list,"Tones: ");
01203 #endif
01204 for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) {
01205 #ifdef DEBUG_DSP_BUSYDETECT
01206 snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]);
01207 strcat(silence_list, buf);
01208 snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]);
01209 strcat(tone_list, buf);
01210 #endif
01211 if (!dsp->busytoneonly) {
01212 if (avgsilence > dsp->historicsilence[x]) {
01213 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01214 hitsilence++;
01215 } else {
01216 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01217 hitsilence++;
01218 }
01219 }
01220 if (avgtone > dsp->historicnoise[x]) {
01221 if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
01222 hittone++;
01223 }
01224 } else {
01225 if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
01226 hittone++;
01227 }
01228 }
01229 }
01230 #ifdef DEBUG_DSP_BUSYDETECT
01231 fprintf(stderr, "BUSY DETECTOR\n");
01232 fprintf(stderr, "%s\n", tone_list);
01233 fprintf(stderr, "%s\n", silence_list)
01234 #endif
01235 if ((dsp->busytoneonly ||
01236 (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) &&
01237 (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01238 if (dsp->busycompare) {
01239 if (dsp->busytoneonly) {
01240 res = 1;
01241 ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare");
01242 } else {
01243 if (avgtone > avgsilence) {
01244 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01245 res = 1;
01246 } else {
01247 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01248 res = 1;
01249 }
01250 }
01251 } else {
01252 res = 1;
01253 }
01254 }
01255
01256 if (res && (dsp->busy_tonelength > 0)) {
01257 if (abs(avgtone - dsp->busy_tonelength) > MAX(dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100, 20)) {
01258 #ifdef BUSYDETECT_DEBUG
01259 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01260 avgtone, dsp->busy_tonelength);
01261 #endif
01262 res = 0;
01263 }
01264 }
01265
01266 if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) {
01267 if (abs(avgsilence - dsp->busy_quietlength) > MAX(dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100, 20)) {
01268 #ifdef BUSYDETECT_DEBUG
01269 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01270 avgsilence, dsp->busy_quietlength);
01271 #endif
01272 res = 0;
01273 }
01274 }
01275 if (res) {
01276 if (option_debug)
01277 ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01278 } else {
01279 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01280 }
01281 return res;
01282 }
01283
01284 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01285 {
01286 short *s;
01287 int len;
01288
01289 if (f->frametype != AST_FRAME_VOICE) {
01290 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01291 return 0;
01292 }
01293 if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01294 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01295 return 0;
01296 }
01297 s = f->data.ptr;
01298 len = f->datalen/2;
01299 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
01300 }
01301
01302 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
01303 {
01304 short *s;
01305 int len;
01306
01307 if (f->frametype != AST_FRAME_VOICE) {
01308 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
01309 return 0;
01310 }
01311 if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01312 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
01313 return 0;
01314 }
01315 s = f->data.ptr;
01316 len = f->datalen/2;
01317 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
01318 }
01319
01320
01321 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01322 {
01323 int silence;
01324 int res;
01325 int digit = 0, fax_digit = 0;
01326 int x;
01327 short *shortdata;
01328 unsigned char *odata;
01329 int len;
01330 struct ast_frame *outf = NULL;
01331
01332 if (!af) {
01333 return NULL;
01334 }
01335 if (af->frametype != AST_FRAME_VOICE) {
01336 return af;
01337 }
01338
01339 odata = af->data.ptr;
01340 len = af->datalen;
01341
01342 switch (af->subclass.codec) {
01343 case AST_FORMAT_SLINEAR:
01344 shortdata = af->data.ptr;
01345 len = af->datalen / 2;
01346 break;
01347 case AST_FORMAT_ULAW:
01348 case AST_FORMAT_TESTLAW:
01349 shortdata = alloca(af->datalen * 2);
01350 for (x = 0;x < len; x++) {
01351 shortdata[x] = AST_MULAW(odata[x]);
01352 }
01353 break;
01354 case AST_FORMAT_ALAW:
01355 shortdata = alloca(af->datalen * 2);
01356 for (x = 0; x < len; x++) {
01357 shortdata[x] = AST_ALAW(odata[x]);
01358 }
01359 break;
01360 default:
01361
01362 if (dsp->display_inband_dtmf_warning)
01363 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
01364 dsp->display_inband_dtmf_warning = 0;
01365 return af;
01366 }
01367
01368
01369 dsp->mute_fragments = 0;
01370
01371
01372 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01373 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
01374 }
01375
01376 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01377 memset(&dsp->f, 0, sizeof(dsp->f));
01378 dsp->f.frametype = AST_FRAME_NULL;
01379 ast_frfree(af);
01380 return ast_frisolate(&dsp->f);
01381 }
01382 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01383 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01384 memset(&dsp->f, 0, sizeof(dsp->f));
01385 dsp->f.frametype = AST_FRAME_CONTROL;
01386
01387 dsp->f.subclass.integer = AST_CONTROL_HANGUP;
01388 ast_frfree(af);
01389 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01390 return ast_frisolate(&dsp->f);
01391 }
01392
01393 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01394 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01395 fax_digit = 'f';
01396 }
01397
01398 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01399 fax_digit = 'e';
01400 }
01401 }
01402
01403 if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
01404 if (dsp->digitmode & DSP_DIGITMODE_MF)
01405 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01406 else
01407 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01408
01409 if (dsp->digit_state.current_digits) {
01410 int event = 0, event_len = 0;
01411 char event_digit = 0;
01412
01413 if (!dsp->dtmf_began) {
01414
01415
01416 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01417 event = AST_FRAME_DTMF_BEGIN;
01418 event_digit = dsp->digit_state.digits[0];
01419 }
01420 dsp->dtmf_began = 1;
01421
01422 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01423
01424 if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01425 event = AST_FRAME_DTMF_END;
01426 event_digit = dsp->digit_state.digits[0];
01427 event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
01428 }
01429 memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
01430 memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
01431 dsp->digit_state.current_digits--;
01432 dsp->dtmf_began = 0;
01433
01434 if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
01435
01436 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01437 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01438 ast_debug(1, "DTMF Detected - Reset busydetector\n");
01439 }
01440 }
01441
01442 if (event) {
01443 memset(&dsp->f, 0, sizeof(dsp->f));
01444 dsp->f.frametype = event;
01445 dsp->f.subclass.integer = event_digit;
01446 dsp->f.len = event_len;
01447 outf = &dsp->f;
01448 goto done;
01449 }
01450 }
01451 }
01452
01453 if (fax_digit) {
01454
01455
01456 memset(&dsp->f, 0, sizeof(dsp->f));
01457 dsp->f.frametype = AST_FRAME_DTMF;
01458 dsp->f.subclass.integer = fax_digit;
01459 outf = &dsp->f;
01460 goto done;
01461 }
01462
01463 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01464 res = __ast_dsp_call_progress(dsp, shortdata, len);
01465 if (res) {
01466 switch (res) {
01467 case AST_CONTROL_ANSWER:
01468 case AST_CONTROL_BUSY:
01469 case AST_CONTROL_RINGING:
01470 case AST_CONTROL_CONGESTION:
01471 case AST_CONTROL_HANGUP:
01472 memset(&dsp->f, 0, sizeof(dsp->f));
01473 dsp->f.frametype = AST_FRAME_CONTROL;
01474 dsp->f.subclass.integer = res;
01475 dsp->f.src = "dsp_progress";
01476 if (chan)
01477 ast_queue_frame(chan, &dsp->f);
01478 break;
01479 default:
01480 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01481 }
01482 }
01483 } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
01484 res = __ast_dsp_call_progress(dsp, shortdata, len);
01485 }
01486
01487 done:
01488
01489 for (x = 0; x < dsp->mute_fragments; x++) {
01490 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01491 }
01492
01493 switch (af->subclass.codec) {
01494 case AST_FORMAT_SLINEAR:
01495 break;
01496 case AST_FORMAT_ULAW:
01497 for (x = 0; x < len; x++) {
01498 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01499 }
01500 break;
01501 case AST_FORMAT_ALAW:
01502 for (x = 0; x < len; x++) {
01503 odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01504 }
01505 break;
01506 }
01507
01508 if (outf) {
01509 if (chan) {
01510 ast_queue_frame(chan, af);
01511 }
01512 ast_frfree(af);
01513 return ast_frisolate(outf);
01514 } else {
01515 return af;
01516 }
01517 }
01518
01519 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01520 {
01521 int max = 0;
01522 int x;
01523
01524 dsp->gsamp_size = modes[dsp->progmode].size;
01525 dsp->gsamps = 0;
01526 for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
01527 if (modes[dsp->progmode].freqs[x]) {
01528 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01529 max = x + 1;
01530 }
01531 }
01532 dsp->freqcount = max;
01533 dsp->ringtimeout= 0;
01534 }
01535
01536 struct ast_dsp *ast_dsp_new(void)
01537 {
01538 struct ast_dsp *dsp;
01539
01540 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
01541 dsp->threshold = DEFAULT_THRESHOLD;
01542 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01543 dsp->busycount = DSP_HISTORY;
01544 dsp->digitmode = DSP_DIGITMODE_DTMF;
01545 dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01546 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT;
01547 #ifdef BUSYDETECT_TONEONLY
01548 dsp->busytoneonly = 1;
01549 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01550 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
01551 #endif
01552 #else
01553 dsp->busytoneonly = 0;
01554 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01555 dsp->busycompare = 1;
01556 #else
01557 dsp->busycompare = 0;
01558 #endif
01559 #endif
01560
01561 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01562 dsp->display_inband_dtmf_warning = 1;
01563
01564 ast_dsp_prog_reset(dsp);
01565
01566 ast_fax_detect_init(dsp);
01567 }
01568 return dsp;
01569 }
01570
01571 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01572 {
01573 dsp->features = features;
01574 if (!(features & DSP_FEATURE_DIGIT_DETECT)) {
01575 dsp->display_inband_dtmf_warning = 0;
01576 }
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