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