1 /* 2 * DTMF decoder. 3 * 4 * Copyright by Andreas Eversberg (jolly@eversberg.eu) 5 * based on different decoders such as ISDN4Linux 6 * 7 * This software may be used and distributed according to the terms 8 * of the GNU General Public License, incorporated herein by reference. 9 * 10 */ 11 12 #include <linux/mISDNif.h> 13 #include <linux/mISDNdsp.h> 14 #include "core.h" 15 #include "dsp.h" 16 17 #define NCOEFF 8 /* number of frequencies to be analyzed */ 18 19 /* For DTMF recognition: 20 * 2 * cos(2 * PI * k / N) precalculated for all k 21 */ 22 static u64 cos2pik[NCOEFF] = 23 { 24 /* k << 15 (source: hfc-4s/8s documentation (www.colognechip.de)) */ 25 55960, 53912, 51402, 48438, 38146, 32650, 26170, 18630 26 }; 27 28 /* digit matrix */ 29 static char dtmf_matrix[4][4] = 30 { 31 {'1', '2', '3', 'A'}, 32 {'4', '5', '6', 'B'}, 33 {'7', '8', '9', 'C'}, 34 {'*', '0', '#', 'D'} 35 }; 36 37 /* dtmf detection using goertzel algorithm 38 * init function 39 */ 40 void dsp_dtmf_goertzel_init(struct dsp *dsp) 41 { 42 dsp->dtmf.size = 0; 43 dsp->dtmf.lastwhat = '\0'; 44 dsp->dtmf.lastdigit = '\0'; 45 dsp->dtmf.count = 0; 46 } 47 48 /* check for hardware or software features 49 */ 50 void dsp_dtmf_hardware(struct dsp *dsp) 51 { 52 int hardware = 1; 53 54 if (!dsp->features.hfc_dtmf) 55 hardware = 0; 56 57 /* check for volume change */ 58 if (dsp->tx_volume) { 59 if (dsp_debug & DEBUG_DSP_DTMF) 60 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " 61 "because tx_volume is changed\n", 62 __func__, dsp->name); 63 hardware = 0; 64 } 65 if (dsp->rx_volume) { 66 if (dsp_debug & DEBUG_DSP_DTMF) 67 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " 68 "because rx_volume is changed\n", 69 __func__, dsp->name); 70 hardware = 0; 71 } 72 /* check if encryption is enabled */ 73 if (dsp->bf_enable) { 74 if (dsp_debug & DEBUG_DSP_DTMF) 75 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " 76 "because encryption is enabled\n", 77 __func__, dsp->name); 78 hardware = 0; 79 } 80 /* check if pipeline exists */ 81 if (dsp->pipeline.inuse) { 82 if (dsp_debug & DEBUG_DSP_DTMF) 83 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, " 84 "because pipeline exists.\n", 85 __func__, dsp->name); 86 hardware = 0; 87 } 88 89 dsp->dtmf.hardware = hardware; 90 dsp->dtmf.software = !hardware; 91 } 92 93 94 /************************************************************* 95 * calculate the coefficients of the given sample and decode * 96 *************************************************************/ 97 98 /* the given sample is decoded. if the sample is not long enough for a 99 * complete frame, the decoding is finished and continued with the next 100 * call of this function. 101 * 102 * the algorithm is very good for detection with a minimum of errors. i 103 * tested it allot. it even works with very short tones (40ms). the only 104 * disadvantage is, that it doesn't work good with different volumes of both 105 * tones. this will happen, if accoustically coupled dialers are used. 106 * it sometimes detects tones during speach, which is normal for decoders. 107 * use sequences to given commands during calls. 108 * 109 * dtmf - points to a structure of the current dtmf state 110 * spl and len - the sample 111 * fmt - 0 = alaw, 1 = ulaw, 2 = coefficients from HFC DTMF hw-decoder 112 */ 113 114 u8 115 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, int fmt) 116 { 117 u8 what; 118 int size; 119 signed short *buf; 120 s32 sk, sk1, sk2; 121 int k, n, i; 122 s32 *hfccoeff; 123 s32 result[NCOEFF], tresh, treshl; 124 int lowgroup, highgroup; 125 s64 cos2pik_; 126 127 dsp->dtmf.digits[0] = '\0'; 128 129 /* Note: The function will loop until the buffer has not enough samples 130 * left to decode a full frame. 131 */ 132 again: 133 /* convert samples */ 134 size = dsp->dtmf.size; 135 buf = dsp->dtmf.buffer; 136 switch (fmt) { 137 case 0: /* alaw */ 138 case 1: /* ulaw */ 139 while (size < DSP_DTMF_NPOINTS && len) { 140 buf[size++] = dsp_audio_law_to_s32[*data++]; 141 len--; 142 } 143 break; 144 145 case 2: /* HFC coefficients */ 146 default: 147 if (len < 64) { 148 if (len > 0) 149 printk(KERN_ERR "%s: coefficients have invalid " 150 "size. (is=%d < must=%d)\n", 151 __func__, len, 64); 152 return dsp->dtmf.digits; 153 } 154 hfccoeff = (s32 *)data; 155 for (k = 0; k < NCOEFF; k++) { 156 sk2 = (*hfccoeff++)>>4; 157 sk = (*hfccoeff++)>>4; 158 if (sk > 32767 || sk < -32767 || sk2 > 32767 159 || sk2 < -32767) 160 printk(KERN_WARNING 161 "DTMF-Detection overflow\n"); 162 /* compute |X(k)|**2 */ 163 result[k] = 164 (sk * sk) - 165 (((cos2pik[k] * sk) >> 15) * sk2) + 166 (sk2 * sk2); 167 } 168 data += 64; 169 len -= 64; 170 goto coefficients; 171 break; 172 } 173 dsp->dtmf.size = size; 174 175 if (size < DSP_DTMF_NPOINTS) 176 return dsp->dtmf.digits; 177 178 dsp->dtmf.size = 0; 179 180 /* now we have a full buffer of signed long samples - we do goertzel */ 181 for (k = 0; k < NCOEFF; k++) { 182 sk = 0; 183 sk1 = 0; 184 sk2 = 0; 185 buf = dsp->dtmf.buffer; 186 cos2pik_ = cos2pik[k]; 187 for (n = 0; n < DSP_DTMF_NPOINTS; n++) { 188 sk = ((cos2pik_*sk1)>>15) - sk2 + (*buf++); 189 sk2 = sk1; 190 sk1 = sk; 191 } 192 sk >>= 8; 193 sk2 >>= 8; 194 if (sk > 32767 || sk < -32767 || sk2 > 32767 || sk2 < -32767) 195 printk(KERN_WARNING "DTMF-Detection overflow\n"); 196 /* compute |X(k)|**2 */ 197 result[k] = 198 (sk * sk) - 199 (((cos2pik[k] * sk) >> 15) * sk2) + 200 (sk2 * sk2); 201 } 202 203 /* our (squared) coefficients have been calculated, we need to process 204 * them. 205 */ 206 coefficients: 207 tresh = 0; 208 for (i = 0; i < NCOEFF; i++) { 209 if (result[i] < 0) 210 result[i] = 0; 211 if (result[i] > dsp->dtmf.treshold) { 212 if (result[i] > tresh) 213 tresh = result[i]; 214 } 215 } 216 217 if (tresh == 0) { 218 what = 0; 219 goto storedigit; 220 } 221 222 if (dsp_debug & DEBUG_DSP_DTMFCOEFF) 223 printk(KERN_DEBUG "a %3d %3d %3d %3d %3d %3d %3d %3d" 224 " tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n", 225 result[0]/10000, result[1]/10000, result[2]/10000, 226 result[3]/10000, result[4]/10000, result[5]/10000, 227 result[6]/10000, result[7]/10000, tresh/10000, 228 result[0]/(tresh/100), result[1]/(tresh/100), 229 result[2]/(tresh/100), result[3]/(tresh/100), 230 result[4]/(tresh/100), result[5]/(tresh/100), 231 result[6]/(tresh/100), result[7]/(tresh/100)); 232 233 /* calc digit (lowgroup/highgroup) */ 234 lowgroup = -1; 235 highgroup = -1; 236 treshl = tresh >> 3; /* tones which are not on, must be below 9 dB */ 237 tresh = tresh >> 2; /* touchtones must match within 6 dB */ 238 for (i = 0; i < NCOEFF; i++) { 239 if (result[i] < treshl) 240 continue; /* ignore */ 241 if (result[i] < tresh) { 242 lowgroup = -1; 243 highgroup = -1; 244 break; /* noise inbetween */ 245 } 246 /* good level found. This is allowed only one time per group */ 247 if (i < NCOEFF/2) { 248 /* lowgroup */ 249 if (lowgroup >= 0) { 250 /* Bad. Another tone found. */ 251 lowgroup = -1; 252 break; 253 } else 254 lowgroup = i; 255 } else { 256 /* higroup */ 257 if (highgroup >= 0) { 258 /* Bad. Another tone found. */ 259 highgroup = -1; 260 break; 261 } else 262 highgroup = i-(NCOEFF/2); 263 } 264 } 265 266 /* get digit or null */ 267 what = 0; 268 if (lowgroup >= 0 && highgroup >= 0) 269 what = dtmf_matrix[lowgroup][highgroup]; 270 271 storedigit: 272 if (what && (dsp_debug & DEBUG_DSP_DTMF)) 273 printk(KERN_DEBUG "DTMF what: %c\n", what); 274 275 if (dsp->dtmf.lastwhat != what) 276 dsp->dtmf.count = 0; 277 278 /* the tone (or no tone) must remain 3 times without change */ 279 if (dsp->dtmf.count == 2) { 280 if (dsp->dtmf.lastdigit != what) { 281 dsp->dtmf.lastdigit = what; 282 if (what) { 283 if (dsp_debug & DEBUG_DSP_DTMF) 284 printk(KERN_DEBUG "DTMF digit: %c\n", 285 what); 286 if ((strlen(dsp->dtmf.digits)+1) 287 < sizeof(dsp->dtmf.digits)) { 288 dsp->dtmf.digits[strlen( 289 dsp->dtmf.digits)+1] = '\0'; 290 dsp->dtmf.digits[strlen( 291 dsp->dtmf.digits)] = what; 292 } 293 } 294 } 295 } else 296 dsp->dtmf.count++; 297 298 dsp->dtmf.lastwhat = what; 299 300 goto again; 301 } 302 303 304