mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-05 16:26:42 +10:00
updated ui added new features
This commit is contained in:
+17
@@ -0,0 +1,17 @@
|
||||
add_definitions(-DFLOATING_POINT -DVAR_ARRAYS)
|
||||
include_directories(../src)
|
||||
|
||||
add_executable(c2demo c2demo.c)
|
||||
target_link_libraries(c2demo codec2)
|
||||
add_executable(freedv_700d_tx freedv_700d_tx.c)
|
||||
target_link_libraries(freedv_700d_tx codec2)
|
||||
add_executable(freedv_700d_rx freedv_700d_rx.c)
|
||||
target_link_libraries(freedv_700d_rx codec2)
|
||||
add_executable(freedv_datac1_tx freedv_datac1_tx.c)
|
||||
target_link_libraries(freedv_datac1_tx codec2)
|
||||
add_executable(freedv_datac1_rx freedv_datac1_rx.c)
|
||||
target_link_libraries(freedv_datac1_rx codec2)
|
||||
add_executable(freedv_datac0c1_tx freedv_datac0c1_tx.c)
|
||||
target_link_libraries(freedv_datac0c1_tx codec2)
|
||||
add_executable(freedv_datac0c1_rx freedv_datac0c1_rx.c)
|
||||
target_link_libraries(freedv_datac0c1_rx codec2)
|
||||
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: c2demo.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: 15/11/2010
|
||||
|
||||
Encodes and decodes a file of raw speech samples using Codec 2.
|
||||
Demonstrates use of Codec 2 function API.
|
||||
|
||||
cd codec2/build_linux
|
||||
./demo/c2demo ../raw/hts1a.raw his1a_out.raw
|
||||
aplay -f S16_LE hts1a_out.raw
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2010 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "codec2.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct CODEC2 *codec2;
|
||||
FILE *fin;
|
||||
FILE *fout;
|
||||
|
||||
if (argc != 3) {
|
||||
printf("usage: %s InputRawSpeechFile OutputRawSpeechFile\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((fin = fopen(argv[1], "rb")) == NULL) {
|
||||
fprintf(stderr, "Error opening input speech file: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((fout = fopen(argv[2], "wb")) == NULL) {
|
||||
fprintf(stderr, "Error opening output speech file: %s\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Note only one set of Codec 2 states is required for an encoder
|
||||
and decoder pair. */
|
||||
codec2 = codec2_create(CODEC2_MODE_1300);
|
||||
size_t nsam = codec2_samples_per_frame(codec2);
|
||||
short speech_samples[nsam];
|
||||
/* Bits from the encoder are packed into bytes */
|
||||
unsigned char compressed_bytes[codec2_bytes_per_frame(codec2)];
|
||||
|
||||
while (fread(speech_samples, sizeof(short), nsam, fin) == nsam) {
|
||||
codec2_encode(codec2, compressed_bytes, speech_samples);
|
||||
codec2_decode(codec2, speech_samples, compressed_bytes);
|
||||
fwrite(speech_samples, sizeof(short), nsam, fout);
|
||||
}
|
||||
|
||||
codec2_destroy(codec2);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_700d_rx.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 2021
|
||||
|
||||
Demo receive program for FreeDV API (700D mode), see freedv_700d_tx.c for
|
||||
instructions.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "freedv_api.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *freedv;
|
||||
|
||||
freedv = freedv_open(FREEDV_MODE_700D);
|
||||
assert(freedv != NULL);
|
||||
|
||||
/* note API functions to tell us how big our buffers need to be */
|
||||
short speech_out[freedv_get_n_max_speech_samples(freedv)];
|
||||
short demod_in[freedv_get_n_max_modem_samples(freedv)];
|
||||
|
||||
size_t nin, nout;
|
||||
nin = freedv_nin(freedv);
|
||||
while (fread(demod_in, sizeof(short), nin, stdin) == nin) {
|
||||
nout = freedv_rx(freedv, speech_out, demod_in);
|
||||
nin = freedv_nin(freedv); /* call me on every loop! */
|
||||
fwrite(speech_out, sizeof(short), nout, stdout);
|
||||
}
|
||||
|
||||
freedv_close(freedv);
|
||||
return 0;
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
'''
|
||||
Demo receive program for FreeDV API 700D mode.
|
||||
|
||||
cd ~/codec2/build_linux
|
||||
cat ../raw/ve9qrp_10s.raw | ./demo/freedv_700d_tx | ../demo/freedv_700d_rx.py | aplay -f S16_LE
|
||||
|
||||
Credits: Thanks DJ2LS, xssfox, VK5QI
|
||||
'''
|
||||
|
||||
import ctypes
|
||||
from ctypes import *
|
||||
import sys
|
||||
import pathlib
|
||||
import platform
|
||||
|
||||
if platform.system() == 'Darwin':
|
||||
libname = pathlib.Path().absolute() / "src/libcodec2.dylib"
|
||||
else:
|
||||
libname = pathlib.Path().absolute() / "src/libcodec2.so"
|
||||
|
||||
# See: https://docs.python.org/3/library/ctypes.html
|
||||
|
||||
c_lib = ctypes.CDLL(libname)
|
||||
|
||||
c_lib.freedv_open.argype = [c_int]
|
||||
c_lib.freedv_open.restype = c_void_p
|
||||
|
||||
c_lib.freedv_get_n_max_speech_samples.argtype = [c_void_p]
|
||||
c_lib.freedv_get_n_max_speech_samples.restype = c_int
|
||||
|
||||
c_lib.freedv_nin.argtype = [c_void_p]
|
||||
c_lib.freedv_nin.restype = c_int
|
||||
|
||||
c_lib.freedv_rx.argtype = [c_void_p, c_char_p, c_char_p]
|
||||
c_lib.freedv_rx.restype = c_int
|
||||
|
||||
FREEDV_MODE_700D = 7 # from freedv_api.h
|
||||
freedv = cast(c_lib.freedv_open(FREEDV_MODE_700D), c_void_p)
|
||||
|
||||
n_max_speech_samples = c_lib.freedv_get_n_max_speech_samples(freedv)
|
||||
speech_out = create_string_buffer(2*n_max_speech_samples)
|
||||
|
||||
while True:
|
||||
nin = c_lib.freedv_nin(freedv)
|
||||
demod_in = sys.stdin.buffer.read(nin*2)
|
||||
if len(demod_in) == 0: quit()
|
||||
nout = c_lib.freedv_rx(freedv, speech_out, demod_in)
|
||||
sys.stdout.buffer.write(speech_out[:nout*2])
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_700d_tx.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 2021
|
||||
|
||||
Demo transmit program using the FreeDV API (700D mode).
|
||||
|
||||
usage:
|
||||
|
||||
cd ~/codec2/build_linux
|
||||
cat ../raw/ve9qrp_10s.raw | ./demo/freedv_700d_tx | ./demo/freedv_700d_rx |
|
||||
aplay -f S16_LE
|
||||
|
||||
Listen to the modulated Tx signal:
|
||||
|
||||
cat ../raw/ve9qrp_10s.raw | ./demo/freedv_700d_tx | aplay -f S16_LE
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "freedv_api.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *freedv;
|
||||
|
||||
freedv = freedv_open(FREEDV_MODE_700D);
|
||||
assert(freedv != NULL);
|
||||
|
||||
/* handy functions to set buffer sizes */
|
||||
int n_speech_samples = freedv_get_n_speech_samples(freedv);
|
||||
short speech_in[n_speech_samples];
|
||||
int n_nom_modem_samples = freedv_get_n_nom_modem_samples(freedv);
|
||||
short mod_out[n_nom_modem_samples];
|
||||
|
||||
/* OK main loop --------------------------------------- */
|
||||
|
||||
while (fread(speech_in, sizeof(short), n_speech_samples, stdin) ==
|
||||
n_speech_samples) {
|
||||
freedv_tx(freedv, mod_out, speech_in);
|
||||
fwrite(mod_out, sizeof(short), n_nom_modem_samples, stdout);
|
||||
}
|
||||
|
||||
freedv_close(freedv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
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 "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;
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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);
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_datac1_rx.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 2021
|
||||
|
||||
Demonstrates receiving frames of raw data bytes using the FreeDV API.
|
||||
|
||||
See freedv_datac1_tx.c for instructions.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
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 "freedv_api.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *freedv;
|
||||
|
||||
freedv = freedv_open(FREEDV_MODE_DATAC1);
|
||||
assert(freedv != NULL);
|
||||
freedv_set_frames_per_burst(freedv, 1);
|
||||
freedv_set_verbose(freedv, 2);
|
||||
|
||||
int bytes_per_modem_frame = freedv_get_bits_per_modem_frame(freedv) / 8;
|
||||
uint8_t bytes_out[bytes_per_modem_frame];
|
||||
short demod_in[freedv_get_n_max_modem_samples(freedv)];
|
||||
|
||||
size_t nin, nbytes_out;
|
||||
nin = freedv_nin(freedv);
|
||||
while (fread(demod_in, sizeof(short), nin, stdin) == nin) {
|
||||
nbytes_out = freedv_rawdatarx(freedv, bytes_out, demod_in);
|
||||
nin = freedv_nin(freedv); /* must call this every loop */
|
||||
if (nbytes_out) {
|
||||
/* don't output CRC */
|
||||
fwrite(bytes_out, sizeof(uint8_t), nbytes_out - 2, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
freedv_close(freedv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
||||
FILE........: freedv_datac1_tx.c
|
||||
AUTHOR......: David Rowe
|
||||
DATE CREATED: April 2021
|
||||
|
||||
Demonstrates transmitting frames of raw data bytes using the FreeDV API datac1
|
||||
mode. The data on stdin is transmitted as a sequence of modulated bursts.
|
||||
|
||||
Format of each burst: ...|preamble|data frame|postamble|silence|....
|
||||
|
||||
There is just one data frame per burst in this demo.
|
||||
|
||||
usage:
|
||||
|
||||
cd codec2/build_linux
|
||||
head -c $((510*10)) </dev/urandom > binaryIn.bin
|
||||
cat binaryIn.bin | ./demo/freedv_datac1_tx | ./demo/freedv_datac1_rx >
|
||||
binaryOut.bin diff binaryIn.bin binaryOut.bin
|
||||
|
||||
Listen to the modulated Tx signal:
|
||||
|
||||
cat binaryIn.bin | ./demo/freedv_datac1_tx | aplay -f S16_LE
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
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 "freedv_api.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct freedv *freedv;
|
||||
|
||||
freedv = freedv_open(FREEDV_MODE_DATAC1);
|
||||
assert(freedv != NULL);
|
||||
|
||||
size_t bytes_per_modem_frame = freedv_get_bits_per_modem_frame(freedv) / 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];
|
||||
|
||||
for (int b = 0; b < 10; b++) {
|
||||
/* send preamble */
|
||||
int n_preamble = freedv_rawdatapreambletx(freedv, mod_out_short);
|
||||
fwrite(mod_out_short, sizeof(short), n_preamble, stdout);
|
||||
|
||||
/* read our input data frame from stdin */
|
||||
size_t nread =
|
||||
fread(bytes_in, sizeof(uint8_t), payload_bytes_per_modem_frame, stdin);
|
||||
if (nread != payload_bytes_per_modem_frame) break;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
freedv_close(freedv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user