Bug Summary

File:fsk.c
Warning:line 379, column 26
The right operand of '==' is a garbage value

Annotated Source Code

1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * fsk.c - FSK modem transmit and receive parts
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2003 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 2.1,
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26/*! \file */
27
28#if defined(HAVE_CONFIG_H1)
29#include "config.h"
30#endif
31
32#include <stdlib.h>
33#include <inttypes.h>
34#include <string.h>
35#if defined(HAVE_TGMATH_H1)
36#include <tgmath.h>
37#endif
38#if defined(HAVE_MATH_H1)
39#include <math.h>
40#endif
41#if defined(HAVE_STDBOOL_H1)
42#include <stdbool.h>
43#else
44#include "spandsp/stdbool.h"
45#endif
46#include "floating_fudge.h"
47#include <assert.h>
48
49#include "spandsp/telephony.h"
50#include "spandsp/alloc.h"
51#include "spandsp/complex.h"
52#include "spandsp/dds.h"
53#include "spandsp/power_meter.h"
54#include "spandsp/bit_operations.h"
55#include "spandsp/async.h"
56#include "spandsp/fsk.h"
57
58#include "spandsp/private/power_meter.h"
59#include "spandsp/private/fsk.h"
60
61const fsk_spec_t preset_fsk_specs[] =
62{
63 {
64 /* For duplex operation, this is the tx channel for the caller. */
65 "V21 ch 1",
66 1080 + 100,
67 1080 - 100,
68 -14,
69 -30,
70 300*100
71 },
72 {
73 /* For duplex operation, this is the tx channel for the answerer. */
74 /* This is the channel used for one way signaling for FAX. */
75 "V21 ch 2",
76 1750 + 100,
77 1750 - 100,
78 -14,
79 -30,
80 300*100
81 },
82 {
83 /* This is mode 2 of the V.23 spec. Mode 1 (the 600baud mode) is not defined here */
84 "V23 ch 1",
85 1700 + 400,
86 1700 - 400,
87 -14,
88 -30,
89 1200*100
90 },
91 {
92 "V23 ch 2",
93 420 + 30,
94 420 - 30,
95 -14,
96 -30,
97 75*100
98 },
99 {
100 /* For duplex operation, this is the tx channel for the caller. */
101 "Bell103 ch 1",
102 1170 - 100,
103 1170 + 100,
104 -14,
105 -30,
106 300*100
107 },
108 {
109 /* For duplex operation, this is the tx channel for the answerer. */
110 "Bell103 ch 2",
111 2125 - 100,
112 2125 + 100,
113 -14,
114 -30,
115 300*100
116 },
117 {
118 "Bell202",
119 1700 + 500,
120 1700 - 500,
121 -14,
122 -30,
123 1200*100
124 },
125 {
126 /* Used for US TDD (Telecoms Device for the Deaf) */
127 "Weitbrecht 45.45",
128 1600 + 200,
129 1600 - 200,
130 -14,
131 -30,
132 4545
133 },
134 {
135 /* Used for international TDD (Telecoms Device for the Deaf) */
136 "Weitbrecht 50",
137 1600 + 200,
138 1600 - 200,
139 -14,
140 -30,
141 50*100
142 },
143 {
144 /* Used for V.18 probing */
145 "Weitbrecht 47.6",
146 1600 + 200,
147 1600 - 200,
148 -14,
149 -30,
150 4760
151 },
152 {
153 "V21 (110bps) ch 1",
154 1080 + 100,
155 1080 - 100,
156 -14,
157 -30,
158 110*100
159 }
160};
161
162SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx(fsk_tx_state_t *s, int16_t amp[], int len)
163{
164 int sample;
165 int bit;
166
167 if (s->shutdown)
168 return 0;
169 /*endif*/
170 /* Make the transitions between 0 and 1 phase coherent, but instantaneous
171 jumps. There is currently no interpolation for bauds that end mid-sample.
172 Mainstream users will not care. Some specialist users might have a problem
173 with them, if they care about accurate transition timing. */
174 for (sample = 0; sample < len; sample++)
175 {
176 if ((s->baud_frac += s->baud_rate) >= SAMPLE_RATE8000*100)
177 {
178 s->baud_frac -= SAMPLE_RATE8000*100;
179 if ((bit = s->get_bit(s->get_bit_user_data)) == SIG_STATUS_END_OF_DATA)
180 {
181 if (s->status_handler)
182 s->status_handler(s->status_user_data, SIG_STATUS_END_OF_DATA);
183 /*endif*/
184 if (s->status_handler)
185 s->status_handler(s->status_user_data, SIG_STATUS_SHUTDOWN_COMPLETE);
186 /*endif*/
187 s->shutdown = true1;
188 break;
189 }
190 /*endif*/
191 s->current_phase_rate = s->phase_rates[bit & 1];
192 }
193 /*endif*/
194 amp[sample] = dds_mod(&s->phase_acc, s->current_phase_rate, s->scaling, 0);
195 }
196 /*endfor*/
197 return sample;
198}
199/*- End of function --------------------------------------------------------*/
200
201SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_tx_power(fsk_tx_state_t *s, float power)
202{
203 s->scaling = dds_scaling_dbm0(power);
204}
205/*- End of function --------------------------------------------------------*/
206
207SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_tx_set_get_bit(fsk_tx_state_t *s, span_get_bit_func_t get_bit, void *user_data)
208{
209 s->get_bit = get_bit;
210 s->get_bit_user_data = user_data;
211}
212/*- End of function --------------------------------------------------------*/
213
214SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_tx_set_modem_status_handler(fsk_tx_state_t *s, span_modem_status_func_t handler, void *user_data)
215{
216 s->status_handler = handler;
217 s->status_user_data = user_data;
218}
219/*- End of function --------------------------------------------------------*/
220
221SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx_restart(fsk_tx_state_t *s, const fsk_spec_t *spec)
222{
223 s->baud_rate = spec->baud_rate;
224 s->phase_rates[0] = dds_phase_rate((float) spec->freq_zero);
225 s->phase_rates[1] = dds_phase_rate((float) spec->freq_one);
226 s->scaling = dds_scaling_dbm0((float) spec->tx_level);
227 /* Initialise fractional sample baud generation. */
228 s->phase_acc = 0;
229 s->baud_frac = 0;
230 s->current_phase_rate = s->phase_rates[1];
231
232 s->shutdown = false0;
233 return 0;
234}
235/*- End of function --------------------------------------------------------*/
236
237SPAN_DECLARE(fsk_tx_state_t *)__attribute__((visibility("default"))) fsk_tx_state_t * fsk_tx_init(fsk_tx_state_t *s,
238 const fsk_spec_t *spec,
239 span_get_bit_func_t get_bit,
240 void *user_data)
241{
242 if (s == NULL((void*)0))
243 {
244 if ((s = (fsk_tx_state_t *) span_alloc(sizeof(*s))) == NULL((void*)0))
245 return NULL((void*)0);
246 /*endif*/
247 }
248 /*endif*/
249 memset(s, 0, sizeof(*s));
250
251 s->get_bit = get_bit;
252 s->get_bit_user_data = user_data;
253 fsk_tx_restart(s, spec);
254 return s;
255}
256/*- End of function --------------------------------------------------------*/
257
258SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx_release(fsk_tx_state_t *s)
259{
260 return 0;
261}
262/*- End of function --------------------------------------------------------*/
263
264SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_tx_free(fsk_tx_state_t *s)
265{
266 span_free(s);
267 return 0;
268}
269/*- End of function --------------------------------------------------------*/
270
271SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_signal_cutoff(fsk_rx_state_t *s, float cutoff)
272{
273 /* The 6.04 allows for the gain of the DC blocker */
274 s->carrier_on_power = (int32_t) (power_meter_level_dbm0(cutoff + 2.5f - 6.04f));
275 s->carrier_off_power = (int32_t) (power_meter_level_dbm0(cutoff - 2.5f - 6.04f));
276}
277/*- End of function --------------------------------------------------------*/
278
279SPAN_DECLARE(float)__attribute__((visibility("default"))) float fsk_rx_signal_power(fsk_rx_state_t *s)
280{
281 return power_meter_current_dbm0(&s->power);
282}
283/*- End of function --------------------------------------------------------*/
284
285SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_put_bit(fsk_rx_state_t *s, span_put_bit_func_t put_bit, void *user_data)
286{
287 s->put_bit = put_bit;
288 s->put_bit_user_data = user_data;
289}
290/*- End of function --------------------------------------------------------*/
291
292SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_modem_status_handler(fsk_rx_state_t *s, span_modem_status_func_t handler, void *user_data)
293{
294 s->status_handler = handler;
295 s->status_user_data = user_data;
296}
297/*- End of function --------------------------------------------------------*/
298
299SPAN_DECLARE(void)__attribute__((visibility("default"))) void fsk_rx_set_frame_parameters(fsk_rx_state_t *s,
300 int data_bits,
301 int parity,
302 int stop_bits)
303{
304 if (s->framing_mode == FSK_FRAME_MODE_FRAMED)
305 {
306 s->data_bits = data_bits;
307 s->parity = parity;
308 s->stop_bits = stop_bits;
309 s->total_data_bits = s->data_bits;
310 if (s->parity != ASYNC_PARITY_NONE)
311 s->total_data_bits++;
312 /*endif*/
313 }
314 /*endif*/
315}
316/*- End of function --------------------------------------------------------*/
317
318SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_get_parity_errors(fsk_rx_state_t *s, bool_Bool reset)
319{
320 int errors;
321
322 errors = s->parity_errors;
323 if (reset)
324 s->parity_errors = 0;
325 /*endif*/
326 return errors;
327}
328/*- End of function --------------------------------------------------------*/
329
330SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_get_framing_errors(fsk_rx_state_t *s, bool_Bool reset)
331{
332 int errors;
333
334 errors = s->framing_errors;
335 if (reset)
336 s->framing_errors = 0;
337 /*endif*/
338 return errors;
339}
340/*- End of function --------------------------------------------------------*/
341
342static void report_status_change(fsk_rx_state_t *s, int status)
343{
344 if (s->status_handler)
345 s->status_handler(s->status_user_data, status);
346 else if (s->put_bit)
347 s->put_bit(s->put_bit_user_data, status);
348 /*endif*/
349}
350/*- End of function --------------------------------------------------------*/
351
352static void put_frame(fsk_rx_state_t *s, uint16_t frame)
353{
354 uint16_t parity_bit_a;
355 uint16_t parity_bit_b;
25
'parity_bit_b' declared without an initial value
356
357 if (s->parity != ASYNC_PARITY_NONE)
26
Assuming the condition is true
27
Taking true branch
358 {
359 parity_bit_a = (frame >> 15) & 0x01;
360 /* Trim off the parity bit */
361 frame &= 0x7FFF;
362 frame >>= (16 - s->total_data_bits);
363 switch (s->parity)
28
'Default' branch taken. Execution continues on line 379
364 {
365 case ASYNC_PARITY_ODD:
366 parity_bit_b = parity8(frame) ^ 1;
367 break;
368 case ASYNC_PARITY_EVEN:
369 parity_bit_b = parity8(frame);
370 break;
371 case ASYNC_PARITY_MARK:
372 parity_bit_b = 1;
373 break;
374 case ASYNC_PARITY_SPACE:
375 parity_bit_b = 0;
376 break;
377 }
378 /*endswitch*/
379 if (parity_bit_a == parity_bit_b)
29
The right operand of '==' is a garbage value
380 s->put_bit(s->put_bit_user_data, frame);
381 else
382 s->parity_errors++;
383 /*endif*/
384 }
385 else
386 {
387 frame >>= (16 - s->total_data_bits);
388 s->put_bit(s->put_bit_user_data, frame);
389 }
390 /*endif*/
391}
392/*- End of function --------------------------------------------------------*/
393
394SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len)
395{
396 int buf_ptr;
397 int baudstate;
398 int i;
399 int j;
400 int16_t x;
401 int32_t dot;
402 int32_t sum[2];
403 int32_t power;
404 complexi_t ph;
405
406 buf_ptr = s->buf_ptr;
407 for (i = 0; i < len; i++)
1
Assuming 'i' is < 'len'
2
Loop condition is true. Entering loop body
408 {
409 /* The *totally* asynchronous character to character behaviour of these
410 modems, when carrying async. data, seems to force a sample by sample
411 approach. */
412 for (j = 0; j < 2; j++)
3
Loop condition is true. Entering loop body
4
Loop condition is true. Entering loop body
5
Loop condition is false. Execution continues on line 435
413 {
414 s->dot[j].re -= s->window[j][buf_ptr].re;
415 s->dot[j].im -= s->window[j][buf_ptr].im;
416
417 ph = dds_complexi(&s->phase_acc[j], s->phase_rate[j]);
418 s->window[j][buf_ptr].re = (ph.re*amp[i]) >> s->scaling_shift;
419 s->window[j][buf_ptr].im = (ph.im*amp[i]) >> s->scaling_shift;
420
421 s->dot[j].re += s->window[j][buf_ptr].re;
422 s->dot[j].im += s->window[j][buf_ptr].im;
423
424 dot = s->dot[j].re >> 15;
425 sum[j] = dot*dot;
426 dot = s->dot[j].im >> 15;
427 sum[j] += dot*dot;
428 }
429 /*endfor*/
430 /* If there isn't much signal, don't demodulate - it will only produce
431 useless junk results. */
432 /* There should be no DC in the signal, but sometimes there is.
433 We need to measure the power with the DC blocked, but not using
434 a slow to respond DC blocker. Use the most elementary HPF. */
435 x = amp[i] >> 1;
436 power = power_meter_update(&s->power, x - s->last_sample);
437 s->last_sample = x;
438 if (s->signal_present)
6
Assuming the condition is true
7
Taking true branch
439 {
440 /* Look for power below turn-off threshold to turn the carrier off */
441 if (power < s->carrier_off_power)
8
Taking false branch
442 {
443 if (--s->signal_present <= 0)
444 {
445 /* Count down a short delay, to ensure we push the last
446 few bits through the filters before stopping. */
447 report_status_change(s, SIG_STATUS_CARRIER_DOWN);
448 s->baud_phase = 0;
449 continue;
450 }
451 /*endif*/
452 }
453 /*endif*/
454 }
455 else
456 {
457 /* Look for power exceeding turn-on threshold to turn the carrier on */
458 if (power < s->carrier_on_power)
459 {
460 s->baud_phase = 0;
461 continue;
462 }
463 /*endif*/
464 if (s->baud_phase < (s->correlation_span >> 1) - 30)
465 {
466 s->baud_phase++;
467 continue;
468 }
469 /*endif*/
470 s->signal_present = 1;
471 /* Initialise the baud/bit rate tracking. */
472 s->baud_phase = 0;
473 s->frame_pos = -2;
474 s->frame_in_progress = 0;
475 s->last_bit = 0;
476 report_status_change(s, SIG_STATUS_CARRIER_UP);
477 }
478 /*endif*/
479 /* Non-coherent FSK demodulation by correlation with the target tones
480 over a one baud interval. The slow V.xx specs. are too open ended
481 to allow anything fancier to be used. The dot products are calculated
482 using a sliding window approach, so the compute load is not that great. */
483
484 baudstate = (sum[0] < sum[1]);
485 switch (s->framing_mode)
9
Control jumps to the 'default' case at line 535
486 {
487 case FSK_FRAME_MODE_SYNC:
488 /* Synchronous serial operation - e.g. for HDLC */
489 if (s->last_bit != baudstate)
490 {
491 /* On a transition we check our timing */
492 s->last_bit = baudstate;
493 /* For synchronous use (e.g. HDLC channels in FAX modems), nudge
494 the baud phase gently, trying to keep it centred on the bauds. */
495 if (s->baud_phase < (SAMPLE_RATE8000*50))
496 s->baud_phase += (s->baud_rate >> 3);
497 else
498 s->baud_phase -= (s->baud_rate >> 3);
499 /*endif*/
500 }
501 /*endif*/
502 if ((s->baud_phase += s->baud_rate) >= (SAMPLE_RATE8000*100))
503 {
504 /* We should be in the middle of a baud now, so report the current
505 state as the next bit */
506 s->baud_phase -= (SAMPLE_RATE8000*100);
507 s->put_bit(s->put_bit_user_data, baudstate);
508 }
509 /*endif*/
510 break;
511 case FSK_FRAME_MODE_ASYNC:
512 /* Fully asynchronous mode */
513 if (s->last_bit != baudstate)
514 {
515 /* On a transition we check our timing */
516 s->last_bit = baudstate;
517 /* For async. operation, believe transitions completely, and
518 sample appropriately. This allows instant start on the first
519 transition. */
520 /* We must now be about half way to a sampling point. We do not do
521 any fractional sample estimation of the transitions, so this is
522 the most accurate baud alignment we can do. */
523 s->baud_phase = SAMPLE_RATE8000*50;
524 }
525 /*endif*/
526 if ((s->baud_phase += s->baud_rate) >= (SAMPLE_RATE8000*100))
527 {
528 /* We should be in the middle of a baud now, so report the current
529 state as the next bit */
530 s->baud_phase -= (SAMPLE_RATE8000*100);
531 s->put_bit(s->put_bit_user_data, baudstate);
532 }
533 /*endif*/
534 break;
535 default:
536 /* Gather the specified number of bits, with robust checking to ensure reasonable voice
537 immunity. The first bit should be a start bit (0), and the last bit should be a stop
538 bit (1) */
539 if (s->frame_pos == -2)
10
Assuming the condition is false
11
Taking false branch
540 {
541 /* Looking for the start of a zero bit, which could be a start bit */
542 if (baudstate == 0)
543 {
544 s->baud_phase = SAMPLE_RATE8000*(100 - 40)/2;
545 s->frame_pos = -1;
546 s->frame_in_progress = 0;
547 s->last_bit = -1;
548 }
549 /*endif*/
550 }
551 else if (s->frame_pos == -1)
12
Assuming the condition is false
13
Taking false branch
552 {
553 /* Look for a continuous zero from the start of the start bit until
554 beyond the middle */
555 if (baudstate != 0)
556 {
557 /* If we aren't seeing a stable start bit, restart */
558 s->frame_pos = -2;
559 }
560 else
561 {
562 s->baud_phase += s->baud_rate;
563 if (s->baud_phase >= SAMPLE_RATE8000*100)
564 {
565 s->frame_pos = 0;
566 s->last_bit = baudstate;
567 }
568 /*endif*/
569 }
570 /*endif*/
571 }
572 else
573 {
574 s->baud_phase += s->baud_rate;
575 if (s->baud_phase >= SAMPLE_RATE8000*(100 - 40))
14
Assuming the condition is true
15
Taking true branch
576 {
577 if (s->last_bit < 0)
16
Assuming the condition is false
17
Taking false branch
578 s->last_bit = baudstate;
579 /*endif*/
580 /* Look for the bit being consistent over the central 20% of the bit time. */
581 if (s->last_bit != baudstate)
18
Taking false branch
582 {
583 s->frame_pos = -2;
584 s->framing_errors++;
585 }
586 else
587 {
588 if (s->baud_phase >= SAMPLE_RATE8000*100)
19
Assuming the condition is true
20
Taking true branch
589 {
590 /* We should be in the middle of a baud now, so report the current
591 state as the next bit */
592 if (s->frame_pos++ > s->total_data_bits)
21
Taking true branch
593 {
594 /* Check we have a stop bit */
595 if (baudstate == 1)
22
Assuming 'baudstate' is equal to 1
23
Taking true branch
596 {
597 put_frame(s, s->frame_in_progress);
24
Calling 'put_frame'
598 }
599 else
600 {
601 s->framing_errors++;
602 }
603 /*endif*/
604 s->frame_pos = -2;
605 }
606 else
607 {
608 s->frame_in_progress = (s->frame_in_progress >> 1) | (baudstate << 15);
609 }
610 /*endif*/
611 s->baud_phase -= (SAMPLE_RATE8000*100);
612 s->last_bit = -1;
613 }
614 /*endif*/
615 }
616 /*endif*/
617 }
618 /*endif*/
619 }
620 /*endif*/
621 break;
622 }
623 /*endswitch*/
624 if (++buf_ptr >= s->correlation_span)
625 buf_ptr = 0;
626 /*endif*/
627 }
628 /*endfor*/
629 s->buf_ptr = buf_ptr;
630 return 0;
631}
632/*- End of function --------------------------------------------------------*/
633
634SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_fillin(fsk_rx_state_t *s, int len)
635{
636 int buf_ptr;
637 int i;
638 int j;
639
640 /* The valid choice here is probably to do nothing. We don't change state
641 (i.e carrier on<->carrier off), and we'll just output less bits than we
642 should. */
643 buf_ptr = s->buf_ptr;
644 for (i = 0; i < len; i++)
645 {
646 for (j = 0; j < 2; j++)
647 {
648 s->dot[j].re -= s->window[j][buf_ptr].re;
649 s->dot[j].im -= s->window[j][buf_ptr].im;
650
651 dds_advance(&s->phase_acc[j], s->phase_rate[j]);
652
653 s->window[j][buf_ptr].re = 0;
654 s->window[j][buf_ptr].im = 0;
655
656 s->dot[j].re += s->window[j][buf_ptr].re;
657 s->dot[j].im += s->window[j][buf_ptr].im;
658 }
659 /*endfor*/
660 }
661 /*endfor*/
662 s->buf_ptr = buf_ptr;
663 return 0;
664}
665/*- End of function --------------------------------------------------------*/
666
667SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_restart(fsk_rx_state_t *s,
668 const fsk_spec_t *spec,
669 int framing_mode)
670{
671 int chop;
672
673 s->baud_rate = spec->baud_rate;
674 s->framing_mode = framing_mode;
675 if (s->framing_mode == FSK_FRAME_MODE_FRAMED)
676 fsk_rx_set_frame_parameters(s, 8, ASYNC_PARITY_NONE, 1);
677 /*endif*/
678 fsk_rx_set_signal_cutoff(s, (float) spec->min_level);
679
680 /* Detect by correlating against the tones we want, over a period
681 of one baud. The correlation must be quadrature. */
682
683 /* First we need the quadrature tone generators to correlate
684 against. */
685 s->phase_rate[0] = dds_phase_rate((float) spec->freq_zero);
686 s->phase_rate[1] = dds_phase_rate((float) spec->freq_one);
687 s->phase_acc[0] = 0;
688 s->phase_acc[1] = 0;
689 s->last_sample = 0;
690
691 /* The correlation should be over one baud. */
692 s->correlation_span = SAMPLE_RATE8000*100/spec->baud_rate;
693 /* But limit it for very slow baud rates, so we do not overflow our
694 buffer. */
695 if (s->correlation_span > FSK_MAX_WINDOW_LEN128)
696 s->correlation_span = FSK_MAX_WINDOW_LEN128;
697 /*endif*/
698
699 /* We need to scale, to avoid overflow in the correlation. */
700 s->scaling_shift = 0;
701 chop = s->correlation_span;
702 while (chop != 0)
703 {
704 s->scaling_shift++;
705 chop >>= 1;
706 }
707 /*endwhile*/
708
709 /* Initialise the baud/bit rate tracking. */
710 s->baud_phase = 0;
711 s->frame_pos = -2;
712 s->frame_in_progress = 0;
713 s->last_bit = 0;
714
715 /* Initialise a power detector, so sense when a signal is present. */
716 power_meter_init(&s->power, 4);
717 s->signal_present = 0;
718 return 0;
719}
720/*- End of function --------------------------------------------------------*/
721
722SPAN_DECLARE(fsk_rx_state_t *)__attribute__((visibility("default"))) fsk_rx_state_t * fsk_rx_init(fsk_rx_state_t *s,
723 const fsk_spec_t *spec,
724 int framing_mode,
725 span_put_bit_func_t put_bit,
726 void *user_data)
727{
728 if (s == NULL((void*)0))
729 {
730 if ((s = (fsk_rx_state_t *) span_alloc(sizeof(*s))) == NULL((void*)0))
731 return NULL((void*)0);
732 /*endif*/
733 }
734 /*endif*/
735 memset(s, 0, sizeof(*s));
736
737 s->put_bit = put_bit;
738 s->put_bit_user_data = user_data;
739 fsk_rx_restart(s, spec, framing_mode);
740 return s;
741}
742/*- End of function --------------------------------------------------------*/
743
744SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_release(fsk_rx_state_t *s)
745{
746 return 0;
747}
748/*- End of function --------------------------------------------------------*/
749
750SPAN_DECLARE(int)__attribute__((visibility("default"))) int fsk_rx_free(fsk_rx_state_t *s)
751{
752 span_free(s);
753 return 0;
754}
755/*- End of function --------------------------------------------------------*/
756/*- End of file ------------------------------------------------------------*/