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