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("\n350: 425: 440: 480: 620: 950: 1400: 1800: Energy: \n");
01140 printf("%.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e %.2e\n",
01141 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);
01142 #endif
01143 switch(dsp->progmode) {
01144 case PROG_MODE_NA:
01145 if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
01146 newstate = TONE_STATE_BUSY;
01147 } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01148 newstate = TONE_STATE_RINGING;
01149 } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01150 newstate = TONE_STATE_DIALTONE;
01151 } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01152 newstate = TONE_STATE_SPECIAL1;
01153 } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01154 if (dsp->tstate == TONE_STATE_SPECIAL1)
01155 newstate = TONE_STATE_SPECIAL2;
01156 } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01157 if (dsp->tstate == TONE_STATE_SPECIAL2)
01158 newstate = TONE_STATE_SPECIAL3;
01159 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01160 newstate = TONE_STATE_TALKING;
01161 } else
01162 newstate = TONE_STATE_SILENCE;
01163 break;
01164 case PROG_MODE_CR:
01165 if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01166 newstate = TONE_STATE_RINGING;
01167 } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01168 newstate = TONE_STATE_TALKING;
01169 } else
01170 newstate = TONE_STATE_SILENCE;
01171 break;
01172 default:
01173 ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01174 }
01175 if (newstate == dsp->tstate) {
01176 dsp->tcount++;
01177 if (dsp->tcount == COUNT_THRESH) {
01178 if (dsp->tstate == TONE_STATE_BUSY) {
01179 res = AST_CONTROL_BUSY;
01180 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01181 } else if (dsp->tstate == TONE_STATE_TALKING) {
01182 res = AST_CONTROL_ANSWER;
01183 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01184 } else if (dsp->tstate == TONE_STATE_RINGING)
01185 res = AST_CONTROL_RINGING;
01186 else if (dsp->tstate == TONE_STATE_SPECIAL3) {
01187 res = AST_CONTROL_CONGESTION;
01188 dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01189 }
01190
01191 }
01192 } else {
01193 #if 0
01194 printf("Newstate: %d\n", newstate);
01195 #endif
01196 dsp->tstate = newstate;
01197 dsp->tcount = 1;
01198 }
01199
01200
01201 for (x=0;x<7;x++)
01202 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01203 dsp->gsamps = 0;
01204 dsp->genergy = 0.0;
01205 }
01206 }
01207 #if 0
01208 if (res)
01209 printf("Returning %d\n", res);
01210 #endif
01211 return res;
01212 }
01213
01214 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01215 {
01216 if (inf->frametype != AST_FRAME_VOICE) {
01217 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01218 return 0;
01219 }
01220 if (inf->subclass != AST_FORMAT_SLINEAR) {
01221 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01222 return 0;
01223 }
01224 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01225 }
01226
01227 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
01228 {
01229 int accum;
01230 int x;
01231 int res = 0;
01232
01233 if (!len)
01234 return 0;
01235
01236 accum = 0;
01237 for (x=0;x<len; x++)
01238 accum += abs(s[x]);
01239 accum /= len;
01240 if (accum < dsp->threshold) {
01241 dsp->totalsilence += len/8;
01242 if (dsp->totalnoise) {
01243
01244 memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
01245 dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01246
01247 #if 0
01248 dsp->busymaybe = 1;
01249 #endif
01250 }
01251 dsp->totalnoise = 0;
01252 res = 1;
01253 } else {
01254 dsp->totalnoise += len/8;
01255 if (dsp->totalsilence) {
01256 int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01257 int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01258
01259 memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
01260 dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01261
01262 if (silence1 < silence2) {
01263 if (silence1 + silence1/BUSY_PERCENT >= silence2)
01264 dsp->busymaybe = 1;
01265 else
01266 dsp->busymaybe = 0;
01267 } else {
01268 if (silence1 - silence1/BUSY_PERCENT <= silence2)
01269 dsp->busymaybe = 1;
01270 else
01271 dsp->busymaybe = 0;
01272 }
01273
01274 }
01275 dsp->totalsilence = 0;
01276 }
01277 if (totalsilence)
01278 *totalsilence = dsp->totalsilence;
01279 return res;
01280 }
01281 #ifdef BUSYDETECT_MARTIN
01282 int ast_dsp_busydetect(struct ast_dsp *dsp)
01283 {
01284 int res = 0, x;
01285 #ifndef BUSYDETECT_TONEONLY
01286 int avgsilence = 0, hitsilence = 0;
01287 #endif
01288 int avgtone = 0, hittone = 0;
01289 if (!dsp->busymaybe)
01290 return res;
01291 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01292 #ifndef BUSYDETECT_TONEONLY
01293 avgsilence += dsp->historicsilence[x];
01294 #endif
01295 avgtone += dsp->historicnoise[x];
01296 }
01297 #ifndef BUSYDETECT_TONEONLY
01298 avgsilence /= dsp->busycount;
01299 #endif
01300 avgtone /= dsp->busycount;
01301 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01302 #ifndef BUSYDETECT_TONEONLY
01303 if (avgsilence > dsp->historicsilence[x]) {
01304 if (avgsilence - (avgsilence / BUSY_PERCENT) <= dsp->historicsilence[x])
01305 hitsilence++;
01306 } else {
01307 if (avgsilence + (avgsilence / BUSY_PERCENT) >= dsp->historicsilence[x])
01308 hitsilence++;
01309 }
01310 #endif
01311 if (avgtone > dsp->historicnoise[x]) {
01312 if (avgtone - (avgtone / BUSY_PERCENT) <= dsp->historicnoise[x])
01313 hittone++;
01314 } else {
01315 if (avgtone + (avgtone / BUSY_PERCENT) >= dsp->historicnoise[x])
01316 hittone++;
01317 }
01318 }
01319 #ifndef BUSYDETECT_TONEONLY
01320 if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01321 #else
01322 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01323 #endif
01324 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01325 #ifdef BUSYDETECT_TONEONLY
01326 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
01327 #endif
01328 if (avgtone > avgsilence) {
01329 if (avgtone - avgtone/(BUSY_PERCENT*2) <= avgsilence)
01330 res = 1;
01331 } else {
01332 if (avgtone + avgtone/(BUSY_PERCENT*2) >= avgsilence)
01333 res = 1;
01334 }
01335 #else
01336 res = 1;
01337 #endif
01338 }
01339 #if 0
01340 if (res)
01341 ast_log(LOG_NOTICE, "detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01342 #endif
01343 return res;
01344 }
01345 #endif
01346
01347 #ifdef BUSYDETECT
01348 int ast_dsp_busydetect(struct ast_dsp *dsp)
01349 {
01350 int x;
01351 int res = 0;
01352 int max, min;
01353
01354 #if 0
01355 if (dsp->busy_hits > 5);
01356 return 0;
01357 #endif
01358 if (dsp->busymaybe) {
01359 #if 0
01360 printf("Maybe busy!\n");
01361 #endif
01362 dsp->busymaybe = 0;
01363 min = 9999;
01364 max = 0;
01365 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01366 #if 0
01367 printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
01368 #endif
01369 if (dsp->historicsilence[x] < min)
01370 min = dsp->historicsilence[x];
01371 if (dsp->historicnoise[x] < min)
01372 min = dsp->historicnoise[x];
01373 if (dsp->historicsilence[x] > max)
01374 max = dsp->historicsilence[x];
01375 if (dsp->historicnoise[x] > max)
01376 max = dsp->historicnoise[x];
01377 }
01378 if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
01379 #if 0
01380 printf("Busy!\n");
01381 #endif
01382 res = 1;
01383 }
01384 #if 0
01385 printf("Min: %d, max: %d\n", min, max);
01386 #endif
01387 }
01388 return res;
01389 }
01390 #endif
01391
01392 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01393 {
01394 short *s;
01395 int len;
01396
01397 if (f->frametype != AST_FRAME_VOICE) {
01398 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01399 return 0;
01400 }
01401 if (f->subclass != AST_FORMAT_SLINEAR) {
01402 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01403 return 0;
01404 }
01405 s = f->data;
01406 len = f->datalen/2;
01407 return __ast_dsp_silence(dsp, s, len, totalsilence);
01408 }
01409
01410 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01411 {
01412 int silence;
01413 int res;
01414 int digit;
01415 int x;
01416 unsigned short *shortdata;
01417 unsigned char *odata;
01418 int len;
01419 int writeback = 0;
01420
01421 #define FIX_INF(inf) do { \
01422 if (writeback) { \
01423 switch(inf->subclass) { \
01424 case AST_FORMAT_SLINEAR: \
01425 break; \
01426 case AST_FORMAT_ULAW: \
01427 for (x=0;x<len;x++) \
01428 odata[x] = AST_LIN2MU(shortdata[x]); \
01429 break; \
01430 case AST_FORMAT_ALAW: \
01431 for (x=0;x<len;x++) \
01432 odata[x] = AST_LIN2A(shortdata[x]); \
01433 break; \
01434 } \
01435 } \
01436 } while(0)
01437
01438 if (!af)
01439 return NULL;
01440 if (af->frametype != AST_FRAME_VOICE)
01441 return af;
01442 odata = af->data;
01443 len = af->datalen;
01444
01445 switch(af->subclass) {
01446 case AST_FORMAT_SLINEAR:
01447 shortdata = af->data;
01448 len = af->datalen / 2;
01449 break;
01450 case AST_FORMAT_ULAW:
01451 shortdata = alloca(af->datalen * 2);
01452 if (!shortdata) {
01453 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01454 return af;
01455 }
01456 for (x=0;x<len;x++)
01457 shortdata[x] = AST_MULAW(odata[x]);
01458 break;
01459 case AST_FORMAT_ALAW:
01460 shortdata = alloca(af->datalen * 2);
01461 if (!shortdata) {
01462 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01463 return af;
01464 }
01465 for (x=0;x<len;x++)
01466 shortdata[x] = AST_ALAW(odata[x]);
01467 break;
01468 default:
01469 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01470 return af;
01471 }
01472 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01473 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01474 memset(&dsp->f, 0, sizeof(dsp->f));
01475 dsp->f.frametype = AST_FRAME_NULL;
01476 return &dsp->f;
01477 }
01478 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01479 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01480 memset(&dsp->f, 0, sizeof(dsp->f));
01481 dsp->f.frametype = AST_FRAME_CONTROL;
01482 dsp->f.subclass = AST_CONTROL_BUSY;
01483 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01484 return &dsp->f;
01485 }
01486 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01487 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01488 #if 0
01489 if (digit)
01490 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01491 #endif
01492 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01493 if (!dsp->thinkdigit) {
01494 if (digit) {
01495
01496 memset(&dsp->f, 0, sizeof(dsp->f));
01497 dsp->f.frametype = AST_FRAME_DTMF;
01498 dsp->f.subclass = 'm';
01499 dsp->thinkdigit = 'x';
01500 FIX_INF(af);
01501 if (chan)
01502 ast_queue_frame(chan, af);
01503 ast_frfree(af);
01504 return &dsp->f;
01505 }
01506 } else {
01507 if (digit) {
01508
01509 if (dsp->thinkdigit) {
01510 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01511
01512
01513
01514 memset(&dsp->f, 0, sizeof(dsp->f));
01515 dsp->f.frametype = AST_FRAME_DTMF;
01516 dsp->f.subclass = dsp->thinkdigit;
01517 FIX_INF(af);
01518 if (chan)
01519 ast_queue_frame(chan, af);
01520 ast_frfree(af);
01521 }
01522 dsp->thinkdigit = digit;
01523 return &dsp->f;
01524 }
01525 dsp->thinkdigit = digit;
01526 } else {
01527 if (dsp->thinkdigit) {
01528 memset(&dsp->f, 0, sizeof(dsp->f));
01529 if (dsp->thinkdigit != 'x') {
01530
01531 dsp->f.frametype = AST_FRAME_DTMF;
01532 dsp->f.subclass = dsp->thinkdigit;
01533 dsp->thinkdigit = 0;
01534 } else {
01535 dsp->f.frametype = AST_FRAME_DTMF;
01536 dsp->f.subclass = 'u';
01537 dsp->thinkdigit = 0;
01538 }
01539 FIX_INF(af);
01540 if (chan)
01541 ast_queue_frame(chan, af);
01542 ast_frfree(af);
01543 return &dsp->f;
01544 }
01545 }
01546 }
01547 } else if (!digit) {
01548
01549 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01550 if (dsp->td.mf.current_digits) {
01551 memset(&dsp->f, 0, sizeof(dsp->f));
01552 dsp->f.frametype = AST_FRAME_DTMF;
01553 dsp->f.subclass = dsp->td.mf.digits[0];
01554 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01555 dsp->td.mf.current_digits--;
01556 FIX_INF(af);
01557 if (chan)
01558 ast_queue_frame(chan, af);
01559 ast_frfree(af);
01560 return &dsp->f;
01561 }
01562 } else {
01563 if (dsp->td.dtmf.current_digits) {
01564 memset(&dsp->f, 0, sizeof(dsp->f));
01565 dsp->f.frametype = AST_FRAME_DTMF;
01566 dsp->f.subclass = dsp->td.dtmf.digits[0];
01567 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01568 dsp->td.dtmf.current_digits--;
01569 FIX_INF(af);
01570 if (chan)
01571 ast_queue_frame(chan, af);
01572 ast_frfree(af);
01573 return &dsp->f;
01574 }
01575 }
01576 }
01577 }
01578 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01579 res = __ast_dsp_call_progress(dsp, shortdata, len);
01580 memset(&dsp->f, 0, sizeof(dsp->f));
01581 dsp->f.frametype = AST_FRAME_CONTROL;
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 dsp->f.subclass = res;
01589 if (chan)
01590 ast_queue_frame(chan, &dsp->f);
01591 break;
01592 default:
01593 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01594 }
01595 }
01596 }
01597 FIX_INF(af);
01598 return af;
01599 }
01600
01601 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01602 {
01603 int max = 0;
01604 int x;
01605 dsp->gsamp_size = modes[dsp->progmode].size;
01606 dsp->gsamps = 0;
01607 for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
01608 if (modes[dsp->progmode].freqs[x]) {
01609 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01610 max = x;
01611 }
01612 }
01613 dsp->freqcount = max;
01614 }
01615
01616 struct ast_dsp *ast_dsp_new(void)
01617 {
01618 struct ast_dsp *dsp;
01619 dsp = malloc(sizeof(struct ast_dsp));
01620 if (dsp) {
01621 memset(dsp, 0, sizeof(struct ast_dsp));
01622 dsp->threshold = DEFAULT_THRESHOLD;
01623 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01624 dsp->busycount = DSP_HISTORY;
01625
01626 ast_dtmf_detect_init(&dsp->td.dtmf);
01627
01628 ast_dsp_prog_reset(dsp);
01629 }
01630 return dsp;
01631 }
01632
01633 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01634 {
01635 dsp->features = features;
01636 }
01637
01638 void ast_dsp_free(struct ast_dsp *dsp)
01639 {
01640 free(dsp);
01641 }
01642
01643 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01644 {
01645 dsp->threshold = threshold;
01646 }
01647
01648 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01649 {
01650 if (cadences < 4)
01651 cadences = 4;
01652 if (cadences > DSP_HISTORY)
01653 cadences = DSP_HISTORY;
01654 dsp->busycount = cadences;
01655 }
01656
01657 void ast_dsp_digitreset(struct ast_dsp *dsp)
01658 {
01659 int i;
01660 dsp->thinkdigit = 0;
01661 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01662 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01663 dsp->td.mf.current_digits = 0;
01664
01665 for (i = 0; i < 6; i++) {
01666 goertzel_reset(&dsp->td.mf.tone_out[i]);
01667 #ifdef OLD_DSP_ROUTINES
01668 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01669 #endif
01670 }
01671 #ifdef OLD_DSP_ROUTINES
01672 dsp->td.mf.energy = 0.0;
01673 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01674 #else
01675 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;
01676 #endif
01677 dsp->td.mf.current_sample = 0;
01678 } else {
01679 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01680 dsp->td.dtmf.current_digits = 0;
01681
01682 for (i = 0; i < 4; i++) {
01683 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01684 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01685 #ifdef OLD_DSP_ROUTINES
01686 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01687 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01688 #endif
01689 }
01690 #ifdef FAX_DETECT
01691 goertzel_reset (&dsp->td.dtmf.fax_tone);
01692 #endif
01693 #ifdef OLD_DSP_ROUTINES
01694 #ifdef FAX_DETECT
01695 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01696 #endif
01697 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01698 #else
01699 dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0;
01700 #endif
01701 dsp->td.dtmf.energy = 0.0;
01702 dsp->td.dtmf.current_sample = 0;
01703 }
01704 }
01705
01706 void ast_dsp_reset(struct ast_dsp *dsp)
01707 {
01708 int x;
01709 dsp->totalsilence = 0;
01710 dsp->gsamps = 0;
01711 for (x=0;x<4;x++)
01712 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01713 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01714 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01715
01716 }
01717
01718 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01719 {
01720 int new, old;
01721 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01722 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01723 if (old != new) {
01724
01725 if (new & DSP_DIGITMODE_MF)
01726 ast_mf_detect_init(&dsp->td.mf);
01727 else
01728 ast_dtmf_detect_init(&dsp->td.dtmf);
01729 }
01730 dsp->digitmode = digitmode;
01731 return 0;
01732 }
01733
01734 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01735 {
01736 int x;
01737 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01738 if (!strcasecmp(aliases[x].name, zone)) {
01739 dsp->progmode = aliases[x].mode;
01740 ast_dsp_prog_reset(dsp);
01741 return 0;
01742 }
01743 }
01744 return -1;
01745 }