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