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