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