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