GNU Linux-libre 4.9.311-gnu1
[releases.git] / drivers / isdn / hardware / eicon / capidtmf.c
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
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
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
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
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
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
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
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
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 /*---------------------------------------------------------------------------*/