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: 58388 $")
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 #ifndef BUSYDETECT_TONEONLY
01283
01284 if (res && (dsp->busy_quietlength > 0)) {
01285 if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01286 #if 0
01287 ast_log(LOG_NOTICE, "busy detector: avgsilence of %d not close enough to desired %d\n",
01288 avgsilence, dsp->busy_quietlength);
01289 #endif
01290 res = 0;
01291 }
01292 }
01293 #endif
01294 #if 1
01295 #ifndef BUSYDETECT_TONEONLY
01296 if (res)
01297 ast_log(LOG_DEBUG, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01298 #endif
01299 #endif
01300 return res;
01301 }
01302 #endif
01303
01304 #ifdef BUSYDETECT
01305 int ast_dsp_busydetect(struct ast_dsp *dsp)
01306 {
01307 int x;
01308 int res = 0;
01309 int max, min;
01310
01311 #if 0
01312 if (dsp->busy_hits > 5);
01313 return 0;
01314 #endif
01315 if (dsp->busymaybe) {
01316 #if 0
01317 printf("Maybe busy!\n");
01318 #endif
01319 dsp->busymaybe = 0;
01320 min = 9999;
01321 max = 0;
01322 for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01323 #if 0
01324 printf("Silence: %d, Noise: %d\n", dsp->historicsilence[x], dsp->historicnoise[x]);
01325 #endif
01326 if (dsp->historicsilence[x] < min)
01327 min = dsp->historicsilence[x];
01328 if (dsp->historicnoise[x] < min)
01329 min = dsp->historicnoise[x];
01330 if (dsp->historicsilence[x] > max)
01331 max = dsp->historicsilence[x];
01332 if (dsp->historicnoise[x] > max)
01333 max = dsp->historicnoise[x];
01334 }
01335 if ((max - min < BUSY_THRESHOLD) && (max < BUSY_MAX) && (min > BUSY_MIN)) {
01336 #if 0
01337 printf("Busy!\n");
01338 #endif
01339 res = 1;
01340 }
01341 #if 0
01342 printf("Min: %d, max: %d\n", min, max);
01343 #endif
01344 }
01345 return res;
01346 }
01347 #endif
01348
01349 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01350 {
01351 short *s;
01352 int len;
01353
01354 if (f->frametype != AST_FRAME_VOICE) {
01355 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01356 return 0;
01357 }
01358 if (f->subclass != AST_FORMAT_SLINEAR) {
01359 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01360 return 0;
01361 }
01362 s = f->data;
01363 len = f->datalen/2;
01364 return __ast_dsp_silence(dsp, s, len, totalsilence);
01365 }
01366
01367 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01368 {
01369 int silence;
01370 int res;
01371 int digit;
01372 int x;
01373 short *shortdata;
01374 unsigned char *odata;
01375 int len;
01376 int writeback = 0;
01377
01378 #define FIX_INF(inf) do { \
01379 if (writeback) { \
01380 switch(inf->subclass) { \
01381 case AST_FORMAT_SLINEAR: \
01382 break; \
01383 case AST_FORMAT_ULAW: \
01384 for (x=0;x<len;x++) \
01385 odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01386 break; \
01387 case AST_FORMAT_ALAW: \
01388 for (x=0;x<len;x++) \
01389 odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01390 break; \
01391 } \
01392 } \
01393 } while(0)
01394
01395 if (!af)
01396 return NULL;
01397 if (af->frametype != AST_FRAME_VOICE)
01398 return af;
01399 odata = af->data;
01400 len = af->datalen;
01401
01402 switch(af->subclass) {
01403 case AST_FORMAT_SLINEAR:
01404 shortdata = af->data;
01405 len = af->datalen / 2;
01406 break;
01407 case AST_FORMAT_ULAW:
01408 shortdata = alloca(af->datalen * 2);
01409 if (!shortdata) {
01410 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01411 return af;
01412 }
01413 for (x=0;x<len;x++)
01414 shortdata[x] = AST_MULAW(odata[x]);
01415 break;
01416 case AST_FORMAT_ALAW:
01417 shortdata = alloca(af->datalen * 2);
01418 if (!shortdata) {
01419 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01420 return af;
01421 }
01422 for (x=0;x<len;x++)
01423 shortdata[x] = AST_ALAW(odata[x]);
01424 break;
01425 default:
01426 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01427 return af;
01428 }
01429 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01430 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01431 memset(&dsp->f, 0, sizeof(dsp->f));
01432 dsp->f.frametype = AST_FRAME_NULL;
01433 return &dsp->f;
01434 }
01435 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01436 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01437 memset(&dsp->f, 0, sizeof(dsp->f));
01438 dsp->f.frametype = AST_FRAME_CONTROL;
01439 dsp->f.subclass = AST_CONTROL_BUSY;
01440 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01441 return &dsp->f;
01442 }
01443 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01444 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01445 #if 0
01446 if (digit)
01447 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01448 #endif
01449 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01450 if (!dsp->thinkdigit) {
01451 if (digit) {
01452
01453
01454 memset(&dsp->f, 0, sizeof(dsp->f));
01455 dsp->f.frametype = AST_FRAME_DTMF;
01456 dsp->f.subclass = 'm';
01457 dsp->thinkdigit = 'x';
01458 FIX_INF(af);
01459 if (chan)
01460 ast_queue_frame(chan, af);
01461 ast_frfree(af);
01462 return &dsp->f;
01463 }
01464 } else {
01465 if (digit) {
01466
01467 if (dsp->thinkdigit) {
01468 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01469
01470
01471
01472 memset(&dsp->f, 0, sizeof(dsp->f));
01473 dsp->f.frametype = AST_FRAME_DTMF;
01474 dsp->f.subclass = dsp->thinkdigit;
01475 FIX_INF(af);
01476 if (chan)
01477 ast_queue_frame(chan, af);
01478 ast_frfree(af);
01479 }
01480 dsp->thinkdigit = digit;
01481 return &dsp->f;
01482 }
01483 dsp->thinkdigit = digit;
01484 } else {
01485 if (dsp->thinkdigit) {
01486 memset(&dsp->f, 0, sizeof(dsp->f));
01487 if (dsp->thinkdigit != 'x') {
01488
01489 dsp->f.frametype = AST_FRAME_DTMF;
01490 dsp->f.subclass = dsp->thinkdigit;
01491 dsp->thinkdigit = 0;
01492 } else {
01493 dsp->f.frametype = AST_FRAME_DTMF;
01494 dsp->f.subclass = 'u';
01495 dsp->thinkdigit = 0;
01496 }
01497 FIX_INF(af);
01498 if (chan)
01499 ast_queue_frame(chan, af);
01500 ast_frfree(af);
01501 return &dsp->f;
01502 }
01503 }
01504 }
01505 } else if (!digit) {
01506
01507 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01508 if (dsp->td.mf.current_digits) {
01509 memset(&dsp->f, 0, sizeof(dsp->f));
01510 dsp->f.frametype = AST_FRAME_DTMF;
01511 dsp->f.subclass = dsp->td.mf.digits[0];
01512 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01513 dsp->td.mf.current_digits--;
01514 FIX_INF(af);
01515 if (chan)
01516 ast_queue_frame(chan, af);
01517 ast_frfree(af);
01518 return &dsp->f;
01519 }
01520 } else {
01521 if (dsp->td.dtmf.current_digits) {
01522 memset(&dsp->f, 0, sizeof(dsp->f));
01523 dsp->f.frametype = AST_FRAME_DTMF;
01524 dsp->f.subclass = dsp->td.dtmf.digits[0];
01525 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01526 dsp->td.dtmf.current_digits--;
01527 FIX_INF(af);
01528 if (chan)
01529 ast_queue_frame(chan, af);
01530 ast_frfree(af);
01531 return &dsp->f;
01532 }
01533 }
01534 }
01535 }
01536 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01537 res = __ast_dsp_call_progress(dsp, shortdata, len);
01538 if (res) {
01539 switch(res) {
01540 case AST_CONTROL_ANSWER:
01541 case AST_CONTROL_BUSY:
01542 case AST_CONTROL_RINGING:
01543 case AST_CONTROL_CONGESTION:
01544 case AST_CONTROL_HANGUP:
01545 memset(&dsp->f, 0, sizeof(dsp->f));
01546 dsp->f.frametype = AST_FRAME_CONTROL;
01547 dsp->f.subclass = res;
01548 dsp->f.src = "dsp_progress";
01549 if (chan)
01550 ast_queue_frame(chan, &dsp->f);
01551 break;
01552 default:
01553 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01554 }
01555 }
01556 }
01557 FIX_INF(af);
01558 return af;
01559 }
01560
01561 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01562 {
01563 int max = 0;
01564 int x;
01565
01566 dsp->gsamp_size = modes[dsp->progmode].size;
01567 dsp->gsamps = 0;
01568 for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
01569 if (modes[dsp->progmode].freqs[x]) {
01570 goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01571 max = x + 1;
01572 }
01573 }
01574 dsp->freqcount = max;
01575 }
01576
01577 struct ast_dsp *ast_dsp_new(void)
01578 {
01579 struct ast_dsp *dsp;
01580
01581 dsp = malloc(sizeof(struct ast_dsp));
01582 if (dsp) {
01583 memset(dsp, 0, sizeof(struct ast_dsp));
01584 dsp->threshold = DEFAULT_THRESHOLD;
01585 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01586 dsp->busycount = DSP_HISTORY;
01587
01588 ast_dtmf_detect_init(&dsp->td.dtmf);
01589
01590 ast_dsp_prog_reset(dsp);
01591 }
01592 return dsp;
01593 }
01594
01595 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01596 {
01597 dsp->features = features;
01598 }
01599
01600 void ast_dsp_free(struct ast_dsp *dsp)
01601 {
01602 free(dsp);
01603 }
01604
01605 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01606 {
01607 dsp->threshold = threshold;
01608 }
01609
01610 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01611 {
01612 if (cadences < 4)
01613 cadences = 4;
01614 if (cadences > DSP_HISTORY)
01615 cadences = DSP_HISTORY;
01616 dsp->busycount = cadences;
01617 }
01618
01619 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
01620 {
01621 dsp->busy_tonelength = tonelength;
01622 dsp->busy_quietlength = quietlength;
01623 ast_log(LOG_DEBUG, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01624 }
01625
01626 void ast_dsp_digitreset(struct ast_dsp *dsp)
01627 {
01628 int i;
01629
01630 dsp->thinkdigit = 0;
01631 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01632 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01633 dsp->td.mf.current_digits = 0;
01634
01635 for (i = 0; i < 6; i++) {
01636 goertzel_reset(&dsp->td.mf.tone_out[i]);
01637 #ifdef OLD_DSP_ROUTINES
01638 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01639 #endif
01640 }
01641 #ifdef OLD_DSP_ROUTINES
01642 dsp->td.mf.energy = 0.0;
01643 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01644 #else
01645 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;
01646 #endif
01647 dsp->td.mf.current_sample = 0;
01648 } else {
01649 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01650 dsp->td.dtmf.current_digits = 0;
01651
01652 for (i = 0; i < 4; i++) {
01653 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01654 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01655 #ifdef OLD_DSP_ROUTINES
01656 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01657 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01658 #endif
01659 }
01660 #ifdef FAX_DETECT
01661 goertzel_reset (&dsp->td.dtmf.fax_tone);
01662 #endif
01663 #ifdef OLD_DSP_ROUTINES
01664 #ifdef FAX_DETECT
01665 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01666 #endif
01667 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01668 #else
01669 dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0;
01670 #endif
01671 dsp->td.dtmf.energy = 0.0;
01672 dsp->td.dtmf.current_sample = 0;
01673 }
01674 }
01675
01676 void ast_dsp_reset(struct ast_dsp *dsp)
01677 {
01678 int x;
01679
01680 dsp->totalsilence = 0;
01681 dsp->gsamps = 0;
01682 for (x=0;x<4;x++)
01683 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01684 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01685 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01686 }
01687
01688 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01689 {
01690 int new;
01691 int old;
01692
01693 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01694 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01695 if (old != new) {
01696
01697 if (new & DSP_DIGITMODE_MF)
01698 ast_mf_detect_init(&dsp->td.mf);
01699 else
01700 ast_dtmf_detect_init(&dsp->td.dtmf);
01701 }
01702 dsp->digitmode = digitmode;
01703 return 0;
01704 }
01705
01706 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01707 {
01708 int x;
01709
01710 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01711 if (!strcasecmp(aliases[x].name, zone)) {
01712 dsp->progmode = aliases[x].mode;
01713 ast_dsp_prog_reset(dsp);
01714 return 0;
01715 }
01716 }
01717 return -1;
01718 }
01719
01720 int ast_dsp_get_tstate(struct ast_dsp *dsp)
01721 {
01722 return dsp->tstate;
01723 }
01724
01725 int ast_dsp_get_tcount(struct ast_dsp *dsp)
01726 {
01727 return dsp->tcount;
01728 }