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