Bug Summary

File:libs/libteletone/src/libteletone_detect.c
Location:line 324, column 2
Description:Value stored to 'hit' is never read

Annotated Source Code

1/*
2 * libteletone
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
18 *
19 *
20 * The Initial Developer of the Original Code is
21 * Stephen Underwood <steveu@coppice.org>
22 * Portions created by the Initial Developer are Copyright (C)
23 * the Initial Developer. All Rights Reserved.
24 *
25 * Contributor(s):
26 *
27 * The the original interface designed by Steve Underwood was preserved to retain
28 *the optimizations when considering DTMF tones though the names were changed in the interest
29 * of namespace.
30 *
31 * Much less efficient expansion interface was added to allow for the detection of
32 * a single arbitrary tone combination which may also exceed 2 simultaneous tones.
33 * (controlled by compile time constant TELETONE_MAX_TONES)
34 *
35 * Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
36 *
37 *
38 * libteletone_detect.c Tone Detection Code
39 *
40 *
41 *********************************************************************************
42 *
43 * Derived from tone_detect.c - General telephony tone detection, and specific
44 * detection of DTMF.
45 *
46 * Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
47 *
48 * Despite my general liking of the GPL, I place this code in the
49 * public domain for the benefit of all mankind - even the slimy
50 * ones who might try to proprietize my work and use it to my
51 * detriment.
52 *
53 *
54 * Exception:
55 * The author hereby grants the use of this source code under the
56 * following license if and only if the source code is distributed
57 * as part of the OpenZAP or FreeTDM library. Any use or distribution of this
58 * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
59 * following license and reinact the MPL 1.1 as stated above.
60 *
61 * Copyright (c) 2007, Anthony Minessale II
62 * All rights reserved.
63 *
64 * Redistribution and use in source and binary forms, with or without
65 * modification, are permitted provided that the following conditions
66 * are met:
67 *
68 * * Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer.
70 *
71 * * Redistributions in binary form must reproduce the above copyright
72 * notice, this list of conditions and the following disclaimer in the
73 * documentation and/or other materials provided with the distribution.
74 *
75 * * Neither the name of the original author; nor the names of any contributors
76 * may be used to endorse or promote products derived from this software
77 * without specific prior written permission.
78 *
79 *
80 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
81 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
82 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
83 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
84 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
85 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
86 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
87 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
88 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
89 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91 */
92
93#include <libteletone_detect.h>
94
95#ifndef _MSC_VER
96#include <stdint.h>
97#endif
98#include <string.h>
99#include <stdio.h>
100#include <time.h>
101#include <fcntl.h>
102
103#define LOW_ENG10000000 10000000
104#define ZC2 2
105static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR4];
106static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR4];
107static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR4];
108static teletone_detection_descriptor_t dtmf_detect_col_2nd[GRID_FACTOR4];
109
110static float dtmf_row[] = {697.0f, 770.0f, 852.0f, 941.0f};
111static float dtmf_col[] = {1209.0f, 1336.0f, 1477.0f, 1633.0f};
112
113static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
114
115static void goertzel_init(teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc) {
116 goertzel_state->v2 = goertzel_state->v3 = 0.0;
117 goertzel_state->fac = tdesc->fac;
118}
119
120TELETONE_API(void)__attribute__((visibility("default"))) void teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state,
121 int16_t sample_buffer[],
122 int samples)
123{
124 int i;
125 float v1;
126
127 for (i = 0; i < samples; i++) {
128 v1 = goertzel_state->v2;
129 goertzel_state->v2 = goertzel_state->v3;
130 goertzel_state->v3 = (float)(goertzel_state->fac*goertzel_state->v2 - v1 + sample_buffer[i]);
131 }
132}
133#ifdef _MSC_VER
134#pragma warning(disable:4244)
135#endif
136
137#define teletone_goertzel_result(gs)(double)(((gs)->v3 * (gs)->v3 + (gs)->v2 * (gs)->
v2 - (gs)->v2 * (gs)->v3 * (gs)->fac))
(double)(((gs)->v3 * (gs)->v3 + (gs)->v2 * (gs)->v2 - (gs)->v2 * (gs)->v3 * (gs)->fac))
138
139TELETONE_API(void)__attribute__((visibility("default"))) void teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate)
140{
141 int i;
142 float theta;
143
144 if (!sample_rate) {
145 sample_rate = 8000;
146 }
147
148 dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
149
150 for (i = 0; i < GRID_FACTOR4; i++) {
151 theta = (float)(M_TWO_PI2.0*3.14159265358979323846*(dtmf_row[i]/(float)sample_rate));
152 dtmf_detect_row[i].fac = (float)(2.0*cos(theta));
153
154 theta = (float)(M_TWO_PI2.0*3.14159265358979323846*(dtmf_col[i]/(float)sample_rate));
155 dtmf_detect_col[i].fac = (float)(2.0*cos(theta));
156
157 theta = (float)(M_TWO_PI2.0*3.14159265358979323846*(dtmf_row[i]*2.0/(float)sample_rate));
158 dtmf_detect_row_2nd[i].fac = (float)(2.0*cos(theta));
159
160 theta = (float)(M_TWO_PI2.0*3.14159265358979323846*(dtmf_col[i]*2.0/(float)sample_rate));
161 dtmf_detect_col_2nd[i].fac = (float)(2.0*cos(theta));
162
163 goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
164 goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
165 goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
166 goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
167
168 dtmf_detect_state->energy = 0.0;
169 }
170 dtmf_detect_state->current_sample = 0;
171 dtmf_detect_state->detected_digits = 0;
172 dtmf_detect_state->lost_digits = 0;
173 dtmf_detect_state->digit = 0;
174 dtmf_detect_state->dur = 0;
175}
176
177TELETONE_API(void)__attribute__((visibility("default"))) void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
178{
179 float theta = 0;
180 int x = 0;
181
182 if (!mt->sample_rate) {
183 mt->sample_rate = 8000;
184 }
185
186 if (!mt->min_samples) {
187 mt->min_samples = 102;
188 }
189
190 mt->min_samples *= (mt->sample_rate / 8000);
191
192 if (!mt->positive_factor) {
193 mt->positive_factor = 2;
194 }
195
196 if(!mt->negative_factor) {
197 mt->negative_factor = 10;
198 }
199
200 if (!mt->hit_factor) {
201 mt->hit_factor = 2;
202 }
203
204 for(x = 0; x < TELETONE_MAX_TONES18; x++) {
205 if ((int) map->freqs[x] == 0) {
206 break;
207 }
208 mt->tone_count++;
209 theta = (float)(M_TWO_PI2.0*3.14159265358979323846*(map->freqs[x]/(float)mt->sample_rate));
210 mt->tdd[x].fac = (float)(2.0 * cos(theta));
211 goertzel_init (&mt->gs[x], &mt->tdd[x]);
212 goertzel_init (&mt->gs2[x], &mt->tdd[x]);
213 }
214
215}
216
217TELETONE_API(int)__attribute__((visibility("default"))) int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
218 int16_t sample_buffer[],
219 int samples)
220{
221 int sample, limit = 0, j, x = 0;
222 float v1, famp;
223 float eng_sum = 0, eng_all[TELETONE_MAX_TONES18] = {0.0};
224 int gtest = 0, see_hit = 0;
225
226 for (sample = 0; sample >= 0 && sample < samples; sample = limit) {
227 mt->total_samples++;
228
229 if ((samples - sample) >= (mt->min_samples - mt->current_sample)) {
230 limit = sample + (mt->min_samples - mt->current_sample);
231 } else {
232 limit = samples;
233 }
234 if (limit < 0 || limit > samples) {
235 limit = samples;
236 }
237
238 for (j = sample; j < limit; j++) {
239 famp = sample_buffer[j];
240
241 mt->energy += famp*famp;
242
243 for(x = 0; x < TELETONE_MAX_TONES18 && x < mt->tone_count; x++) {
244 v1 = mt->gs[x].v2;
245 mt->gs[x].v2 = mt->gs[x].v3;
246 mt->gs[x].v3 = (float)(mt->gs[x].fac * mt->gs[x].v2 - v1 + famp);
247
248 v1 = mt->gs2[x].v2;
249 mt->gs2[x].v2 = mt->gs2[x].v3;
250 mt->gs2[x].v3 = (float)(mt->gs2[x].fac*mt->gs2[x].v2 - v1 + famp);
251 }
252 }
253
254 mt->current_sample += (limit - sample);
255 if (mt->current_sample < mt->min_samples) {
256 continue;
257 }
258
259 eng_sum = 0;
260 for(x = 0; x < TELETONE_MAX_TONES18 && x < mt->tone_count; x++) {
261 eng_all[x] = (float)(teletone_goertzel_result (&mt->gs[x])(double)(((&mt->gs[x])->v3 * (&mt->gs[x])->
v3 + (&mt->gs[x])->v2 * (&mt->gs[x])->v2 -
(&mt->gs[x])->v2 * (&mt->gs[x])->v3 * (&
mt->gs[x])->fac))
);
262 eng_sum += eng_all[x];
263 }
264
265 gtest = 0;
266 for(x = 0; x < TELETONE_MAX_TONES18 && x < mt->tone_count; x++) {
267 gtest += teletone_goertzel_result (&mt->gs2[x])(double)(((&mt->gs2[x])->v3 * (&mt->gs2[x])->
v3 + (&mt->gs2[x])->v2 * (&mt->gs2[x])->v2
- (&mt->gs2[x])->v2 * (&mt->gs2[x])->v3 *
(&mt->gs2[x])->fac))
< eng_all[x] ? 1 : 0;
268 }
269
270 if ((gtest >= 2 || gtest == mt->tone_count) && eng_sum > 42.0 * mt->energy) {
271 if(mt->negatives) {
272 mt->negatives--;
273 }
274 mt->positives++;
275
276 if(mt->positives >= mt->positive_factor) {
277 mt->hits++;
278 }
279 if (mt->hits >= mt->hit_factor) {
280 see_hit++;
281 mt->positives = mt->negatives = mt->hits = 0;
282 }
283 } else {
284 mt->negatives++;
285 if(mt->positives) {
286 mt->positives--;
287 }
288 if(mt->negatives > mt->negative_factor) {
289 mt->positives = mt->hits = 0;
290 }
291 }
292
293 /* Reinitialise the detector for the next block */
294 for(x = 0; x < TELETONE_MAX_TONES18 && x < mt->tone_count; x++) {
295 goertzel_init (&mt->gs[x], &mt->tdd[x]);
296 goertzel_init (&mt->gs2[x], &mt->tdd[x]);
297 }
298
299 mt->energy = 0.0;
300 mt->current_sample = 0;
301 }
302
303 return see_hit;
304}
305
306
307TELETONE_API(teletone_hit_type_t)__attribute__((visibility("default"))) teletone_hit_type_t teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
308 int16_t sample_buffer[],
309 int samples)
310{
311 float row_energy[GRID_FACTOR4];
312 float col_energy[GRID_FACTOR4];
313 float famp;
314 float v1;
315 int i;
316 int j;
317 int sample;
318 int best_row;
319 int best_col;
320 char hit;
321 int limit;
322 teletone_hit_type_t r = 0;
323
324 hit = 0;
Value stored to 'hit' is never read
325 for (sample = 0; sample < samples; sample = limit) {
326 /* BLOCK_LEN is optimised to meet the DTMF specs. */
327 if ((samples - sample) >= (BLOCK_LEN102 - dtmf_detect_state->current_sample)) {
328 limit = sample + (BLOCK_LEN102 - dtmf_detect_state->current_sample);
329 } else {
330 limit = samples;
331 }
332
333 for (j = sample; j < limit; j++) {
334 int x = 0;
335 famp = sample_buffer[j];
336
337 dtmf_detect_state->energy += famp*famp;
338
339 for(x = 0; x < GRID_FACTOR4; x++) {
340 v1 = dtmf_detect_state->row_out[x].v2;
341 dtmf_detect_state->row_out[x].v2 = dtmf_detect_state->row_out[x].v3;
342 dtmf_detect_state->row_out[x].v3 = (float)(dtmf_detect_state->row_out[x].fac*dtmf_detect_state->row_out[x].v2 - v1 + famp);
343
344 v1 = dtmf_detect_state->col_out[x].v2;
345 dtmf_detect_state->col_out[x].v2 = dtmf_detect_state->col_out[x].v3;
346 dtmf_detect_state->col_out[x].v3 = (float)(dtmf_detect_state->col_out[x].fac*dtmf_detect_state->col_out[x].v2 - v1 + famp);
347
348 v1 = dtmf_detect_state->col_out2nd[x].v2;
349 dtmf_detect_state->col_out2nd[x].v2 = dtmf_detect_state->col_out2nd[x].v3;
350 dtmf_detect_state->col_out2nd[x].v3 = (float)(dtmf_detect_state->col_out2nd[x].fac*dtmf_detect_state->col_out2nd[x].v2 - v1 + famp);
351
352 v1 = dtmf_detect_state->row_out2nd[x].v2;
353 dtmf_detect_state->row_out2nd[x].v2 = dtmf_detect_state->row_out2nd[x].v3;
354 dtmf_detect_state->row_out2nd[x].v3 = (float)(dtmf_detect_state->row_out2nd[x].fac*dtmf_detect_state->row_out2nd[x].v2 - v1 + famp);
355 }
356
357 }
358
359 if (dtmf_detect_state->zc > 0) {
360 if (dtmf_detect_state->energy < LOW_ENG10000000 && dtmf_detect_state->lenergy < LOW_ENG10000000) {
361 if (!--dtmf_detect_state->zc) {
362 /* Reinitialise the detector for the next block */
363 dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
364 for (i = 0; i < GRID_FACTOR4; i++) {
365 goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
366 goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
367 goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
368 goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
369 }
370 dtmf_detect_state->dur -= samples;
371 return TT_HIT_END;
372 }
373 }
374
375 dtmf_detect_state->dur += samples;
376 dtmf_detect_state->lenergy = dtmf_detect_state->energy;
377 dtmf_detect_state->energy = 0.0;
378 dtmf_detect_state->current_sample = 0;
379 return TT_HIT_MIDDLE;
380 } else if (dtmf_detect_state->digit) {
381 return TT_HIT_END;
382 }
383
384
385 dtmf_detect_state->current_sample += (limit - sample);
386 if (dtmf_detect_state->current_sample < BLOCK_LEN102) {
387 continue;
388 }
389 /* We are at the end of a DTMF detection block */
390 /* Find the peak row and the peak column */
391 row_energy[0] = teletone_goertzel_result (&dtmf_detect_state->row_out[0])(double)(((&dtmf_detect_state->row_out[0])->v3 * (&
dtmf_detect_state->row_out[0])->v3 + (&dtmf_detect_state
->row_out[0])->v2 * (&dtmf_detect_state->row_out
[0])->v2 - (&dtmf_detect_state->row_out[0])->v2 *
(&dtmf_detect_state->row_out[0])->v3 * (&dtmf_detect_state
->row_out[0])->fac))
;
392 col_energy[0] = teletone_goertzel_result (&dtmf_detect_state->col_out[0])(double)(((&dtmf_detect_state->col_out[0])->v3 * (&
dtmf_detect_state->col_out[0])->v3 + (&dtmf_detect_state
->col_out[0])->v2 * (&dtmf_detect_state->col_out
[0])->v2 - (&dtmf_detect_state->col_out[0])->v2 *
(&dtmf_detect_state->col_out[0])->v3 * (&dtmf_detect_state
->col_out[0])->fac))
;
393
394 for (best_row = best_col = 0, i = 1; i < GRID_FACTOR4; i++) {
395 row_energy[i] = teletone_goertzel_result (&dtmf_detect_state->row_out[i])(double)(((&dtmf_detect_state->row_out[i])->v3 * (&
dtmf_detect_state->row_out[i])->v3 + (&dtmf_detect_state
->row_out[i])->v2 * (&dtmf_detect_state->row_out
[i])->v2 - (&dtmf_detect_state->row_out[i])->v2 *
(&dtmf_detect_state->row_out[i])->v3 * (&dtmf_detect_state
->row_out[i])->fac))
;
396 if (row_energy[i] > row_energy[best_row]) {
397 best_row = i;
398 }
399 col_energy[i] = teletone_goertzel_result (&dtmf_detect_state->col_out[i])(double)(((&dtmf_detect_state->col_out[i])->v3 * (&
dtmf_detect_state->col_out[i])->v3 + (&dtmf_detect_state
->col_out[i])->v2 * (&dtmf_detect_state->col_out
[i])->v2 - (&dtmf_detect_state->col_out[i])->v2 *
(&dtmf_detect_state->col_out[i])->v3 * (&dtmf_detect_state
->col_out[i])->fac))
;
400 if (col_energy[i] > col_energy[best_col]) {
401 best_col = i;
402 }
403 }
404 hit = 0;
405 /* Basic signal level test and the twist test */
406 if (row_energy[best_row] >= DTMF_THRESHOLD8.0e7 &&
407 col_energy[best_col] >= DTMF_THRESHOLD8.0e7 &&
408 col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST2.5 &&
409 col_energy[best_col]*DTMF_NORMAL_TWIST6.3 > row_energy[best_row]) {
410 /* Relative peak test */
411 for (i = 0; i < GRID_FACTOR4; i++) {
412 if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL6.3 > col_energy[best_col]) ||
413 (i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW6.3 > row_energy[best_row])) {
414 break;
415 }
416 }
417 /* ... and second harmonic test */
418 if (i >= GRID_FACTOR4 && (row_energy[best_row] + col_energy[best_col]) > 42.0*dtmf_detect_state->energy &&
419 teletone_goertzel_result (&dtmf_detect_state->col_out2nd[best_col])(double)(((&dtmf_detect_state->col_out2nd[best_col])->
v3 * (&dtmf_detect_state->col_out2nd[best_col])->v3
+ (&dtmf_detect_state->col_out2nd[best_col])->v2 *
(&dtmf_detect_state->col_out2nd[best_col])->v2 - (
&dtmf_detect_state->col_out2nd[best_col])->v2 * (&
dtmf_detect_state->col_out2nd[best_col])->v3 * (&dtmf_detect_state
->col_out2nd[best_col])->fac))
*DTMF_2ND_HARMONIC_COL63.1 < col_energy[best_col] &&
420 teletone_goertzel_result (&dtmf_detect_state->row_out2nd[best_row])(double)(((&dtmf_detect_state->row_out2nd[best_row])->
v3 * (&dtmf_detect_state->row_out2nd[best_row])->v3
+ (&dtmf_detect_state->row_out2nd[best_row])->v2 *
(&dtmf_detect_state->row_out2nd[best_row])->v2 - (
&dtmf_detect_state->row_out2nd[best_row])->v2 * (&
dtmf_detect_state->row_out2nd[best_row])->v3 * (&dtmf_detect_state
->row_out2nd[best_row])->fac))
*DTMF_2ND_HARMONIC_ROW2.5 < row_energy[best_row]) {
421 hit = dtmf_positions[(best_row << 2) + best_col];
422 /* Look for two successive similar results */
423 /* The logic in the next test is:
424 We need two successive identical clean detects, with
425 something different preceeding it. This can work with
426 back to back differing digits. More importantly, it
427 can work with nasty phones that give a very wobbly start
428 to a digit. */
429 if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
430 dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
431 dtmf_detect_state->detected_digits++;
432 if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS128) {
433 dtmf_detect_state->digit = hit;
434 } else {
435 dtmf_detect_state->lost_digits++;
436 }
437
438 if (!dtmf_detect_state->zc) {
439 dtmf_detect_state->zc = ZC2;
440 dtmf_detect_state->dur = 0;
441 r = TT_HIT_BEGIN;
442 break;
443 }
444
445 }
446 }
447 }
448
449 dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
450 dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
451 dtmf_detect_state->hit3 = hit;
452
453 dtmf_detect_state->energy = 0.0;
454 dtmf_detect_state->current_sample = 0;
455
456 }
457
458 return r;
459}
460
461
462TELETONE_API(int)__attribute__((visibility("default"))) int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
463{
464 if (!dtmf_detect_state->digit) {
465 return 0;
466 }
467
468 *buf = dtmf_detect_state->digit;
469
470 *dur = dtmf_detect_state->dur;
471
472 if (!dtmf_detect_state->zc) {
473 dtmf_detect_state->dur = 0;
474 dtmf_detect_state->digit = 0;
475 }
476
477 return 1;
478}
479
480/* For Emacs:
481 * Local Variables:
482 * mode:c
483 * indent-tabs-mode:t
484 * tab-width:4
485 * c-basic-offset:4
486 * End:
487 * For VIM:
488 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
489 */