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