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