forked from 0815employee/codec2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
freedv_datac0c1_rx.c
131 lines (105 loc) · 4.12 KB
/
freedv_datac0c1_rx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*---------------------------------------------------------------------------*\
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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defines.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;
VLA_CALLOC(uint8_t, bytes_out_c0, bytes_per_modem_frame_c0);
VLA_CALLOC(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;
VLA_CALLOC(uint8_t, bytes_out_c1, bytes_per_modem_frame_c1);
VLA_CALLOC(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);
VLA_FREE(bytes_out_c0, demod_in_c0);
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;
}