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

Generated on Sat Jun 12 16:40:58 2004 for Asterisk by doxygen 1.3.7