comparison spandsp-0.0.6pre17/src/modem_connect_tones.c @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
comparison
equal deleted inserted replaced
3:c6c5a16ce2f2 4:26cd8f1ef0b1
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * modem_connect_tones.c - Generation and detection of tones
5 * associated with modems calling and answering calls.
6 *
7 * Written by Steve Underwood <steveu@coppice.org>
8 *
9 * Copyright (C) 2006 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License version 2.1,
15 * as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * $Id: modem_connect_tones.c,v 1.41 2009/11/06 19:21:33 steveu Exp $
27 */
28
29 /*! \file */
30
31 /* CNG is 0.5s+-15% of 1100+-38Hz, 3s+-15% off, repeating.
32
33 CED is 0.2s silence, 3.3+-0.7s of 2100+-15Hz, and 75+-20ms of silence.
34
35 ANS is 3.3+-0.7s of 2100+-15Hz.
36
37 ANS/ is 3.3+-0.7s of 2100+-15Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms.
38
39 ANSam/ is 2100+-1Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms, and AM with a sinewave of 15+-0.1Hz.
40 The modulated envelope ranges in amplitude between (0.8+-0.01) and (1.2+-0.01) times its average
41 amplitude. It lasts up to 5s, but will be stopped early if the V.8 protocol proceeds. */
42
43 #if defined(HAVE_CONFIG_H)
44 #include "config.h"
45 #endif
46
47 #include <inttypes.h>
48 #include <stdlib.h>
49 #include <memory.h>
50 #if defined(HAVE_TGMATH_H)
51 #include <tgmath.h>
52 #endif
53 #if defined(HAVE_MATH_H)
54 #include <math.h>
55 #endif
56 #include "floating_fudge.h"
57 #include <stdio.h>
58
59 #include "spandsp/telephony.h"
60 #include "spandsp/fast_convert.h"
61 #include "spandsp/logging.h"
62 #include "spandsp/complex.h"
63 #include "spandsp/dds.h"
64 #include "spandsp/tone_detect.h"
65 #include "spandsp/tone_generate.h"
66 #include "spandsp/super_tone_rx.h"
67 #include "spandsp/power_meter.h"
68 #include "spandsp/async.h"
69 #include "spandsp/fsk.h"
70 #include "spandsp/modem_connect_tones.h"
71
72 #include "spandsp/private/fsk.h"
73 #include "spandsp/private/modem_connect_tones.h"
74
75 #define HDLC_FRAMING_OK_THRESHOLD 5
76
77 SPAN_DECLARE(const char *) modem_connect_tone_to_str(int tone)
78 {
79 switch (tone)
80 {
81 case MODEM_CONNECT_TONES_NONE:
82 return "No tone";
83 case MODEM_CONNECT_TONES_FAX_CNG:
84 return "FAX CNG";
85 case MODEM_CONNECT_TONES_ANS:
86 return "ANS or FAX CED";
87 case MODEM_CONNECT_TONES_ANS_PR:
88 return "ANS/";
89 case MODEM_CONNECT_TONES_ANSAM:
90 return "ANSam";
91 case MODEM_CONNECT_TONES_ANSAM_PR:
92 return "ANSam/";
93 case MODEM_CONNECT_TONES_FAX_PREAMBLE:
94 return "FAX preamble";
95 case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE:
96 return "FAX CED or preamble";
97 }
98 return "???";
99 }
100 /*- End of function --------------------------------------------------------*/
101
102 SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *s,
103 int16_t amp[],
104 int len)
105 {
106 int16_t mod;
107 int i;
108 int xlen;
109
110 i = 0;
111 switch (s->tone_type)
112 {
113 case MODEM_CONNECT_TONES_FAX_CNG:
114 for ( ; i < len; i++)
115 {
116 if (s->duration_timer > ms_to_samples(3000))
117 {
118 if ((xlen = i + s->duration_timer - ms_to_samples(3000)) > len)
119 xlen = len;
120 s->duration_timer -= (xlen - i);
121 for ( ; i < xlen; i++)
122 amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
123 }
124 if (s->duration_timer > 0)
125 {
126 if ((xlen = i + s->duration_timer) > len)
127 xlen = len;
128 s->duration_timer -= (xlen - i);
129 memset(amp + i, 0, sizeof(int16_t)*(xlen - i));
130 i = xlen;
131 }
132 if (s->duration_timer == 0)
133 s->duration_timer = ms_to_samples(500 + 3000);
134 }
135 break;
136 case MODEM_CONNECT_TONES_ANS:
137 if (s->duration_timer < len)
138 len = s->duration_timer;
139 if (s->duration_timer > ms_to_samples(2600))
140 {
141 /* There is some initial silence to be generated. */
142 if ((i = s->duration_timer - ms_to_samples(2600)) > len)
143 i = len;
144 memset(amp, 0, sizeof(int16_t)*i);
145 }
146 for ( ; i < len; i++)
147 amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
148 s->duration_timer -= len;
149 break;
150 case MODEM_CONNECT_TONES_ANS_PR:
151 if (s->duration_timer < len)
152 len = s->duration_timer;
153 if (s->duration_timer > ms_to_samples(3300))
154 {
155 if ((i = s->duration_timer - ms_to_samples(3300)) > len)
156 i = len;
157 memset(amp, 0, sizeof(int16_t)*i);
158 }
159 for ( ; i < len; i++)
160 {
161 if (--s->hop_timer <= 0)
162 {
163 s->hop_timer = ms_to_samples(450);
164 s->tone_phase += 0x80000000;
165 }
166 amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
167 }
168 s->duration_timer -= len;
169 break;
170 case MODEM_CONNECT_TONES_ANSAM:
171 if (s->duration_timer < len)
172 len = s->duration_timer;
173 if (s->duration_timer > ms_to_samples(5000))
174 {
175 if ((i = s->duration_timer - ms_to_samples(5000)) > len)
176 i = len;
177 memset(amp, 0, sizeof(int16_t)*i);
178 }
179 for ( ; i < len; i++)
180 {
181 mod = (int16_t) (s->level + dds_mod(&s->mod_phase, s->mod_phase_rate, s->mod_level, 0));
182 amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, mod, 0);
183 }
184 s->duration_timer -= len;
185 break;
186 case MODEM_CONNECT_TONES_ANSAM_PR:
187 if (s->duration_timer < len)
188 len = s->duration_timer;
189 if (s->duration_timer > ms_to_samples(5000))
190 {
191 if ((i = s->duration_timer - ms_to_samples(5000)) > len)
192 i = len;
193 memset(amp, 0, sizeof(int16_t)*i);
194 }
195 for ( ; i < len; i++)
196 {
197 if (--s->hop_timer <= 0)
198 {
199 s->hop_timer = ms_to_samples(450);
200 s->tone_phase += 0x80000000;
201 }
202 mod = (int16_t) (s->level + dds_mod(&s->mod_phase, s->mod_phase_rate, s->mod_level, 0));
203 amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, mod, 0);
204 }
205 s->duration_timer -= len;
206 break;
207 }
208 return len;
209 }
210 /*- End of function --------------------------------------------------------*/
211
212 SPAN_DECLARE(modem_connect_tones_tx_state_t *) modem_connect_tones_tx_init(modem_connect_tones_tx_state_t *s,
213 int tone_type)
214 {
215 int alloced;
216
217 alloced = FALSE;
218 if (s == NULL)
219 {
220 if ((s = (modem_connect_tones_tx_state_t *) malloc(sizeof(*s))) == NULL)
221 return NULL;
222 alloced = TRUE;
223 }
224 s->tone_type = tone_type;
225 switch (s->tone_type)
226 {
227 case MODEM_CONNECT_TONES_FAX_CNG:
228 /* 0.5s of 1100Hz+-38Hz + 3.0s of silence repeating. Timing +-15% */
229 s->tone_phase_rate = dds_phase_rate(1100.0);
230 s->level = dds_scaling_dbm0(-11);
231 s->duration_timer = ms_to_samples(500 + 3000);
232 s->mod_phase_rate = 0;
233 s->tone_phase = 0;
234 s->mod_phase = 0;
235 s->mod_level = 0;
236 s->hop_timer = 0;
237 break;
238 case MODEM_CONNECT_TONES_ANS:
239 case MODEM_CONNECT_TONES_ANSAM:
240 /* 0.2s of silence, then 2.6s to 4s of 2100Hz+-15Hz tone, then 75ms of silence. */
241 s->tone_phase_rate = dds_phase_rate(2100.0);
242 s->level = dds_scaling_dbm0(-11);
243 if (s->tone_type == MODEM_CONNECT_TONES_ANSAM)
244 {
245 s->mod_phase_rate = dds_phase_rate(15.0);
246 s->mod_level = s->level/5;
247 s->duration_timer = ms_to_samples(200 + 5000);
248 }
249 else
250 {
251 s->mod_phase_rate = 0;
252 s->mod_level = 0;
253 s->duration_timer = ms_to_samples(200 + 2600);
254 }
255 s->tone_phase = 0;
256 s->mod_phase = 0;
257 s->hop_timer = 0;
258 break;
259 case MODEM_CONNECT_TONES_ANS_PR:
260 case MODEM_CONNECT_TONES_ANSAM_PR:
261 s->tone_phase_rate = dds_phase_rate(2100.0);
262 s->level = dds_scaling_dbm0(-12);
263 if (s->tone_type == MODEM_CONNECT_TONES_ANSAM_PR)
264 {
265 s->mod_phase_rate = dds_phase_rate(15.0);
266 s->mod_level = s->level/5;
267 s->duration_timer = ms_to_samples(200 + 5000);
268 }
269 else
270 {
271 s->mod_phase_rate = 0;
272 s->mod_level = 0;
273 s->duration_timer = ms_to_samples(200 + 3300);
274 }
275 s->tone_phase = 0;
276 s->mod_phase = 0;
277 s->hop_timer = ms_to_samples(450);
278 break;
279 default:
280 if (alloced)
281 free(s);
282 return NULL;
283 }
284 return s;
285 }
286 /*- End of function --------------------------------------------------------*/
287
288 SPAN_DECLARE(int) modem_connect_tones_tx_release(modem_connect_tones_tx_state_t *s)
289 {
290 return 0;
291 }
292 /*- End of function --------------------------------------------------------*/
293
294 SPAN_DECLARE(int) modem_connect_tones_tx_free(modem_connect_tones_tx_state_t *s)
295 {
296 free(s);
297 return 0;
298 }
299 /*- End of function --------------------------------------------------------*/
300
301 static void report_tone_state(modem_connect_tones_rx_state_t *s, int tone, int level)
302 {
303 if (tone != s->tone_present)
304 {
305 if (s->tone_callback)
306 {
307 s->tone_callback(s->callback_data, tone, level, 0);
308 }
309 else
310 {
311 if (tone != MODEM_CONNECT_TONES_NONE)
312 s->hit = tone;
313 }
314 s->tone_present = tone;
315 }
316 }
317 /*- End of function --------------------------------------------------------*/
318
319 static void v21_put_bit(void *user_data, int bit)
320 {
321 modem_connect_tones_rx_state_t *s;
322
323 s = (modem_connect_tones_rx_state_t *) user_data;
324 if (bit < 0)
325 {
326 /* Special conditions. */
327 switch (bit)
328 {
329 case SIG_STATUS_CARRIER_DOWN:
330 /* Only declare tone off, if we were the one to declare tone on. */
331 if (s->tone_present == MODEM_CONNECT_TONES_FAX_PREAMBLE)
332 report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
333 /* Fall through */
334 case SIG_STATUS_CARRIER_UP:
335 s->raw_bit_stream = 0;
336 s->num_bits = 0;
337 s->flags_seen = 0;
338 s->framing_ok_announced = FALSE;
339 break;
340 }
341 return;
342 }
343 /* Look for enough FAX V.21 message preamble (back to back HDLC flag octets) to be sure
344 we are really seeing preamble, and declare the signal to be present. Any change from
345 preamble declares the signal to not be present, though it will probably be the body
346 of the messages following the preamble. */
347 s->raw_bit_stream = (s->raw_bit_stream << 1) | ((bit << 8) & 0x100);
348 s->num_bits++;
349 if ((s->raw_bit_stream & 0x7F00) == 0x7E00)
350 {
351 if ((s->raw_bit_stream & 0x8000))
352 {
353 /* Hit HDLC abort */
354 s->flags_seen = 0;
355 }
356 else
357 {
358 /* Hit HDLC flag */
359 if (s->flags_seen < HDLC_FRAMING_OK_THRESHOLD)
360 {
361 /* Check the flags are back-to-back when testing for valid preamble. This
362 greatly reduces the chances of false preamble detection, and anything
363 which doesn't send them back-to-back is badly broken. */
364 if (s->num_bits != 8)
365 s->flags_seen = 0;
366 if (++s->flags_seen >= HDLC_FRAMING_OK_THRESHOLD && !s->framing_ok_announced)
367 {
368 report_tone_state(s, MODEM_CONNECT_TONES_FAX_PREAMBLE, lfastrintf(fsk_rx_signal_power(&(s->v21rx))));
369 s->framing_ok_announced = TRUE;
370 }
371 }
372 }
373 s->num_bits = 0;
374 }
375 else
376 {
377 if (s->flags_seen >= HDLC_FRAMING_OK_THRESHOLD)
378 {
379 if (s->num_bits == 8)
380 {
381 s->framing_ok_announced = FALSE;
382 s->flags_seen = 0;
383 }
384 }
385 }
386 }
387 /*- End of function --------------------------------------------------------*/
388
389 SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *s,
390 const int16_t amp[],
391 int len)
392 {
393 int i;
394 int16_t notched;
395 float v1;
396 float famp;
397 float filtered;
398
399 switch (s->tone_type)
400 {
401 case MODEM_CONNECT_TONES_FAX_CNG:
402 for (i = 0; i < len; i++)
403 {
404 famp = amp[i];
405 /* A Cauer notch at 1100Hz, spread just wide enough to meet our detection bandwidth
406 criteria. */
407 v1 = 0.792928f*famp + 1.0018744927985f*s->znotch_1 - 0.54196833412465f*s->znotch_2;
408 famp = v1 - 1.2994747954630f*s->znotch_1 + s->znotch_2;
409 s->znotch_2 = s->znotch_1;
410 s->znotch_1 = v1;
411 notched = (int16_t) lfastrintf(famp);
412
413 /* Estimate the overall energy in the channel, and the energy in
414 the notch (i.e. overall channel energy - tone energy => noise).
415 Use abs instead of multiply for speed (is it really faster?). */
416 s->channel_level += ((abs(amp[i]) - s->channel_level) >> 5);
417 s->notch_level += ((abs(notched) - s->notch_level) >> 5);
418 if (s->channel_level > 70 && s->notch_level*6 < s->channel_level)
419 {
420 /* There is adequate energy in the channel, and it is mostly at 1100Hz. */
421 if (s->tone_present != MODEM_CONNECT_TONES_FAX_CNG)
422 {
423 if (++s->tone_cycle_duration >= ms_to_samples(415))
424 report_tone_state(s, MODEM_CONNECT_TONES_FAX_CNG, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
425 }
426 }
427 else
428 {
429 /* If the signal looks wrong, even for a moment, we consider this the
430 end of the tone. */
431 if (s->tone_present == MODEM_CONNECT_TONES_FAX_CNG)
432 report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
433 s->tone_cycle_duration = 0;
434 }
435 }
436 break;
437 case MODEM_CONNECT_TONES_FAX_PREAMBLE:
438 /* Ignore any CED tone, and just look for V.21 preamble. */
439 fsk_rx(&(s->v21rx), amp, len);
440 break;
441 case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE:
442 /* Also look for V.21 preamble. A lot of machines don't send the 2100Hz burst. It
443 might also not be seen all the way through the channel, due to switching delays. */
444 fsk_rx(&(s->v21rx), amp, len);
445 /* Now fall through and look for a 2100Hz tone */
446 case MODEM_CONNECT_TONES_ANS:
447 for (i = 0; i < len; i++)
448 {
449 famp = amp[i];
450 /* A Cauer bandpass at 15Hz, with which we demodulate the AM signal. */
451 v1 = fabs(famp) + 1.996667f*s->z15hz_1 - 0.9968004f*s->z15hz_2;
452 filtered = 0.001599787f*(v1 - s->z15hz_2);
453 s->z15hz_2 = s->z15hz_1;
454 s->z15hz_1 = v1;
455 s->am_level += abs(lfastrintf(filtered)) - (s->am_level >> 8);
456 //printf("%9.1f %10.4f %9d %9d\n", famp, filtered, s->am_level, s->channel_level);
457 /* A Cauer notch at 2100Hz, spread just wide enough to meet our detection bandwidth
458 criteria. */
459 /* This is actually centred at 2095Hz, but gets the balance we want, due
460 to the asymmetric walls of the notch */
461 v1 = 0.76000f*famp - 0.1183852f*s->znotch_1 - 0.5104039f*s->znotch_2;
462 famp = v1 + 0.1567596f*s->znotch_1 + s->znotch_2;
463 s->znotch_2 = s->znotch_1;
464 s->znotch_1 = v1;
465 notched = (int16_t) lfastrintf(famp);
466 /* Estimate the overall energy in the channel, and the energy in
467 the notch (i.e. overall channel energy - tone energy => noise).
468 Use abs instead of multiply for speed (is it really faster?).
469 Damp the overall energy a little more for a stable result.
470 Damp the notch energy a little less, so we don't damp out the
471 blip every time the phase reverses. */
472 s->channel_level += ((abs(amp[i]) - s->channel_level) >> 5);
473 s->notch_level += ((abs(notched) - s->notch_level) >> 4);
474 /* This should cut off at about -43dBm0 */
475 if (s->channel_level <= 70)
476 {
477 /* If the energy level is low, even for a moment, we consider this the
478 end of the tone. */
479 if (s->tone_present != MODEM_CONNECT_TONES_NONE)
480 report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
481 s->tone_cycle_duration = 0;
482 s->good_cycles = 0;
483 s->tone_on = FALSE;
484 continue;
485 }
486 /* There is adequate energy in the channel. Is it mostly at 2100Hz? */
487 s->tone_cycle_duration++;
488 if (s->notch_level*6 < s->channel_level)
489 {
490 /* The notch test says yes, so we have the tone. */
491 /* We should get a kick from the notch filter every 450+-25ms, as the phase reverses, for an
492 EC disable tone. For a simple answer tone, the tone should persist unbroken for longer. */
493 if (!s->tone_on)
494 {
495 if (s->tone_cycle_duration >= ms_to_samples(450 - 25))
496 {
497 if (++s->good_cycles == 3)
498 {
499 report_tone_state(s,
500 (s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM_PR : MODEM_CONNECT_TONES_ANS_PR,
501 lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
502 }
503 }
504 else
505 {
506 s->good_cycles = 0;
507 }
508 /* Cycles are timed from rising edge to rising edge */
509 s->tone_cycle_duration = 0;
510 }
511 else
512 {
513 if (s->tone_cycle_duration >= ms_to_samples(450 + 100))
514 {
515 if (s->tone_present == MODEM_CONNECT_TONES_NONE)
516 {
517 report_tone_state(s,
518 (s->am_level*15/256 > s->channel_level) ? MODEM_CONNECT_TONES_ANSAM : MODEM_CONNECT_TONES_ANS,
519 lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
520 }
521 s->good_cycles = 0;
522 s->tone_cycle_duration = ms_to_samples(450 + 100);
523 }
524 }
525 s->tone_on = TRUE;
526 }
527 else if (s->notch_level*5 > s->channel_level)
528 {
529 if (s->tone_present == MODEM_CONNECT_TONES_ANS)
530 {
531 report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
532 s->good_cycles = 0;
533 }
534 else
535 {
536 if (s->tone_cycle_duration >= ms_to_samples(450 + 25))
537 {
538 /* The change came too late for a cycle of ANS_PR tone */
539 if (s->tone_present == MODEM_CONNECT_TONES_ANS_PR || s->tone_present == MODEM_CONNECT_TONES_ANSAM_PR)
540 report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
541 s->good_cycles = 0;
542 }
543 }
544 s->tone_on = FALSE;
545 }
546 }
547 break;
548 }
549 return 0;
550 }
551 /*- End of function --------------------------------------------------------*/
552
553 SPAN_DECLARE(int) modem_connect_tones_rx_get(modem_connect_tones_rx_state_t *s)
554 {
555 int x;
556
557 x = s->hit;
558 s->hit = MODEM_CONNECT_TONES_NONE;
559 return x;
560 }
561 /*- End of function --------------------------------------------------------*/
562
563 SPAN_DECLARE(modem_connect_tones_rx_state_t *) modem_connect_tones_rx_init(modem_connect_tones_rx_state_t *s,
564 int tone_type,
565 tone_report_func_t tone_callback,
566 void *user_data)
567 {
568 if (s == NULL)
569 {
570 if ((s = (modem_connect_tones_rx_state_t *) malloc(sizeof(*s))) == NULL)
571 return NULL;
572 }
573
574 s->tone_type = tone_type;
575 switch (s->tone_type)
576 {
577 case MODEM_CONNECT_TONES_FAX_PREAMBLE:
578 case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE:
579 fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, v21_put_bit, s);
580 fsk_rx_signal_cutoff(&(s->v21rx), -45.5f);
581 break;
582 case MODEM_CONNECT_TONES_ANS_PR:
583 case MODEM_CONNECT_TONES_ANSAM:
584 case MODEM_CONNECT_TONES_ANSAM_PR:
585 /* Treat these all the same for receive purposes */
586 s->tone_type = MODEM_CONNECT_TONES_ANS;
587 break;
588 }
589 s->channel_level = 0;
590 s->notch_level = 0;
591 s->am_level = 0;
592 s->tone_present = MODEM_CONNECT_TONES_NONE;
593 s->tone_cycle_duration = 0;
594 s->good_cycles = 0;
595 s->hit = MODEM_CONNECT_TONES_NONE;
596 s->tone_on = FALSE;
597 s->tone_callback = tone_callback;
598 s->callback_data = user_data;
599 s->znotch_1 = 0.0f;
600 s->znotch_2 = 0.0f;
601 s->z15hz_1 = 0.0f;
602 s->z15hz_2 = 0.0f;
603 s->num_bits = 0;
604 s->flags_seen = 0;
605 s->framing_ok_announced = FALSE;
606 s->raw_bit_stream = 0;
607 return s;
608 }
609 /*- End of function --------------------------------------------------------*/
610
611 SPAN_DECLARE(int) modem_connect_tones_rx_release(modem_connect_tones_rx_state_t *s)
612 {
613 return 0;
614 }
615 /*- End of function --------------------------------------------------------*/
616
617 SPAN_DECLARE(int) modem_connect_tones_rx_free(modem_connect_tones_rx_state_t *s)
618 {
619 free(s);
620 return 0;
621 }
622 /*- End of function --------------------------------------------------------*/
623 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.