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