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: 224931 $")
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 return ast_frisolate(&dsp->f);
01502 }
01503 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01504 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01505 memset(&dsp->f, 0, sizeof(dsp->f));
01506 dsp->f.frametype = AST_FRAME_CONTROL;
01507 dsp->f.subclass = AST_CONTROL_BUSY;
01508 ast_frfree(af);
01509 return ast_frisolate(&dsp->f);
01510 }
01511 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01512 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01513 #if 0
01514 if (digit)
01515 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01516 #endif
01517 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01518 if (!dsp->thinkdigit) {
01519 if (digit) {
01520
01521
01522 memset(&dsp->f, 0, sizeof(dsp->f));
01523 dsp->f.frametype = AST_FRAME_DTMF;
01524 dsp->f.subclass = 'm';
01525 dsp->thinkdigit = 'x';
01526 FIX_INF(af);
01527 if (chan)
01528 ast_queue_frame(chan, af);
01529 ast_frfree(af);
01530 return ast_frisolate(&dsp->f);
01531 }
01532 } else {
01533 if (digit) {
01534
01535 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01536
01537
01538
01539 memset(&dsp->f, 0, sizeof(dsp->f));
01540 dsp->f.frametype = AST_FRAME_DTMF_END;
01541 dsp->f.subclass = dsp->thinkdigit;
01542 FIX_INF(af);
01543 if (chan)
01544 ast_queue_frame(chan, af);
01545 ast_frfree(af);
01546 } else {
01547 dsp->thinkdigit = digit;
01548 memset(&dsp->f, 0, sizeof(dsp->f));
01549 dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
01550 dsp->f.subclass = dsp->thinkdigit;
01551 FIX_INF(af);
01552 if (chan)
01553 ast_queue_frame(chan, af);
01554 ast_frfree(af);
01555 }
01556 return ast_frisolate(&dsp->f);
01557 } else {
01558 memset(&dsp->f, 0, sizeof(dsp->f));
01559 if (dsp->thinkdigit != 'x') {
01560
01561 dsp->f.frametype = AST_FRAME_DTMF_END;
01562 dsp->f.subclass = dsp->thinkdigit;
01563 dsp->thinkdigit = 0;
01564 } else {
01565 dsp->f.frametype = AST_FRAME_DTMF;
01566 dsp->f.subclass = 'u';
01567 dsp->thinkdigit = 0;
01568 }
01569 FIX_INF(af);
01570 if (chan)
01571 ast_queue_frame(chan, af);
01572 ast_frfree(af);
01573 return ast_frisolate(&dsp->f);
01574 }
01575 }
01576 } else if (!digit) {
01577
01578 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01579 if (dsp->td.mf.current_digits) {
01580 memset(&dsp->f, 0, sizeof(dsp->f));
01581 dsp->f.frametype = AST_FRAME_DTMF;
01582 dsp->f.subclass = dsp->td.mf.digits[0];
01583 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01584 dsp->td.mf.current_digits--;
01585 FIX_INF(af);
01586 if (chan)
01587 ast_queue_frame(chan, af);
01588 ast_frfree(af);
01589 return ast_frisolate(&dsp->f);
01590 }
01591 } else {
01592 if (dsp->td.dtmf.current_digits) {
01593 memset(&dsp->f, 0, sizeof(dsp->f));
01594 dsp->f.frametype = AST_FRAME_DTMF_END;
01595 dsp->f.subclass = dsp->td.dtmf.digits[0];
01596 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01597 dsp->td.dtmf.current_digits--;
01598 FIX_INF(af);
01599 if (chan)
01600 ast_queue_frame(chan, af);
01601 ast_frfree(af);
01602 return ast_frisolate(&dsp->f);
01603 }
01604 }
01605 }
01606 }
01607 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01608 res = __ast_dsp_call_progress(dsp, shortdata, len);
01609 if (res) {
01610 switch(res) {
01611 case AST_CONTROL_ANSWER:
01612 case AST_CONTROL_BUSY:
01613 case AST_CONTROL_RINGING:
01614 case AST_CONTROL_CONGESTION:
01615 case AST_CONTROL_HANGUP:
01616 memset(&dsp->f, 0, sizeof(dsp->f));
01617 dsp->f.frametype = AST_FRAME_CONTROL;
01618 dsp->f.subclass = res;
01619 dsp->f.src = "dsp_progress";
01620 if (chan)
01621 ast_queue_frame(chan, &dsp->f);
01622 break;
01623 default:
01624 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01625 }
01626 }
01627 }
01628 FIX_INF(af);
01629 return af;
01630 }
01631
01632 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01633 {
01634 int max = 0;
01635 int x;
01636
01637 dsp->gsamp_size = modes[dsp->progmode].size;
01638 dsp->gsamps = 0;
01639 for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
01640 if (modes[dsp->progmode].freqs[x]) {
01641 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01642 max = x + 1;
01643 }
01644 }
01645 dsp->freqcount = max;
01646 dsp->ringtimeout= 0;
01647 }
01648
01649 struct ast_dsp *ast_dsp_new(void)
01650 {
01651 struct ast_dsp *dsp;
01652
01653 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
01654 dsp->threshold = DEFAULT_THRESHOLD;
01655 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01656 dsp->busycount = DSP_HISTORY;
01657 dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT;
01658 #ifdef BUSYDETECT_TONEONLY
01659 dsp->busytoneonly = 1;
01660 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01661 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
01662 #endif
01663 #else
01664 dsp->busytoneonly = 0;
01665 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01666 dsp->busycompare = 1;
01667 #else
01668 dsp->busycompare = 0;
01669 #endif
01670 #endif
01671
01672 ast_dtmf_detect_init(&dsp->td.dtmf);
01673
01674 ast_dsp_prog_reset(dsp);
01675 }
01676 return dsp;
01677 }
01678
01679 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01680 {
01681 dsp->features = features;
01682 }
01683
01684 void ast_dsp_free(struct ast_dsp *dsp)
01685 {
01686 free(dsp);
01687 }
01688
01689 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01690 {
01691 if (threshold < 256)
01692 dsp->threshold = 256;
01693 else
01694 dsp->threshold = threshold;
01695 }
01696
01697 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01698 {
01699 if (cadences < 4)
01700 cadences = 4;
01701 if (cadences > DSP_HISTORY)
01702 cadences = DSP_HISTORY;
01703 dsp->busycount = cadences;
01704 }
01705
01706 void ast_dsp_set_busy_compare(struct ast_dsp *dsp, int compare)
01707 {
01708 if (compare > 0)
01709 dsp->busycompare = 1;
01710 else
01711 dsp->busycompare = 0;
01712 }
01713
01714 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength, int fuzzy)
01715 {
01716 dsp->busy_tonelength = tonelength;
01717 if (quietlength > 0)
01718 dsp->busy_quietlength = quietlength;
01719 else
01720 dsp->busytoneonly = 1;
01721 ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01722 if( fuzzy > 0 && fuzzy < 50 )
01723 dsp->busy_pattern_fuzzy = fuzzy;
01724 }
01725
01726 void ast_dsp_digitreset(struct ast_dsp *dsp)
01727 {
01728 int i;
01729
01730 dsp->thinkdigit = 0;
01731 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01732 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01733 dsp->td.mf.current_digits = 0;
01734
01735 for (i = 0; i < 6; i++) {
01736 goertzel_reset(&dsp->td.mf.tone_out[i]);
01737 #ifdef OLD_DSP_ROUTINES
01738 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01739 #endif
01740 }
01741 #ifdef OLD_DSP_ROUTINES
01742 dsp->td.mf.energy = 0.0;
01743 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01744 #else
01745 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;
01746 #endif
01747 dsp->td.mf.current_sample = 0;
01748 } else {
01749 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01750 dsp->td.dtmf.current_digits = 0;
01751
01752 for (i = 0; i < 4; i++) {
01753 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01754 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01755 #ifdef OLD_DSP_ROUTINES
01756 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01757 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01758 #endif
01759 }
01760 #ifdef FAX_DETECT
01761 goertzel_reset (&dsp->td.dtmf.fax_tone);
01762 #endif
01763 #ifdef OLD_DSP_ROUTINES
01764 #ifdef FAX_DETECT
01765 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01766 #endif
01767 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01768 #else
01769 dsp->td.dtmf.lasthit = dsp->td.dtmf.mhit = 0;
01770 #endif
01771 dsp->td.dtmf.energy = 0.0;
01772 dsp->td.dtmf.current_sample = 0;
01773 }
01774 }
01775
01776 void ast_dsp_reset(struct ast_dsp *dsp)
01777 {
01778 int x;
01779
01780 dsp->totalsilence = 0;
01781 dsp->gsamps = 0;
01782 for (x=0;x<4;x++)
01783 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01784 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01785 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01786 dsp->ringtimeout= 0;
01787 }
01788
01789 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01790 {
01791 int new;
01792 int old;
01793
01794 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01795 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01796 if (old != new) {
01797
01798 if (new & DSP_DIGITMODE_MF)
01799 ast_mf_detect_init(&dsp->td.mf);
01800 else
01801 ast_dtmf_detect_init(&dsp->td.dtmf);
01802 }
01803 dsp->digitmode = digitmode;
01804 return 0;
01805 }
01806
01807 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01808 {
01809 int x;
01810
01811 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01812 if (!strcasecmp(aliases[x].name, zone)) {
01813 dsp->progmode = aliases[x].mode;
01814 ast_dsp_prog_reset(dsp);
01815 return 0;
01816 }
01817 }
01818 return -1;
01819 }
01820
01821 int ast_dsp_get_tstate(struct ast_dsp *dsp)
01822 {
01823 return dsp->tstate;
01824 }
01825
01826 int ast_dsp_get_tcount(struct ast_dsp *dsp)
01827 {
01828 return dsp->tcount;
01829 }