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