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