updated ui added new features

This commit is contained in:
zach
2025-12-27 15:32:32 -07:00
parent 02ca7801ea
commit a2cfae3a22
589 changed files with 181780 additions and 569 deletions
+17
View File
@@ -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)
+77
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}