aboutsummaryrefslogtreecommitdiff
path: root/src/freedv_2020.c
diff options
context:
space:
mode:
authordrowe67 <[email protected]>2023-07-20 08:59:48 +0930
committerGitHub <[email protected]>2023-07-20 08:59:48 +0930
commit06d4c11e699b0351765f10398abb4f663a984f36 (patch)
tree33e22af0814c5b6c3d676f096ae8c2ac8a3ed9f0 /src/freedv_2020.c
parent6588e77f38bdebd7adffe091b22e7760d95d0ccb (diff)
parent4d6c143c0abec15e1d6ed1fd95d36f80e6cb7df8 (diff)
Merge pull request #3 from drowe67/dr-cleanup21.2.0
Cleanup Part 2
Diffstat (limited to 'src/freedv_2020.c')
-rw-r--r--src/freedv_2020.c583
1 files changed, 302 insertions, 281 deletions
diff --git a/src/freedv_2020.c b/src/freedv_2020.c
index 135bcd2..f1dee28 100644
--- a/src/freedv_2020.c
+++ b/src/freedv_2020.c
@@ -9,334 +9,355 @@
\*---------------------------------------------------------------------------*/
#include <assert.h>
-#include <stdlib.h>
+#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <math.h>
-#include "fsk.h"
-#include "fmfsk.h"
#include "codec2.h"
#include "codec2_fdmdv.h"
-#include "varicode.h"
+#include "codec2_ofdm.h"
+#include "comp_prim.h"
+#include "debug_alloc.h"
+#include "fmfsk.h"
#include "freedv_api.h"
#include "freedv_api_internal.h"
-#include "comp_prim.h"
-
-#include "codec2_ofdm.h"
-#include "ofdm_internal.h"
-#include "mpdecode_core.h"
+#include "fsk.h"
#include "gp_interleaver.h"
-#include "ldpc_codes.h"
#include "interldpc.h"
-#include "debug_alloc.h"
+#include "ldpc_codes.h"
+#include "mpdecode_core.h"
+#include "ofdm_internal.h"
+#include "varicode.h"
extern char *ofdm_statemode[];
#ifdef __LPCNET__
void freedv_2020x_open(struct freedv *f) {
- f->speech_sample_rate = FREEDV_FS_16000;
- f->snr_squelch_thresh = 4.0;
- f->squelch_en = 0;
+ f->speech_sample_rate = FREEDV_FS_16000;
+ f->snr_squelch_thresh = 4.0;
+ f->squelch_en = 0;
- struct OFDM_CONFIG ofdm_config;
- switch (f->mode) {
+ struct OFDM_CONFIG ofdm_config;
+ switch (f->mode) {
case FREEDV_MODE_2020:
- ofdm_init_mode("2020", &ofdm_config);
- break;
+ ofdm_init_mode("2020", &ofdm_config);
+ break;
case FREEDV_MODE_2020B:
- ofdm_init_mode("2020B", &ofdm_config);
- break;
- case FREEDV_MODE_2020C:
- ofdm_init_mode("2020C", &ofdm_config);
- break;
+ ofdm_init_mode("2020B", &ofdm_config);
+ break;
default:
- assert(0);
- }
-
- f->ofdm = ofdm_create(&ofdm_config);
+ assert(0);
+ }
+
+ f->ofdm = ofdm_create(&ofdm_config);
- f->ldpc = (struct LDPC*)MALLOC(sizeof(struct LDPC));
- assert(f->ldpc != NULL);
+ f->ldpc = (struct LDPC *)MALLOC(sizeof(struct LDPC));
+ assert(f->ldpc != NULL);
- ldpc_codes_setup(f->ldpc, f->ofdm->codename);
- ldpc_mode_specific_setup(f->ofdm, f->ldpc);
- int vq_type;
- switch (f->mode) {
+ ldpc_codes_setup(f->ldpc, f->ofdm->codename);
+ ldpc_mode_specific_setup(f->ofdm, f->ldpc);
+ int vq_type;
+ switch (f->mode) {
case FREEDV_MODE_2020:
- vq_type = 1; /* vanilla VQ */
- break;
+ vq_type = 1; /* vanilla VQ */
+ break;
case FREEDV_MODE_2020B:
- vq_type = 2; /* index optimised VQ for increased robustness to single bit errors */
- break;
- case FREEDV_MODE_2020C:
- vq_type = 2; /* index optimised VQ for increased robustness to single bit errors */
- break;
+ vq_type = 2; /* index optimised VQ for increased robustness to single bit
+ errors */
+ break;
default:
- assert(0);
- }
+ assert(0);
+ }
+
+ int coded_syms_per_frame = f->ldpc->coded_bits_per_frame / f->ofdm->bps;
+ f->ofdm_bitsperframe = ofdm_get_bits_per_frame(f->ofdm);
+ f->ofdm_nuwbits = f->ofdm->config.nuwbits;
+ f->ofdm_ntxtbits = f->ofdm->config.txtbits;
+ assert(f->ofdm_ntxtbits == 4);
+
+ if (f->verbose) {
+ fprintf(stderr, "f->mode = %d\n", f->mode);
+ fprintf(stderr, "vq_type = %d\n", vq_type);
+ fprintf(stderr, "ldpc_data_bits_per_frame = %d\n",
+ f->ldpc->ldpc_data_bits_per_frame);
+ fprintf(stderr, "ldpc_coded_bits_per_frame = %d\n",
+ f->ldpc->ldpc_coded_bits_per_frame);
+ fprintf(stderr, "data_bits_per_frame = %d\n", f->ldpc->data_bits_per_frame);
+ fprintf(stderr, "coded_bits_per_frame = %d\n",
+ f->ldpc->coded_bits_per_frame);
+ fprintf(stderr, "coded_syms_per_frame = %d\n",
+ f->ldpc->coded_bits_per_frame / f->ofdm->bps);
+ fprintf(stderr, "ofdm_bits_per_frame = %d\n", f->ofdm_bitsperframe);
+ fprintf(stderr, "ofdm_nuwbits = %d\n", f->ofdm_nuwbits);
+ fprintf(stderr, "ofdm_ntxtbits = %d\n", f->ofdm_ntxtbits);
+ }
+
+ f->codeword_symbols = (COMP *)MALLOC(sizeof(COMP) * coded_syms_per_frame);
+ assert(f->codeword_symbols != NULL);
+
+ f->codeword_amps = (float *)MALLOC(sizeof(float) * coded_syms_per_frame);
+ assert(f->codeword_amps != NULL);
+
+ for (int i = 0; i < coded_syms_per_frame; i++) {
+ f->codeword_symbols[i].real = 0.0f;
+ f->codeword_symbols[i].imag = 0.0f;
+ f->codeword_amps[i] = 0.0f;
+ }
+
+ f->nin = f->nin_prev = ofdm_get_samples_per_frame(f->ofdm);
+ f->n_nat_modem_samples = ofdm_get_samples_per_frame(f->ofdm);
+ f->n_nom_modem_samples = ofdm_get_samples_per_frame(f->ofdm);
+ f->n_max_modem_samples = ofdm_get_max_samples_per_frame(f->ofdm);
+ f->modem_sample_rate = f->ofdm->config.fs;
+ f->clip_en = false;
+ f->sz_error_pattern = f->ofdm_bitsperframe;
+
+ /* storage for pass through audio interpolating filter. These are
+ the rate FREEDV_FS_8000 modem input samples before interpolation */
+ f->passthrough_2020 =
+ CALLOC(1, sizeof(float) *
+ (FDMDV_OS_TAPS_16K + freedv_get_n_max_modem_samples(f)));
+ assert(f->passthrough_2020 != NULL);
+
+ // make sure we have enough storage for worst case nin with passthrough, in
+ // 2020 we oversample the 8 kHz input Rx audio to 16 kHz
+ int nout_max = 2 * freedv_get_n_max_modem_samples(f);
+ assert(nout_max <= freedv_get_n_max_speech_samples(f));
+
+ f->lpcnet = lpcnet_freedv_create(vq_type);
+ assert(f->lpcnet != NULL);
+ f->codec2 = NULL;
+
+ /* should be exactly an integer number of Codec frames in a OFDM modem frame
+ */
+ assert((f->ldpc->data_bits_per_frame % lpcnet_bits_per_frame(f->lpcnet)) ==
+ 0);
+
+ f->n_codec_frames =
+ f->ldpc->data_bits_per_frame / lpcnet_bits_per_frame(f->lpcnet);
+ f->n_speech_samples = f->n_codec_frames * lpcnet_samples_per_frame(f->lpcnet);
+ f->bits_per_codec_frame = lpcnet_bits_per_frame(f->lpcnet);
+ f->bits_per_modem_frame = f->n_codec_frames * f->bits_per_codec_frame;
+
+ f->tx_payload_bits = (unsigned char *)MALLOC(f->bits_per_modem_frame);
+ assert(f->tx_payload_bits != NULL);
+ f->rx_payload_bits = (unsigned char *)MALLOC(f->bits_per_modem_frame);
+ assert(f->rx_payload_bits != NULL);
+
+ /* attenuate audio 12dB as channel noise isn't that pleasant */
+ f->passthrough_gain = 0.25;
+}
- int coded_syms_per_frame = f->ldpc->coded_bits_per_frame/f->ofdm->bps;
- f->ofdm_bitsperframe = ofdm_get_bits_per_frame(f->ofdm);
- f->ofdm_nuwbits = f->ofdm->config.nuwbits;
- f->ofdm_ntxtbits = f->ofdm->config.txtbits;
- assert(f->ofdm_ntxtbits == 4);
-
- if (f->verbose) {
- fprintf(stderr, "f->mode = %d\n", f->mode);
- fprintf(stderr, "vq_type = %d\n", vq_type);
- fprintf(stderr, "ldpc_data_bits_per_frame = %d\n", f->ldpc->ldpc_data_bits_per_frame);
- fprintf(stderr, "ldpc_coded_bits_per_frame = %d\n", f->ldpc->ldpc_coded_bits_per_frame);
- fprintf(stderr, "data_bits_per_frame = %d\n", f->ldpc->data_bits_per_frame);
- fprintf(stderr, "coded_bits_per_frame = %d\n", f->ldpc->coded_bits_per_frame);
- fprintf(stderr, "coded_syms_per_frame = %d\n", f->ldpc->coded_bits_per_frame/f->ofdm->bps);
- fprintf(stderr, "ofdm_bits_per_frame = %d\n", f->ofdm_bitsperframe);
- fprintf(stderr, "ofdm_nuwbits = %d\n", f->ofdm_nuwbits);
- fprintf(stderr, "ofdm_ntxtbits = %d\n", f->ofdm_ntxtbits);
+void freedv_comptx_2020(struct freedv *f, COMP mod_out[]) {
+ int i, k;
+
+ int data_bits_per_frame = f->ldpc->data_bits_per_frame;
+ uint8_t tx_bits[data_bits_per_frame];
+
+ memcpy(tx_bits, f->tx_payload_bits, data_bits_per_frame);
+
+ // Generate Varicode txt bits. Txt bits in OFDM frame come just
+ // after Unique Word (UW). Txt bits aren't protected by FEC, and need to be
+ // added to each frame after interleaver as done it's thing
+
+ int nspare = f->ofdm_ntxtbits;
+ uint8_t txt_bits[nspare];
+
+ for (k = 0; k < nspare; k++) {
+ if (f->nvaricode_bits == 0) {
+ /* get new char and encode */
+ char s[2];
+ if (f->freedv_get_next_tx_char != NULL) {
+ s[0] = (*f->freedv_get_next_tx_char)(f->callback_state);
+ f->nvaricode_bits =
+ varicode_encode(f->tx_varicode_bits, s, VARICODE_MAX_BITS, 1,
+ f->varicode_dec_states.code_num);
+ f->varicode_bit_index = 0;
+ }
}
+ if (f->nvaricode_bits) {
+ txt_bits[k] = f->tx_varicode_bits[f->varicode_bit_index++];
+ f->nvaricode_bits--;
+ } else
+ txt_bits[k] = 0;
+ }
- f->codeword_symbols = (COMP*)MALLOC(sizeof(COMP) * coded_syms_per_frame);
- assert(f->codeword_symbols != NULL);
+ /* optionally replace codec payload bits with test frames known to rx */
- f->codeword_amps = (float*)MALLOC(sizeof(float) * coded_syms_per_frame);
- assert(f->codeword_amps != NULL);
+ if (f->test_frames) {
+ uint8_t payload_data_bits[data_bits_per_frame];
+ ofdm_generate_payload_data_bits(payload_data_bits, data_bits_per_frame);
- for (int i=0; i< coded_syms_per_frame; i++) {
- f->codeword_symbols[i].real = 0.0f;
- f->codeword_symbols[i].imag = 0.0f;
- f->codeword_amps[i] = 0.0f;
+ for (i = 0; i < data_bits_per_frame; i++) {
+ tx_bits[i] = payload_data_bits[i];
}
+ }
- f->nin = f->nin_prev = ofdm_get_samples_per_frame(f->ofdm);
- f->n_nat_modem_samples = ofdm_get_samples_per_frame(f->ofdm);
- f->n_nom_modem_samples = ofdm_get_samples_per_frame(f->ofdm);
- f->n_max_modem_samples = ofdm_get_max_samples_per_frame(f->ofdm);
- f->modem_sample_rate = f->ofdm->config.fs;
- f->clip_en = false;
- f->sz_error_pattern = f->ofdm_bitsperframe;
-
- /* storage for pass through audio interpolating filter. These are
- the rate FREEDV_FS_8000 modem input samples before interpolation */
- f->passthrough_2020 = CALLOC(1, sizeof(float)*(FDMDV_OS_TAPS_16K + freedv_get_n_max_modem_samples(f)));
- assert(f->passthrough_2020 != NULL);
-
- // make sure we have enough storage for worst case nin with passthrough, in 2020
- // we oversample the 8 kHz input Rx audio to 16 kHz
- int nout_max = 2*freedv_get_n_max_modem_samples(f);
- assert(nout_max <= freedv_get_n_max_speech_samples(f));
-
- f->lpcnet = lpcnet_freedv_create(vq_type); assert(f->lpcnet != NULL);
- f->codec2 = NULL;
-
- /* should be exactly an integer number of Codec frames in a OFDM modem frame */
- assert((f->ldpc->data_bits_per_frame % lpcnet_bits_per_frame(f->lpcnet)) == 0);
-
- f->n_codec_frames = f->ldpc->data_bits_per_frame/lpcnet_bits_per_frame(f->lpcnet);
- f->n_speech_samples = f->n_codec_frames*lpcnet_samples_per_frame(f->lpcnet);
- f->bits_per_codec_frame = lpcnet_bits_per_frame(f->lpcnet);
- f->bits_per_modem_frame = f->n_codec_frames*f->bits_per_codec_frame;
-
- f->tx_payload_bits = (unsigned char*)MALLOC(f->bits_per_modem_frame);
- assert(f->tx_payload_bits != NULL);
- f->rx_payload_bits = (unsigned char*)MALLOC(f->bits_per_modem_frame);
- assert(f->rx_payload_bits != NULL);
-
- /* attenuate audio 12dB as channel noise isn't that pleasant */
- f->passthrough_gain = 0.25;
+ /* OK now ready to LDPC encode, interleave, and OFDM modulate */
+ ofdm_ldpc_interleave_tx(f->ofdm, f->ldpc, (complex float *)mod_out, tx_bits,
+ txt_bits);
}
-void freedv_comptx_2020(struct freedv *f, COMP mod_out[]) {
- int i, k;
-
- int data_bits_per_frame = f->ldpc->data_bits_per_frame;
- uint8_t tx_bits[data_bits_per_frame];
-
- memcpy(tx_bits, f->tx_payload_bits, data_bits_per_frame);
-
- // Generate Varicode txt bits. Txt bits in OFDM frame come just
- // after Unique Word (UW). Txt bits aren't protected by FEC, and need to be
- // added to each frame after interleaver as done it's thing
-
- int nspare = f->ofdm_ntxtbits;
- uint8_t txt_bits[nspare];
-
- for(k=0; k<nspare; k++) {
- if (f->nvaricode_bits == 0) {
- /* get new char and encode */
- char s[2];
- if (f->freedv_get_next_tx_char != NULL) {
- s[0] = (*f->freedv_get_next_tx_char)(f->callback_state);
- f->nvaricode_bits = varicode_encode(f->tx_varicode_bits, s, VARICODE_MAX_BITS, 1, f->varicode_dec_states.code_num);
- f->varicode_bit_index = 0;
- }
- }
- if (f->nvaricode_bits) {
- txt_bits[k] = f->tx_varicode_bits[f->varicode_bit_index++];
- f->nvaricode_bits--;
- } else txt_bits[k] = 0;
- }
+int freedv_comprx_2020(struct freedv *f, COMP demod_in[]) {
+ int i, k;
+ int n_ascii;
+ char ascii_out;
+ struct OFDM *ofdm = f->ofdm;
+ struct LDPC *ldpc = f->ldpc;
- /* optionally replace codec payload bits with test frames known to rx */
+ int data_bits_per_frame = ldpc->data_bits_per_frame;
+ int coded_bits_per_frame = ldpc->coded_bits_per_frame;
+ int coded_syms_per_frame = ldpc->coded_bits_per_frame / ofdm->bps;
+ COMP *codeword_symbols = f->codeword_symbols;
+ float *codeword_amps = f->codeword_amps;
+ int rx_bits[f->ofdm_bitsperframe];
+ short txt_bits[f->ofdm_ntxtbits];
+ COMP payload_syms[coded_syms_per_frame];
+ float payload_amps[coded_syms_per_frame];
- if (f->test_frames) {
- uint8_t payload_data_bits[data_bits_per_frame];
- ofdm_generate_payload_data_bits(payload_data_bits, data_bits_per_frame);
+ int rx_status = 0;
+
+ int Nerrs_raw = 0;
+ int Nerrs_coded = 0;
+ int Ncoded;
+ int iter = 0;
+ int parityCheckCount = 0;
+ uint8_t rx_uw[f->ofdm_nuwbits];
+
+ f->sync = 0;
+
+ // TODO: should be higher for 2020?
+ float EsNo = 3.0;
+
+ /* looking for modem sync */
+
+ if (ofdm->sync_state == search) {
+ ofdm_sync_search(f->ofdm, demod_in);
+ f->snr_est = -5.0;
+ }
+
+ /* OK modem is in sync */
+
+ if ((ofdm->sync_state == synced) || (ofdm->sync_state == trial)) {
+ rx_status |= FREEDV_RX_SYNC;
+ if (ofdm->sync_state == trial) rx_status |= FREEDV_RX_TRIAL_SYNC;
+
+ int txt_sym_index = 0;
+
+ ofdm_demod(ofdm, rx_bits, demod_in);
+ ofdm_extract_uw(ofdm, ofdm->rx_np, ofdm->rx_amp, rx_uw);
+ ofdm_disassemble_qpsk_modem_packet_with_text_amps(
+ ofdm, ofdm->rx_np, ofdm->rx_amp, payload_syms, payload_amps, txt_bits,
+ &txt_sym_index);
+
+ f->sync = 1;
- for (i = 0; i < data_bits_per_frame; i++) {
- tx_bits[i] = payload_data_bits[i];
- }
+ assert((f->ofdm_nuwbits + f->ofdm_ntxtbits + coded_bits_per_frame) ==
+ f->ofdm_bitsperframe);
+
+ /* newest symbols at end of buffer (uses final i from last loop), note we
+ change COMP formats from what modem uses internally */
+
+ for (i = 0; i < coded_syms_per_frame; i++) {
+ codeword_symbols[i] = payload_syms[i];
+ codeword_amps[i] = payload_amps[i];
}
- /* OK now ready to LDPC encode, interleave, and OFDM modulate */
- ofdm_ldpc_interleave_tx(f->ofdm, f->ldpc, (complex float*)mod_out, tx_bits, txt_bits);
-}
+ /* run de-interleaver */
-int freedv_comprx_2020(struct freedv *f, COMP demod_in[]) {
- int i, k;
- int n_ascii;
- char ascii_out;
- struct OFDM *ofdm = f->ofdm;
- struct LDPC *ldpc = f->ldpc;
-
- int data_bits_per_frame = ldpc->data_bits_per_frame;
- int coded_bits_per_frame = ldpc->coded_bits_per_frame;
- int coded_syms_per_frame = ldpc->coded_bits_per_frame/ofdm->bps;
- COMP *codeword_symbols = f->codeword_symbols;
- float *codeword_amps = f->codeword_amps;
- int rx_bits[f->ofdm_bitsperframe];
- short txt_bits[f->ofdm_ntxtbits];
- COMP payload_syms[coded_syms_per_frame];
- float payload_amps[coded_syms_per_frame];
-
- int rx_status = 0;
-
- int Nerrs_raw = 0;
- int Nerrs_coded = 0;
- int Ncoded;
- int iter = 0;
- int parityCheckCount = 0;
- uint8_t rx_uw[f->ofdm_nuwbits];
-
- f->sync = 0;
-
- // TODO: should be higher for 2020?
- float EsNo = 3.0;
-
- /* looking for modem sync */
-
- if (ofdm->sync_state == search) {
- ofdm_sync_search(f->ofdm, demod_in);
- f->snr_est = -5.0;
+ COMP codeword_symbols_de[coded_syms_per_frame];
+ float codeword_amps_de[coded_syms_per_frame];
+
+ gp_deinterleave_comp(codeword_symbols_de, codeword_symbols,
+ coded_syms_per_frame);
+ gp_deinterleave_float(codeword_amps_de, codeword_amps,
+ coded_syms_per_frame);
+
+ float llr[coded_bits_per_frame];
+ uint8_t out_char[coded_bits_per_frame];
+
+ if (f->test_frames) {
+ Nerrs_raw =
+ count_uncoded_errors(ldpc, &f->ofdm->config, codeword_symbols_de, 0);
+ f->total_bit_errors += Nerrs_raw;
+ f->total_bits += f->ofdm_bitsperframe;
}
- /* OK modem is in sync */
-
- if ((ofdm->sync_state == synced) || (ofdm->sync_state == trial)) {
- rx_status |= FREEDV_RX_SYNC;
- if (ofdm->sync_state == trial) rx_status |= FREEDV_RX_TRIAL_SYNC;
-
- int txt_sym_index = 0;
-
- ofdm_demod(ofdm, rx_bits, demod_in);
- ofdm_extract_uw(ofdm, ofdm->rx_np, ofdm->rx_amp, rx_uw);
- ofdm_disassemble_qpsk_modem_packet_with_text_amps(ofdm, ofdm->rx_np, ofdm->rx_amp, payload_syms, payload_amps, txt_bits, &txt_sym_index);
-
- f->sync = 1;
-
- assert((f->ofdm_nuwbits+f->ofdm_ntxtbits+coded_bits_per_frame) == f->ofdm_bitsperframe);
-
- /* newest symbols at end of buffer (uses final i from last loop), note we
- change COMP formats from what modem uses internally */
-
- for(i=0; i< coded_syms_per_frame; i++) {
- codeword_symbols[i] = payload_syms[i];
- codeword_amps[i] = payload_amps[i];
- }
-
- /* run de-interleaver */
-
- COMP codeword_symbols_de[coded_syms_per_frame];
- float codeword_amps_de[coded_syms_per_frame];
-
- gp_deinterleave_comp (codeword_symbols_de, codeword_symbols, coded_syms_per_frame);
- gp_deinterleave_float(codeword_amps_de , codeword_amps , coded_syms_per_frame);
-
- float llr[coded_bits_per_frame];
- uint8_t out_char[coded_bits_per_frame];
-
- if (f->test_frames) {
- Nerrs_raw = count_uncoded_errors(ldpc, &f->ofdm->config, codeword_symbols_de, 0);
- f->total_bit_errors += Nerrs_raw;
- f->total_bits += f->ofdm_bitsperframe;
- }
-
- symbols_to_llrs(llr, codeword_symbols_de, codeword_amps_de,
- EsNo, ofdm->mean_amp, coded_syms_per_frame);
- ldpc_decode_frame(ldpc, &parityCheckCount, &iter, out_char, llr);
- if (parityCheckCount != ldpc->NumberParityBits) rx_status |= FREEDV_RX_BIT_ERRORS;
-
- if (f->test_frames) {
- uint8_t payload_data_bits[data_bits_per_frame];
- ofdm_generate_payload_data_bits(payload_data_bits, data_bits_per_frame);
- count_errors_protection_mode(ldpc->protection_mode, &Nerrs_coded, &Ncoded, payload_data_bits, out_char, data_bits_per_frame);
- f->total_bit_errors_coded += Nerrs_coded;
- f->total_bits_coded += Ncoded;
- if (Nerrs_coded) f->total_packet_errors++;
- f->total_packets++;
- } else {
- memcpy(f->rx_payload_bits, out_char, data_bits_per_frame);
- }
-
- rx_status |= FREEDV_RX_BITS;
-
- /* If modem is synced we can decode txt bits */
-
- for(k=0; k<f->ofdm_ntxtbits; k++) {
- if (k % 2 == 0 && (f->freedv_put_next_rx_symbol != NULL))
- {
- (*f->freedv_put_next_rx_symbol)(f->callback_state_sym,
- ofdm->rx_np[txt_sym_index],
- ofdm->rx_amp[txt_sym_index]);
- txt_sym_index++;
- }
-
- //fprintf(stderr, "txt_bits[%d] = %d\n", k, rx_bits[i]);
- n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, &txt_bits[k], 1, 1);
- if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
- (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
- }
- }
-
- /* estimate uncoded BER from UW. Coded bit errors could
- probably be estimated as half of all failed LDPC parity
- checks */
-
- for(i=0; i<f->ofdm_nuwbits; i++) {
- if (rx_uw[i] != ofdm->tx_uw[i]) {
- f->total_bit_errors++;
- }
- }
- f->total_bits += f->ofdm_nuwbits;
-
- ofdm_get_demod_stats(f->ofdm, &f->stats, ofdm->rx_np, ofdm->rowsperframe*ofdm->nc);
- f->snr_est = f->stats.snr_est;
+ symbols_to_llrs(llr, codeword_symbols_de, codeword_amps_de, EsNo,
+ ofdm->mean_amp, coded_syms_per_frame);
+ ldpc_decode_frame(ldpc, &parityCheckCount, &iter, out_char, llr);
+ if (parityCheckCount != ldpc->NumberParityBits)
+ rx_status |= FREEDV_RX_BIT_ERRORS;
+
+ if (f->test_frames) {
+ uint8_t payload_data_bits[data_bits_per_frame];
+ ofdm_generate_payload_data_bits(payload_data_bits, data_bits_per_frame);
+ count_errors_protection_mode(ldpc->protection_mode, &Nerrs_coded, &Ncoded,
+ payload_data_bits, out_char,
+ data_bits_per_frame);
+ f->total_bit_errors_coded += Nerrs_coded;
+ f->total_bits_coded += Ncoded;
+ if (Nerrs_coded) f->total_packet_errors++;
+ f->total_packets++;
+ } else {
+ memcpy(f->rx_payload_bits, out_char, data_bits_per_frame);
}
- /* iterate state machine and update nin for next call */
+ rx_status |= FREEDV_RX_BITS;
- f->nin = ofdm_get_nin(ofdm);
- ofdm_sync_state_machine(ofdm, rx_uw);
+ /* If modem is synced we can decode txt bits */
- if ((f->verbose && (ofdm->last_sync_state == search)) || (f->verbose == 2)) {
- assert(rx_status <= 15);
- fprintf(stderr, "%3d st: %-6s euw: %2d %1d f: %5.1f pbw: %d snr: %4.1f eraw: %3d ecdd: %3d iter: %3d pcc: %3d rxst: %s\n",
- f->frames++, ofdm_statemode[ofdm->last_sync_state], ofdm->uw_errors, ofdm->sync_counter,
- (double)ofdm->foff_est_hz, ofdm->phase_est_bandwidth,
- f->snr_est, Nerrs_raw, Nerrs_coded, iter, parityCheckCount, rx_sync_flags_to_text[rx_status]);
+ for (k = 0; k < f->ofdm_ntxtbits; k++) {
+ if (k % 2 == 0 && (f->freedv_put_next_rx_symbol != NULL)) {
+ (*f->freedv_put_next_rx_symbol)(f->callback_state_sym,
+ ofdm->rx_np[txt_sym_index],
+ ofdm->rx_amp[txt_sym_index]);
+ txt_sym_index++;
+ }
+
+ // fprintf(stderr, "txt_bits[%d] = %d\n", k, rx_bits[i]);
+ n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out,
+ &txt_bits[k], 1, 1);
+ if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+ (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+ }
}
- return rx_status;
+ /* estimate uncoded BER from UW. Coded bit errors could
+ probably be estimated as half of all failed LDPC parity
+ checks */
+
+ for (i = 0; i < f->ofdm_nuwbits; i++) {
+ if (rx_uw[i] != ofdm->tx_uw[i]) {
+ f->total_bit_errors++;
+ }
+ }
+ f->total_bits += f->ofdm_nuwbits;
+
+ ofdm_get_demod_stats(f->ofdm, &f->stats, ofdm->rx_np,
+ ofdm->rowsperframe * ofdm->nc);
+ f->snr_est = f->stats.snr_est;
+ }
+
+ /* iterate state machine and update nin for next call */
+
+ f->nin = ofdm_get_nin(ofdm);
+ ofdm_sync_state_machine(ofdm, rx_uw);
+
+ if ((f->verbose && (ofdm->last_sync_state == search)) || (f->verbose == 2)) {
+ assert(rx_status <= 15);
+ fprintf(stderr,
+ "%3d st: %-6s euw: %2d %1d f: %5.1f pbw: %d snr: %4.1f eraw: %3d "
+ "ecdd: %3d iter: %3d pcc: %3d rxst: %s\n",
+ f->frames++, ofdm_statemode[ofdm->last_sync_state], ofdm->uw_errors,
+ ofdm->sync_counter, (double)ofdm->foff_est_hz,
+ ofdm->phase_est_bandwidth, f->snr_est, Nerrs_raw, Nerrs_coded, iter,
+ parityCheckCount, rx_sync_flags_to_text[rx_status]);
+ }
+
+ return rx_status;
}
#endif