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