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