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