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: 77845 $")
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 hits[3];
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->hits[0] = s->hits[1] = s->hits[2] = 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
00599
00600
00601
00602
00603
00604
00605 #ifdef OLD_DSP_ROUTINES
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 #else
00618 if (hit == s->hits[2] && hit != s->hits[1] && hit != s->hits[0]) {
00619 s->mhit = hit;
00620 s->digit_hits[(best_row << 2) + best_col]++;
00621 s->detected_digits++;
00622 if (s->current_digits < MAX_DTMF_DIGITS) {
00623 s->digits[s->current_digits++] = hit;
00624 s->digits[s->current_digits] = '\0';
00625 } else {
00626 s->lost_digits++;
00627 }
00628 }
00629 #endif
00630 }
00631 }
00632 #ifdef FAX_DETECT
00633 if (!hit && (fax_energy >= FAX_THRESHOLD) &&
00634 (fax_energy >= DTMF_TO_TOTAL_ENERGY*s->energy) &&
00635 (faxdetect)) {
00636 #if 0
00637 printf("Fax energy/Second Harmonic: %f\n", fax_energy);
00638 #endif
00639
00640 hit = 'f';
00641 s->fax_hits++;
00642 } else {
00643 if (s->fax_hits > 5) {
00644 hit = 'f';
00645 s->mhit = 'f';
00646 s->detected_digits++;
00647 if (s->current_digits < MAX_DTMF_DIGITS) {
00648 s->digits[s->current_digits++] = hit;
00649 s->digits[s->current_digits] = '\0';
00650 } else {
00651 s->lost_digits++;
00652 }
00653 }
00654 s->fax_hits = 0;
00655 }
00656 #endif
00657 #ifdef OLD_DSP_ROUTINES
00658 s->hit1 = s->hit2;
00659 s->hit2 = s->hit3;
00660 s->hit3 = hit;
00661 #else
00662 s->hits[0] = s->hits[1];
00663 s->hits[1] = s->hits[2];
00664 s->hits[2] = hit;
00665 #endif
00666
00667 for (i = 0; i < 4; i++) {
00668 goertzel_reset(&s->row_out[i]);
00669 goertzel_reset(&s->col_out[i]);
00670 #ifdef OLD_DSP_ROUTINES
00671 goertzel_reset(&s->row_out2nd[i]);
00672 goertzel_reset(&s->col_out2nd[i]);
00673 #endif
00674 }
00675 #ifdef FAX_DETECT
00676 goertzel_reset (&s->fax_tone);
00677 #ifdef OLD_DSP_ROUTINES
00678 goertzel_reset (&s->fax_tone2nd);
00679 #endif
00680 #endif
00681 s->energy = 0.0;
00682 s->current_sample = 0;
00683 }
00684 if ((!s->mhit) || (s->mhit != hit)) {
00685 s->mhit = 0;
00686 return(0);
00687 }
00688 return (hit);
00689 }
00690
00691
00692 #ifdef OLD_DSP_ROUTINES
00693 #define MF_GSIZE 160
00694 #else
00695 #define MF_GSIZE 120
00696 #endif
00697
00698 static int mf_detect (mf_detect_state_t *s, int16_t amp[],
00699 int samples, int digitmode, int *writeback)
00700 {
00701 #ifdef OLD_DSP_ROUTINES
00702 float tone_energy[6];
00703 int best1;
00704 int best2;
00705 float max;
00706 int sofarsogood;
00707 #else
00708 float energy[6];
00709 int best;
00710 int second_best;
00711 #endif
00712 float famp;
00713 float v1;
00714 int i;
00715 int j;
00716 int sample;
00717 int hit;
00718 int limit;
00719
00720 hit = 0;
00721 for (sample = 0; sample < samples; sample = limit) {
00722
00723 if ((samples - sample) >= (MF_GSIZE - s->current_sample))
00724 limit = sample + (MF_GSIZE - s->current_sample);
00725 else
00726 limit = samples;
00727 #if defined(USE_3DNOW)
00728 _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample);
00729 _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample);
00730 #ifdef OLD_DSP_ROUTINES
00731 _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample);
00732 _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample);
00733 #endif
00734
00735 #warning "Fax Support Broken"
00736 #else
00737
00738
00739 for (j = sample; j < limit; j++) {
00740 famp = amp[j];
00741 #ifdef OLD_DSP_ROUTINES
00742 s->energy += famp*famp;
00743 #endif
00744
00745
00746 v1 = s->tone_out[0].v2;
00747 s->tone_out[0].v2 = s->tone_out[0].v3;
00748 s->tone_out[0].v3 = s->tone_out[0].fac*s->tone_out[0].v2 - v1 + famp;
00749 v1 = s->tone_out[1].v2;
00750 s->tone_out[1].v2 = s->tone_out[1].v3;
00751 s->tone_out[1].v3 = s->tone_out[1].fac*s->tone_out[1].v2 - v1 + famp;
00752 v1 = s->tone_out[2].v2;
00753 s->tone_out[2].v2 = s->tone_out[2].v3;
00754 s->tone_out[2].v3 = s->tone_out[2].fac*s->tone_out[2].v2 - v1 + famp;
00755 v1 = s->tone_out[3].v2;
00756 s->tone_out[3].v2 = s->tone_out[3].v3;
00757 s->tone_out[3].v3 = s->tone_out[3].fac*s->tone_out[3].v2 - v1 + famp;
00758 v1 = s->tone_out[4].v2;
00759 s->tone_out[4].v2 = s->tone_out[4].v3;
00760 s->tone_out[4].v3 = s->tone_out[4].fac*s->tone_out[4].v2 - v1 + famp;
00761 v1 = s->tone_out[5].v2;
00762 s->tone_out[5].v2 = s->tone_out[5].v3;
00763 s->tone_out[5].v3 = s->tone_out[5].fac*s->tone_out[5].v2 - v1 + famp;
00764 #ifdef OLD_DSP_ROUTINES
00765 v1 = s->tone_out2nd[0].v2;
00766 s->tone_out2nd[0].v2 = s->tone_out2nd[0].v3;
00767 s->tone_out2nd[0].v3 = s->tone_out2nd[0].fac*s->tone_out2nd[0].v2 - v1 + famp;
00768 v1 = s->tone_out2nd[1].v2;
00769 s->tone_out2nd[1].v2 = s->tone_out2nd[1].v3;
00770 s->tone_out2nd[1].v3 = s->tone_out2nd[1].fac*s->tone_out2nd[1].v2 - v1 + famp;
00771 v1 = s->tone_out2nd[2].v2;
00772 s->tone_out2nd[2].v2 = s->tone_out2nd[2].v3;
00773 s->tone_out2nd[2].v3 = s->tone_out2nd[2].fac*s->tone_out2nd[2].v2 - v1 + famp;
00774 v1 = s->tone_out2nd[3].v2;
00775 s->tone_out2nd[3].v2 = s->tone_out2nd[3].v3;
00776 s->tone_out2nd[3].v3 = s->tone_out2nd[3].fac*s->tone_out2nd[3].v2 - v1 + famp;
00777 v1 = s->tone_out2nd[4].v2;
00778 s->tone_out2nd[4].v2 = s->tone_out2nd[4].v3;
00779 s->tone_out2nd[4].v3 = s->tone_out2nd[4].fac*s->tone_out2nd[2].v2 - v1 + famp;
00780 v1 = s->tone_out2nd[3].v2;
00781 s->tone_out2nd[5].v2 = s->tone_out2nd[6].v3;
00782 s->tone_out2nd[5].v3 = s->tone_out2nd[6].fac*s->tone_out2nd[3].v2 - v1 + famp;
00783 #endif
00784 }
00785 #endif
00786 s->current_sample += (limit - sample);
00787 if (s->current_sample < MF_GSIZE) {
00788 if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00789
00790
00791 for (i=sample;i<limit;i++)
00792 amp[i] = 0;
00793 *writeback = 1;
00794 }
00795 continue;
00796 }
00797 #ifdef OLD_DSP_ROUTINES
00798
00799
00800 for (i=0;i<6;i++) {
00801 tone_energy[i] = goertzel_result(&s->tone_out[i]);
00802 }
00803
00804 best1 = 0;
00805 max = tone_energy[0];
00806 for (i=1;i<6;i++) {
00807 if (tone_energy[i] > max) {
00808 max = tone_energy[i];
00809 best1 = i;
00810 }
00811 }
00812
00813
00814 if (best1) {
00815 max = tone_energy[0];
00816 best2 = 0;
00817 } else {
00818 max = tone_energy[1];
00819 best2 = 1;
00820 }
00821
00822 for (i=0;i<6;i++) {
00823 if (i == best1) continue;
00824 if (tone_energy[i] > max) {
00825 max = tone_energy[i];
00826 best2 = i;
00827 }
00828 }
00829 hit = 0;
00830 if (best1 != best2)
00831 sofarsogood=1;
00832 else
00833 sofarsogood=0;
00834
00835 for (i=0;i<6;i++) {
00836 if (i == best1)
00837 continue;
00838 if (i == best2)
00839 continue;
00840 if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
00841 sofarsogood = 0;
00842 break;
00843 }
00844 if (tone_energy[best2] < tone_energy[i] * MF_RELATIVE_PEAK) {
00845 sofarsogood = 0;
00846 break;
00847 }
00848 }
00849
00850 if (sofarsogood) {
00851
00852 if (goertzel_result(&s->tone_out2nd[best1]) * MF_2ND_HARMONIC > tone_energy[best1])
00853 sofarsogood = 0;
00854 else if (goertzel_result(&s->tone_out2nd[best2]) * MF_2ND_HARMONIC > tone_energy[best2])
00855 sofarsogood = 0;
00856 }
00857 if (sofarsogood) {
00858 hit = mf_hit[best1][best2];
00859 if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
00860
00861 for (i=sample;i<limit;i++)
00862 amp[i] = 0;
00863 *writeback = 1;
00864 }
00865
00866 if ((hit == s->hit3) && (s->hit3 != s->hit2)) {
00867 s->mhit = hit;
00868 s->detected_digits++;
00869 if (s->current_digits < MAX_DTMF_DIGITS - 2) {
00870 s->digits[s->current_digits++] = hit;
00871 s->digits[s->current_digits] = '\0';
00872 } else {
00873 s->lost_digits++;
00874 }
00875 }
00876 }
00877
00878 s->hit1 = s->hit2;
00879 s->hit2 = s->hit3;
00880 s->hit3 = hit;
00881
00882 for (i = 0; i < 6; i++) {
00883 goertzel_reset(&s->tone_out[i]);
00884 goertzel_reset(&s->tone_out2nd[i]);
00885 }
00886 s->energy = 0.0;
00887 s->current_sample = 0;
00888 }
00889 #else
00890
00891
00892
00893
00894
00895
00896
00897 energy[0] = goertzel_result(&s->tone_out[0]);
00898 energy[1] = goertzel_result(&s->tone_out[1]);
00899 if (energy[0] > energy[1]) {
00900 best = 0;
00901 second_best = 1;
00902 } else {
00903 best = 1;
00904 second_best = 0;
00905 }
00906
00907 for (i=2;i<6;i++) {
00908 energy[i] = goertzel_result(&s->tone_out[i]);
00909 if (energy[i] >= energy[best]) {
00910 second_best = best;
00911 best = i;
00912 } else if (energy[i] >= energy[second_best]) {
00913 second_best = i;
00914 }
00915 }
00916
00917 hit = 0;
00918 if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
00919 && energy[best] < energy[second_best]*BELL_MF_TWIST
00920 && energy[best]*BELL_MF_TWIST > energy[second_best]) {
00921
00922 hit = -1;
00923 for (i=0;i<6;i++) {
00924 if (i != best && i != second_best) {
00925 if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
00926
00927 hit = 0;
00928 break;
00929 }
00930 }
00931 }
00932 }
00933 if (hit) {
00934
00935 if (second_best < best) {
00936 i = best;
00937 best = second_best;
00938 second_best = i;
00939 }
00940 best = best*5 + second_best - 1;
00941 hit = bell_mf_positions[best];
00942
00943
00944
00945
00946
00947
00948 if (hit == s->hits[4] && hit == s->hits[3] &&
00949 ((hit != '*' && hit != s->hits[2] && hit != s->hits[1])||
00950 (hit == '*' && hit == s->hits[2] && hit != s->hits[1] &&
00951 hit != s->hits[0]))) {
00952 s->detected_digits++;
00953 if (s->current_digits < MAX_DTMF_DIGITS) {
00954 s->digits[s->current_digits++] = hit;
00955 s->digits[s->current_digits] = '\0';
00956 } else {
00957 s->lost_digits++;
00958 }
00959 }
00960 } else {
00961 hit = 0;
00962 }
00963 s->hits[0] = s->hits[1];
00964 s->hits[1] = s->hits[2];
00965 s->hits[2] = s->hits[3];
00966 s->hits[3] = s->hits[4];
00967 s->hits[4] = hit;
00968
00969 for (i = 0; i < 6; i++)
00970 goertzel_reset(&s->tone_out[i]);
00971 s->current_sample = 0;
00972 }
00973 #endif
00974 if ((!s->mhit) || (s->mhit != hit)) {
00975 s->mhit = 0;
00976 return(0);
00977 }
00978 return (hit);
00979 }
00980
00981 static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
00982 {
00983 int res;
00984
00985 if (dsp->digitmode & DSP_DIGITMODE_MF)
00986 res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00987 else
00988 res = dtmf_detect(&dsp->td.dtmf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback, dsp->features & DSP_FEATURE_FAX_DETECT);
00989 return res;
00990 }
00991
00992 int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
00993 {
00994 short *s;
00995 int len;
00996 int ign=0;
00997
00998 if (inf->frametype != AST_FRAME_VOICE) {
00999 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01000 return 0;
01001 }
01002 if (inf->subclass != AST_FORMAT_SLINEAR) {
01003 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01004 return 0;
01005 }
01006 s = inf->data;
01007 len = inf->datalen / 2;
01008 return __ast_dsp_digitdetect(dsp, s, len, &ign);
01009 }
01010
01011 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
01012 {
01013
01014
01015 if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
01016 return 0;
01017
01018 i2 *= TONE_THRESH;
01019 i1 *= TONE_THRESH;
01020 e *= TONE_THRESH;
01021
01022 if ((p1 < i1) || (p1 < i2) || (p1 < e))
01023 return 0;
01024
01025 if ((p2 < i1) || (p2 < i2) || (p2 < e))
01026 return 0;
01027
01028 return 1;
01029 }
01030
01031 int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max)
01032 {
01033 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01034 if (max > dsp->td.mf.current_digits)
01035 max = dsp->td.mf.current_digits;
01036 if (max > 0) {
01037 memcpy(buf, dsp->td.mf.digits, max);
01038 memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
01039 dsp->td.mf.current_digits -= max;
01040 }
01041 buf[max] = '\0';
01042 return max;
01043 } else {
01044 if (max > dsp->td.dtmf.current_digits)
01045 max = dsp->td.dtmf.current_digits;
01046 if (max > 0) {
01047 memcpy (buf, dsp->td.dtmf.digits, max);
01048 memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
01049 dsp->td.dtmf.current_digits -= max;
01050 }
01051 buf[max] = '\0';
01052 return max;
01053 }
01054 }
01055
01056 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
01057 {
01058 int x;
01059 int y;
01060 int pass;
01061 int newstate = DSP_TONE_STATE_SILENCE;
01062 int res = 0;
01063 while(len) {
01064
01065 pass = len;
01066 if (pass > dsp->gsamp_size - dsp->gsamps)
01067 pass = dsp->gsamp_size - dsp->gsamps;
01068 for (x=0;x<pass;x++) {
01069 for (y=0;y<dsp->freqcount;y++)
01070 goertzel_sample(&dsp->freqs[y], s[x]);
01071 dsp->genergy += s[x] * s[x];
01072 }
01073 s += pass;
01074 dsp->gsamps += pass;
01075 len -= pass;
01076 if (dsp->gsamps == dsp->gsamp_size) {
01077 float hz[7];
01078 for (y=0;y<7;y++)
01079 hz[y] = goertzel_result(&dsp->freqs[y]);
01080 #if 0
01081 printf("\n350: 425: 440: 480: 620: 950: 1400: 1800: Energy: \n");
01082 printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n",
01083 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);
01084 #endif
01085 switch(dsp->progmode) {
01086 case PROG_MODE_NA:
01087 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
01088 newstate = DSP_TONE_STATE_BUSY;
01089 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01090 newstate = DSP_TONE_STATE_RINGING;
01091 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01092 newstate = DSP_TONE_STATE_DIALTONE;
01093 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01094 newstate = DSP_TONE_STATE_SPECIAL1;
01095 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01096 if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
01097 newstate = DSP_TONE_STATE_SPECIAL2;
01098 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01099 if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
01100 newstate = DSP_TONE_STATE_SPECIAL3;
01101 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01102 newstate = DSP_TONE_STATE_TALKING;
01103 } else
01104 newstate = DSP_TONE_STATE_SILENCE;
01105 break;
01106 case PROG_MODE_CR:
01107 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01108 newstate = DSP_TONE_STATE_RINGING;
01109 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01110 newstate = DSP_TONE_STATE_TALKING;
01111 } else
01112 newstate = DSP_TONE_STATE_SILENCE;
01113 break;
01114 case PROG_MODE_UK:
01115 if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
01116 newstate = DSP_TONE_STATE_HUNGUP;
01117 }
01118 break;
01119 default:
01120 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01121 }
01122 if (newstate == dsp->tstate) {
01123 dsp->tcount++;
01124 if (dsp->ringtimeout)
01125 dsp->ringtimeout++;
01126 switch (dsp->tstate) {
01127 case DSP_TONE_STATE_RINGING:
01128 if ((dsp->features & DSP_PROGRESS_RINGING) &&
01129 (dsp->tcount==THRESH_RING)) {
01130 res = AST_CONTROL_RINGING;
01131 dsp->ringtimeout= 1;
01132 }
01133 break;
01134 case DSP_TONE_STATE_BUSY:
01135 if ((dsp->features & DSP_PROGRESS_BUSY) &&
01136 (dsp->tcount==THRESH_BUSY)) {
01137 res = AST_CONTROL_BUSY;
01138 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01139 }
01140 break;
01141 case DSP_TONE_STATE_TALKING:
01142 if ((dsp->features & DSP_PROGRESS_TALK) &&
01143 (dsp->tcount==THRESH_TALK)) {
01144 res = AST_CONTROL_ANSWER;
01145 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01146 }
01147 break;
01148 case DSP_TONE_STATE_SPECIAL3:
01149 if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
01150 (dsp->tcount==THRESH_CONGESTION)) {
01151 res = AST_CONTROL_CONGESTION;
01152 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01153 }
01154 break;
01155 case DSP_TONE_STATE_HUNGUP:
01156 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
01157 (dsp->tcount==THRESH_HANGUP)) {
01158 res = AST_CONTROL_HANGUP;
01159 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01160 }
01161 break;
01162 }
01163 if (dsp->ringtimeout==THRESH_RING2ANSWER) {
01164 #if 0
01165 ast_log(LOG_NOTICE, "Consider call as answered because of timeout after last ring\n");
01166 #endif
01167 res = AST_CONTROL_ANSWER;
01168 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01169 }
01170 } else {
01171 #if 0
01172 ast_log(LOG_NOTICE, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
01173 ast_log(LOG_NOTICE, "Start state %d\n", newstate);
01174 #endif
01175 dsp->tstate = newstate;
01176 dsp->tcount = 1;
01177 }
01178
01179
01180 for (x=0;x<7;x++)
01181 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01182 dsp->gsamps = 0;
01183 dsp->genergy = 0.0;
01184 }
01185 }
01186 #if 0
01187 if (res)
01188 printf("Returning %d\n", res);
01189 #endif
01190 return res;
01191 }
01192
01193 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01194 {
01195 if (inf->frametype != AST_FRAME_VOICE) {
01196 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01197 return 0;
01198 }
01199 if (inf->subclass != AST_FORMAT_SLINEAR) {
01200 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01201 return 0;
01202 }
01203 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01204 }
01205
01206 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
01207 {
01208 int accum;
01209 int x;
01210 int res = 0;
01211
01212 if (!len)
01213 return 0;
01214 accum = 0;
01215 for (x=0;x<len; x++)
01216 accum += abs(s[x]);
01217 accum /= len;
01218 if (accum < dsp->threshold) {
01219
01220 dsp->totalsilence += len/8;
01221 if (dsp->totalnoise) {
01222
01223 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
01224 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01225
01226 #if 0
01227 dsp->busymaybe = 1;
01228 #endif
01229 }
01230 dsp->totalnoise = 0;
01231 res = 1;
01232 } else {
01233
01234 dsp->totalnoise += len/8;
01235 if (dsp->totalsilence) {
01236 int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01237 int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01238
01239 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
01240 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01241
01242 if (silence1 < silence2) {
01243 if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
01244 dsp->busymaybe = 1;
01245 else
01246 dsp->busymaybe = 0;
01247 } else {
01248 if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
01249 dsp->busymaybe = 1;
01250 else
01251 dsp->busymaybe = 0;
01252 }
01253 }
01254 dsp->totalsilence = 0;
01255 }
01256 if (totalsilence)
01257 *totalsilence = dsp->totalsilence;
01258 return res;
01259 }
01260
01261 #ifdef BUSYDETECT_MARTIN
01262 int ast_dsp_busydetect(struct ast_dsp *dsp)
01263 {
01264 int res = 0, x;
01265 #ifndef BUSYDETECT_TONEONLY
01266 int avgsilence = 0, hitsilence = 0;
01267 #endif
01268 int avgtone = 0, hittone = 0;
01269 if (!dsp->busymaybe)
01270 return res;
01271 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01272 #ifndef BUSYDETECT_TONEONLY
01273 avgsilence += dsp->historicsilence[x];
01274 #endif
01275 avgtone += dsp->historicnoise[x];
01276 }
01277 #ifndef BUSYDETECT_TONEONLY
01278 avgsilence /= dsp->busycount;
01279 #endif
01280 avgtone /= dsp->busycount;
01281 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01282 #ifndef BUSYDETECT_TONEONLY
01283 if (avgsilence > dsp->historicsilence[x]) {
01284 if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01285 hitsilence++;
01286 } else {
01287 if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01288 hitsilence++;
01289 }
01290 #endif
01291 if (avgtone > dsp->historicnoise[x]) {
01292 if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01293 hittone++;
01294 } else {
01295 if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01296 hittone++;
01297 }
01298 }
01299 #ifndef BUSYDETECT_TONEONLY
01300 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
01301 (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
01302 (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01303 #else
01304 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01305 #endif
01306 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01307 #ifdef BUSYDETECT_TONEONLY
01308 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01309 #endif
01310 if (avgtone > avgsilence) {
01311 if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01312 res = 1;
01313 } else {
01314 if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01315 res = 1;
01316 }
01317 #else
01318 res = 1;
01319 #endif
01320 }
01321
01322 if (res && (dsp->busy_tonelength > 0)) {
01323 if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
01324 #if 0
01325 ast_log(LOG_NOTICE, "busy detector: avgtone of %d not close enough to desired %d\n",
01326 avgtone, dsp->busy_tonelength);
01327 #endif
01328 res = 0;
01329 }
01330 }
01331 #ifndef BUSYDETECT_TONEONLY
01332
01333 if (res && (dsp->busy_quietlength > 0)) {
01334 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01335 #if 0
01336 ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
01337 avgsilence, dsp->busy_quietlength);
01338 #endif
01339 res = 0;
01340 }
01341 }
01342 #endif
01343 #ifndef BUSYDETECT_TONEONLY
01344 #if 1
01345 if (res)
01346 ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01347 #endif
01348 #endif
01349 return res;
01350 }
01351 #endif
01352
01353 #ifdef BUSYDETECT
01354 int ast_dsp_busydetect(struct ast_dsp *dsp)
01355 {
01356 int x;
01357 int res = 0;
01358 int max, min;
01359
01360 #if 0
01361 if (dsp->busy_hits > 5);
01362 return 0;
01363 #endif
01364 if (dsp->busymaybe) {
01365 #if 0
01366 printf("Maybe busy!\n");
01367 #endif
01368 dsp->busymaybe = 0;
01369 min = 9999;
01370 max = 0;
01371 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01372 #if 0
01373 printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
01374 #endif
01375 if (dsp->historicsilence[x] < min)
01376 min = dsp->historicsilence[x];
01377 if (dsp->historicnoise[x] < min)
01378 min = dsp->historicnoise[x];
01379 if (dsp->historicsilence[x] > max)
01380 max = dsp->historicsilence[x];
01381 if (dsp->historicnoise[x] > max)
01382 max = dsp->historicnoise[x];
01383 }
01384 if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
01385 #if 0
01386 printf("Busy!\n");
01387 #endif
01388 res = 1;
01389 }
01390 #if 0
01391 printf("Min: %d, max: %d\n", min, max);
01392 #endif
01393 }
01394 return res;
01395 }
01396 #endif
01397
01398 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01399 {
01400 short *s;
01401 int len;
01402
01403 if (f->frametype != AST_FRAME_VOICE) {
01404 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01405 return 0;
01406 }
01407 if (f->subclass != AST_FORMAT_SLINEAR) {
01408 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01409 return 0;
01410 }
01411 s = f->data;
01412 len = f->datalen/2;
01413 return __ast_dsp_silence(dsp, s, len, totalsilence);
01414 }
01415
01416 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01417 {
01418 int silence;
01419 int res;
01420 int digit;
01421 int x;
01422 short *shortdata;
01423 unsigned char *odata;
01424 int len;
01425 int writeback = 0;
01426
01427 #define FIX_INF(inf) do { \
01428 if (writeback) { \
01429 switch(inf->subclass) { \
01430 case AST_FORMAT_SLINEAR: \
01431 break; \
01432 case AST_FORMAT_ULAW: \
01433 for (x=0;x<len;x++) \
01434 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01435 break; \
01436 case AST_FORMAT_ALAW: \
01437 for (x=0;x<len;x++) \
01438 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01439 break; \
01440 } \
01441 } \
01442 } while(0)
01443
01444 if (!af)
01445 return NULL;
01446 if (af->frametype != AST_FRAME_VOICE)
01447 return af;
01448 odata = af->data;
01449 len = af->datalen;
01450
01451 switch(af->subclass) {
01452 case AST_FORMAT_SLINEAR:
01453 shortdata = af->data;
01454 len = af->datalen / 2;
01455 break;
01456 case AST_FORMAT_ULAW:
01457 shortdata = alloca(af->datalen * 2);
01458 for (x = 0;x < len; x++)
01459 shortdata[x] = AST_MULAW(odata[x]);
01460 break;
01461 case AST_FORMAT_ALAW:
01462 shortdata = alloca(af->datalen * 2);
01463 for (x = 0; x < len; x++)
01464 shortdata[x] = AST_ALAW(odata[x]);
01465 break;
01466 default:
01467 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01468 return af;
01469 }
01470 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01471 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01472 memset(&dsp->f, 0, sizeof(dsp->f));
01473 dsp->f.frametype = AST_FRAME_NULL;
01474 return &dsp->f;
01475 }
01476 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01477 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01478 memset(&dsp->f, 0, sizeof(dsp->f));
01479 dsp->f.frametype = AST_FRAME_CONTROL;
01480 dsp->f.subclass = AST_CONTROL_BUSY;
01481 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01482 return &dsp->f;
01483 }
01484 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01485 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01486 #if 0
01487 if (digit)
01488 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01489 #endif
01490 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01491 if (!dsp->thinkdigit) {
01492 if (digit) {
01493
01494
01495 memset(&dsp->f, 0, sizeof(dsp->f));
01496 dsp->f.frametype = AST_FRAME_DTMF;
01497 dsp->f.subclass = 'm';
01498 dsp->thinkdigit = 'x';
01499 FIX_INF(af);
01500 if (chan)
01501 ast_queue_frame(chan, af);
01502 ast_frfree(af);
01503 return &dsp->f;
01504 }
01505 } else {
01506 if (digit) {
01507
01508 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01509
01510
01511
01512 memset(&dsp->f, 0, sizeof(dsp->f));
01513 dsp->f.frametype = AST_FRAME_DTMF_END;
01514 dsp->f.subclass = dsp->thinkdigit;
01515 FIX_INF(af);
01516 if (chan)
01517 ast_queue_frame(chan, af);
01518 ast_frfree(af);
01519 } else {
01520 dsp->thinkdigit = digit;
01521 memset(&dsp->f, 0, sizeof(dsp->f));
01522 dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
01523 dsp->f.subclass = dsp->thinkdigit;
01524 FIX_INF(af);
01525 if (chan)
01526 ast_queue_frame(chan, af);
01527 ast_frfree(af);
01528 }
01529 return &dsp->f;
01530 } else {
01531 memset(&dsp->f, 0, sizeof(dsp->f));
01532 if (dsp->thinkdigit != 'x') {
01533
01534 dsp->f.frametype = AST_FRAME_DTMF_END;
01535 dsp->f.subclass = dsp->thinkdigit;
01536 dsp->thinkdigit = 0;
01537 } else {
01538 dsp->f.frametype = AST_FRAME_DTMF;
01539 dsp->f.subclass = 'u';
01540 dsp->thinkdigit = 0;
01541 }
01542 FIX_INF(af);
01543 if (chan)
01544 ast_queue_frame(chan, af);
01545 ast_frfree(af);
01546 return &dsp->f;
01547 }
01548 }
01549 } else if (!digit) {
01550
01551 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01552 if (dsp->td.mf.current_digits) {
01553 memset(&dsp->f, 0, sizeof(dsp->f));
01554 dsp->f.frametype = AST_FRAME_DTMF;
01555 dsp->f.subclass = dsp->td.mf.digits[0];
01556 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01557 dsp->td.mf.current_digits--;
01558 FIX_INF(af);
01559 if (chan)
01560 ast_queue_frame(chan, af);
01561 ast_frfree(af);
01562 return &dsp->f;
01563 }
01564 } else {
01565 if (dsp->td.dtmf.current_digits) {
01566 memset(&dsp->f, 0, sizeof(dsp->f));
01567 dsp->f.frametype = AST_FRAME_DTMF_END;
01568 dsp->f.subclass = dsp->td.dtmf.digits[0];
01569 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01570 dsp->td.dtmf.current_digits--;
01571 FIX_INF(af);
01572 if (chan)
01573 ast_queue_frame(chan, af);
01574 ast_frfree(af);
01575 return &dsp->f;
01576 }
01577 }
01578 }
01579 }
01580 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01581 res = __ast_dsp_call_progress(dsp, shortdata, len);
01582 if (res) {
01583 switch(res) {
01584 case AST_CONTROL_ANSWER:
01585 case AST_CONTROL_BUSY:
01586 case AST_CONTROL_RINGING:
01587 case AST_CONTROL_CONGESTION:
01588 case AST_CONTROL_HANGUP:
01589 memset(&dsp->f, 0, sizeof(dsp->f));
01590 dsp->f.frametype = AST_FRAME_CONTROL;
01591 dsp->f.subclass = res;
01592 dsp->f.src = "dsp_progress";
01593 if (chan)
01594 ast_queue_frame(chan, &dsp->f);
01595 break;
01596 default:
01597 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01598 }
01599 }
01600 }
01601 FIX_INF(af);
01602 return af;
01603 }
01604
01605 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01606 {
01607 int max = 0;
01608 int x;
01609
01610 dsp->gsamp_size = modes[dsp->progmode].size;
01611 dsp->gsamps = 0;
01612 for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
01613 if (modes[dsp->progmode].freqs[x]) {
01614 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01615 max = x + 1;
01616 }
01617 }
01618 dsp->freqcount = max;
01619 dsp->ringtimeout= 0;
01620 }
01621
01622 struct ast_dsp *ast_dsp_new(void)
01623 {
01624 struct ast_dsp *dsp;
01625
01626 if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
01627 dsp->threshold = DEFAULT_THRESHOLD;
01628 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01629 dsp->busycount = DSP_HISTORY;
01630
01631 ast_dtmf_detect_init(&dsp->td.dtmf);
01632
01633 ast_dsp_prog_reset(dsp);
01634 }
01635 return dsp;
01636 }
01637
01638 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01639 {
01640 dsp->features = features;
01641 }
01642
01643 void ast_dsp_free(struct ast_dsp *dsp)
01644 {
01645 free(dsp);
01646 }
01647
01648 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01649 {
01650 dsp->threshold = threshold;
01651 }
01652
01653 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01654 {
01655 if (cadences < 4)
01656 cadences = 4;
01657 if (cadences > DSP_HISTORY)
01658 cadences = DSP_HISTORY;
01659 dsp->busycount = cadences;
01660 }
01661
01662 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
01663 {
01664 dsp->busy_tonelength = tonelength;
01665 dsp->busy_quietlength = quietlength;
01666 ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01667 }
01668
01669 void ast_dsp_digitreset(struct ast_dsp *dsp)
01670 {
01671 int i;
01672
01673 dsp->thinkdigit = 0;
01674 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01675 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01676 dsp->td.mf.current_digits = 0;
01677
01678 for (i = 0; i < 6; i++) {
01679 goertzel_reset(&dsp->td.mf.tone_out[i]);
01680 #ifdef OLD_DSP_ROUTINES
01681 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01682 #endif
01683 }
01684 #ifdef OLD_DSP_ROUTINES
01685 dsp->td.mf.energy = 0.0;
01686 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01687 #else
01688 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;
01689 #endif
01690 dsp->td.mf.current_sample = 0;
01691 } else {
01692 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01693 dsp->td.dtmf.current_digits = 0;
01694
01695 for (i = 0; i < 4; i++) {
01696 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01697 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01698 #ifdef OLD_DSP_ROUTINES
01699 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01700 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01701 #endif
01702 }
01703 #ifdef FAX_DETECT
01704 goertzel_reset (&dsp->td.dtmf.fax_tone);
01705 #endif
01706 #ifdef OLD_DSP_ROUTINES
01707 #ifdef FAX_DETECT
01708 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01709 #endif
01710 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01711 #else
01712 dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0;
01713 #endif
01714 dsp->td.dtmf.energy = 0.0;
01715 dsp->td.dtmf.current_sample = 0;
01716 }
01717 }
01718
01719 void ast_dsp_reset(struct ast_dsp *dsp)
01720 {
01721 int x;
01722
01723 dsp->totalsilence = 0;
01724 dsp->gsamps = 0;
01725 for (x=0;x<4;x++)
01726 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01727 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01728 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01729 dsp->ringtimeout= 0;
01730 }
01731
01732 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01733 {
01734 int new;
01735 int old;
01736
01737 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01738 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01739 if (old != new) {
01740
01741 if (new & DSP_DIGITMODE_MF)
01742 ast_mf_detect_init(&dsp->td.mf);
01743 else
01744 ast_dtmf_detect_init(&dsp->td.dtmf);
01745 }
01746 dsp->digitmode = digitmode;
01747 return 0;
01748 }
01749
01750 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01751 {
01752 int x;
01753
01754 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01755 if (!strcasecmp(aliases[x].name, zone)) {
01756 dsp->progmode = aliases[x].mode;
01757 ast_dsp_prog_reset(dsp);
01758 return 0;
01759 }
01760 }
01761 return -1;
01762 }
01763
01764 int ast_dsp_get_tstate(struct ast_dsp *dsp)
01765 {
01766 return dsp->tstate;
01767 }
01768
01769 int ast_dsp_get_tcount(struct ast_dsp *dsp)
01770 {
01771 return dsp->tcount;
01772 }