aboutsummaryrefslogtreecommitdiff
path: root/demo/freedv_datac0c1_rx.c
diff options
context:
space:
mode:
authorAuthor Name <[email protected]>2023-07-07 12:20:59 +0930
committerDavid Rowe <[email protected]>2023-07-07 12:29:06 +0930
commitac7c48b4dee99d4c772f133d70d8d1b38262fcd2 (patch)
treea2d0ace57a9c0e2e5b611c4987f6fed1b38b81e7 /demo/freedv_datac0c1_rx.c
shallow zip-file copy from codec2 e9d726bf20
Diffstat (limited to 'demo/freedv_datac0c1_rx.c')
-rw-r--r--demo/freedv_datac0c1_rx.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/demo/freedv_datac0c1_rx.c b/demo/freedv_datac0c1_rx.c
new file mode 100644
index 0000000..cfbef14
--- /dev/null
+++ b/demo/freedv_datac0c1_rx.c
@@ -0,0 +1,128 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: freedv_datac0c1_rx.c
+ AUTHOR......: David Rowe
+ DATE CREATED: Dec 2021
+
+ Demonstrates receiving frames of raw data bytes using the FreeDV
+ API. Two parallel receivers are running, so we can receive either
+ DATAC0 or DATAC1 frames. Demonstrates a common use case for HF data
+ - the ability to receive signalling as well as payload data frames.
+
+ usage:
+
+ cd codec2/build_linux
+ ./demo/freedv_datacc01_tx | ./demo/freedv_datac0c1_rx
+
+ Give it a hard time with some channel noise, frequency offset, and sample
+ clock offsets:
+
+ ./demo/freedv_datac0c1_tx | ./src/cohpsk_ch - - -24 -f 20 --Fs 8000 |
+ sox -t .s16 -c 1 -r 8000 - -t .s16 -c 1 -r 8008 - |
+ ./demo/freedv_datac0c1_rx
+
+ Replace the final line with "aplay -f S16" to listen to the
+ simulated Rx signal.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2021 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "freedv_api.h"
+
+#define NBUF 160
+
+int run_receiver(struct freedv *freedv, short buf[], short demod_in[], int *pn, uint8_t bytes_out[]);
+
+int main(int argc, char *argv[]) {
+
+ // set up DATAC0 Rx
+ struct freedv *freedv_c0 = freedv_open(FREEDV_MODE_DATAC0);
+ assert(freedv_c0 != NULL);
+ freedv_set_frames_per_burst(freedv_c0, 1);
+ freedv_set_verbose(freedv_c0, 0);
+ int bytes_per_modem_frame_c0 = freedv_get_bits_per_modem_frame(freedv_c0)/8;
+ uint8_t bytes_out_c0[bytes_per_modem_frame_c0];
+ short demod_in_c0[freedv_get_n_max_modem_samples(freedv_c0)];
+
+ // set up DATAC1 Rx
+ struct freedv *freedv_c1 = freedv_open(FREEDV_MODE_DATAC1);
+ assert(freedv_c1 != NULL);
+ freedv_set_frames_per_burst(freedv_c1, 1);
+ freedv_set_verbose(freedv_c1, 0);
+ int bytes_per_modem_frame_c1 = freedv_get_bits_per_modem_frame(freedv_c1)/8;
+ uint8_t bytes_out_c1[bytes_per_modem_frame_c1];
+ short demod_in_c1[freedv_get_n_max_modem_samples(freedv_c1)];
+
+ // number of samples in demod_in buffer for each Rx
+ int n_c0 = 0;
+ int n_c1 = 0;
+ // number of frames received in each mode
+ int c0_frames = 0;
+ int c1_frames = 0;
+
+ short buf[NBUF];
+
+ // read a fixed buffer from stdin, use that to fill c0 and c1 demod_in buffers
+ while(fread(buf, sizeof(short), NBUF, stdin) == NBUF) {
+
+ if (run_receiver(freedv_c0, buf, demod_in_c0, &n_c0, bytes_out_c0)) {
+ fprintf(stderr, "DATAC0 frame received!\n");
+ c0_frames++;
+ }
+ if (run_receiver(freedv_c1, buf, demod_in_c1, &n_c1, bytes_out_c1)) {
+ fprintf(stderr, "DATAC1 frame received!\n");
+ c1_frames++;
+ }
+
+ }
+
+ fprintf(stderr, "DATAC0 Frames: %d DATAC1 Frames: %d\n", c0_frames, c1_frames);
+
+ freedv_close(freedv_c0);
+ freedv_close(freedv_c1);
+
+ return 0;
+}
+
+int run_receiver(struct freedv *freedv, short buf[], short demod_in[], int *pn, uint8_t bytes_out[]) {
+ int n = *pn;
+ int nbytes_out = 0;
+ int nin;
+
+ // NBUF new samples into DATAC1 Rx
+ memcpy(&demod_in[n], buf, sizeof(short)*NBUF);
+ n += NBUF; assert(n <= freedv_get_n_max_modem_samples(freedv));
+ nin = freedv_nin(freedv);
+ while (n > nin) {
+ nbytes_out = freedv_rawdatarx(freedv, bytes_out, demod_in);
+ // nin samples were read
+ n -= nin; assert(n >= 0);
+ memmove(demod_in, &demod_in[nin], sizeof(short)*n);
+ nin = freedv_nin(freedv);
+ }
+
+ *pn = n;
+ return nbytes_out;
+}