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: 233014 $")
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 for (x=0;x<pass;x++) {
01088 for (y=0;y<dsp->freqcount;y++)
01089 goertzel_sample(&dsp->freqs[y], s[x]);
01090 dsp->genergy += s[x] * s[x];
01091 }
01092 s += pass;
01093 dsp->gsamps += pass;
01094 len -= pass;
01095 if (dsp->gsamps == dsp->gsamp_size) {
01096 float hz[7];
01097 for (y=0;y<7;y++)
01098 hz[y] = goertzel_result(&dsp->freqs[y]);
01099 #if 0
01100 printf("\n350: 425: 440: 480: 620: 950: 1400: 1800: Energy: \n");
01101 printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n",
01102 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);
01103 #endif
01104 switch(dsp->progmode) {
01105 case PROG_MODE_NA:
01106 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
01107 newstate = DSP_TONE_STATE_BUSY;
01108 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01109 newstate = DSP_TONE_STATE_RINGING;
01110 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01111 newstate = DSP_TONE_STATE_DIALTONE;
01112 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01113 newstate = DSP_TONE_STATE_SPECIAL1;
01114 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01115 if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
01116 newstate = DSP_TONE_STATE_SPECIAL2;
01117 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01118 if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
01119 newstate = DSP_TONE_STATE_SPECIAL3;
01120 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01121 newstate = DSP_TONE_STATE_TALKING;
01122 } else
01123 newstate = DSP_TONE_STATE_SILENCE;
01124 break;
01125 case PROG_MODE_CR:
01126 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01127 newstate = DSP_TONE_STATE_RINGING;
01128 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01129 newstate = DSP_TONE_STATE_TALKING;
01130 } else
01131 newstate = DSP_TONE_STATE_SILENCE;
01132 break;
01133 case PROG_MODE_UK:
01134 if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
01135 newstate = DSP_TONE_STATE_HUNGUP;
01136 }
01137 break;
01138 default:
01139 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01140 }
01141 if (newstate == dsp->tstate) {
01142 dsp->tcount++;
01143 if (dsp->ringtimeout)
01144 dsp->ringtimeout++;
01145 switch (dsp->tstate) {
01146 case DSP_TONE_STATE_RINGING:
01147 if ((dsp->features & DSP_PROGRESS_RINGING) &&
01148 (dsp->tcount==THRESH_RING)) {
01149 res = AST_CONTROL_RINGING;
01150 dsp->ringtimeout= 1;
01151 }
01152 break;
01153 case DSP_TONE_STATE_BUSY:
01154 if ((dsp->features & DSP_PROGRESS_BUSY) &&
01155 (dsp->tcount==THRESH_BUSY)) {
01156 res = AST_CONTROL_BUSY;
01157 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01158 }
01159 break;
01160 case DSP_TONE_STATE_TALKING:
01161 if ((dsp->features & DSP_PROGRESS_TALK) &&
01162 (dsp->tcount==THRESH_TALK)) {
01163 res = AST_CONTROL_ANSWER;
01164 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01165 }
01166 break;
01167 case DSP_TONE_STATE_SPECIAL3:
01168 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
01169 (dsp->tcount==THRESH_CONGESTION)) {
01170 res = AST_CONTROL_CONGESTION;
01171 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01172 }
01173 break;
01174 case DSP_TONE_STATE_HUNGUP:
01175 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
01176 (dsp->tcount==THRESH_HANGUP)) {
01177 res = AST_CONTROL_HANGUP;
01178 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01179 }
01180 break;
01181 }
01182 if (dsp->ringtimeout==THRESH_RING2ANSWER) {
01183 #if 0
01184 ast_log(LOG_NOTICE, "Consider call as answered because of timeout after last ring\n");
01185 #endif
01186 res = AST_CONTROL_ANSWER;
01187 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01188 }
01189 } else {
01190 #if 0
01191 ast_log(LOG_NOTICE, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
01192 ast_log(LOG_NOTICE, "Start state %d\n", newstate);
01193 #endif
01194 dsp->tstate = newstate;
01195 dsp->tcount = 1;
01196 }
01197
01198
01199 for (x=0;x<7;x++)
01200 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01201 dsp->gsamps = 0;
01202 dsp->genergy = 0.0;
01203 }
01204 }
01205 #if 0
01206 if (res)
01207 printf("Returning %d\n", res);
01208 #endif
01209 return res;
01210 }
01211
01212 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01213 {
01214 if (inf->frametype != AST_FRAME_VOICE) {
01215 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01216 return 0;
01217 }
01218 if (inf->subclass != AST_FORMAT_SLINEAR) {
01219 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01220 return 0;
01221 }
01222 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01223 }
01224
01225 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
01226 {
01227 int accum;
01228 int x;
01229 int res = 0;
01230
01231 if (!len)
01232 return 0;
01233 accum = 0;
01234 for (x=0;x<len; x++)
01235 accum += abs(s[x]);
01236 accum /= len;
01237 if (accum < dsp->threshold) {
01238
01239 dsp->totalsilence += len/8;
01240 #ifdef DEBUG_DSP_BUSYDETECT
01241 fprintf(stderr, "SILENCE: len = %d, level = %d\n", dsp->totalsilence, accum);
01242 #endif
01243 if (dsp->totalnoise) {
01244
01245 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1)*sizeof(dsp->historicnoise[0]));
01246 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01247
01248 int tone1 = dsp->historicnoise[DSP_HISTORY - 1];
01249 int tone2 = dsp->historicnoise[DSP_HISTORY - 2];
01250 if (tone1 < tone2) {
01251 if ((tone1 + tone1*BUSY_PERCENT/100) >= tone2)
01252 dsp->busymaybe = 1;
01253 else
01254 dsp->busymaybe = 0;
01255 } else {
01256 if ((tone1 - tone1*BUSY_PERCENT/100) <= tone2)
01257 dsp->busymaybe = 1;
01258 else
01259 dsp->busymaybe = 0;
01260 }
01261 }
01262 dsp->totalnoise = 0;
01263 res = 1;
01264 } else {
01265
01266 dsp->totalnoise += len/8;
01267 #ifdef DEBUG_DSP_BUSYDETECT
01268 fprintf(stderr, "NOISE: len = %d, level = %d\n", dsp->totalnoise, accum);
01269 #endif
01270 if (dsp->totalsilence) {
01271
01272 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1)*sizeof(dsp->historicsilence[0]));
01273 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01274 }
01275 dsp->totalsilence = 0;
01276 }
01277 if (totalsilence)
01278 *totalsilence = dsp->totalsilence;
01279 return res;
01280 }
01281
01282 #ifdef BUSYDETECT_MARTIN
01283 int ast_dsp_busydetect(struct ast_dsp *dsp)
01284 {
01285 int res = 0, x;
01286 int avgsilence = 0, hitsilence = 0;
01287 int avgtone = 0, hittone = 0;
01288 #ifdef DEBUG_DSP_BUSYDETECT
01289 char buf[16];
01290 char silence_list[64]="", tone_list[64]="";
01291 #endif
01292
01293 if (!dsp->busymaybe)
01294 return res;
01295 dsp->busymaybe = 0;
01296
01297 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01298 avgsilence += dsp->historicsilence[x];
01299 avgtone += dsp->historicnoise[x];
01300 }
01301 avgsilence /= dsp->busycount;
01302 avgtone /= dsp->busycount;
01303 #ifdef DEBUG_DSP_BUSYDETECT
01304 sprintf(silence_list,"Silences: ");
01305 sprintf(tone_list,"Tones: ");
01306 #endif
01307 for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) {
01308 #ifdef DEBUG_DSP_BUSYDETECT
01309 snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]);
01310 strcat(silence_list, buf);
01311 snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]);
01312 strcat(tone_list, buf);
01313 #endif
01314 if (!dsp->busytoneonly) {
01315 if (avgsilence > dsp->historicsilence[x]) {
01316 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01317 hitsilence++;
01318 } else {
01319 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01320 hitsilence++;
01321 }
01322 }
01323 if (avgtone > dsp->historicnoise[x]) {
01324 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01325 hittone++;
01326 } else {
01327 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01328 hittone++;
01329 }
01330 }
01331 #ifdef DEBUG_DSP_BUSYDETECT
01332 fprintf(stderr, "BUSY DETECTOR\n");
01333 fprintf(stderr, "%s\n", tone_list);
01334 fprintf(stderr, "%s\n", silence_list)
01335 #endif
01336 if ((dsp->busytoneonly ||
01337 (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) &&
01338 (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01339 if (dsp->busycompare) {
01340 if (dsp->busytoneonly) {
01341 res = 1;
01342 ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare");
01343 } else {
01344 if (avgtone > avgsilence) {
01345 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01346 res = 1;
01347 } else {
01348 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01349 res = 1;
01350 }
01351 }
01352 } else {
01353 res = 1;
01354 }
01355 }
01356
01357 if (res && (dsp->busy_tonelength > 0)) {
01358 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100)) {
01359 if(option_debug) {
01360 ast_log(LOG_DEBUG, "busy detector: avgtone of %d not close enough to desired %d\n", avgtone, dsp->busy_tonelength);
01361 }
01362 res = 0;
01363 }
01364 }
01365
01366 if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) {
01367 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100)) {
01368 if(option_debug) {
01369 ast_log(LOG_DEBUG, "busy detector: avgsilence of %d not close enough to desired %d\n", avgsilence, dsp->busy_quietlength);
01370 }
01371 res = 0;
01372 }
01373 }
01374 if (res && option_debug)
01375 ast_log(LOG_NOTICE, "Detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01376 return res;
01377 }
01378 #endif
01379
01380 #ifdef BUSYDETECT
01381 int ast_dsp_busydetect(struct ast_dsp *dsp)
01382 {
01383 int x;
01384 int res = 0;
01385 int max, min;
01386
01387 #if 0
01388 if (dsp->busy_hits > 5);
01389 return 0;
01390 #endif
01391 if (dsp->busymaybe) {
01392 #if 0
01393 printf("Maybe busy!\n");
01394 #endif
01395 dsp->busymaybe = 0;
01396 min = 9999;
01397 max = 0;
01398 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01399 #if 0
01400 printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
01401 #endif
01402 if (dsp->historicsilence[x] < min)
01403 min = dsp->historicsilence[x];
01404 if (dsp->historicnoise[x] < min)
01405 min = dsp->historicnoise[x];
01406 if (dsp->historicsilence[x] > max)
01407 max = dsp->historicsilence[x];
01408 if (dsp->historicnoise[x] > max)
01409 max = dsp->historicnoise[x];
01410 }
01411 if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
01412 #if 0
01413 printf("Busy!\n");
01414 #endif
01415 res = 1;
01416 }
01417 #if 0
01418 printf("Min: %d, max: %d\n", min, max);
01419 #endif
01420 }
01421 return res;
01422 }
01423 #endif
01424
01425 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01426 {
01427 short *s;
01428 int len;
01429
01430 if (f->frametype != AST_FRAME_VOICE) {
01431 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01432 return 0;
01433 }
01434 if (f->subclass != AST_FORMAT_SLINEAR) {
01435 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01436 return 0;
01437 }
01438 s = f->data;
01439 len = f->datalen/2;
01440 return __ast_dsp_silence(dsp, s, len, totalsilence);
01441 }
01442
01443 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01444 {
01445 int silence;
01446 int res;
01447 int digit;
01448 int x;
01449 short *shortdata;
01450 unsigned char *odata;
01451 int len;
01452 int writeback = 0;
01453
01454 #define FIX_INF(inf) do { \
01455 if (writeback) { \
01456 switch(inf->subclass) { \
01457 case AST_FORMAT_SLINEAR: \
01458 break; \
01459 case AST_FORMAT_ULAW: \
01460 for (x=0;x<len;x++) \
01461 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01462 break; \
01463 case AST_FORMAT_ALAW: \
01464 for (x=0;x<len;x++) \
01465 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01466 break; \
01467 } \
01468 } \
01469 } while(0)
01470
01471 if (!af)
01472 return NULL;
01473 if (af->frametype != AST_FRAME_VOICE)
01474 return af;
01475 odata = af->data;
01476 len = af->datalen;
01477
01478 switch(af->subclass) {
01479 case AST_FORMAT_SLINEAR:
01480 shortdata = af->data;
01481 len = af->datalen / 2;
01482 break;
01483 case AST_FORMAT_ULAW:
01484 shortdata = alloca(af->datalen * 2);
01485 for (x = 0;x < len; x++)
01486 shortdata[x] = AST_MULAW(odata[x]);
01487 break;
01488 case AST_FORMAT_ALAW:
01489 shortdata = alloca(af->datalen * 2);
01490 for (x = 0; x < len; x++)
01491 shortdata[x] = AST_ALAW(odata[x]);
01492 break;
01493 default:
01494
01495 if (dsp->display_inband_dtmf_warning)
01496 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01497 dsp->display_inband_dtmf_warning = 0;
01498 return af;
01499 }
01500 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01501 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01502 memset(&dsp->f, 0, sizeof(dsp->f));
01503 dsp->f.frametype = AST_FRAME_NULL;
01504 ast_frfree(af);
01505 return ast_frisolate(&dsp->f);
01506 }
01507 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01508 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01509 memset(&dsp->f, 0, sizeof(dsp->f));
01510 dsp->f.frametype = AST_FRAME_CONTROL;
01511 dsp->f.subclass = AST_CONTROL_BUSY;
01512 ast_frfree(af);
01513 return ast_frisolate(&dsp->f);
01514 }
01515 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01516 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01517 #if 0
01518 if (digit)
01519 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01520 #endif
01521 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01522 if (!dsp->thinkdigit) {
01523 if (digit) {
01524
01525
01526 memset(&dsp->f, 0, sizeof(dsp->f));
01527 dsp->f.frametype = AST_FRAME_DTMF;
01528 dsp->f.subclass = 'm';
01529 dsp->thinkdigit = 'x';
01530 FIX_INF(af);
01531 if (chan)
01532 ast_queue_frame(chan, af);
01533 ast_frfree(af);
01534 return ast_frisolate(&dsp->f);
01535 }
01536 } else {
01537 if (digit) {
01538
01539 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01540
01541
01542
01543 memset(&dsp->f, 0, sizeof(dsp->f));
01544 dsp->f.frametype = AST_FRAME_DTMF_END;
01545 dsp->f.subclass = dsp->thinkdigit;
01546 FIX_INF(af);
01547 if (chan)
01548 ast_queue_frame(chan, af);
01549 ast_frfree(af);
01550 } else {
01551 dsp->thinkdigit = digit;
01552 memset(&dsp->f, 0, sizeof(dsp->f));
01553 dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
01554 dsp->f.subclass = dsp->thinkdigit;
01555 FIX_INF(af);
01556 if (chan)
01557 ast_queue_frame(chan, af);
01558 ast_frfree(af);
01559 }
01560 return ast_frisolate(&dsp->f);
01561 } else {
01562 memset(&dsp->f, 0, sizeof(dsp->f));
01563 if (dsp->thinkdigit != 'x') {
01564
01565 dsp->f.frametype = AST_FRAME_DTMF_END;
01566 dsp->f.subclass = dsp->thinkdigit;
01567 dsp->thinkdigit = 0;
01568 } else {
01569 dsp->f.frametype = AST_FRAME_DTMF;
01570 dsp->f.subclass = 'u';
01571 dsp->thinkdigit = 0;
01572 }
01573 FIX_INF(af);
01574 if (chan)
01575 ast_queue_frame(chan, af);
01576 ast_frfree(af);
01577 return ast_frisolate(&dsp->f);
01578 }
01579 }
01580 } else if (!digit) {
01581
01582 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01583 if (dsp->td.mf.current_digits) {
01584 memset(&dsp->f, 0, sizeof(dsp->f));
01585 dsp->f.frametype = AST_FRAME_DTMF;
01586 dsp->f.subclass = dsp->td.mf.digits[0];
01587 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01588 dsp->td.mf.current_digits--;
01589 FIX_INF(af);
01590 if (chan)
01591 ast_queue_frame(chan, af);
01592 ast_frfree(af);
01593 return ast_frisolate(&dsp->f);
01594 }
01595 } else {
01596 if (dsp->td.dtmf.current_digits) {
01597 memset(&dsp->f, 0, sizeof(dsp->f));
01598 dsp->f.frametype = AST_FRAME_DTMF_END;
01599 dsp->f.subclass = dsp->td.dtmf.digits[0];
01600 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01601 dsp->td.dtmf.current_digits--;
01602 FIX_INF(af);
01603 if (chan)
01604 ast_queue_frame(chan, af);
01605 ast_frfree(af);
01606 return ast_frisolate(&dsp->f);
01607 }
01608 }
01609 }
01610 }
01611 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01612 res = __ast_dsp_call_progress(dsp, shortdata, len);
01613 if (res) {
01614 switch(res) {
01615 case AST_CONTROL_ANSWER:
01616 case AST_CONTROL_BUSY:
01617 case AST_CONTROL_RINGING:
01618 case AST_CONTROL_CONGESTION:
01619 case AST_CONTROL_HANGUP:
01620 memset(&dsp->f, 0, sizeof(dsp->f));
01621 dsp->f.frametype = AST_FRAME_CONTROL;
01622 dsp->f.subclass = res;
01623 dsp->f.src = "dsp_progress";
01624 if (chan)
01625 ast_queue_frame(chan, &dsp->f);
01626 break;
01627 default:
01628 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01629 }
01630 }
01631 }
01632 FIX_INF(af);
01633 return af;
01634 }
01635
01636 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01637 {
01638 int max = 0;
01639 int x;
01640
01641 dsp->gsamp_size = modes[dsp->progmode].size;
01642 dsp->gsamps = 0;
01643 for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
01644 if (modes[dsp->progmode].freqs[x]) {
01645 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01646 max = x + 1;
01647 }
01648 }
01649 dsp->freqcount = max;
01650 dsp->ringtimeout= 0;
01651 }
01652
01653 struct ast_dsp *ast_dsp_new(void)
01654 {
01655 struct ast_dsp *dsp;
01656
01657 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
01658 dsp->threshold = DEFAULT_THRESHOLD;
01659 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01660 dsp->busycount = DSP_HISTORY;
01661 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT;
01662 #ifdef BUSYDETECT_TONEONLY
01663 dsp->busytoneonly = 1;
01664 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01665 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
01666 #endif
01667 #else
01668 dsp->busytoneonly = 0;
01669 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01670 dsp->busycompare = 1;
01671 #else
01672 dsp->busycompare = 0;
01673 #endif
01674 #endif
01675 dsp->display_inband_dtmf_warning = 1;
01676
01677 ast_dtmf_detect_init(&dsp->td.dtmf);
01678
01679 ast_dsp_prog_reset(dsp);
01680 }
01681 return dsp;
01682 }
01683
01684 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01685 {
01686 dsp->features = features;
01687 }
01688
01689 void ast_dsp_free(struct ast_dsp *dsp)
01690 {
01691 free(dsp);
01692 }
01693
01694 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01695 {
01696 if (threshold < 256)
01697 dsp->threshold = 256;
01698 else
01699 dsp->threshold = threshold;
01700 }
01701
01702 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01703 {
01704 if (cadences < 4)
01705 cadences = 4;
01706 if (cadences > DSP_HISTORY)
01707 cadences = DSP_HISTORY;
01708 dsp->busycount = cadences;
01709 }
01710
01711 void ast_dsp_set_busy_compare(struct ast_dsp *dsp, int compare)
01712 {
01713 if (compare > 0)
01714 dsp->busycompare = 1;
01715 else
01716 dsp->busycompare = 0;
01717 }
01718
01719 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength, int fuzzy)
01720 {
01721 dsp->busy_tonelength = tonelength;
01722 if (quietlength > 0)
01723 dsp->busy_quietlength = quietlength;
01724 else
01725 dsp->busytoneonly = 1;
01726 ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01727 if( fuzzy > 0 && fuzzy < 50 )
01728 dsp->busy_pattern_fuzzy = fuzzy;
01729 }
01730
01731 void ast_dsp_digitreset(struct ast_dsp *dsp)
01732 {
01733 int i;
01734
01735 dsp->thinkdigit = 0;
01736 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01737 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01738 dsp->td.mf.current_digits = 0;
01739
01740 for (i = 0; i < 6; i++) {
01741 goertzel_reset(&dsp->td.mf.tone_out[i]);
01742 #ifdef OLD_DSP_ROUTINES
01743 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01744 #endif
01745 }
01746 #ifdef OLD_DSP_ROUTINES
01747 dsp->td.mf.energy = 0.0;
01748 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01749 #else
01750 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;
01751 #endif
01752 dsp->td.mf.current_sample = 0;
01753 } else {
01754 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01755 dsp->td.dtmf.current_digits = 0;
01756
01757 for (i = 0; i < 4; i++) {
01758 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01759 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01760 #ifdef OLD_DSP_ROUTINES
01761 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01762 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01763 #endif
01764 }
01765 #ifdef FAX_DETECT
01766 goertzel_reset (&dsp->td.dtmf.fax_tone);
01767 #endif
01768 #ifdef OLD_DSP_ROUTINES
01769 #ifdef FAX_DETECT
01770 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01771 #endif
01772 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01773 #else
01774 dsp->td.dtmf.lasthit = dsp->td.dtmf.mhit = 0;
01775 #endif
01776 dsp->td.dtmf.energy = 0.0;
01777 dsp->td.dtmf.current_sample = 0;
01778 }
01779 }
01780
01781 void ast_dsp_reset(struct ast_dsp *dsp)
01782 {
01783 int x;
01784
01785 dsp->totalsilence = 0;
01786 dsp->gsamps = 0;
01787 for (x=0;x<4;x++)
01788 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01789 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01790 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01791 dsp->ringtimeout= 0;
01792 }
01793
01794 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01795 {
01796 int new;
01797 int old;
01798
01799 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01800 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01801 if (old != new) {
01802
01803 if (new & DSP_DIGITMODE_MF)
01804 ast_mf_detect_init(&dsp->td.mf);
01805 else
01806 ast_dtmf_detect_init(&dsp->td.dtmf);
01807 }
01808 dsp->digitmode = digitmode;
01809 return 0;
01810 }
01811
01812 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01813 {
01814 int x;
01815
01816 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01817 if (!strcasecmp(aliases[x].name, zone)) {
01818 dsp->progmode = aliases[x].mode;
01819 ast_dsp_prog_reset(dsp);
01820 return 0;
01821 }
01822 }
01823 return -1;
01824 }
01825
01826 int ast_dsp_get_tstate(struct ast_dsp *dsp)
01827 {
01828 return dsp->tstate;
01829 }
01830
01831 int ast_dsp_get_tcount(struct ast_dsp *dsp)
01832 {
01833 return dsp->tcount;
01834 }