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