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