aboutsummaryrefslogtreecommitdiff
path: root/src/freedv_700.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_700.c
parent6588e77f38bdebd7adffe091b22e7760d95d0ccb (diff)
parent4d6c143c0abec15e1d6ed1fd95d36f80e6cb7df8 (diff)
Merge pull request #3 from drowe67/dr-cleanup21.2.0
Cleanup Part 2
Diffstat (limited to 'src/freedv_700.c')
-rw-r--r--src/freedv_700.c1007
1 files changed, 527 insertions, 480 deletions
diff --git a/src/freedv_700.c b/src/freedv_700.c
index 235284e..3dc4329 100644
--- a/src/freedv_700.c
+++ b/src/freedv_700.c
@@ -4,366 +4,397 @@
AUTHOR......: David Rowe
DATE CREATED: May 2020
- Functions that implement the various FreeDV 700 modes, and more generally
+ Functions that implement the various FreeDV 700 modes, and more generally
OFDM data modes.
\*---------------------------------------------------------------------------*/
#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 "filter.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 "filter.h"
+#include "ldpc_codes.h"
+#include "mpdecode_core.h"
+#include "ofdm_internal.h"
+#include "varicode.h"
extern char *ofdm_statemode[];
void freedv_700c_open(struct freedv *f) {
- f->snr_squelch_thresh = 0.0;
- f->squelch_en = false;
-
- f->cohpsk = cohpsk_create();
- f->nin = f->nin_prev = COHPSK_NOM_SAMPLES_PER_FRAME;
- f->n_nat_modem_samples = COHPSK_NOM_SAMPLES_PER_FRAME; // native modem samples as used by the modem
- f->n_nom_modem_samples = f->n_nat_modem_samples * FREEDV_FS_8000 / COHPSK_FS;// number of samples after native samples are interpolated to 8000 sps
- f->n_max_modem_samples = COHPSK_MAX_SAMPLES_PER_FRAME * FREEDV_FS_8000 / COHPSK_FS + 1;
- f->modem_sample_rate = FREEDV_FS_8000; // note weird sample rate tamed by resampling
- f->clip_en = true;
- f->sz_error_pattern = cohpsk_error_pattern_size();
- f->test_frames_diversity = 1;
-
- f->ptFilter7500to8000 = (struct quisk_cfFilter *)MALLOC(sizeof(struct quisk_cfFilter));
- f->ptFilter8000to7500 = (struct quisk_cfFilter *)MALLOC(sizeof(struct quisk_cfFilter));
- quisk_filt_cfInit(f->ptFilter8000to7500, quiskFilt120t480, sizeof(quiskFilt120t480)/sizeof(float));
- quisk_filt_cfInit(f->ptFilter7500to8000, quiskFilt120t480, sizeof(quiskFilt120t480)/sizeof(float));
-
- f->speech_sample_rate = FREEDV_FS_8000;
- f->codec2 = codec2_create(CODEC2_MODE_700C); assert(f->codec2 != NULL);
-
- f->n_codec_frames = 2;
- f->n_speech_samples = f->n_codec_frames*codec2_samples_per_frame(f->codec2);
- f->bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
- f->bits_per_modem_frame = f->n_codec_frames*codec2_bits_per_frame(f->codec2);
- assert(f->bits_per_modem_frame == COHPSK_BITS_PER_FRAME);
-
- f->tx_payload_bits = (uint8_t*)MALLOC(f->bits_per_modem_frame*sizeof(char)); assert(f->tx_payload_bits != NULL);
- f->rx_payload_bits = (uint8_t*)MALLOC(f->bits_per_modem_frame*sizeof(char)); assert(f->rx_payload_bits != NULL);
+ f->snr_squelch_thresh = 0.0;
+ f->squelch_en = false;
+
+ f->cohpsk = cohpsk_create();
+ f->nin = f->nin_prev = COHPSK_NOM_SAMPLES_PER_FRAME;
+ f->n_nat_modem_samples =
+ COHPSK_NOM_SAMPLES_PER_FRAME; // native modem samples as used by the
+ // modem
+ f->n_nom_modem_samples = f->n_nat_modem_samples * FREEDV_FS_8000 /
+ COHPSK_FS; // number of samples after native samples
+ // are interpolated to 8000 sps
+ f->n_max_modem_samples =
+ COHPSK_MAX_SAMPLES_PER_FRAME * FREEDV_FS_8000 / COHPSK_FS + 1;
+ f->modem_sample_rate =
+ FREEDV_FS_8000; // note weird sample rate tamed by resampling
+ f->clip_en = true;
+ f->sz_error_pattern = cohpsk_error_pattern_size();
+ f->test_frames_diversity = 1;
+
+ f->ptFilter7500to8000 =
+ (struct quisk_cfFilter *)MALLOC(sizeof(struct quisk_cfFilter));
+ f->ptFilter8000to7500 =
+ (struct quisk_cfFilter *)MALLOC(sizeof(struct quisk_cfFilter));
+ quisk_filt_cfInit(f->ptFilter8000to7500, quiskFilt120t480,
+ sizeof(quiskFilt120t480) / sizeof(float));
+ quisk_filt_cfInit(f->ptFilter7500to8000, quiskFilt120t480,
+ sizeof(quiskFilt120t480) / sizeof(float));
+
+ f->speech_sample_rate = FREEDV_FS_8000;
+ f->codec2 = codec2_create(CODEC2_MODE_700C);
+ assert(f->codec2 != NULL);
+
+ f->n_codec_frames = 2;
+ f->n_speech_samples = f->n_codec_frames * codec2_samples_per_frame(f->codec2);
+ f->bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+ f->bits_per_modem_frame =
+ f->n_codec_frames * codec2_bits_per_frame(f->codec2);
+ assert(f->bits_per_modem_frame == COHPSK_BITS_PER_FRAME);
+
+ f->tx_payload_bits =
+ (uint8_t *)MALLOC(f->bits_per_modem_frame * sizeof(char));
+ assert(f->tx_payload_bits != NULL);
+ f->rx_payload_bits =
+ (uint8_t *)MALLOC(f->bits_per_modem_frame * sizeof(char));
+ assert(f->rx_payload_bits != NULL);
}
void freedv_comptx_700c(struct freedv *f, COMP mod_out[]) {
- int i;
- COMP tx_fdm[f->n_nat_modem_samples];
- int tx_bits[COHPSK_BITS_PER_FRAME];
-
- /* earlier modems used one bit per int for unpacked bits */
- for(i=0; i<COHPSK_BITS_PER_FRAME; i++) tx_bits[i] = f->tx_payload_bits[i];
-
- /* optionally overwrite the codec bits with test frames */
- if (f->test_frames) {
- cohpsk_get_test_bits(f->cohpsk, tx_bits);
- }
-
- /* cohpsk modulator */
- cohpsk_mod(f->cohpsk, tx_fdm, tx_bits, COHPSK_BITS_PER_FRAME);
-
- float gain = 1.0;
- if (f->clip_en) {
- cohpsk_clip(tx_fdm, COHPSK_CLIP, COHPSK_NOM_SAMPLES_PER_FRAME);
- gain = 2.5;
- }
- for(i=0; i<f->n_nat_modem_samples; i++)
- mod_out[i] = fcmult(gain*COHPSK_SCALE, tx_fdm[i]);
- i = quisk_cfInterpDecim((complex float *)mod_out, f->n_nat_modem_samples, f->ptFilter7500to8000, 16, 15);
+ int i;
+ COMP tx_fdm[f->n_nat_modem_samples];
+ int tx_bits[COHPSK_BITS_PER_FRAME];
+
+ /* earlier modems used one bit per int for unpacked bits */
+ for (i = 0; i < COHPSK_BITS_PER_FRAME; i++)
+ tx_bits[i] = f->tx_payload_bits[i];
+
+ /* optionally overwrite the codec bits with test frames */
+ if (f->test_frames) {
+ cohpsk_get_test_bits(f->cohpsk, tx_bits);
+ }
+
+ /* cohpsk modulator */
+ cohpsk_mod(f->cohpsk, tx_fdm, tx_bits, COHPSK_BITS_PER_FRAME);
+
+ float gain = 1.0;
+ if (f->clip_en) {
+ cohpsk_clip(tx_fdm, COHPSK_CLIP, COHPSK_NOM_SAMPLES_PER_FRAME);
+ gain = 2.5;
+ }
+ for (i = 0; i < f->n_nat_modem_samples; i++)
+ mod_out[i] = fcmult(gain * COHPSK_SCALE, tx_fdm[i]);
+ i = quisk_cfInterpDecim((complex float *)mod_out, f->n_nat_modem_samples,
+ f->ptFilter7500to8000, 16, 15);
}
// open function for OFDM voice modes
void freedv_ofdm_voice_open(struct freedv *f, char *mode) {
- f->snr_squelch_thresh = 0.0;
- f->squelch_en = false;
- struct OFDM_CONFIG *ofdm_config = (struct OFDM_CONFIG *) calloc(1, sizeof (struct OFDM_CONFIG));
- assert(ofdm_config != NULL);
- ofdm_init_mode(mode, ofdm_config);
-
- f->ofdm = ofdm_create(ofdm_config);
- assert(f->ofdm != NULL);
- free(ofdm_config);
-
- ofdm_config = ofdm_get_config_param(f->ofdm);
- f->ofdm_bitsperpacket = ofdm_get_bits_per_packet(f->ofdm);
- f->ofdm_bitsperframe = ofdm_get_bits_per_frame(f->ofdm);
- f->ofdm_nuwbits = ofdm_config->nuwbits;
- f->ofdm_ntxtbits = ofdm_config->txtbits;
-
- 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);
+ f->snr_squelch_thresh = 0.0;
+ f->squelch_en = false;
+ struct OFDM_CONFIG *ofdm_config =
+ (struct OFDM_CONFIG *)calloc(1, sizeof(struct OFDM_CONFIG));
+ assert(ofdm_config != NULL);
+ ofdm_init_mode(mode, ofdm_config);
+
+ f->ofdm = ofdm_create(ofdm_config);
+ assert(f->ofdm != NULL);
+ free(ofdm_config);
+
+ ofdm_config = ofdm_get_config_param(f->ofdm);
+ f->ofdm_bitsperpacket = ofdm_get_bits_per_packet(f->ofdm);
+ f->ofdm_bitsperframe = ofdm_get_bits_per_frame(f->ofdm);
+ f->ofdm_nuwbits = ofdm_config->nuwbits;
+ f->ofdm_ntxtbits = ofdm_config->txtbits;
+
+ 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);
#ifdef __EMBEDDED__
- f->ldpc->max_iter = 10; /* limit LDPC decoder iterations to limit CPU load */
+ f->ldpc->max_iter = 10; /* limit LDPC decoder iterations to limit CPU load */
#endif
- int Nsymsperpacket = ofdm_get_bits_per_packet(f->ofdm) / f->ofdm->bps;
- f->rx_syms = (COMP*)MALLOC(sizeof(COMP) * Nsymsperpacket);
- assert(f->rx_syms != NULL);
- f->rx_amps = (float*)MALLOC(sizeof(float) * Nsymsperpacket);
- assert(f->rx_amps != NULL);
- for(int i=0; i<Nsymsperpacket; i++) {
- f->rx_syms[i].real = f->rx_syms[i].imag = 0.0;
- f->rx_amps[i]= 0.0;
- }
-
- 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;
-
- f->tx_bits = NULL; /* not used for 700D */
-
- f->speech_sample_rate = FREEDV_FS_8000;
- f->codec2 = codec2_create(CODEC2_MODE_700C); assert(f->codec2 != NULL);
- /* should be exactly an integer number of Codec 2 frames in a OFDM modem frame */
- assert((f->ldpc->data_bits_per_frame % codec2_bits_per_frame(f->codec2)) == 0);
-
- f->n_codec_frames = f->ldpc->data_bits_per_frame/codec2_bits_per_frame(f->codec2);
- f->n_speech_samples = f->n_codec_frames*codec2_samples_per_frame(f->codec2);
- f->bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
- 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;
-
- /* should all add up to a complete frame */
- assert((ofdm_config->ns - 1) * ofdm_config->nc * ofdm_config->bps ==
- f->ldpc->coded_bits_per_frame + ofdm_config->txtbits + f->ofdm_nuwbits);
+ int Nsymsperpacket = ofdm_get_bits_per_packet(f->ofdm) / f->ofdm->bps;
+ f->rx_syms = (COMP *)MALLOC(sizeof(COMP) * Nsymsperpacket);
+ assert(f->rx_syms != NULL);
+ f->rx_amps = (float *)MALLOC(sizeof(float) * Nsymsperpacket);
+ assert(f->rx_amps != NULL);
+ for (int i = 0; i < Nsymsperpacket; i++) {
+ f->rx_syms[i].real = f->rx_syms[i].imag = 0.0;
+ f->rx_amps[i] = 0.0;
+ }
+
+ 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;
+
+ f->tx_bits = NULL; /* not used for 700D */
+
+ f->speech_sample_rate = FREEDV_FS_8000;
+ f->codec2 = codec2_create(CODEC2_MODE_700C);
+ assert(f->codec2 != NULL);
+ /* should be exactly an integer number of Codec 2 frames in a OFDM modem frame
+ */
+ assert((f->ldpc->data_bits_per_frame % codec2_bits_per_frame(f->codec2)) ==
+ 0);
+
+ f->n_codec_frames =
+ f->ldpc->data_bits_per_frame / codec2_bits_per_frame(f->codec2);
+ f->n_speech_samples = f->n_codec_frames * codec2_samples_per_frame(f->codec2);
+ f->bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+ 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;
+
+ /* should all add up to a complete frame */
+ assert((ofdm_config->ns - 1) * ofdm_config->nc * ofdm_config->bps ==
+ f->ldpc->coded_bits_per_frame + ofdm_config->txtbits +
+ f->ofdm_nuwbits);
}
// open function for OFDM data modes, TODO consider moving to a new
// (freedv_ofdm_data.c) file
void freedv_ofdm_data_open(struct freedv *f) {
- struct OFDM_CONFIG ofdm_config;
- char mode[32];
- if (f->mode == FREEDV_MODE_DATAC0) strcpy(mode, "datac0");
- if (f->mode == FREEDV_MODE_DATAC1) strcpy(mode, "datac1");
- if (f->mode == FREEDV_MODE_DATAC3) strcpy(mode, "datac3");
- if (f->mode == FREEDV_MODE_DATAC4) strcpy(mode, "datac4");
- if (f->mode == FREEDV_MODE_DATAC13) strcpy(mode, "datac13");
-
- ofdm_init_mode(mode, &ofdm_config);
- f->ofdm = ofdm_create(&ofdm_config);
- assert(f->ofdm != NULL);
-
- // LDPC set up
- 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);
+ struct OFDM_CONFIG ofdm_config;
+ char mode[32];
+ if (f->mode == FREEDV_MODE_DATAC0) strcpy(mode, "datac0");
+ if (f->mode == FREEDV_MODE_DATAC1) strcpy(mode, "datac1");
+ if (f->mode == FREEDV_MODE_DATAC3) strcpy(mode, "datac3");
+ if (f->mode == FREEDV_MODE_DATAC4) strcpy(mode, "datac4");
+ if (f->mode == FREEDV_MODE_DATAC13) strcpy(mode, "datac13");
+
+ ofdm_init_mode(mode, &ofdm_config);
+ f->ofdm = ofdm_create(&ofdm_config);
+ assert(f->ofdm != NULL);
+
+ // LDPC set up
+ 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);
#ifdef __EMBEDDED__
- f->ldpc->max_iter = 10; /* limit LDPC decoder iterations to limit CPU load */
+ f->ldpc->max_iter = 10; /* limit LDPC decoder iterations to limit CPU load */
#endif
- // useful constants
- f->ofdm_bitsperpacket = ofdm_get_bits_per_packet(f->ofdm);
- f->ofdm_bitsperframe = ofdm_get_bits_per_frame(f->ofdm);
- f->ofdm_nuwbits = ofdm_config.nuwbits;
- f->ofdm_ntxtbits = ofdm_config.txtbits;
-
- /* payload bits per FreeDV API "frame". In OFDM modem nomenclature this is the number of
- payload data bits per packet, or the number of data bits in a LDPC codeword */
- f->bits_per_modem_frame = f->ldpc->data_bits_per_frame;
-
- // buffers for received symbols for one packet/LDPC codeword - may span many OFDM modem frames
- int Nsymsperpacket = ofdm_get_bits_per_packet(f->ofdm) / f->ofdm->bps;
- f->rx_syms = (COMP*)MALLOC(sizeof(COMP) * Nsymsperpacket);
- assert(f->rx_syms != NULL);
- f->rx_amps = (float*)MALLOC(sizeof(float) * Nsymsperpacket);
- assert(f->rx_amps != NULL);
- for(int i=0; i<Nsymsperpacket; i++) {
- f->rx_syms[i].real = f->rx_syms[i].imag = 0.0;
- f->rx_amps[i]= 0.0;
- }
-
- f->nin = f->nin_prev = ofdm_get_nin(f->ofdm);
- f->n_nat_modem_samples = ofdm_get_samples_per_packet(f->ofdm);
- f->n_nom_modem_samples = ofdm_get_samples_per_frame(f->ofdm);
- /* in burst mode we might jump a preamble frame */
- f->n_max_modem_samples = 2*ofdm_get_max_samples_per_frame(f->ofdm);
- f->modem_sample_rate = f->ofdm->config.fs;
- f->sz_error_pattern = f->ofdm_bitsperpacket;
-
- // Note inconsistency: freedv API modem "frame" is a OFDM modem packet
- 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);
+ // useful constants
+ f->ofdm_bitsperpacket = ofdm_get_bits_per_packet(f->ofdm);
+ f->ofdm_bitsperframe = ofdm_get_bits_per_frame(f->ofdm);
+ f->ofdm_nuwbits = ofdm_config.nuwbits;
+ f->ofdm_ntxtbits = ofdm_config.txtbits;
+
+ /* payload bits per FreeDV API "frame". In OFDM modem nomenclature this is
+ the number of payload data bits per packet, or the number of data bits in a
+ LDPC codeword */
+ f->bits_per_modem_frame = f->ldpc->data_bits_per_frame;
+
+ // buffers for received symbols for one packet/LDPC codeword - may span many
+ // OFDM modem frames
+ int Nsymsperpacket = ofdm_get_bits_per_packet(f->ofdm) / f->ofdm->bps;
+ f->rx_syms = (COMP *)MALLOC(sizeof(COMP) * Nsymsperpacket);
+ assert(f->rx_syms != NULL);
+ f->rx_amps = (float *)MALLOC(sizeof(float) * Nsymsperpacket);
+ assert(f->rx_amps != NULL);
+ for (int i = 0; i < Nsymsperpacket; i++) {
+ f->rx_syms[i].real = f->rx_syms[i].imag = 0.0;
+ f->rx_amps[i] = 0.0;
+ }
+
+ f->nin = f->nin_prev = ofdm_get_nin(f->ofdm);
+ f->n_nat_modem_samples = ofdm_get_samples_per_packet(f->ofdm);
+ f->n_nom_modem_samples = ofdm_get_samples_per_frame(f->ofdm);
+ /* in burst mode we might jump a preamble frame */
+ f->n_max_modem_samples = 2 * ofdm_get_max_samples_per_frame(f->ofdm);
+ f->modem_sample_rate = f->ofdm->config.fs;
+ f->sz_error_pattern = f->ofdm_bitsperpacket;
+
+ // Note inconsistency: freedv API modem "frame" is a OFDM modem packet
+ 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);
}
/* speech or raw data, complex OFDM modulation out */
void freedv_comptx_ofdm(struct freedv *f, COMP mod_out[]) {
- int i, k;
- int nspare;
-
- /* Generate Varicode txt bits (if used), waren't protected by FEC */
- 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 i, k;
+ int nspare;
+
+ /* Generate Varicode txt bits (if used), waren't protected by FEC */
+ 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;
+ }
}
-
- /* optionally replace payload bits with test frames known to rx */
- if (f->test_frames) {
- uint8_t payload_data_bits[f->bits_per_modem_frame];
- ofdm_generate_payload_data_bits(payload_data_bits, f->bits_per_modem_frame);
-
- for (i = 0; i < f->bits_per_modem_frame; i++) {
- f->tx_payload_bits[i] = payload_data_bits[i];
- }
+ if (f->nvaricode_bits) {
+ txt_bits[k] = f->tx_varicode_bits[f->varicode_bit_index++];
+ f->nvaricode_bits--;
+ } else
+ txt_bits[k] = 0;
+ }
+
+ /* optionally replace payload bits with test frames known to rx */
+ if (f->test_frames) {
+ uint8_t payload_data_bits[f->bits_per_modem_frame];
+ ofdm_generate_payload_data_bits(payload_data_bits, f->bits_per_modem_frame);
+
+ for (i = 0; i < f->bits_per_modem_frame; i++) {
+ f->tx_payload_bits[i] = payload_data_bits[i];
}
+ }
- /* OK now ready to LDPC encode, interleave, and OFDM modulate */
- ofdm_ldpc_interleave_tx(f->ofdm, f->ldpc, (complex float*)mod_out, f->tx_payload_bits, txt_bits);
+ /* OK now ready to LDPC encode, interleave, and OFDM modulate */
+ ofdm_ldpc_interleave_tx(f->ofdm, f->ldpc, (complex float *)mod_out,
+ f->tx_payload_bits, txt_bits);
}
-
int freedv_comprx_700c(struct freedv *f, COMP demod_in_8kHz[]) {
- int i;
- int sync;
+ int i;
+ int sync;
+
+ int rx_status = 0;
- int rx_status = 0;
+ // quisk_cfInterpDecim() modifies input data so lets make a copy just in case
+ // there is no sync and we need to echo input to output
- // quisk_cfInterpDecim() modifies input data so lets make a copy just in case there
- // is no sync and we need to echo inpout to output
+ // freedv_nin(f): input samples at Fs=8000 Hz
+ // f->nin: input samples at Fs=7500 Hz
- // freedv_nin(f): input samples at Fs=8000 Hz
- // f->nin: input samples at Fs=7500 Hz
+ COMP demod_in[freedv_nin(f)];
- COMP demod_in[freedv_nin(f)];
+ for (i = 0; i < freedv_nin(f); i++) demod_in[i] = demod_in_8kHz[i];
- for(i=0; i<freedv_nin(f); i++)
- demod_in[i] = demod_in_8kHz[i];
+ i = quisk_cfInterpDecim((complex float *)demod_in, freedv_nin(f),
+ f->ptFilter8000to7500, 15, 16);
- i = quisk_cfInterpDecim((complex float *)demod_in, freedv_nin(f), f->ptFilter8000to7500, 15, 16);
+ for (i = 0; i < f->nin; i++)
+ demod_in[i] = fcmult(1.0 / COHPSK_SCALE, demod_in[i]);
- for(i=0; i<f->nin; i++)
- demod_in[i] = fcmult(1.0/COHPSK_SCALE, demod_in[i]);
+ float rx_soft_bits[COHPSK_BITS_PER_FRAME];
- float rx_soft_bits[COHPSK_BITS_PER_FRAME];
+ cohpsk_demod(f->cohpsk, rx_soft_bits, &sync, demod_in, &f->nin);
- cohpsk_demod(f->cohpsk, rx_soft_bits, &sync, demod_in, &f->nin);
+ for (i = 0; i < f->bits_per_modem_frame; i++)
+ f->rx_payload_bits[i] = rx_soft_bits[i] < 0.0f;
- for(i=0; i<f->bits_per_modem_frame; i++)
- f->rx_payload_bits[i] = rx_soft_bits[i] < 0.0f;
+ f->sync = sync;
+ cohpsk_get_demod_stats(f->cohpsk, &f->stats);
+ f->snr_est = f->stats.snr_est;
- f->sync = sync;
- cohpsk_get_demod_stats(f->cohpsk, &f->stats);
- f->snr_est = f->stats.snr_est;
+ if (sync) {
+ rx_status = FREEDV_RX_SYNC;
+ if (f->test_frames == 0) {
+ rx_status |= FREEDV_RX_BITS;
+ } else {
+ if (f->test_frames_diversity) {
+ /* normal operation - error pattern on frame after diveristy combination
+ */
+ short error_pattern[COHPSK_BITS_PER_FRAME];
+ int bit_errors;
- if (sync) {
- rx_status = FREEDV_RX_SYNC;
- if (f->test_frames == 0) {
- rx_status |= FREEDV_RX_BITS;
+ /* test data, lets see if we can sync to the test data sequence */
+
+ char rx_bits_char[COHPSK_BITS_PER_FRAME];
+ for (i = 0; i < COHPSK_BITS_PER_FRAME; i++)
+ rx_bits_char[i] = rx_soft_bits[i] < 0.0;
+ cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state,
+ error_pattern, &bit_errors, rx_bits_char, 0);
+ if (f->test_frame_sync_state) {
+ f->total_bit_errors += bit_errors;
+ f->total_bits += COHPSK_BITS_PER_FRAME;
+ if (f->freedv_put_error_pattern != NULL) {
+ (*f->freedv_put_error_pattern)(f->error_pattern_callback_state,
+ error_pattern,
+ COHPSK_BITS_PER_FRAME);
+ }
}
- else {
-
- if (f->test_frames_diversity) {
- /* normal operation - error pattern on frame after diveristy combination */
- short error_pattern[COHPSK_BITS_PER_FRAME];
- int bit_errors;
-
- /* test data, lets see if we can sync to the test data sequence */
-
- char rx_bits_char[COHPSK_BITS_PER_FRAME];
- for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
- rx_bits_char[i] = rx_soft_bits[i] < 0.0;
- cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors, rx_bits_char, 0);
- if (f->test_frame_sync_state) {
- f->total_bit_errors += bit_errors;
- f->total_bits += COHPSK_BITS_PER_FRAME;
- if (f->freedv_put_error_pattern != NULL) {
- (*f->freedv_put_error_pattern)(f->error_pattern_callback_state, error_pattern, COHPSK_BITS_PER_FRAME);
- }
- }
- }
- else {
- /* calculate error pattern on uncombined carriers - test mode to spot any carrier specific issues like
- tx passband filtering */
-
- short error_pattern[2*COHPSK_BITS_PER_FRAME];
- char rx_bits_char[COHPSK_BITS_PER_FRAME];
- int bit_errors_lower, bit_errors_upper;
-
- /* lower group of carriers */
-
- float *rx_bits_lower = cohpsk_get_rx_bits_lower(f->cohpsk);
- for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
- rx_bits_char[i] = rx_bits_lower[i] < 0.0;
- }
- cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors_lower, rx_bits_char, 0);
-
- /* upper group of carriers */
-
- float *rx_bits_upper = cohpsk_get_rx_bits_upper(f->cohpsk);
- for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
- rx_bits_char[i] = rx_bits_upper[i] < 0.0;
- }
- cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state_upper, &error_pattern[COHPSK_BITS_PER_FRAME], &bit_errors_upper, rx_bits_char, 1);
-
- /* combine total errors and call callback */
-
- if (f->test_frame_sync_state && f->test_frame_sync_state_upper) {
- f->total_bit_errors += bit_errors_lower + bit_errors_upper;
- f->total_bits += 2*COHPSK_BITS_PER_FRAME;
- if (f->freedv_put_error_pattern != NULL) {
- (*f->freedv_put_error_pattern)(f->error_pattern_callback_state, error_pattern, 2*COHPSK_BITS_PER_FRAME);
- }
- }
-
- }
+ } else {
+ /* calculate error pattern on uncombined carriers - test mode to spot
+ any carrier specific issues like tx passband filtering */
+
+ short error_pattern[2 * COHPSK_BITS_PER_FRAME];
+ char rx_bits_char[COHPSK_BITS_PER_FRAME];
+ int bit_errors_lower, bit_errors_upper;
+
+ /* lower group of carriers */
+
+ float *rx_bits_lower = cohpsk_get_rx_bits_lower(f->cohpsk);
+ for (i = 0; i < COHPSK_BITS_PER_FRAME; i++) {
+ rx_bits_char[i] = rx_bits_lower[i] < 0.0;
}
+ cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state,
+ error_pattern, &bit_errors_lower, rx_bits_char, 0);
+ /* upper group of carriers */
+
+ float *rx_bits_upper = cohpsk_get_rx_bits_upper(f->cohpsk);
+ for (i = 0; i < COHPSK_BITS_PER_FRAME; i++) {
+ rx_bits_char[i] = rx_bits_upper[i] < 0.0;
+ }
+ cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state_upper,
+ &error_pattern[COHPSK_BITS_PER_FRAME],
+ &bit_errors_upper, rx_bits_char, 1);
+
+ /* combine total errors and call callback */
+
+ if (f->test_frame_sync_state && f->test_frame_sync_state_upper) {
+ f->total_bit_errors += bit_errors_lower + bit_errors_upper;
+ f->total_bits += 2 * COHPSK_BITS_PER_FRAME;
+ if (f->freedv_put_error_pattern != NULL) {
+ (*f->freedv_put_error_pattern)(f->error_pattern_callback_state,
+ error_pattern,
+ 2 * COHPSK_BITS_PER_FRAME);
+ }
+ }
+ }
}
+ }
- return rx_status;
+ return rx_status;
}
/*
@@ -372,193 +403,209 @@ int freedv_comprx_700c(struct freedv *f, COMP demod_in_8kHz[]) {
the SM1000.
*/
-int freedv_comp_short_rx_ofdm(struct freedv *f, void *demod_in_8kHz, int demod_in_is_short, float gain) {
- int i, k;
- int n_ascii;
- char ascii_out;
- struct OFDM *ofdm = f->ofdm;
- struct LDPC *ldpc = f->ldpc;
-
- /* useful constants */
- int Nbitsperframe = ofdm_get_bits_per_frame(ofdm);
- int Nbitsperpacket = ofdm_get_bits_per_packet(ofdm);
- int Nsymsperframe = Nbitsperframe / ofdm->bps;
- int Nsymsperpacket = Nbitsperpacket / ofdm->bps;
- int Npayloadbitsperpacket = Nbitsperpacket - ofdm->nuwbits - ofdm->ntxtbits;
- int Npayloadsymsperpacket = Npayloadbitsperpacket/ofdm->bps;
- int Ndatabitsperpacket = ldpc->data_bits_per_frame;
-
- complex float *rx_syms = (complex float*)f->rx_syms;
- float *rx_amps = f->rx_amps;
-
- int rx_bits[Nbitsperframe];
- short txt_bits[f->ofdm_ntxtbits];
- COMP payload_syms[Npayloadsymsperpacket];
- float payload_amps[Npayloadsymsperpacket];
-
- int Nerrs_raw = 0;
- int Nerrs_coded = 0;
- int iter = 0;
- int parityCheckCount = 0;
- uint8_t rx_uw[f->ofdm_nuwbits];
-
- float new_gain = gain / f->ofdm->amp_scale;
-
- assert((demod_in_is_short == 0) || (demod_in_is_short == 1));
-
- int rx_status = 0;
- float EsNo = 3.0; /* further work: estimate this properly from signal */
- f->sync = 0;
-
- /* looking for OFDM modem sync */
- if (ofdm->sync_state == search) {
- if (demod_in_is_short)
- ofdm_sync_search_shorts(f->ofdm, (short*)demod_in_8kHz, new_gain);
- else
- ofdm_sync_search(f->ofdm, (COMP*)demod_in_8kHz);
- f->snr_est = -5.0;
+int freedv_comp_short_rx_ofdm(struct freedv *f, void *demod_in_8kHz,
+ int demod_in_is_short, float gain) {
+ int i, k;
+ int n_ascii;
+ char ascii_out;
+ struct OFDM *ofdm = f->ofdm;
+ struct LDPC *ldpc = f->ldpc;
+
+ /* useful constants */
+ int Nbitsperframe = ofdm_get_bits_per_frame(ofdm);
+ int Nbitsperpacket = ofdm_get_bits_per_packet(ofdm);
+ int Nsymsperframe = Nbitsperframe / ofdm->bps;
+ int Nsymsperpacket = Nbitsperpacket / ofdm->bps;
+ int Npayloadbitsperpacket = Nbitsperpacket - ofdm->nuwbits - ofdm->ntxtbits;
+ int Npayloadsymsperpacket = Npayloadbitsperpacket / ofdm->bps;
+ int Ndatabitsperpacket = ldpc->data_bits_per_frame;
+
+ complex float *rx_syms = (complex float *)f->rx_syms;
+ float *rx_amps = f->rx_amps;
+
+ int rx_bits[Nbitsperframe];
+ short txt_bits[f->ofdm_ntxtbits];
+ COMP payload_syms[Npayloadsymsperpacket];
+ float payload_amps[Npayloadsymsperpacket];
+
+ int Nerrs_raw = 0;
+ int Nerrs_coded = 0;
+ int iter = 0;
+ int parityCheckCount = 0;
+ uint8_t rx_uw[f->ofdm_nuwbits];
+
+ float new_gain = gain / f->ofdm->amp_scale;
+
+ assert((demod_in_is_short == 0) || (demod_in_is_short == 1));
+
+ int rx_status = 0;
+ float EsNo = 3.0; /* further work: estimate this properly from signal */
+ f->sync = 0;
+
+ /* looking for OFDM modem sync */
+ if (ofdm->sync_state == search) {
+ if (demod_in_is_short)
+ ofdm_sync_search_shorts(f->ofdm, (short *)demod_in_8kHz, new_gain);
+ else
+ ofdm_sync_search(f->ofdm, (COMP *)demod_in_8kHz);
+ f->snr_est = -5.0;
+ }
+
+ if ((ofdm->sync_state == synced) || (ofdm->sync_state == trial)) {
+ /* OK we have OFDM modem sync */
+ rx_status |= FREEDV_RX_SYNC;
+ if (ofdm->sync_state == trial) rx_status |= FREEDV_RX_TRIAL_SYNC;
+ if (demod_in_is_short)
+ ofdm_demod_shorts(ofdm, rx_bits, (short *)demod_in_8kHz, new_gain);
+ else
+ ofdm_demod(ofdm, rx_bits, (COMP *)demod_in_8kHz);
+
+ /* accumulate a buffer of data symbols for this packet */
+ for (i = 0; i < Nsymsperpacket - Nsymsperframe; i++) {
+ rx_syms[i] = rx_syms[i + Nsymsperframe];
+ rx_amps[i] = rx_amps[i + Nsymsperframe];
}
-
- if ((ofdm->sync_state == synced) || (ofdm->sync_state == trial)) {
- /* OK we have OFDM modem sync */
- rx_status |= FREEDV_RX_SYNC;
- if (ofdm->sync_state == trial) rx_status |= FREEDV_RX_TRIAL_SYNC;
- if (demod_in_is_short)
- ofdm_demod_shorts(ofdm, rx_bits, (short*)demod_in_8kHz, new_gain);
+ memcpy(&rx_syms[Nsymsperpacket - Nsymsperframe], ofdm->rx_np,
+ sizeof(complex float) * Nsymsperframe);
+ memcpy(&rx_amps[Nsymsperpacket - Nsymsperframe], ofdm->rx_amp,
+ sizeof(float) * Nsymsperframe);
+
+ /* look for UW as frames enter packet buffer, note UW may span several modem
+ * frames */
+ int st_uw = Nsymsperpacket - ofdm->nuwframes * Nsymsperframe;
+ ofdm_extract_uw(ofdm, &rx_syms[st_uw], &rx_amps[st_uw], rx_uw);
+
+ // update some FreeDV API level stats
+ f->sync = 1;
+
+ if (ofdm->modem_frame == (ofdm->np - 1)) {
+ /* we have received enough modem frames to complete packet and run LDPC
+ * decoder */
+ int txt_sym_index = 0;
+ ofdm_disassemble_qpsk_modem_packet_with_text_amps(
+ ofdm, rx_syms, rx_amps, payload_syms, payload_amps, txt_bits,
+ &txt_sym_index);
+
+ COMP payload_syms_de[Npayloadsymsperpacket];
+ float payload_amps_de[Npayloadsymsperpacket];
+ gp_deinterleave_comp(payload_syms_de, payload_syms,
+ Npayloadsymsperpacket);
+ gp_deinterleave_float(payload_amps_de, payload_amps,
+ Npayloadsymsperpacket);
+
+ float llr[Npayloadbitsperpacket];
+ uint8_t decoded_codeword[Npayloadbitsperpacket];
+ symbols_to_llrs(llr, payload_syms_de, payload_amps_de, EsNo,
+ ofdm->mean_amp, Npayloadsymsperpacket);
+ ldpc_decode_frame(ldpc, &parityCheckCount, &iter, decoded_codeword, llr);
+ // iter = run_ldpc_decoder(ldpc, decoded_codeword, llr,
+ // &parityCheckCount);
+ memcpy(f->rx_payload_bits, decoded_codeword, Ndatabitsperpacket);
+
+ if (strlen(ofdm->data_mode)) {
+ // we need a valid CRC to declare a data packet valid
+ if (freedv_check_crc16_unpacked(f->rx_payload_bits, Ndatabitsperpacket))
+ rx_status |= FREEDV_RX_BITS;
else
- ofdm_demod(ofdm, rx_bits, (COMP*)demod_in_8kHz);
-
- /* accumulate a buffer of data symbols for this packet */
- for(i=0; i<Nsymsperpacket-Nsymsperframe; i++) {
- rx_syms[i] = rx_syms[i+Nsymsperframe];
- rx_amps[i] = rx_amps[i+Nsymsperframe];
+ rx_status |= FREEDV_RX_BIT_ERRORS;
+ } else {
+ // voice modes aren't as strict - pass everything through to the speech
+ // decoder, but flag frame with possible errors
+ rx_status |= FREEDV_RX_BITS;
+ if (parityCheckCount != ldpc->NumberParityBits)
+ rx_status |= FREEDV_RX_BIT_ERRORS;
+ }
+
+ if (f->test_frames) {
+ /* est uncoded BER from payload bits */
+ Nerrs_raw = count_uncoded_errors(
+ ldpc, &f->ofdm->config, payload_syms_de, strlen(ofdm->data_mode));
+ f->total_bit_errors += Nerrs_raw;
+ f->total_bits += Npayloadbitsperpacket;
+
+ /* coded errors from decoded bits */
+ uint8_t payload_data_bits[Ndatabitsperpacket];
+ ofdm_generate_payload_data_bits(payload_data_bits, Ndatabitsperpacket);
+ if (strlen(ofdm->data_mode)) {
+ uint16_t tx_crc16 =
+ freedv_crc16_unpacked(payload_data_bits, Ndatabitsperpacket - 16);
+ uint8_t tx_crc16_bytes[] = {tx_crc16 >> 8, tx_crc16 & 0xff};
+ freedv_unpack(payload_data_bits + Ndatabitsperpacket - 16,
+ tx_crc16_bytes, 16);
}
- memcpy(&rx_syms[Nsymsperpacket-Nsymsperframe], ofdm->rx_np, sizeof(complex float)*Nsymsperframe);
- memcpy(&rx_amps[Nsymsperpacket-Nsymsperframe], ofdm->rx_amp, sizeof(float)*Nsymsperframe);
-
- /* look for UW as frames enter packet buffer, note UW may span several modem frames */
- int st_uw = Nsymsperpacket - ofdm->nuwframes*Nsymsperframe;
- ofdm_extract_uw(ofdm, &rx_syms[st_uw], &rx_amps[st_uw], rx_uw);
-
- // update some FreeDV API level stats
- f->sync = 1;
-
- if (ofdm->modem_frame == (ofdm->np-1)) {
- /* we have received enough modem frames to complete packet and run LDPC decoder */
- int txt_sym_index = 0;
- ofdm_disassemble_qpsk_modem_packet_with_text_amps(ofdm, rx_syms, rx_amps, payload_syms, payload_amps, txt_bits, &txt_sym_index);
-
- COMP payload_syms_de[Npayloadsymsperpacket];
- float payload_amps_de[Npayloadsymsperpacket];
- gp_deinterleave_comp (payload_syms_de, payload_syms, Npayloadsymsperpacket);
- gp_deinterleave_float(payload_amps_de, payload_amps, Npayloadsymsperpacket);
-
- float llr[Npayloadbitsperpacket];
- uint8_t decoded_codeword[Npayloadbitsperpacket];
- symbols_to_llrs(llr, payload_syms_de, payload_amps_de,
- EsNo, ofdm->mean_amp, Npayloadsymsperpacket);
- ldpc_decode_frame(ldpc, &parityCheckCount, &iter, decoded_codeword, llr);
- //iter = run_ldpc_decoder(ldpc, decoded_codeword, llr, &parityCheckCount);
- memcpy(f->rx_payload_bits, decoded_codeword, Ndatabitsperpacket);
-
- if (strlen(ofdm->data_mode)) {
- // we need a valid CRC to declare a data packet valid
- if (freedv_check_crc16_unpacked(f->rx_payload_bits, Ndatabitsperpacket))
- rx_status |= FREEDV_RX_BITS;
- else
- rx_status |= FREEDV_RX_BIT_ERRORS;
- } else {
-
- // voice modes aren't as strict - pass everything through to the speech decoder, but flag
- // frame with possible errors
- rx_status |= FREEDV_RX_BITS;
- if (parityCheckCount != ldpc->NumberParityBits)
- rx_status |= FREEDV_RX_BIT_ERRORS;
- }
-
- if (f->test_frames) {
- /* est uncoded BER from payload bits */
- Nerrs_raw = count_uncoded_errors(ldpc, &f->ofdm->config, payload_syms_de, strlen(ofdm->data_mode));
- f->total_bit_errors += Nerrs_raw;
- f->total_bits += Npayloadbitsperpacket;
-
- /* coded errors from decoded bits */
- uint8_t payload_data_bits[Ndatabitsperpacket];
- ofdm_generate_payload_data_bits(payload_data_bits, Ndatabitsperpacket);
- if (strlen(ofdm->data_mode)) {
- uint16_t tx_crc16 = freedv_crc16_unpacked(payload_data_bits, Ndatabitsperpacket - 16);
- uint8_t tx_crc16_bytes[] = { tx_crc16 >> 8, tx_crc16 & 0xff };
- freedv_unpack(payload_data_bits + Ndatabitsperpacket - 16, tx_crc16_bytes, 16);
- }
- Nerrs_coded = count_errors(payload_data_bits, f->rx_payload_bits, Ndatabitsperpacket);
- f->total_bit_errors_coded += Nerrs_coded;
- f->total_bits_coded += Ndatabitsperpacket;
- if (Nerrs_coded) f->total_packet_errors++;
- f->total_packets++;
- }
-
- /* decode txt bits (if used) */
- 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, rx_syms[txt_sym_index], rx_amps[txt_sym_index]);
- txt_sym_index++;
- }
- 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);
- }
- }
-
- ofdm_get_demod_stats(ofdm, &f->stats, rx_syms, Nsymsperpacket);
- f->snr_est = f->stats.snr_est;
- } /* complete packet */
-
- if ((ofdm->np == 1) && (ofdm->modem_frame == 0)) {
- /* add in UW bit errors, useful in non-testframe,
- single modem frame per packet modes */
- 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;
+ Nerrs_coded = count_errors(payload_data_bits, f->rx_payload_bits,
+ Ndatabitsperpacket);
+ f->total_bit_errors_coded += Nerrs_coded;
+ f->total_bits_coded += Ndatabitsperpacket;
+ if (Nerrs_coded) f->total_packet_errors++;
+ f->total_packets++;
+ }
+
+ /* decode txt bits (if used) */
+ 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,
+ rx_syms[txt_sym_index],
+ rx_amps[txt_sym_index]);
+ txt_sym_index++;
}
-
- }
-
- /* iterate state machine and update nin for next call */
-
- f->nin = ofdm_get_nin(ofdm);
- ofdm_sync_state_machine(ofdm, rx_uw);
-
- int print_full = 0; int print_truncated = 0;
- if (f->verbose && ((rx_status & FREEDV_RX_BITS) || (rx_status & FREEDV_RX_BIT_ERRORS)))
- print_full = 1;
- if ((f->verbose == 2) && !((rx_status & FREEDV_RX_BITS) || (rx_status & FREEDV_RX_BIT_ERRORS)))
- print_truncated = 1;
- if (print_full) {
- fprintf(stderr, "%3d nin: %4d st: %-6s euw: %2d %2d mf: %2d f: %5.1f pbw: %d snr: %4.1f eraw: %4d ecdd: %4d iter: %3d "
- "pcc: %4d rxst: %s\n",
- f->frames++, ofdm->nin,
- ofdm_statemode[ofdm->last_sync_state],
- ofdm->uw_errors,
- ofdm->sync_counter,
- ofdm->modem_frame,
- (double)ofdm->foff_est_hz, ofdm->phase_est_bandwidth,
- (double)f->snr_est, Nerrs_raw, Nerrs_coded, iter, parityCheckCount, rx_sync_flags_to_text[rx_status]);
- }
- if (print_truncated) {
- fprintf(stderr, "%3d nin: %4d st: %-6s euw: %2d %2d mf: %2d f: %5.1f pbw: %d "
- " rxst: %s\n",
- f->frames++, ofdm->nin,
- ofdm_statemode[ofdm->last_sync_state],
- ofdm->uw_errors,
- ofdm->sync_counter,
- ofdm->modem_frame,
- (double)ofdm->foff_est_hz, ofdm->phase_est_bandwidth,
- rx_sync_flags_to_text[rx_status]);
+ 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);
+ }
+ }
+
+ ofdm_get_demod_stats(ofdm, &f->stats, rx_syms, Nsymsperpacket);
+ f->snr_est = f->stats.snr_est;
+ } /* complete packet */
+
+ if ((ofdm->np == 1) && (ofdm->modem_frame == 0)) {
+ /* add in UW bit errors, useful in non-testframe,
+ single modem frame per packet modes */
+ 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;
}
-
- return rx_status;
+ }
+
+ /* iterate state machine and update nin for next call */
+
+ f->nin = ofdm_get_nin(ofdm);
+ ofdm_sync_state_machine(ofdm, rx_uw);
+
+ int print_full = 0;
+ int print_truncated = 0;
+ if (f->verbose &&
+ ((rx_status & FREEDV_RX_BITS) || (rx_status & FREEDV_RX_BIT_ERRORS)))
+ print_full = 1;
+ if ((f->verbose == 2) &&
+ !((rx_status & FREEDV_RX_BITS) || (rx_status & FREEDV_RX_BIT_ERRORS)))
+ print_truncated = 1;
+ if (print_full) {
+ fprintf(stderr,
+ "%3d nin: %4d st: %-6s euw: %2d %2d mf: %2d f: %5.1f pbw: %d snr: "
+ "%4.1f eraw: %4d ecdd: %4d iter: %3d "
+ "pcc: %4d rxst: %s\n",
+ f->frames++, ofdm->nin, ofdm_statemode[ofdm->last_sync_state],
+ ofdm->uw_errors, ofdm->sync_counter, ofdm->modem_frame,
+ (double)ofdm->foff_est_hz, ofdm->phase_est_bandwidth,
+ (double)f->snr_est, Nerrs_raw, Nerrs_coded, iter, parityCheckCount,
+ rx_sync_flags_to_text[rx_status]);
+ }
+ if (print_truncated) {
+ fprintf(stderr,
+ "%3d nin: %4d st: %-6s euw: %2d %2d mf: %2d f: %5.1f pbw: %d "
+ " "
+ " rxst: %s\n",
+ f->frames++, ofdm->nin, ofdm_statemode[ofdm->last_sync_state],
+ ofdm->uw_errors, ofdm->sync_counter, ofdm->modem_frame,
+ (double)ofdm->foff_est_hz, ofdm->phase_est_bandwidth,
+ rx_sync_flags_to_text[rx_status]);
+ }
+
+ return rx_status;
}