-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #265 from drowe67/dr-tnc
FreeData TNC support
- Loading branch information
Showing
17 changed files
with
713 additions
and
299 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/*---------------------------------------------------------------------------*\ | ||
FILE........: freedv_datac0c1_tx.c | ||
AUTHOR......: David Rowe | ||
DATE CREATED: Dec 2021 | ||
Transmitting alternate frames of two different raw data modes. See | ||
freedv_datac0c1_rx.c | ||
\*---------------------------------------------------------------------------*/ | ||
|
||
/* | ||
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 "freedv_api.h" | ||
#include "ofdm_internal.h" | ||
|
||
#define FRAMES 10 | ||
|
||
void send_burst(struct freedv *freedv); | ||
|
||
int main(void) { | ||
struct freedv *freedv_c0, *freedv_c1; | ||
|
||
freedv_c0 = freedv_open(FREEDV_MODE_DATAC0); assert(freedv_c0 != NULL); | ||
freedv_c1 = freedv_open(FREEDV_MODE_DATAC1); assert(freedv_c1 != NULL); | ||
|
||
// send frames in different modes in random order | ||
int c0_frames = 0; | ||
int c1_frames = 0; | ||
while ((c0_frames < FRAMES) || (c1_frames < FRAMES)) { | ||
if (rand() & 1) { | ||
if (c0_frames < FRAMES) { | ||
send_burst(freedv_c0); | ||
c0_frames++; | ||
} | ||
} else { | ||
if (c1_frames < FRAMES) { | ||
send_burst(freedv_c1); | ||
c1_frames++; | ||
} | ||
} | ||
} | ||
|
||
freedv_close(freedv_c0); | ||
freedv_close(freedv_c1); | ||
|
||
return 0; | ||
} | ||
|
||
|
||
void send_burst(struct freedv *freedv) { | ||
size_t bits_per_frame = freedv_get_bits_per_modem_frame(freedv); | ||
size_t bytes_per_modem_frame = bits_per_frame/8; | ||
size_t payload_bytes_per_modem_frame = bytes_per_modem_frame - 2; /* 16 bits used for the CRC */ | ||
size_t n_mod_out = freedv_get_n_tx_modem_samples(freedv); | ||
uint8_t bytes_in[bytes_per_modem_frame]; | ||
short mod_out_short[n_mod_out]; | ||
|
||
/* generate a test frame */ | ||
uint8_t testframe_bits[bits_per_frame]; | ||
ofdm_generate_payload_data_bits(testframe_bits, bits_per_frame); | ||
freedv_pack(bytes_in, testframe_bits, bits_per_frame); | ||
|
||
/* send preamble */ | ||
int n_preamble = freedv_rawdatapreambletx(freedv, mod_out_short); | ||
fwrite(mod_out_short, sizeof(short), n_preamble, stdout); | ||
|
||
/* The raw data modes require a CRC in the last two bytes */ | ||
uint16_t crc16 = freedv_gen_crc16(bytes_in, payload_bytes_per_modem_frame); | ||
bytes_in[bytes_per_modem_frame-2] = crc16 >> 8; | ||
bytes_in[bytes_per_modem_frame-1] = crc16 & 0xff; | ||
|
||
/* modulate and send a data frame */ | ||
freedv_rawdatatx(freedv, mod_out_short, bytes_in); | ||
fwrite(mod_out_short, sizeof(short), n_mod_out, stdout); | ||
|
||
/* send postamble */ | ||
int n_postamble = freedv_rawdatapostambletx(freedv, mod_out_short); | ||
fwrite(mod_out_short, sizeof(short), n_postamble, stdout); | ||
|
||
/* create some silence between bursts */ | ||
int inter_burst_delay_ms = 200; | ||
int samples_delay = FREEDV_FS_8000*inter_burst_delay_ms/1000; | ||
short sil_short[samples_delay]; | ||
for(int i=0; i<samples_delay; i++) sil_short[i] = 0; | ||
fwrite(sil_short, sizeof(short), samples_delay, stdout); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.