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