Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

dsp.c

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

Generated on Fri Sep 24 21:03:47 2004 for Asterisk by doxygen 1.3.8