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: 224935 $")
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 = 7,
00120 BUSY_THRESHOLD = 100,
00121 BUSY_MIN = 75,
00122 BUSY_MAX =3100
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 busy_tonelength;
00379 int busy_quietlength;
00380 int historicnoise[DSP_HISTORY];
00381 int historicsilence[DSP_HISTORY];
00382 goertzel_state_t freqs[7];
00383 int freqcount;
00384 int gsamps;
00385 enum gsamp_size gsamp_size;
00386 enum prog_mode progmode;
00387 int tstate;
00388 int tcount;
00389 int digitmode;
00390 int faxmode;
00391 int dtmf_began;
00392 float genergy;
00393 int mute_fragments;
00394 fragment_t mute_data[5];
00395 digit_detect_state_t digit_state;
00396 tone_detect_state_t cng_tone_state;
00397 tone_detect_state_t ced_tone_state;
00398 };
00399
00400 static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
00401 {
00402 if (dsp->mute_fragments >= ARRAY_LEN(dsp->mute_data)) {
00403 ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
00404 return;
00405 }
00406
00407 dsp->mute_data[dsp->mute_fragments++] = *fragment;
00408 }
00409
00410 static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
00411 {
00412 int duration_samples;
00413 float x;
00414 int periods_in_block;
00415
00416 s->freq = freq;
00417
00418
00419 duration_samples = duration * SAMPLE_RATE / 1000;
00420
00421 duration_samples = duration_samples * 9 / 10;
00422
00423
00424
00425
00426 s->block_size = SAMPLES_IN_FRAME;
00427
00428 periods_in_block = s->block_size * freq / SAMPLE_RATE;
00429
00430
00431
00432
00433 if (periods_in_block < 5)
00434 periods_in_block = 5;
00435
00436
00437 s->block_size = periods_in_block * SAMPLE_RATE / freq;
00438
00439
00440
00441 s->squelch = 0;
00442
00443
00444
00445 s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
00446
00447 goertzel_init(&s->tone, freq, s->block_size);
00448
00449 s->samples_pending = s->block_size;
00450 s->hit_count = 0;
00451 s->last_hit = 0;
00452 s->energy = 0.0;
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 x = pow(10.0, amp / 10.0);
00465 s->threshold = x / (x + 1);
00466
00467 ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
00468 }
00469
00470 static void ast_fax_detect_init(struct ast_dsp *s)
00471 {
00472 ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
00473 ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
00474 }
00475
00476 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00477 {
00478 int i;
00479
00480 s->lasthit = 0;
00481 s->current_hit = 0;
00482 for (i = 0; i < 4; i++) {
00483 goertzel_init (&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
00484 goertzel_init (&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
00485 s->energy = 0.0;
00486 }
00487 s->current_sample = 0;
00488 s->hits = 0;
00489 s->misses = 0;
00490
00491 s->hits_to_begin = DTMF_HITS_TO_BEGIN;
00492 s->misses_to_end = DTMF_MISSES_TO_END;
00493 }
00494
00495 static void ast_mf_detect_init (mf_detect_state_t *s)
00496 {
00497 int i;
00498 s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
00499 for (i = 0; i < 6; i++) {
00500 goertzel_init (&s->tone_out[i], mf_tones[i], 160);
00501 }
00502 s->current_sample = 0;
00503 s->current_hit = 0;
00504 }
00505
00506 static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
00507 {
00508 s->current_digits = 0;
00509 s->detected_digits = 0;
00510 s->lost_digits = 0;
00511 s->digits[0] = '\0';
00512
00513 if (mf)
00514 ast_mf_detect_init(&s->td.mf);
00515 else
00516 ast_dtmf_detect_init(&s->td.dtmf);
00517 }
00518
00519 static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
00520 {
00521 float tone_energy;
00522 int i;
00523 int hit = 0;
00524 int limit;
00525 int res = 0;
00526 int16_t *ptr;
00527 int start, end;
00528 fragment_t mute = {0, 0};
00529
00530 if (s->squelch && s->mute_samples > 0) {
00531 mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
00532 s->mute_samples -= mute.end;
00533 }
00534
00535 for (start = 0; start < samples; start = end) {
00536
00537 limit = samples - start;
00538 if (limit > s->samples_pending)
00539 limit = s->samples_pending;
00540 end = start + limit;
00541
00542 for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
00543
00544 s->energy += (int32_t) *ptr * (int32_t) *ptr;
00545
00546 goertzel_sample(&s->tone, *ptr);
00547 }
00548
00549 s->samples_pending -= limit;
00550
00551 if (s->samples_pending) {
00552
00553 break;
00554 }
00555
00556 tone_energy = goertzel_result(&s->tone);
00557
00558
00559 tone_energy *= 2.0;
00560 s->energy *= s->block_size;
00561
00562 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));
00563 hit = 0;
00564 if (tone_energy > s->energy * s->threshold) {
00565 ast_debug(10, "Hit! count=%d\n", s->hit_count);
00566 hit = 1;
00567 }
00568
00569 if (s->hit_count)
00570 s->hit_count++;
00571
00572 if (hit == s->last_hit) {
00573 if (!hit) {
00574
00575 s->hit_count = 0;
00576 } else if (!s->hit_count) {
00577 s->hit_count++;
00578 }
00579
00580 }
00581
00582 if (s->hit_count == s->hits_required) {
00583 ast_debug(1, "%d Hz done detected\n", s->freq);
00584 res = 1;
00585 }
00586
00587 s->last_hit = hit;
00588
00589
00590 if (s->squelch && hit) {
00591 if (mute.end < start - s->block_size) {
00592
00593 mute_fragment(dsp, &mute);
00594 mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
00595 }
00596 mute.end = end + s->block_size;
00597 }
00598
00599
00600
00601 goertzel_reset(&s->tone);
00602
00603
00604 s->energy = 0.0;
00605 s->samples_pending = s->block_size;
00606
00607 amp += limit;
00608 }
00609
00610 if (s->squelch && mute.end) {
00611 if (mute.end > samples) {
00612 s->mute_samples = mute.end - samples;
00613 mute.end = samples;
00614 }
00615 mute_fragment(dsp, &mute);
00616 }
00617
00618 return res;
00619 }
00620
00621 static void store_digit(digit_detect_state_t *s, char digit)
00622 {
00623 s->detected_digits++;
00624 if (s->current_digits < MAX_DTMF_DIGITS) {
00625 s->digits[s->current_digits++] = digit;
00626 s->digits[s->current_digits] = '\0';
00627 } else {
00628 ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
00629 s->lost_digits++;
00630 }
00631 }
00632
00633 static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
00634 {
00635 float row_energy[4];
00636 float col_energy[4];
00637 float famp;
00638 int i;
00639 int j;
00640 int sample;
00641 int best_row;
00642 int best_col;
00643 int hit;
00644 int limit;
00645 fragment_t mute = {0, 0};
00646
00647 if (squelch && s->td.dtmf.mute_samples > 0) {
00648 mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
00649 s->td.dtmf.mute_samples -= mute.end;
00650 }
00651
00652 hit = 0;
00653 for (sample = 0; sample < samples; sample = limit) {
00654
00655 if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample))
00656 limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
00657 else
00658 limit = samples;
00659
00660
00661 for (j = sample; j < limit; j++) {
00662 famp = amp[j];
00663 s->td.dtmf.energy += famp*famp;
00664
00665
00666 goertzel_sample(s->td.dtmf.row_out, amp[j]);
00667 goertzel_sample(s->td.dtmf.col_out, amp[j]);
00668 goertzel_sample(s->td.dtmf.row_out + 1, amp[j]);
00669 goertzel_sample(s->td.dtmf.col_out + 1, amp[j]);
00670 goertzel_sample(s->td.dtmf.row_out + 2, amp[j]);
00671 goertzel_sample(s->td.dtmf.col_out + 2, amp[j]);
00672 goertzel_sample(s->td.dtmf.row_out + 3, amp[j]);
00673 goertzel_sample(s->td.dtmf.col_out + 3, amp[j]);
00674 }
00675 s->td.dtmf.current_sample += (limit - sample);
00676 if (s->td.dtmf.current_sample < DTMF_GSIZE) {
00677 continue;
00678 }
00679
00680
00681 row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
00682 col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
00683
00684 for (best_row = best_col = 0, i = 1; i < 4; i++) {
00685 row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
00686 if (row_energy[i] > row_energy[best_row])
00687 best_row = i;
00688 col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
00689 if (col_energy[i] > col_energy[best_col])
00690 best_col = i;
00691 }
00692 hit = 0;
00693
00694 if (row_energy[best_row] >= DTMF_THRESHOLD &&
00695 col_energy[best_col] >= DTMF_THRESHOLD &&
00696 col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
00697 col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
00698
00699 for (i = 0; i < 4; i++) {
00700 if ((i != best_col &&
00701 col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
00702 (i != best_row
00703 && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
00704 break;
00705 }
00706 }
00707
00708 if (i >= 4 &&
00709 (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->td.dtmf.energy) {
00710
00711 hit = dtmf_positions[(best_row << 2) + best_col];
00712 }
00713 }
00714
00715 if (s->td.dtmf.current_hit) {
00716
00717 if (hit != s->td.dtmf.current_hit) {
00718 s->td.dtmf.misses++;
00719 if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) {
00720
00721 s->td.dtmf.current_hit = 0;
00722 }
00723 } else {
00724 s->td.dtmf.misses = 0;
00725 }
00726 }
00727
00728
00729
00730
00731 if (hit) {
00732 if (hit == s->td.dtmf.lasthit) {
00733 s->td.dtmf.hits++;
00734 } else {
00735 s->td.dtmf.hits = 1;
00736 }
00737
00738 if (s->td.dtmf.hits == s->td.dtmf.hits_to_begin && hit != s->td.dtmf.current_hit) {
00739 store_digit(s, hit);
00740 s->td.dtmf.current_hit = hit;
00741 s->td.dtmf.misses = 0;
00742 }
00743 } else {
00744 s->td.dtmf.hits = 0;
00745 }
00746
00747 s->td.dtmf.lasthit = hit;
00748
00749
00750 if (squelch && hit) {
00751 if (mute.end < sample - DTMF_GSIZE) {
00752
00753 mute_fragment(dsp, &mute);
00754 mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
00755 }
00756 mute.end = limit + DTMF_GSIZE;
00757 }
00758
00759
00760 for (i = 0; i < 4; i++) {
00761 goertzel_reset(&s->td.dtmf.row_out[i]);
00762 goertzel_reset(&s->td.dtmf.col_out[i]);
00763 }
00764 s->td.dtmf.energy = 0.0;
00765 s->td.dtmf.current_sample = 0;
00766 }
00767
00768 if (squelch && mute.end) {
00769 if (mute.end > samples) {
00770 s->td.dtmf.mute_samples = mute.end - samples;
00771 mute.end = samples;
00772 }
00773 mute_fragment(dsp, &mute);
00774 }
00775
00776 return (s->td.dtmf.current_hit);
00777 }
00778
00779 static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
00780 int samples, int squelch, int relax)
00781 {
00782 float energy[6];
00783 int best;
00784 int second_best;
00785 float famp;
00786 int i;
00787 int j;
00788 int sample;
00789 int hit;
00790 int limit;
00791 fragment_t mute = {0, 0};
00792
00793 if (squelch && s->td.mf.mute_samples > 0) {
00794 mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
00795 s->td.mf.mute_samples -= mute.end;
00796 }
00797
00798 hit = 0;
00799 for (sample = 0; sample < samples; sample = limit) {
00800
00801
00802 if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample))
00803 limit = sample + (MF_GSIZE - s->td.mf.current_sample);
00804 else
00805 limit = samples;
00806
00807
00808 for (j = sample; j < limit; j++) {
00809 famp = amp[j];
00810
00811
00812 goertzel_sample(s->td.mf.tone_out, amp[j]);
00813 goertzel_sample(s->td.mf.tone_out + 1, amp[j]);
00814 goertzel_sample(s->td.mf.tone_out + 2, amp[j]);
00815 goertzel_sample(s->td.mf.tone_out + 3, amp[j]);
00816 goertzel_sample(s->td.mf.tone_out + 4, amp[j]);
00817 goertzel_sample(s->td.mf.tone_out + 5, amp[j]);
00818 }
00819 s->td.mf.current_sample += (limit - sample);
00820 if (s->td.mf.current_sample < MF_GSIZE) {
00821 continue;
00822 }
00823
00824
00825
00826
00827
00828
00829
00830 energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
00831 energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
00832 if (energy[0] > energy[1]) {
00833 best = 0;
00834 second_best = 1;
00835 } else {
00836 best = 1;
00837 second_best = 0;
00838 }
00839
00840 for (i=2;i<6;i++) {
00841 energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
00842 if (energy[i] >= energy[best]) {
00843 second_best = best;
00844 best = i;
00845 } else if (energy[i] >= energy[second_best]) {
00846 second_best = i;
00847 }
00848 }
00849
00850 hit = 0;
00851 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
00852 && energy[best] < energy[second_best]*BELL_MF_TWIST
00853 && energy[best]*BELL_MF_TWIST > energy[second_best]) {
00854
00855 hit = -1;
00856 for (i=0;i<6;i++) {
00857 if (i != best && i != second_best) {
00858 if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
00859
00860 hit = 0;
00861 break;
00862 }
00863 }
00864 }
00865 }
00866 if (hit) {
00867
00868 if (second_best < best) {
00869 i = best;
00870 best = second_best;
00871 second_best = i;
00872 }
00873 best = best*5 + second_best - 1;
00874 hit = bell_mf_positions[best];
00875
00876
00877
00878
00879
00880
00881 if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
00882 ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
00883 (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
00884 hit != s->td.mf.hits[0]))) {
00885 store_digit(s, hit);
00886 }
00887 }
00888
00889
00890 if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
00891
00892 s->td.mf.current_hit = 0;
00893 }
00894
00895 s->td.mf.hits[0] = s->td.mf.hits[1];
00896 s->td.mf.hits[1] = s->td.mf.hits[2];
00897 s->td.mf.hits[2] = s->td.mf.hits[3];
00898 s->td.mf.hits[3] = s->td.mf.hits[4];
00899 s->td.mf.hits[4] = hit;
00900
00901
00902 if (squelch && hit) {
00903 if (mute.end < sample - MF_GSIZE) {
00904
00905 mute_fragment(dsp, &mute);
00906 mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
00907 }
00908 mute.end = limit + DTMF_GSIZE;
00909 }
00910
00911
00912 for (i = 0; i < 6; i++)
00913 goertzel_reset(&s->td.mf.tone_out[i]);
00914 s->td.mf.current_sample = 0;
00915 }
00916
00917 if (squelch && mute.end) {
00918 if (mute.end > samples) {
00919 s->td.mf.mute_samples = mute.end - samples;
00920 mute.end = samples;
00921 }
00922 mute_fragment(dsp, &mute);
00923 }
00924
00925 return (s->td.mf.current_hit);
00926 }
00927
00928 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
00929 {
00930
00931
00932 if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
00933 return 0;
00934
00935 i2 *= TONE_THRESH;
00936 i1 *= TONE_THRESH;
00937 e *= TONE_THRESH;
00938
00939 if ((p1 < i1) || (p1 < i2) || (p1 < e))
00940 return 0;
00941
00942 if ((p2 < i1) || (p2 < i2) || (p2 < e))
00943 return 0;
00944
00945 return 1;
00946 }
00947
00948 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
00949 {
00950 int x;
00951 int y;
00952 int pass;
00953 int newstate = DSP_TONE_STATE_SILENCE;
00954 int res = 0;
00955 while (len) {
00956
00957 pass = len;
00958 if (pass > dsp->gsamp_size - dsp->gsamps)
00959 pass = dsp->gsamp_size - dsp->gsamps;
00960 for (x=0;x<pass;x++) {
00961 for (y=0;y<dsp->freqcount;y++)
00962 goertzel_sample(&dsp->freqs[y], s[x]);
00963 dsp->genergy += s[x] * s[x];
00964 }
00965 s += pass;
00966 dsp->gsamps += pass;
00967 len -= pass;
00968 if (dsp->gsamps == dsp->gsamp_size) {
00969 float hz[7];
00970 for (y=0;y<7;y++)
00971 hz[y] = goertzel_result(&dsp->freqs[y]);
00972 switch (dsp->progmode) {
00973 case PROG_MODE_NA:
00974 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
00975 newstate = DSP_TONE_STATE_BUSY;
00976 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
00977 newstate = DSP_TONE_STATE_RINGING;
00978 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
00979 newstate = DSP_TONE_STATE_DIALTONE;
00980 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
00981 newstate = DSP_TONE_STATE_SPECIAL1;
00982 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
00983 if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
00984 newstate = DSP_TONE_STATE_SPECIAL2;
00985 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
00986 if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
00987 newstate = DSP_TONE_STATE_SPECIAL3;
00988 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
00989 newstate = DSP_TONE_STATE_TALKING;
00990 } else
00991 newstate = DSP_TONE_STATE_SILENCE;
00992 break;
00993 case PROG_MODE_CR:
00994 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
00995 newstate = DSP_TONE_STATE_RINGING;
00996 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
00997 newstate = DSP_TONE_STATE_TALKING;
00998 } else
00999 newstate = DSP_TONE_STATE_SILENCE;
01000 break;
01001 case PROG_MODE_UK:
01002 if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
01003 newstate = DSP_TONE_STATE_HUNGUP;
01004 }
01005 break;
01006 default:
01007 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01008 }
01009 if (newstate == dsp->tstate) {
01010 dsp->tcount++;
01011 if (dsp->ringtimeout)
01012 dsp->ringtimeout++;
01013 switch (dsp->tstate) {
01014 case DSP_TONE_STATE_RINGING:
01015 if ((dsp->features & DSP_PROGRESS_RINGING) &&
01016 (dsp->tcount==THRESH_RING)) {
01017 res = AST_CONTROL_RINGING;
01018 dsp->ringtimeout= 1;
01019 }
01020 break;
01021 case DSP_TONE_STATE_BUSY:
01022 if ((dsp->features & DSP_PROGRESS_BUSY) &&
01023 (dsp->tcount==THRESH_BUSY)) {
01024 res = AST_CONTROL_BUSY;
01025 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01026 }
01027 break;
01028 case DSP_TONE_STATE_TALKING:
01029 if ((dsp->features & DSP_PROGRESS_TALK) &&
01030 (dsp->tcount==THRESH_TALK)) {
01031 res = AST_CONTROL_ANSWER;
01032 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01033 }
01034 break;
01035 case DSP_TONE_STATE_SPECIAL3:
01036 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
01037 (dsp->tcount==THRESH_CONGESTION)) {
01038 res = AST_CONTROL_CONGESTION;
01039 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01040 }
01041 break;
01042 case DSP_TONE_STATE_HUNGUP:
01043 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
01044 (dsp->tcount==THRESH_HANGUP)) {
01045 res = AST_CONTROL_HANGUP;
01046 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01047 }
01048 break;
01049 }
01050 if (dsp->ringtimeout==THRESH_RING2ANSWER) {
01051 ast_debug(1, "Consider call as answered because of timeout after last ring\n");
01052 res = AST_CONTROL_ANSWER;
01053 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01054 }
01055 } else {
01056 ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
01057 ast_debug(5, "Start state %d\n", newstate);
01058 dsp->tstate = newstate;
01059 dsp->tcount = 1;
01060 }
01061
01062
01063 for (x=0;x<7;x++)
01064 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01065 dsp->gsamps = 0;
01066 dsp->genergy = 0.0;
01067 }
01068 }
01069
01070 return res;
01071 }
01072
01073 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01074 {
01075 if (inf->frametype != AST_FRAME_VOICE) {
01076 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01077 return 0;
01078 }
01079 if (inf->subclass != AST_FORMAT_SLINEAR) {
01080 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01081 return 0;
01082 }
01083 return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
01084 }
01085
01086 static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
01087 {
01088 int accum;
01089 int x;
01090 int res = 0;
01091
01092 if (!len)
01093 return 0;
01094 accum = 0;
01095 for (x=0;x<len; x++)
01096 accum += abs(s[x]);
01097 accum /= len;
01098 if (accum < dsp->threshold) {
01099
01100 dsp->totalsilence += len/8;
01101 if (dsp->totalnoise) {
01102
01103 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
01104 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01105
01106 #if 0
01107 dsp->busymaybe = 1;
01108 #endif
01109 }
01110 dsp->totalnoise = 0;
01111 res = 1;
01112 } else {
01113
01114 dsp->totalnoise += len/8;
01115 if (dsp->totalsilence) {
01116 int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01117 int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01118
01119 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
01120 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01121
01122 if (silence1 < silence2) {
01123 if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
01124 dsp->busymaybe = 1;
01125 else
01126 dsp->busymaybe = 0;
01127 } else {
01128 if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
01129 dsp->busymaybe = 1;
01130 else
01131 dsp->busymaybe = 0;
01132 }
01133 }
01134 dsp->totalsilence = 0;
01135 }
01136 if (totalsilence)
01137 *totalsilence = dsp->totalsilence;
01138 if (totalnoise)
01139 *totalnoise = dsp->totalnoise;
01140 return res;
01141 }
01142
01143 int ast_dsp_busydetect(struct ast_dsp *dsp)
01144 {
01145 int res = 0, x;
01146 #ifndef BUSYDETECT_TONEONLY
01147 int avgsilence = 0, hitsilence = 0;
01148 #endif
01149 int avgtone = 0, hittone = 0;
01150 if (!dsp->busymaybe)
01151 return res;
01152 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01153 #ifndef BUSYDETECT_TONEONLY
01154 avgsilence += dsp->historicsilence[x];
01155 #endif
01156 avgtone += dsp->historicnoise[x];
01157 }
01158 #ifndef BUSYDETECT_TONEONLY
01159 avgsilence /= dsp->busycount;
01160 #endif
01161 avgtone /= dsp->busycount;
01162 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01163 #ifndef BUSYDETECT_TONEONLY
01164 if (avgsilence > dsp->historicsilence[x]) {
01165 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01166 hitsilence++;
01167 } else {
01168 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01169 hitsilence++;
01170 }
01171 #endif
01172 if (avgtone > dsp->historicnoise[x]) {
01173 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01174 hittone++;
01175 } else {
01176 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01177 hittone++;
01178 }
01179 }
01180 #ifndef BUSYDETECT_TONEONLY
01181 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
01182 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
01183 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01184 #else
01185 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01186 #endif
01187 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01188 if (avgtone > avgsilence) {
01189 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01190 res = 1;
01191 } else {
01192 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01193 res = 1;
01194 }
01195 #else
01196 res = 1;
01197 #endif
01198 }
01199
01200 if (res && (dsp->busy_tonelength > 0)) {
01201 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
01202 #ifdef BUSYDETECT_DEBUG
01203 ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01204 avgtone, dsp->busy_tonelength);
01205 #endif
01206 res = 0;
01207 }
01208 }
01209 #ifndef BUSYDETECT_TONEONLY
01210
01211 if (res && (dsp->busy_quietlength > 0)) {
01212 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01213 #ifdef BUSYDETECT_DEBUG
01214 ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01215 avgsilence, dsp->busy_quietlength);
01216 #endif
01217 res = 0;
01218 }
01219 }
01220 #endif
01221 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
01222 if (res) {
01223 ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01224 } else {
01225 ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01226 }
01227 #endif
01228 return res;
01229 }
01230
01231 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01232 {
01233 short *s;
01234 int len;
01235
01236 if (f->frametype != AST_FRAME_VOICE) {
01237 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01238 return 0;
01239 }
01240 if (f->subclass != AST_FORMAT_SLINEAR) {
01241 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01242 return 0;
01243 }
01244 s = f->data.ptr;
01245 len = f->datalen/2;
01246 return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
01247 }
01248
01249 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
01250 {
01251 short *s;
01252 int len;
01253
01254 if (f->frametype != AST_FRAME_VOICE) {
01255 ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
01256 return 0;
01257 }
01258 if (f->subclass != AST_FORMAT_SLINEAR) {
01259 ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
01260 return 0;
01261 }
01262 s = f->data.ptr;
01263 len = f->datalen/2;
01264 return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
01265 }
01266
01267
01268 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01269 {
01270 int silence;
01271 int res;
01272 int digit = 0, fax_digit = 0;
01273 int x;
01274 short *shortdata;
01275 unsigned char *odata;
01276 int len;
01277 struct ast_frame *outf = NULL;
01278
01279 if (!af)
01280 return NULL;
01281 if (af->frametype != AST_FRAME_VOICE)
01282 return af;
01283
01284 odata = af->data.ptr;
01285 len = af->datalen;
01286
01287 switch (af->subclass) {
01288 case AST_FORMAT_SLINEAR:
01289 shortdata = af->data.ptr;
01290 len = af->datalen / 2;
01291 break;
01292 case AST_FORMAT_ULAW:
01293 shortdata = alloca(af->datalen * 2);
01294 for (x = 0;x < len; x++)
01295 shortdata[x] = AST_MULAW(odata[x]);
01296 break;
01297 case AST_FORMAT_ALAW:
01298 shortdata = alloca(af->datalen * 2);
01299 for (x = 0; x < len; x++)
01300 shortdata[x] = AST_ALAW(odata[x]);
01301 break;
01302 default:
01303 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01304 return af;
01305 }
01306
01307
01308 dsp->mute_fragments = 0;
01309
01310
01311 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01312 res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
01313 }
01314
01315 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01316 memset(&dsp->f, 0, sizeof(dsp->f));
01317 dsp->f.frametype = AST_FRAME_NULL;
01318 ast_frfree(af);
01319 return ast_frisolate(&dsp->f);
01320 }
01321 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01322 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01323 memset(&dsp->f, 0, sizeof(dsp->f));
01324 dsp->f.frametype = AST_FRAME_CONTROL;
01325 dsp->f.subclass = AST_CONTROL_BUSY;
01326 ast_frfree(af);
01327 ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01328 return ast_frisolate(&dsp->f);
01329 }
01330
01331 if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01332 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01333 fax_digit = 'f';
01334 }
01335
01336 if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01337 fax_digit = 'e';
01338 }
01339 }
01340
01341 if ((dsp->features & DSP_FEATURE_DIGIT_DETECT)) {
01342 if ((dsp->digitmode & DSP_DIGITMODE_MF))
01343 digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01344 else
01345 digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01346
01347 if (dsp->digit_state.current_digits) {
01348 int event = 0;
01349 char event_digit = 0;
01350
01351 if (!dsp->dtmf_began) {
01352
01353
01354 event = AST_FRAME_DTMF_BEGIN;
01355 event_digit = dsp->digit_state.digits[0];
01356 dsp->dtmf_began = 1;
01357
01358 } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01359
01360
01361 event = AST_FRAME_DTMF_END;
01362 event_digit = dsp->digit_state.digits[0];
01363 memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits);
01364 dsp->digit_state.current_digits--;
01365 dsp->dtmf_began = 0;
01366 }
01367
01368 if (event) {
01369 memset(&dsp->f, 0, sizeof(dsp->f));
01370 dsp->f.frametype = event;
01371 dsp->f.subclass = event_digit;
01372 outf = &dsp->f;
01373 goto done;
01374 }
01375 }
01376 }
01377
01378 if (fax_digit) {
01379
01380
01381 memset(&dsp->f, 0, sizeof(dsp->f));
01382 dsp->f.frametype = AST_FRAME_DTMF;
01383 dsp->f.subclass = fax_digit;
01384 outf = &dsp->f;
01385 goto done;
01386 }
01387
01388 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01389 res = __ast_dsp_call_progress(dsp, shortdata, len);
01390 if (res) {
01391 switch (res) {
01392 case AST_CONTROL_ANSWER:
01393 case AST_CONTROL_BUSY:
01394 case AST_CONTROL_RINGING:
01395 case AST_CONTROL_CONGESTION:
01396 case AST_CONTROL_HANGUP:
01397 memset(&dsp->f, 0, sizeof(dsp->f));
01398 dsp->f.frametype = AST_FRAME_CONTROL;
01399 dsp->f.subclass = res;
01400 dsp->f.src = "dsp_progress";
01401 if (chan)
01402 ast_queue_frame(chan, &dsp->f);
01403 break;
01404 default:
01405 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01406 }
01407 }
01408 }
01409
01410 done:
01411
01412 for (x = 0; x < dsp->mute_fragments; x++) {
01413 memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01414 }
01415
01416 switch (af->subclass) {
01417 case AST_FORMAT_SLINEAR:
01418 break;
01419 case AST_FORMAT_ULAW:
01420 for (x = 0; x < len; x++)
01421 odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01422 break;
01423 case AST_FORMAT_ALAW:
01424 for (x = 0; x < len; x++)
01425 odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01426 break;
01427 }
01428
01429 if (outf) {
01430 if (chan)
01431 ast_queue_frame(chan, af);
01432 ast_frfree(af);
01433 return ast_frisolate(outf);
01434 } else {
01435 return af;
01436 }
01437 }
01438
01439 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01440 {
01441 int max = 0;
01442 int x;
01443
01444 dsp->gsamp_size = modes[dsp->progmode].size;
01445 dsp->gsamps = 0;
01446 for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
01447 if (modes[dsp->progmode].freqs[x]) {
01448 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01449 max = x + 1;
01450 }
01451 }
01452 dsp->freqcount = max;
01453 dsp->ringtimeout= 0;
01454 }
01455
01456 struct ast_dsp *ast_dsp_new(void)
01457 {
01458 struct ast_dsp *dsp;
01459
01460 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
01461 dsp->threshold = DEFAULT_THRESHOLD;
01462 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01463 dsp->busycount = DSP_HISTORY;
01464 dsp->digitmode = DSP_DIGITMODE_DTMF;
01465 dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01466
01467 ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01468
01469 ast_dsp_prog_reset(dsp);
01470
01471 ast_fax_detect_init(dsp);
01472 }
01473 return dsp;
01474 }
01475
01476 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01477 {
01478 dsp->features = features;
01479 }
01480
01481 void ast_dsp_free(struct ast_dsp *dsp)
01482 {
01483 ast_free(dsp);
01484 }
01485
01486 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01487 {
01488 dsp->threshold = threshold;
01489 }
01490
01491 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01492 {
01493 if (cadences < 4)
01494 cadences = 4;
01495 if (cadences > DSP_HISTORY)
01496 cadences = DSP_HISTORY;
01497 dsp->busycount = cadences;
01498 }
01499
01500 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
01501 {
01502 dsp->busy_tonelength = tonelength;
01503 dsp->busy_quietlength = quietlength;
01504 ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01505 }
01506
01507 void ast_dsp_digitreset(struct ast_dsp *dsp)
01508 {
01509 int i;
01510
01511 dsp->dtmf_began = 0;
01512 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01513 mf_detect_state_t *s = &dsp->digit_state.td.mf;
01514
01515 for (i = 0; i < 6; i++) {
01516 goertzel_reset(&s->tone_out[i]);
01517 }
01518 s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01519 s->current_sample = 0;
01520 } else {
01521 dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01522
01523 for (i = 0; i < 4; i++) {
01524 goertzel_reset(&s->row_out[i]);
01525 goertzel_reset(&s->col_out[i]);
01526 }
01527 s->lasthit = s->current_hit = 0;
01528 s->energy = 0.0;
01529 s->current_sample = 0;
01530 s->hits = 0;
01531 s->misses = 0;
01532 }
01533
01534 dsp->digit_state.digits[0] = '\0';
01535 dsp->digit_state.current_digits = 0;
01536 }
01537
01538 void ast_dsp_reset(struct ast_dsp *dsp)
01539 {
01540 int x;
01541
01542 dsp->totalsilence = 0;
01543 dsp->gsamps = 0;
01544 for (x=0;x<4;x++)
01545 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01546 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01547 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01548 dsp->ringtimeout= 0;
01549 }
01550
01551 int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
01552 {
01553 int new;
01554 int old;
01555
01556 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01557 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01558 if (old != new) {
01559
01560 ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01561 }
01562 dsp->digitmode = digitmode;
01563 return 0;
01564 }
01565
01566 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
01567 {
01568 if (dsp->faxmode != faxmode) {
01569 ast_fax_detect_init(dsp);
01570 }
01571 dsp->faxmode = faxmode;
01572 return 0;
01573 }
01574
01575 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01576 {
01577 int x;
01578
01579 for (x = 0; x < ARRAY_LEN(aliases); x++) {
01580 if (!strcasecmp(aliases[x].name, zone)) {
01581 dsp->progmode = aliases[x].mode;
01582 ast_dsp_prog_reset(dsp);
01583 return 0;
01584 }
01585 }
01586 return -1;
01587 }
01588
01589 int ast_dsp_was_muted(struct ast_dsp *dsp)
01590 {
01591 return (dsp->mute_fragments > 0);
01592 }
01593
01594 int ast_dsp_get_tstate(struct ast_dsp *dsp)
01595 {
01596 return dsp->tstate;
01597 }
01598
01599 int ast_dsp_get_tcount(struct ast_dsp *dsp)
01600 {
01601 return dsp->tcount;
01602 }
01603
01604 static int _dsp_init(int reload)
01605 {
01606 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01607 struct ast_config *cfg;
01608
01609 cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags);
01610
01611 if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED) {
01612 const char *value;
01613
01614 value = ast_variable_retrieve(cfg, "default", "silencethreshold");
01615 if (value && sscanf(value, "%30d", &thresholds[THRESHOLD_SILENCE]) != 1) {
01616 ast_log(LOG_WARNING, "%s: '%s' is not a valid silencethreshold value\n", CONFIG_FILE_NAME, value);
01617 thresholds[THRESHOLD_SILENCE] = 256;
01618 } else if (!value)
01619 thresholds[THRESHOLD_SILENCE] = 256;
01620
01621 ast_config_destroy(cfg);
01622 }
01623 return 0;
01624 }
01625
01626 int ast_dsp_get_threshold_from_settings(enum threshold which)
01627 {
01628 return thresholds[which];
01629 }
01630
01631 int ast_dsp_init(void)
01632 {
01633 return _dsp_init(0);
01634 }
01635
01636 int ast_dsp_reload(void)
01637 {
01638 return _dsp_init(1);
01639 }
01640