From 735d7882764134f6982586683a42ed79f5e95951 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Wed, 3 Apr 2024 17:16:58 +1030 Subject: WIP freedv API support for custom raw data modes --- src/freedv_api.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src/freedv_api.c') diff --git a/src/freedv_api.c b/src/freedv_api.c index 3ccf63d..a158d2a 100644 --- a/src/freedv_api.c +++ b/src/freedv_api.c @@ -60,7 +60,7 @@ /* The API version number. The first version is 10. Increment if the API changes in a way that would require changes by the API user. */ -#define VERSION 15 +#define VERSION 16 /* Version 10 Initial version August 2, 2015. @@ -79,6 +79,9 @@ Version 15 December 2022 Removing rarely used DPSK support which is not needed given fast fading modes + + Version 16 April 2024, added field to struct freedv_advanced to support + FREEDV_MODE_DATA_CUSTOM */ char *ofdm_statemode[] = {"search", "trial", "synced"}; @@ -101,7 +104,8 @@ char *rx_sync_flags_to_text[] = {"----", "---T", "--S-", "--ST", "-B--", "-B-T", struct freedv *freedv_open(int mode) { // defaults for those modes that support the use of adv - struct freedv_advanced adv = {0, 2, 100, 8000, 1000, 200, "H_256_512_4"}; + struct freedv_advanced adv = {0, 2, 100, 8000, + 1000, 200, "H_256_512_4", NULL}; return freedv_open_advanced(mode, &adv); } @@ -126,7 +130,8 @@ struct freedv *freedv_open_advanced(int mode, struct freedv_advanced *adv) { FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, mode) || - FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, mode)) == false) + FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, mode) || + FDV_MODE_ACTIVE(FREEDV_MODE_DATA_CUSTOM, mode)) == false) return NULL; /* set everything to zero just in case */ @@ -150,12 +155,16 @@ struct freedv *freedv_open_advanced(int mode, struct freedv_advanced *adv) { if (FDV_MODE_ACTIVE(FREEDV_MODE_2400B, mode)) freedv_2400b_open(f); if (FDV_MODE_ACTIVE(FREEDV_MODE_800XA, mode)) freedv_800xa_open(f); if (FDV_MODE_ACTIVE(FREEDV_MODE_FSK_LDPC, mode)) freedv_fsk_ldpc_open(f, adv); - if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC0, mode)) freedv_ofdm_data_open(f); - if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC1, mode)) freedv_ofdm_data_open(f); - if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, mode)) freedv_ofdm_data_open(f); - if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, mode)) freedv_ofdm_data_open(f); - if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, mode)) freedv_ofdm_data_open(f); - if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, mode)) freedv_ofdm_data_open(f); + if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC0, mode)) freedv_ofdm_data_open(f, NULL); + if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC1, mode)) freedv_ofdm_data_open(f, NULL); + if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, mode)) freedv_ofdm_data_open(f, NULL); + if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, mode)) freedv_ofdm_data_open(f, NULL); + if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, mode)) + freedv_ofdm_data_open(f, NULL); + if (FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, mode)) + freedv_ofdm_data_open(f, NULL); + if (FDV_MODE_ACTIVE(FREEDV_MODE_DATA_CUSTOM, mode)) + freedv_ofdm_data_open(f, adv); varicode_decode_init(&f->varicode_dec_states, 1); -- cgit v1.2.3 From cf069d2e62bd1e69efaddcfa60ca37374ed025b5 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Wed, 3 Apr 2024 18:00:35 +1030 Subject: demo custom mode --- src/freedv_api.c | 15 ++++++++++----- src/freedv_data_raw_rx.c | 24 ++++++++++++++++++++++-- src/freedv_data_raw_tx.c | 26 +++++++++++++++++++++++--- 3 files changed, 55 insertions(+), 10 deletions(-) (limited to 'src/freedv_api.c') diff --git a/src/freedv_api.c b/src/freedv_api.c index a158d2a..d04dd7c 100644 --- a/src/freedv_api.c +++ b/src/freedv_api.c @@ -247,7 +247,8 @@ void freedv_close(struct freedv *freedv) { FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, freedv->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, freedv->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, freedv->mode) || - FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, freedv->mode)) { + FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, freedv->mode) || + FDV_MODE_ACTIVE(FREEDV_MODE_DATA_CUSTOM, freedv->mode)) { FREE(freedv->rx_syms); FREE(freedv->rx_amps); FREE(freedv->ldpc); @@ -279,7 +280,8 @@ static int is_ofdm_mode(struct freedv *f) { FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, f->mode) || - FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode); + FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode) || + FDV_MODE_ACTIVE(FREEDV_MODE_DATA_CUSTOM, f->mode); } static int is_ofdm_data_mode(struct freedv *f) { @@ -288,7 +290,8 @@ static int is_ofdm_data_mode(struct freedv *f) { FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, f->mode) || - FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode); + FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode) || + FDV_MODE_ACTIVE(FREEDV_MODE_DATA_CUSTOM, f->mode); } /*---------------------------------------------------------------------------*\ @@ -479,7 +482,8 @@ void freedv_rawdatacomptx(struct freedv *f, COMP mod_out[], FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, f->mode) || - FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode)) + FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode) || + FDV_MODE_ACTIVE(FREEDV_MODE_DATA_CUSTOM, f->mode)) freedv_comptx_ofdm(f, mod_out); if (FDV_MODE_ACTIVE(FREEDV_MODE_FSK_LDPC, f->mode)) { @@ -1079,7 +1083,8 @@ int freedv_rawdatacomprx(struct freedv *f, unsigned char *packed_payload_bits, FDV_MODE_ACTIVE(FREEDV_MODE_DATAC3, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC4, f->mode) || FDV_MODE_ACTIVE(FREEDV_MODE_DATAC13, f->mode) || - FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode)) + FDV_MODE_ACTIVE(FREEDV_MODE_DATAC14, f->mode) || + FDV_MODE_ACTIVE(FREEDV_MODE_DATA_CUSTOM, f->mode)) rx_status = freedv_comp_short_rx_ofdm(f, (void *)demod_in, 0, 1.0f); if (FDV_MODE_ACTIVE(FREEDV_MODE_FSK_LDPC, f->mode)) { rx_status = freedv_rx_fsk_ldpc_data(f, demod_in); diff --git a/src/freedv_data_raw_rx.c b/src/freedv_data_raw_rx.c index 0353ae5..435648d 100644 --- a/src/freedv_data_raw_rx.c +++ b/src/freedv_data_raw_rx.c @@ -39,6 +39,7 @@ #include "ldpc_codes.h" #include "modem_stats.h" #include "octave.h" +#include "ofdm_internal.h" /* other processes can end this program using signals */ @@ -216,6 +217,8 @@ int main(int argc, char *argv[]) { mode = FREEDV_MODE_DATAC13; if (!strcmp(argv[dx], "DATAC14") || !strcmp(argv[dx], "datac14")) mode = FREEDV_MODE_DATAC14; + if (!strcmp(argv[dx], "CUSTOM") || !strcmp(argv[dx], "custom")) + mode = FREEDV_MODE_DATA_CUSTOM; if (mode == -1) { fprintf(stderr, "Error in mode: %s\n", argv[dx]); exit(1); @@ -248,6 +251,23 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Setting estimator limits to %d to %d Hz.\n", fsk_lower, fsk_upper); fsk_set_freq_est_limits(fsk, fsk_lower, fsk_upper); + } else if (mode == FREEDV_MODE_DATA_CUSTOM) { + // demonstrate custom OFDM raw data modes + struct OFDM_CONFIG ofdm_config; + ofdm_init_mode("datac14", &ofdm_config); + // modify datac14 to have 3 carriers instead of 4, which means + // we have to tweak Np, and the number of unique word bits + ofdm_config.nc = 3; + ofdm_config.np = 6; + ofdm_config.nuwbits = 48; + ofdm_config.bad_uw_errors = 18; + uint8_t uw[] = {1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}; + memcpy(ofdm_config.tx_uw, uw, sizeof(uw)); + memcpy(&ofdm_config.tx_uw[ofdm_config.nuwbits - sizeof(uw)], uw, + sizeof(uw)); + adv.config = (void *)&ofdm_config; + freedv = freedv_open_advanced(mode, &adv); } else { freedv = freedv_open(mode); } @@ -264,8 +284,8 @@ int main(int argc, char *argv[]) { fsk->Ndft); } - /* for streaming bytes it's much easier use the modes that have a multiple of - * 8 payload bits/frame */ + /* for streaming bytes it's much easier use the modes that have a multiple + * of 8 payload bits/frame */ assert((freedv_get_bits_per_modem_frame(freedv) % 8) == 0); int bytes_per_modem_frame = freedv_get_bits_per_modem_frame(freedv) / 8; // last two bytes used for CRC diff --git a/src/freedv_data_raw_tx.c b/src/freedv_data_raw_tx.c index cb74107..ce5da56 100644 --- a/src/freedv_data_raw_tx.c +++ b/src/freedv_data_raw_tx.c @@ -238,6 +238,8 @@ int main(int argc, char *argv[]) { mode = FREEDV_MODE_DATAC13; if (!strcmp(argv[dx], "DATAC14") || !strcmp(argv[dx], "datac14")) mode = FREEDV_MODE_DATAC14; + if (!strcmp(argv[dx], "CUSTOM") || !strcmp(argv[dx], "custom")) + mode = FREEDV_MODE_DATA_CUSTOM; if (mode == -1) { fprintf(stderr, "Error: in mode: %s", argv[dx]); exit(1); @@ -259,10 +261,28 @@ int main(int argc, char *argv[]) { exit(1); } - if (mode != FREEDV_MODE_FSK_LDPC) - freedv = freedv_open(mode); - else + if (mode == FREEDV_MODE_FSK_LDPC) + freedv = freedv_open_advanced(mode, &adv); + else if (mode == FREEDV_MODE_DATA_CUSTOM) { + // demonstrate custom OFDM raw data modes + struct OFDM_CONFIG ofdm_config; + ofdm_init_mode("datac14", &ofdm_config); + // modify datac14 to have 3 carriers instead of 4, which means + // we have to tweak Np, and the number of unique word bits + ofdm_config.nc = 3; + ofdm_config.np = 6; + ofdm_config.nuwbits = 48; + ofdm_config.bad_uw_errors = 18; + uint8_t uw[] = {1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}; + memcpy(ofdm_config.tx_uw, uw, sizeof(uw)); + memcpy(&ofdm_config.tx_uw[ofdm_config.nuwbits - sizeof(uw)], uw, + sizeof(uw)); + adv.config = (void *)&ofdm_config; freedv = freedv_open_advanced(mode, &adv); + } else { + freedv = freedv_open(mode); + } assert(freedv != NULL); -- cgit v1.2.3 From b2311e5a967e09e5b293578bb596c83c50af536d Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sat, 4 May 2024 07:16:26 +0930 Subject: custom config debugging: dump ofdm config from a FreeDV API function --- src/freedv_api.c | 4 ++++ src/freedv_api.h | 3 +++ src/freedv_data_raw_tx.c | 5 +++++ src/ofdm.c | 5 +++++ 4 files changed, 17 insertions(+) (limited to 'src/freedv_api.c') diff --git a/src/freedv_api.c b/src/freedv_api.c index d04dd7c..3c812ca 100644 --- a/src/freedv_api.c +++ b/src/freedv_api.c @@ -1626,3 +1626,7 @@ unsigned short freedv_gen_crc16(unsigned char *data_p, int length) { return crc; } + +void freedv_ofdm_print_info(struct freedv *freedv) { + ofdm_print_info(freedv->ofdm); +} diff --git a/src/freedv_api.h b/src/freedv_api.h index 9f72c8f..0ca80ce 100644 --- a/src/freedv_api.h +++ b/src/freedv_api.h @@ -341,6 +341,9 @@ int freedv_get_bits_per_modem_frame(struct freedv *freedv); int freedv_get_sz_error_pattern(struct freedv *freedv); int freedv_get_protocol_bits(struct freedv *freedv); +// dump OFDM modem config +void freedv_ofdm_print_info(struct freedv *freedv); + #ifdef __cplusplus } #endif diff --git a/src/freedv_data_raw_tx.c b/src/freedv_data_raw_tx.c index ce5da56..7fa1e84 100644 --- a/src/freedv_data_raw_tx.c +++ b/src/freedv_data_raw_tx.c @@ -278,8 +278,13 @@ int main(int argc, char *argv[]) { memcpy(ofdm_config.tx_uw, uw, sizeof(uw)); memcpy(&ofdm_config.tx_uw[ofdm_config.nuwbits - sizeof(uw)], uw, sizeof(uw)); + /* set up a trivial Tx band pass filter as a demo */ + static float tx_bpf[] = {1.0, 1.0, 1.0}; + ofdm_config.tx_bpf_proto = tx_bpf; + ofdm_config.tx_bpf_proto_n = 3; adv.config = (void *)&ofdm_config; freedv = freedv_open_advanced(mode, &adv); + freedv_ofdm_print_info(freedv); } else { freedv = freedv_open(mode); } diff --git a/src/ofdm.c b/src/ofdm.c index 8d7a6df..953179f 100644 --- a/src/ofdm.c +++ b/src/ofdm.c @@ -2669,6 +2669,11 @@ void ofdm_print_info(struct OFDM *ofdm) { ofdm->phase_est_en ? "true" : "false"); fprintf(stderr, "ofdm->tx_bpf_en = %s\n", ofdm->tx_bpf_en ? "true" : "false"); fprintf(stderr, "ofdm->rx_bpf_en = %s\n", ofdm->rx_bpf_en ? "true" : "false"); + fprintf(stderr, "ofdm->tx_bpf_proto_n = %d\n", ofdm->tx_bpf_proto_n); + fprintf(stderr, "ofdm->tx_bpf_proto:\n"); + for (int i = 0; i < ofdm->tx_bpf_proto_n; i++) + fprintf(stderr, "%f\t", ofdm->tx_bpf_proto[i]); + fprintf(stderr, "\n"); fprintf(stderr, "ofdm->dpsk_en = %s\n", ofdm->dpsk_en ? "true" : "false"); fprintf(stderr, "ofdm->phase_est_bandwidth_mode = %s\n", phase_est_bandwidth_mode[ofdm->phase_est_bandwidth_mode]); -- cgit v1.2.3