1 2/* 3 * 4 Copyright (c) Eicon Networks, 2002. 5 * 6 This source file is supplied for the use with 7 Eicon Networks range of DIVA Server Adapters. 8 * 9 Eicon File Revision : 2.1 10 * 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 2, or (at your option) 14 any later version. 15 * 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 See the GNU General Public License for more details. 20 * 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 25 */ 26 27#include "platform.h" 28 29 30 31 32 33 34 35 36 37#include "capidtmf.h" 38 39/* #define TRACE_ */ 40 41#define FILE_ "CAPIDTMF.C" 42 43/*---------------------------------------------------------------------------*/ 44 45 46#define trace(a) 47 48 49 50/*---------------------------------------------------------------------------*/ 51 52static short capidtmf_expand_table_alaw[0x0100] = 53{ 54 -5504, 5504, -344, 344, -22016, 22016, -1376, 1376, 55 -2752, 2752, -88, 88, -11008, 11008, -688, 688, 56 -7552, 7552, -472, 472, -30208, 30208, -1888, 1888, 57 -3776, 3776, -216, 216, -15104, 15104, -944, 944, 58 -4480, 4480, -280, 280, -17920, 17920, -1120, 1120, 59 -2240, 2240, -24, 24, -8960, 8960, -560, 560, 60 -6528, 6528, -408, 408, -26112, 26112, -1632, 1632, 61 -3264, 3264, -152, 152, -13056, 13056, -816, 816, 62 -6016, 6016, -376, 376, -24064, 24064, -1504, 1504, 63 -3008, 3008, -120, 120, -12032, 12032, -752, 752, 64 -8064, 8064, -504, 504, -32256, 32256, -2016, 2016, 65 -4032, 4032, -248, 248, -16128, 16128, -1008, 1008, 66 -4992, 4992, -312, 312, -19968, 19968, -1248, 1248, 67 -2496, 2496, -56, 56, -9984, 9984, -624, 624, 68 -7040, 7040, -440, 440, -28160, 28160, -1760, 1760, 69 -3520, 3520, -184, 184, -14080, 14080, -880, 880, 70 -5248, 5248, -328, 328, -20992, 20992, -1312, 1312, 71 -2624, 2624, -72, 72, -10496, 10496, -656, 656, 72 -7296, 7296, -456, 456, -29184, 29184, -1824, 1824, 73 -3648, 3648, -200, 200, -14592, 14592, -912, 912, 74 -4224, 4224, -264, 264, -16896, 16896, -1056, 1056, 75 -2112, 2112, -8, 8, -8448, 8448, -528, 528, 76 -6272, 6272, -392, 392, -25088, 25088, -1568, 1568, 77 -3136, 3136, -136, 136, -12544, 12544, -784, 784, 78 -5760, 5760, -360, 360, -23040, 23040, -1440, 1440, 79 -2880, 2880, -104, 104, -11520, 11520, -720, 720, 80 -7808, 7808, -488, 488, -31232, 31232, -1952, 1952, 81 -3904, 3904, -232, 232, -15616, 15616, -976, 976, 82 -4736, 4736, -296, 296, -18944, 18944, -1184, 1184, 83 -2368, 2368, -40, 40, -9472, 9472, -592, 592, 84 -6784, 6784, -424, 424, -27136, 27136, -1696, 1696, 85 -3392, 3392, -168, 168, -13568, 13568, -848, 848 86}; 87 88static short capidtmf_expand_table_ulaw[0x0100] = 89{ 90 -32124, 32124, -1884, 1884, -7932, 7932, -372, 372, 91 -15996, 15996, -876, 876, -3900, 3900, -120, 120, 92 -23932, 23932, -1372, 1372, -5884, 5884, -244, 244, 93 -11900, 11900, -620, 620, -2876, 2876, -56, 56, 94 -28028, 28028, -1628, 1628, -6908, 6908, -308, 308, 95 -13948, 13948, -748, 748, -3388, 3388, -88, 88, 96 -19836, 19836, -1116, 1116, -4860, 4860, -180, 180, 97 -9852, 9852, -492, 492, -2364, 2364, -24, 24, 98 -30076, 30076, -1756, 1756, -7420, 7420, -340, 340, 99 -14972, 14972, -812, 812, -3644, 3644, -104, 104, 100 -21884, 21884, -1244, 1244, -5372, 5372, -212, 212, 101 -10876, 10876, -556, 556, -2620, 2620, -40, 40, 102 -25980, 25980, -1500, 1500, -6396, 6396, -276, 276, 103 -12924, 12924, -684, 684, -3132, 3132, -72, 72, 104 -17788, 17788, -988, 988, -4348, 4348, -148, 148, 105 -8828, 8828, -428, 428, -2108, 2108, -8, 8, 106 -31100, 31100, -1820, 1820, -7676, 7676, -356, 356, 107 -15484, 15484, -844, 844, -3772, 3772, -112, 112, 108 -22908, 22908, -1308, 1308, -5628, 5628, -228, 228, 109 -11388, 11388, -588, 588, -2748, 2748, -48, 48, 110 -27004, 27004, -1564, 1564, -6652, 6652, -292, 292, 111 -13436, 13436, -716, 716, -3260, 3260, -80, 80, 112 -18812, 18812, -1052, 1052, -4604, 4604, -164, 164, 113 -9340, 9340, -460, 460, -2236, 2236, -16, 16, 114 -29052, 29052, -1692, 1692, -7164, 7164, -324, 324, 115 -14460, 14460, -780, 780, -3516, 3516, -96, 96, 116 -20860, 20860, -1180, 1180, -5116, 5116, -196, 196, 117 -10364, 10364, -524, 524, -2492, 2492, -32, 32, 118 -24956, 24956, -1436, 1436, -6140, 6140, -260, 260, 119 -12412, 12412, -652, 652, -3004, 3004, -64, 64, 120 -16764, 16764, -924, 924, -4092, 4092, -132, 132, 121 -8316, 8316, -396, 396, -1980, 1980, 0, 0 122}; 123 124 125/*---------------------------------------------------------------------------*/ 126 127static short capidtmf_recv_window_function[CAPIDTMF_RECV_ACCUMULATE_CYCLES] = 128{ 129 -500L, -999L, -1499L, -1998L, -2496L, -2994L, -3491L, -3988L, 130 -4483L, -4978L, -5471L, -5963L, -6454L, -6943L, -7431L, -7917L, 131 -8401L, -8883L, -9363L, -9840L, -10316L, -10789L, -11259L, -11727L, 132 -12193L, -12655L, -13115L, -13571L, -14024L, -14474L, -14921L, -15364L, 133 -15804L, -16240L, -16672L, -17100L, -17524L, -17944L, -18360L, -18772L, 134 -19180L, -19583L, -19981L, -20375L, -20764L, -21148L, -21527L, -21901L, 135 -22270L, -22634L, -22993L, -23346L, -23694L, -24037L, -24374L, -24705L, 136 -25030L, -25350L, -25664L, -25971L, -26273L, -26568L, -26858L, -27141L, 137 -27418L, -27688L, -27952L, -28210L, -28461L, -28705L, -28943L, -29174L, 138 -29398L, -29615L, -29826L, -30029L, -30226L, -30415L, -30598L, -30773L, 139 -30941L, -31102L, -31256L, -31402L, -31541L, -31673L, -31797L, -31914L, 140 -32024L, -32126L, -32221L, -32308L, -32388L, -32460L, -32524L, -32581L, 141 -32631L, -32673L, -32707L, -32734L, -32753L, -32764L, -32768L, -32764L, 142 -32753L, -32734L, -32707L, -32673L, -32631L, -32581L, -32524L, -32460L, 143 -32388L, -32308L, -32221L, -32126L, -32024L, -31914L, -31797L, -31673L, 144 -31541L, -31402L, -31256L, -31102L, -30941L, -30773L, -30598L, -30415L, 145 -30226L, -30029L, -29826L, -29615L, -29398L, -29174L, -28943L, -28705L, 146 -28461L, -28210L, -27952L, -27688L, -27418L, -27141L, -26858L, -26568L, 147 -26273L, -25971L, -25664L, -25350L, -25030L, -24705L, -24374L, -24037L, 148 -23694L, -23346L, -22993L, -22634L, -22270L, -21901L, -21527L, -21148L, 149 -20764L, -20375L, -19981L, -19583L, -19180L, -18772L, -18360L, -17944L, 150 -17524L, -17100L, -16672L, -16240L, -15804L, -15364L, -14921L, -14474L, 151 -14024L, -13571L, -13115L, -12655L, -12193L, -11727L, -11259L, -10789L, 152 -10316L, -9840L, -9363L, -8883L, -8401L, -7917L, -7431L, -6943L, 153 -6454L, -5963L, -5471L, -4978L, -4483L, -3988L, -3491L, -2994L, 154 -2496L, -1998L, -1499L, -999L, -500L, 155}; 156 157static byte capidtmf_leading_zeroes_table[0x100] = 158{ 159 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 160 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 161 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 162 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 163 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 164 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 165 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 166 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 175}; 176 177#define capidtmf_byte_leading_zeroes(b) (capidtmf_leading_zeroes_table[(BYTE)(b)]) 178#define capidtmf_word_leading_zeroes(w) (((w) & 0xff00) ? capidtmf_leading_zeroes_table[(w) >> 8] : 8 + capidtmf_leading_zeroes_table[(w)]) 179#define capidtmf_dword_leading_zeroes(d) (((d) & 0xffff0000L) ? (((d) & 0xff000000L) ? capidtmf_leading_zeroes_table[(d) >> 24] : 8 + capidtmf_leading_zeroes_table[(d) >> 16]) : (((d) & 0xff00) ? 16 + capidtmf_leading_zeroes_table[(d) >> 8] : 24 + capidtmf_leading_zeroes_table[(d)])) 180 181 182/*---------------------------------------------------------------------------*/ 183 184 185static void capidtmf_goertzel_loop(long *buffer, long *coeffs, short *sample, long count) 186{ 187 int i, j; 188 long c, d, q0, q1, q2; 189 190 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1; i++) 191 { 192 q1 = buffer[i]; 193 q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; 194 d = coeffs[i] >> 1; 195 c = d << 1; 196 if (c >= 0) 197 { 198 for (j = 0; j < count; j++) 199 { 200 q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15); 201 q2 = q1; 202 q1 = q0; 203 } 204 } 205 else 206 { 207 c = -c; 208 d = -d; 209 for (j = 0; j < count; j++) 210 { 211 q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15)); 212 q2 = q1; 213 q1 = q0; 214 } 215 } 216 buffer[i] = q1; 217 buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2; 218 } 219 q1 = buffer[i]; 220 q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; 221 c = (coeffs[i] >> 1) << 1; 222 if (c >= 0) 223 { 224 for (j = 0; j < count; j++) 225 { 226 q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15); 227 q2 = q1; 228 q1 = q0; 229 c -= CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT; 230 } 231 } 232 else 233 { 234 c = -c; 235 for (j = 0; j < count; j++) 236 { 237 q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15)); 238 q2 = q1; 239 q1 = q0; 240 c += CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT; 241 } 242 } 243 coeffs[i] = c; 244 buffer[i] = q1; 245 buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2; 246} 247 248 249static void capidtmf_goertzel_result(long *buffer, long *coeffs) 250{ 251 int i; 252 long d, e, q1, q2, lo, mid, hi; 253 dword k; 254 255 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) 256 { 257 q1 = buffer[i]; 258 q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; 259 d = coeffs[i] >> 1; 260 if (d >= 0) 261 d = ((d << 1) * (-q1 >> 16)) + (((dword)(((dword) d) * ((dword)(-q1 & 0xffff)))) >> 15); 262 else 263 d = ((-d << 1) * (-q1 >> 16)) + (((dword)(((dword) -d) * ((dword)(-q1 & 0xffff)))) >> 15); 264 e = (q2 >= 0) ? q2 : -q2; 265 if (d >= 0) 266 { 267 k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff)); 268 lo = k & 0xffff; 269 mid = k >> 16; 270 k = ((dword)(d >> 16)) * ((dword)(e & 0xffff)); 271 mid += k & 0xffff; 272 hi = k >> 16; 273 k = ((dword)(d & 0xffff)) * ((dword)(e >> 16)); 274 mid += k & 0xffff; 275 hi += k >> 16; 276 hi += ((dword)(d >> 16)) * ((dword)(e >> 16)); 277 } 278 else 279 { 280 d = -d; 281 k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff)); 282 lo = -((long)(k & 0xffff)); 283 mid = -((long)(k >> 16)); 284 k = ((dword)(d >> 16)) * ((dword)(e & 0xffff)); 285 mid -= k & 0xffff; 286 hi = -((long)(k >> 16)); 287 k = ((dword)(d & 0xffff)) * ((dword)(e >> 16)); 288 mid -= k & 0xffff; 289 hi -= k >> 16; 290 hi -= ((dword)(d >> 16)) * ((dword)(e >> 16)); 291 } 292 if (q2 < 0) 293 { 294 lo = -lo; 295 mid = -mid; 296 hi = -hi; 297 } 298 d = (q1 >= 0) ? q1 : -q1; 299 k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff)); 300 lo += k & 0xffff; 301 mid += k >> 16; 302 k = ((dword)(d >> 16)) * ((dword)(d & 0xffff)); 303 mid += (k & 0xffff) << 1; 304 hi += (k >> 16) << 1; 305 hi += ((dword)(d >> 16)) * ((dword)(d >> 16)); 306 d = (q2 >= 0) ? q2 : -q2; 307 k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff)); 308 lo += k & 0xffff; 309 mid += k >> 16; 310 k = ((dword)(d >> 16)) * ((dword)(d & 0xffff)); 311 mid += (k & 0xffff) << 1; 312 hi += (k >> 16) << 1; 313 hi += ((dword)(d >> 16)) * ((dword)(d >> 16)); 314 mid += lo >> 16; 315 hi += mid >> 16; 316 buffer[i] = (lo & 0xffff) | (mid << 16); 317 buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = hi; 318 } 319} 320 321 322/*---------------------------------------------------------------------------*/ 323 324#define CAPIDTMF_RECV_GUARD_SNR_INDEX_697 0 325#define CAPIDTMF_RECV_GUARD_SNR_INDEX_770 1 326#define CAPIDTMF_RECV_GUARD_SNR_INDEX_852 2 327#define CAPIDTMF_RECV_GUARD_SNR_INDEX_941 3 328#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1209 4 329#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1336 5 330#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1477 6 331#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1633 7 332#define CAPIDTMF_RECV_GUARD_SNR_INDEX_635 8 333#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1010 9 334#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1140 10 335#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1272 11 336#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1405 12 337#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1555 13 338#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1715 14 339#define CAPIDTMF_RECV_GUARD_SNR_INDEX_1875 15 340 341#define CAPIDTMF_RECV_GUARD_SNR_DONTCARE 0xc000 342#define CAPIDTMF_RECV_NO_DIGIT 0xff 343#define CAPIDTMF_RECV_TIME_GRANULARITY (CAPIDTMF_RECV_ACCUMULATE_CYCLES + 1) 344 345#define CAPIDTMF_RECV_INDICATION_DIGIT 0x0001 346 347static long capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = 348{ 349 0xda97L * 2, /* 697 Hz (Low group 697 Hz) */ 350 0xd299L * 2, /* 770 Hz (Low group 770 Hz) */ 351 0xc8cbL * 2, /* 852 Hz (Low group 852 Hz) */ 352 0xbd36L * 2, /* 941 Hz (Low group 941 Hz) */ 353 0x9501L * 2, /* 1209 Hz (High group 1209 Hz) */ 354 0x7f89L * 2, /* 1336 Hz (High group 1336 Hz) */ 355 0x6639L * 2, /* 1477 Hz (High group 1477 Hz) */ 356 0x48c6L * 2, /* 1633 Hz (High group 1633 Hz) */ 357 0xe14cL * 2, /* 630 Hz (Lower guard of low group 631 Hz) */ 358 0xb2e0L * 2, /* 1015 Hz (Upper guard of low group 1039 Hz) */ 359 0xa1a0L * 2, /* 1130 Hz (Lower guard of high group 1140 Hz) */ 360 0x8a87L * 2, /* 1272 Hz (Guard between 1209 Hz and 1336 Hz: 1271 Hz) */ 361 0x7353L * 2, /* 1405 Hz (2nd harmonics of 697 Hz and guard between 1336 Hz and 1477 Hz: 1405 Hz) */ 362 0x583bL * 2, /* 1552 Hz (2nd harmonics of 770 Hz and guard between 1477 Hz and 1633 Hz: 1553 Hz) */ 363 0x37d8L * 2, /* 1720 Hz (2nd harmonics of 852 Hz and upper guard of high group: 1715 Hz) */ 364 0x0000L * 2 /* 100-630 Hz (fundamentals) */ 365}; 366 367 368static word capidtmf_recv_guard_snr_low_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = 369{ 370 14, /* Low group peak versus 697 Hz */ 371 14, /* Low group peak versus 770 Hz */ 372 16, /* Low group peak versus 852 Hz */ 373 16, /* Low group peak versus 941 Hz */ 374 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1209 Hz */ 375 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1336 Hz */ 376 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1477 Hz */ 377 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1633 Hz */ 378 14, /* Low group peak versus 635 Hz */ 379 16, /* Low group peak versus 1010 Hz */ 380 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1140 Hz */ 381 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1272 Hz */ 382 DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 8, /* Low group peak versus 1405 Hz */ 383 DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1555 Hz */ 384 DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1715 Hz */ 385 12 /* Low group peak versus 100-630 Hz */ 386}; 387 388 389static word capidtmf_recv_guard_snr_high_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = 390{ 391 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 697 Hz */ 392 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 770 Hz */ 393 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 852 Hz */ 394 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 941 Hz */ 395 20, /* High group peak versus 1209 Hz */ 396 20, /* High group peak versus 1336 Hz */ 397 20, /* High group peak versus 1477 Hz */ 398 20, /* High group peak versus 1633 Hz */ 399 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 635 Hz */ 400 CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 1010 Hz */ 401 16, /* High group peak versus 1140 Hz */ 402 4, /* High group peak versus 1272 Hz */ 403 6, /* High group peak versus 1405 Hz */ 404 8, /* High group peak versus 1555 Hz */ 405 16, /* High group peak versus 1715 Hz */ 406 12 /* High group peak versus 100-630 Hz */ 407}; 408 409 410/*---------------------------------------------------------------------------*/ 411 412static void capidtmf_recv_init(t_capidtmf_state *p_state) 413{ 414 p_state->recv.min_gap_duration = 1; 415 p_state->recv.min_digit_duration = 1; 416 417 p_state->recv.cycle_counter = 0; 418 p_state->recv.current_digit_on_time = 0; 419 p_state->recv.current_digit_off_time = 0; 420 p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT; 421 422 p_state->recv.digit_write_pos = 0; 423 p_state->recv.digit_read_pos = 0; 424 p_state->recv.indication_state = 0; 425 p_state->recv.indication_state_ack = 0; 426 p_state->recv.state = CAPIDTMF_RECV_STATE_IDLE; 427} 428 429 430void capidtmf_recv_enable(t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration) 431{ 432 p_state->recv.indication_state_ack &= CAPIDTMF_RECV_INDICATION_DIGIT; 433 p_state->recv.min_digit_duration = (word)(((((dword) min_digit_duration) * 8) + 434 ((dword)(CAPIDTMF_RECV_TIME_GRANULARITY / 2))) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY)); 435 if (p_state->recv.min_digit_duration <= 1) 436 p_state->recv.min_digit_duration = 1; 437 else 438 (p_state->recv.min_digit_duration)--; 439 p_state->recv.min_gap_duration = 440 (word)((((dword) min_gap_duration) * 8) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY)); 441 if (p_state->recv.min_gap_duration <= 1) 442 p_state->recv.min_gap_duration = 1; 443 else 444 (p_state->recv.min_gap_duration)--; 445 p_state->recv.state |= CAPIDTMF_RECV_STATE_DTMF_ACTIVE; 446} 447 448 449void capidtmf_recv_disable(t_capidtmf_state *p_state) 450{ 451 p_state->recv.state &= ~CAPIDTMF_RECV_STATE_DTMF_ACTIVE; 452 if (p_state->recv.state == CAPIDTMF_RECV_STATE_IDLE) 453 capidtmf_recv_init(p_state); 454 else 455 { 456 p_state->recv.cycle_counter = 0; 457 p_state->recv.current_digit_on_time = 0; 458 p_state->recv.current_digit_off_time = 0; 459 p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT; 460 } 461} 462 463 464word capidtmf_recv_indication(t_capidtmf_state *p_state, byte *buffer) 465{ 466 word i, j, k, flags; 467 468 flags = p_state->recv.indication_state ^ p_state->recv.indication_state_ack; 469 p_state->recv.indication_state_ack ^= flags & CAPIDTMF_RECV_INDICATION_DIGIT; 470 if (p_state->recv.digit_write_pos != p_state->recv.digit_read_pos) 471 { 472 i = 0; 473 k = p_state->recv.digit_write_pos; 474 j = p_state->recv.digit_read_pos; 475 do 476 { 477 buffer[i++] = p_state->recv.digit_buffer[j]; 478 j = (j == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 0 : j + 1; 479 } while (j != k); 480 p_state->recv.digit_read_pos = k; 481 return (i); 482 } 483 p_state->recv.indication_state_ack ^= flags; 484 return (0); 485} 486 487 488#define CAPIDTMF_RECV_WINDOWED_SAMPLES 32 489 490void capidtmf_recv_block(t_capidtmf_state *p_state, byte *buffer, word length) 491{ 492 byte result_digit; 493 word sample_number, cycle_counter, n, i; 494 word low_peak, high_peak; 495 dword lo, hi; 496 byte *p; 497 short *q; 498 byte goertzel_result_buffer[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; 499 short windowed_sample_buffer[CAPIDTMF_RECV_WINDOWED_SAMPLES]; 500 501 502 if (p_state->recv.state & CAPIDTMF_RECV_STATE_DTMF_ACTIVE) 503 { 504 cycle_counter = p_state->recv.cycle_counter; 505 sample_number = 0; 506 while (sample_number < length) 507 { 508 if (cycle_counter < CAPIDTMF_RECV_ACCUMULATE_CYCLES) 509 { 510 if (cycle_counter == 0) 511 { 512 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) 513 { 514 p_state->recv.goertzel_buffer[0][i] = 0; 515 p_state->recv.goertzel_buffer[1][i] = 0; 516 } 517 } 518 n = CAPIDTMF_RECV_ACCUMULATE_CYCLES - cycle_counter; 519 if (n > length - sample_number) 520 n = length - sample_number; 521 if (n > CAPIDTMF_RECV_WINDOWED_SAMPLES) 522 n = CAPIDTMF_RECV_WINDOWED_SAMPLES; 523 p = buffer + sample_number; 524 q = capidtmf_recv_window_function + cycle_counter; 525 if (p_state->ulaw) 526 { 527 for (i = 0; i < n; i++) 528 { 529 windowed_sample_buffer[i] = 530 (short)((capidtmf_expand_table_ulaw[p[i]] * ((long)(q[i]))) >> 15); 531 } 532 } 533 else 534 { 535 for (i = 0; i < n; i++) 536 { 537 windowed_sample_buffer[i] = 538 (short)((capidtmf_expand_table_alaw[p[i]] * ((long)(q[i]))) >> 15); 539 } 540 } 541 capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1] = CAPIDTMF_RECV_FUNDAMENTAL_OFFSET; 542 capidtmf_goertzel_loop(p_state->recv.goertzel_buffer[0], 543 capidtmf_recv_goertzel_coef_table, windowed_sample_buffer, n); 544 cycle_counter += n; 545 sample_number += n; 546 } 547 else 548 { 549 capidtmf_goertzel_result(p_state->recv.goertzel_buffer[0], 550 capidtmf_recv_goertzel_coef_table); 551 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) 552 { 553 lo = (dword)(p_state->recv.goertzel_buffer[0][i]); 554 hi = (dword)(p_state->recv.goertzel_buffer[1][i]); 555 if (hi != 0) 556 { 557 n = capidtmf_dword_leading_zeroes(hi); 558 hi = (hi << n) | (lo >> (32 - n)); 559 } 560 else 561 { 562 n = capidtmf_dword_leading_zeroes(lo); 563 hi = lo << n; 564 n += 32; 565 } 566 n = 195 - 3 * n; 567 if (hi >= 0xcb300000L) 568 n += 2; 569 else if (hi >= 0xa1450000L) 570 n++; 571 goertzel_result_buffer[i] = (byte) n; 572 } 573 low_peak = DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT; 574 result_digit = CAPIDTMF_RECV_NO_DIGIT; 575 for (i = 0; i < CAPIDTMF_LOW_GROUP_FREQUENCIES; i++) 576 { 577 if (goertzel_result_buffer[i] > low_peak) 578 { 579 low_peak = goertzel_result_buffer[i]; 580 result_digit = (byte) i; 581 } 582 } 583 high_peak = DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT; 584 n = CAPIDTMF_RECV_NO_DIGIT; 585 for (i = CAPIDTMF_LOW_GROUP_FREQUENCIES; i < CAPIDTMF_RECV_BASE_FREQUENCY_COUNT; i++) 586 { 587 if (goertzel_result_buffer[i] > high_peak) 588 { 589 high_peak = goertzel_result_buffer[i]; 590 n = (i - CAPIDTMF_LOW_GROUP_FREQUENCIES) << 2; 591 } 592 } 593 result_digit |= (byte) n; 594 if (low_peak + DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT < high_peak) 595 result_digit = CAPIDTMF_RECV_NO_DIGIT; 596 if (high_peak + DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT < low_peak) 597 result_digit = CAPIDTMF_RECV_NO_DIGIT; 598 n = 0; 599 for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) 600 { 601 if ((((short)(low_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_low_table[i])) < 0) 602 || (((short)(high_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_high_table[i])) < 0)) 603 { 604 n++; 605 } 606 } 607 if (n != 2) 608 result_digit = CAPIDTMF_RECV_NO_DIGIT; 609 610 if (result_digit == CAPIDTMF_RECV_NO_DIGIT) 611 { 612 if (p_state->recv.current_digit_on_time != 0) 613 { 614 if (++(p_state->recv.current_digit_off_time) >= p_state->recv.min_gap_duration) 615 { 616 p_state->recv.current_digit_on_time = 0; 617 p_state->recv.current_digit_off_time = 0; 618 } 619 } 620 else 621 { 622 if (p_state->recv.current_digit_off_time != 0) 623 (p_state->recv.current_digit_off_time)--; 624 } 625 } 626 else 627 { 628 if ((p_state->recv.current_digit_on_time == 0) 629 && (p_state->recv.current_digit_off_time != 0)) 630 { 631 (p_state->recv.current_digit_off_time)--; 632 } 633 else 634 { 635 n = p_state->recv.current_digit_off_time; 636 if ((p_state->recv.current_digit_on_time != 0) 637 && (result_digit != p_state->recv.current_digit_value)) 638 { 639 p_state->recv.current_digit_on_time = 0; 640 n = 0; 641 } 642 p_state->recv.current_digit_value = result_digit; 643 p_state->recv.current_digit_off_time = 0; 644 if (p_state->recv.current_digit_on_time != 0xffff) 645 { 646 p_state->recv.current_digit_on_time += n + 1; 647 if (p_state->recv.current_digit_on_time >= p_state->recv.min_digit_duration) 648 { 649 p_state->recv.current_digit_on_time = 0xffff; 650 i = (p_state->recv.digit_write_pos == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 651 0 : p_state->recv.digit_write_pos + 1; 652 if (i == p_state->recv.digit_read_pos) 653 { 654 trace(dprintf("%s,%d: Receive digit overrun", 655 (char *)(FILE_), __LINE__)); 656 } 657 else 658 { 659 p_state->recv.digit_buffer[p_state->recv.digit_write_pos] = result_digit; 660 p_state->recv.digit_write_pos = i; 661 p_state->recv.indication_state = 662 (p_state->recv.indication_state & ~CAPIDTMF_RECV_INDICATION_DIGIT) | 663 (~p_state->recv.indication_state_ack & CAPIDTMF_RECV_INDICATION_DIGIT); 664 } 665 } 666 } 667 } 668 } 669 cycle_counter = 0; 670 sample_number++; 671 } 672 } 673 p_state->recv.cycle_counter = cycle_counter; 674 } 675} 676 677 678void capidtmf_init(t_capidtmf_state *p_state, byte ulaw) 679{ 680 p_state->ulaw = ulaw; 681 capidtmf_recv_init(p_state); 682} 683 684 685/*---------------------------------------------------------------------------*/ 686