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 
52 static 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 
88 static 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 
127 static 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 
157 static 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 
capidtmf_goertzel_loop(long * buffer,long * coeffs,short * sample,long count)185 static 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 
capidtmf_goertzel_result(long * buffer,long * coeffs)249 static 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 
347 static 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 
368 static 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 
389 static 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 
capidtmf_recv_init(t_capidtmf_state * p_state)412 static 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 
capidtmf_recv_enable(t_capidtmf_state * p_state,word min_digit_duration,word min_gap_duration)430 void 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 
capidtmf_recv_disable(t_capidtmf_state * p_state)449 void 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 
capidtmf_recv_indication(t_capidtmf_state * p_state,byte * buffer)464 word 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 
capidtmf_recv_block(t_capidtmf_state * p_state,byte * buffer,word length)490 void 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 
capidtmf_init(t_capidtmf_state * p_state,byte ulaw)678 void 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