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