diff options
Diffstat (limited to 'unittest/tofdm.c')
| -rw-r--r-- | unittest/tofdm.c | 893 |
1 files changed, 468 insertions, 425 deletions
diff --git a/unittest/tofdm.c b/unittest/tofdm.c index 332e79e..b4d60b7 100644 --- a/unittest/tofdm.c +++ b/unittest/tofdm.c @@ -28,55 +28,52 @@ */ #include <assert.h> +#include <complex.h> +#include <getopt.h> +#include <math.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> -#include <stdint.h> #include <string.h> -#include <math.h> -#include <complex.h> -#include <getopt.h> -#include "ofdm_internal.h" +#include "HRA_112_112.h" /* generated by ldpc_fsk_lib.m:ldpc_decode() */ #include "codec2_ofdm.h" -#include "octave.h" -#include "test_bits_ofdm.h" #include "comp_prim.h" #include "mpdecode_core.h" +#include "octave.h" +#include "ofdm_internal.h" +#include "test_bits_ofdm.h" -#include "HRA_112_112.h" /* generated by ldpc_fsk_lib.m:ldpc_decode() */ - -#define NFRAMES 10 +#define NFRAMES 10 #define SAMPLE_CLOCK_OFFSET_PPM 100 -#define FOFF_HZ 0.5f +#define FOFF_HZ 0.5f -#define ASCALE (2E5f * 1.1491f / 2.0f) /* scale from shorts back to floats */ +#define ASCALE (2E5f * 1.1491f / 2.0f) /* scale from shorts back to floats */ -#define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */ +#define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */ /* QPSK constellation for symbol likelihood calculations */ static COMP S_matrix[] = { - { 1.0f, 0.0f}, - { 0.0f, 1.0f}, - { 0.0f, -1.0f}, - {-1.0f, 0.0f} -}; + {1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}}; /* constants we use a lot and don't want to have to deference all the time */ -static float ofdm_tx_centre; /* TX Center frequency */ -static float ofdm_rx_centre; /* RX Center frequency */ -static float ofdm_fs; /* Sample rate */ -static float ofdm_ts; /* Symbol cycle time */ -static float ofdm_rs; /* Symbol rate */ -static float ofdm_tcp; /* Cyclic prefix duration */ -static float ofdm_timing_mx_thresh; /* See 700D Part 4 Acquisition blog post and ofdm_dev.m routines for how this was set */ - -static int ofdm_nc; /* NS-1 data symbols between pilots */ +static float ofdm_tx_centre; /* TX Center frequency */ +static float ofdm_rx_centre; /* RX Center frequency */ +static float ofdm_fs; /* Sample rate */ +static float ofdm_ts; /* Symbol cycle time */ +static float ofdm_rs; /* Symbol rate */ +static float ofdm_tcp; /* Cyclic prefix duration */ +static float + ofdm_timing_mx_thresh; /* See 700D Part 4 Acquisition blog post and + ofdm_dev.m routines for how this was set */ + +static int ofdm_nc; /* NS-1 data symbols between pilots */ static int ofdm_ns; -static int ofdm_bps; /* Bits per symbol */ -static int ofdm_m; /* duration of each symbol in samples */ -static int ofdm_ncp; /* duration of CP in samples */ +static int ofdm_bps; /* Bits per symbol */ +static int ofdm_m; /* duration of each symbol in samples */ +static int ofdm_ncp; /* duration of CP in samples */ static int ofdm_ftwindowwidth; static int ofdm_bitsperframe; @@ -85,8 +82,9 @@ static int ofdm_samplesperframe; static int ofdm_samplespersymbol; static int ofdm_max_samplesperframe; static int ofdm_nrxbuf; -static int ofdm_ntxtbits; /* reserve bits/frame for auxiliary text information */ -static int ofdm_nuwbits; /* Unique word, used for positive indication of lock */ +static int + ofdm_ntxtbits; /* reserve bits/frame for auxiliary text information */ +static int ofdm_nuwbits; /* Unique word, used for positive indication of lock */ /*---------------------------------------------------------------------------*\ @@ -100,27 +98,29 @@ static int ofdm_nuwbits; /* Unique word, used for positive indication \*---------------------------------------------------------------------------*/ static int fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm) { - double f; - double tin = 0.0; - double step = 1.0 + sample_rate_ppm/1E6; - int t1, t2; - int tout = 0; - - while (tin < (double) (n-1)) { - t1 = (int) floor(tin); - t2 = (int) ceil(tin); - assert(t2 < n); - f = tin - (double) t1; - - out[tout].real = ((double)1.0-f)*(double)in[t1].real + f*(double)in[t2].real; - out[tout].imag = ((double)1.0-f)*(double)in[t1].imag + f*(double)in[t2].imag; - - tin += step; - tout++; - //printf("tin: %f tout: %d f: %f\n", tin, tout, f); - } - - return tout; + double f; + double tin = 0.0; + double step = 1.0 + sample_rate_ppm / 1E6; + int t1, t2; + int tout = 0; + + while (tin < (double)(n - 1)) { + t1 = (int)floor(tin); + t2 = (int)ceil(tin); + assert(t2 < n); + f = tin - (double)t1; + + out[tout].real = + ((double)1.0 - f) * (double)in[t1].real + f * (double)in[t2].real; + out[tout].imag = + ((double)1.0 - f) * (double)in[t1].imag + f * (double)in[t2].imag; + + tin += step; + tout++; + // printf("tin: %f tout: %d f: %f\n", tin, tout, f); + } + + return tout; } /*---------------------------------------------------------------------------*\ @@ -134,450 +134,493 @@ static int fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm) { \*---------------------------------------------------------------------------*/ -static void freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin) { - float temp = (TAU * foff / ofdm_fs); - COMP foff_rect = { cosf(temp), sinf(temp) }; - int i; +static void freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, + COMP *foff_phase_rect, int nin) { + float temp = (TAU * foff / ofdm_fs); + COMP foff_rect = {cosf(temp), sinf(temp)}; + int i; - for (i = 0; i < nin; i++) { - *foff_phase_rect = cmult(*foff_phase_rect, foff_rect); - rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect); - } + for (i = 0; i < nin; i++) { + *foff_phase_rect = cmult(*foff_phase_rect, foff_rect); + rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect); + } - /* normalise digital oscillator as the magnitude can drift over time */ + /* normalise digital oscillator as the magnitude can drift over time */ - float mag = cabsolute(*foff_phase_rect); - foff_phase_rect->real /= mag; - foff_phase_rect->imag /= mag; + float mag = cabsolute(*foff_phase_rect); + foff_phase_rect->real /= mag; + foff_phase_rect->imag /= mag; } -int main(int argc, char *argv[]) -{ - int opt_Nc = 0; - int ldpc_enable = 1; - struct OFDM *ofdm; - struct OFDM_CONFIG *ofdm_config; - - static struct option long_options[] = { - {"nc", required_argument, 0, 'n'}, - {"noldpc", no_argument, 0, 'l'}, - {0, 0, 0, 0} - }; - - int opt_index = 0; char c; - - while ((c = getopt_long (argc, argv, "n:l", long_options, &opt_index)) != -1) { - switch (c) { - case 'n': - opt_Nc = atoi(optarg); - fprintf(stderr, "Nc = %d\n", opt_Nc); - break; - case 'l': - ldpc_enable = 0; - fprintf(stderr, "LDPC disabled\n"); - break; - default: - fprintf(stderr,"usage: %s [Options]:\n [-l --noldpc]\n [-n --nc NumberoFCarriers]\n", argv[0]); - exit(1); - } +int main(int argc, char *argv[]) { + int opt_Nc = 0; + int ldpc_enable = 1; + struct OFDM *ofdm; + struct OFDM_CONFIG *ofdm_config; + + static struct option long_options[] = {{"nc", required_argument, 0, 'n'}, + {"noldpc", no_argument, 0, 'l'}, + {0, 0, 0, 0}}; + + int opt_index = 0; + char c; + + while ((c = getopt_long(argc, argv, "n:l", long_options, &opt_index)) != -1) { + switch (c) { + case 'n': + opt_Nc = atoi(optarg); + fprintf(stderr, "Nc = %d\n", opt_Nc); + break; + case 'l': + ldpc_enable = 0; + fprintf(stderr, "LDPC disabled\n"); + break; + default: + fprintf(stderr, + "usage: %s [Options]:\n [-l --noldpc]\n [-n --nc " + "NumberoFCarriers]\n", + argv[0]); + exit(1); } + } + + // init once to get a copy of default config params + + ofdm = ofdm_create(NULL); + assert(ofdm != NULL); + struct OFDM_CONFIG ofdm_config_default; + memcpy(&ofdm_config_default, ofdm_get_config_param(ofdm), + sizeof(struct OFDM_CONFIG)); + ofdm_destroy(ofdm); + + // now do a little customisation on default config, and re-create modem + // instance + + if (opt_Nc) ofdm_config_default.nc = opt_Nc; + // printf("ofdm_create() 2\n"); + ofdm = ofdm_create(&ofdm_config_default); + assert(ofdm != NULL); + ofdm_config = ofdm_get_config_param(ofdm); + ofdm_set_tx_bpf(ofdm, false); + + // same levels as Octave sim + ofdm->amp_scale = 1.0; + + // make local copies for convenience + ofdm_tx_centre = ofdm_config->tx_centre; + ofdm_rx_centre = ofdm_config->rx_centre; + ofdm_fs = ofdm_config->fs; + ofdm_ts = ofdm_config->ts; + ofdm_rs = ofdm_config->rs; + ofdm_tcp = ofdm_config->tcp; + ofdm_timing_mx_thresh = ofdm_config->timing_mx_thresh; + ofdm_nc = ofdm_config->nc; + ofdm_ns = ofdm_config->ns; + ofdm_bps = ofdm_config->bps; + ofdm_m = (int)(ofdm_config->fs / ofdm_config->rs); + ofdm_ncp = (int)(ofdm_config->tcp * ofdm_config->fs); + ofdm_ftwindowwidth = ofdm_config->ftwindowwidth; + ofdm_bitsperframe = ofdm_get_bits_per_frame(ofdm); + ofdm_rowsperframe = ofdm_bitsperframe / (ofdm_config->nc * ofdm_config->bps); + ofdm_samplesperframe = ofdm_get_samples_per_frame(ofdm); + ofdm_samplespersymbol = (ofdm->m + ofdm->ncp); + ofdm_max_samplesperframe = ofdm_get_max_samples_per_frame(ofdm); + ofdm_nrxbuf = ofdm->nrxbuf; + ofdm_ntxtbits = ofdm_config->txtbits; + ofdm_nuwbits = ofdm_config->nuwbits; + + int tx_bits[ofdm_samplesperframe]; + COMP tx[ofdm_samplesperframe]; /* one frame of tx samples */ + + int rx_bits[ofdm_bitsperframe]; /* one frame of rx bits */ + printf("Nc = %d ofdm_bitsperframe: %d\n", ofdm_nc, ofdm_bitsperframe); + + /* log arrays */ + + int tx_bits_log[ofdm_bitsperframe * NFRAMES]; + COMP tx_log[ofdm_samplesperframe * NFRAMES]; + COMP rx_log[ofdm_samplesperframe * NFRAMES]; + COMP rxbuf_in_log[ofdm_max_samplesperframe * NFRAMES]; + COMP rxbuf_log[ofdm_nrxbuf * NFRAMES]; + COMP rx_sym_log[(ofdm_ns + 3) * NFRAMES][ofdm_nc + 2]; + float phase_est_pilot_log[ofdm_rowsperframe * NFRAMES][ofdm_nc]; + COMP rx_np_log[ofdm_rowsperframe * ofdm_nc * NFRAMES]; + float rx_amp_log[ofdm_rowsperframe * ofdm_nc * NFRAMES]; + float foff_hz_log[NFRAMES]; + int rx_bits_log[ofdm_bitsperframe * NFRAMES]; + int timing_est_log[NFRAMES]; + int timing_valid_log[NFRAMES]; + float timing_mx_log[NFRAMES]; + float coarse_foff_est_hz_log[NFRAMES]; + int sample_point_log[NFRAMES]; + float symbol_likelihood_log[(CODED_BITSPERFRAME / ofdm_bps) * + (1 << ofdm_bps) * NFRAMES]; + float bit_likelihood_log[CODED_BITSPERFRAME * NFRAMES]; + int detected_data_log[CODED_BITSPERFRAME * NFRAMES]; + float mean_amp_log[NFRAMES]; + float snr_log[NFRAMES]; + + FILE *fout; + int f, i, j; + + /* set up LDPC code */ + + struct LDPC ldpc; + + ldpc.max_iter = HRA_112_112_MAX_ITER; + ldpc.dec_type = 0; + ldpc.q_scale_factor = 1; + ldpc.r_scale_factor = 1; + ldpc.CodeLength = HRA_112_112_CODELENGTH; + ldpc.NumberParityBits = HRA_112_112_NUMBERPARITYBITS; + ldpc.NumberRowsHcols = HRA_112_112_NUMBERROWSHCOLS; + ldpc.max_row_weight = HRA_112_112_MAX_ROW_WEIGHT; + ldpc.max_col_weight = HRA_112_112_MAX_COL_WEIGHT; + ldpc.H_rows = (uint16_t *)HRA_112_112_H_rows; + ldpc.H_cols = (uint16_t *)HRA_112_112_H_cols; + + /* Main Loop + * ---------------------------------------------------------------------*/ + + for (f = 0; f < NFRAMES; f++) { + /* --------------------------------------------------------*\ + Mod + \*---------------------------------------------------------*/ - // init once to get a copy of default config params - - ofdm = ofdm_create(NULL); - assert(ofdm != NULL); - struct OFDM_CONFIG ofdm_config_default; - memcpy(&ofdm_config_default, ofdm_get_config_param(ofdm), sizeof(struct OFDM_CONFIG)); - ofdm_destroy(ofdm); - - // now do a little customisation on default config, and re-create modem instance - - if (opt_Nc) - ofdm_config_default.nc = opt_Nc; - //printf("ofdm_create() 2\n"); - ofdm = ofdm_create(&ofdm_config_default); - assert(ofdm != NULL); - ofdm_config = ofdm_get_config_param(ofdm); - ofdm_set_tx_bpf(ofdm, false); - - // same levels as Octave sim - ofdm->amp_scale = 1.0; - - // make local copies for convenience - ofdm_tx_centre = ofdm_config->tx_centre; - ofdm_rx_centre = ofdm_config->rx_centre; - ofdm_fs = ofdm_config->fs; - ofdm_ts = ofdm_config->ts; - ofdm_rs = ofdm_config->rs; - ofdm_tcp = ofdm_config->tcp; - ofdm_timing_mx_thresh = ofdm_config->timing_mx_thresh; - ofdm_nc = ofdm_config->nc; - ofdm_ns = ofdm_config->ns; - ofdm_bps = ofdm_config->bps; - ofdm_m = (int) (ofdm_config->fs / ofdm_config->rs); - ofdm_ncp = (int) (ofdm_config->tcp * ofdm_config->fs); - ofdm_ftwindowwidth = ofdm_config->ftwindowwidth; - ofdm_bitsperframe = ofdm_get_bits_per_frame(ofdm); - ofdm_rowsperframe = ofdm_bitsperframe / (ofdm_config->nc * ofdm_config->bps); - ofdm_samplesperframe = ofdm_get_samples_per_frame(ofdm); - ofdm_samplespersymbol = (ofdm->m + ofdm->ncp); - ofdm_max_samplesperframe = ofdm_get_max_samples_per_frame(ofdm); - ofdm_nrxbuf = ofdm->nrxbuf; - ofdm_ntxtbits = ofdm_config->txtbits; - ofdm_nuwbits = ofdm_config->nuwbits; - - int tx_bits[ofdm_samplesperframe]; - COMP tx[ofdm_samplesperframe]; /* one frame of tx samples */ - - int rx_bits[ofdm_bitsperframe]; /* one frame of rx bits */ - printf("Nc = %d ofdm_bitsperframe: %d\n", ofdm_nc, ofdm_bitsperframe); - - /* log arrays */ - - int tx_bits_log[ofdm_bitsperframe*NFRAMES]; - COMP tx_log[ofdm_samplesperframe*NFRAMES]; - COMP rx_log[ofdm_samplesperframe*NFRAMES]; - COMP rxbuf_in_log[ofdm_max_samplesperframe*NFRAMES]; - COMP rxbuf_log[ofdm_nrxbuf*NFRAMES]; - COMP rx_sym_log[(ofdm_ns + 3)*NFRAMES][ofdm_nc + 2]; - float phase_est_pilot_log[ofdm_rowsperframe*NFRAMES][ofdm_nc]; - COMP rx_np_log[ofdm_rowsperframe*ofdm_nc*NFRAMES]; - float rx_amp_log[ofdm_rowsperframe*ofdm_nc*NFRAMES]; - float foff_hz_log[NFRAMES]; - int rx_bits_log[ofdm_bitsperframe*NFRAMES]; - int timing_est_log[NFRAMES]; - int timing_valid_log[NFRAMES]; - float timing_mx_log[NFRAMES]; - float coarse_foff_est_hz_log[NFRAMES]; - int sample_point_log[NFRAMES]; - float symbol_likelihood_log[ (CODED_BITSPERFRAME/ofdm_bps) * (1<<ofdm_bps) * NFRAMES]; - float bit_likelihood_log[CODED_BITSPERFRAME * NFRAMES]; - int detected_data_log[CODED_BITSPERFRAME * NFRAMES]; - float mean_amp_log[NFRAMES]; - float snr_log[NFRAMES]; - - FILE *fout; - int f,i,j; - - /* set up LDPC code */ - - struct LDPC ldpc; - - ldpc.max_iter = HRA_112_112_MAX_ITER; - ldpc.dec_type = 0; - ldpc.q_scale_factor = 1; - ldpc.r_scale_factor = 1; - ldpc.CodeLength = HRA_112_112_CODELENGTH; - ldpc.NumberParityBits = HRA_112_112_NUMBERPARITYBITS; - ldpc.NumberRowsHcols = HRA_112_112_NUMBERROWSHCOLS; - ldpc.max_row_weight = HRA_112_112_MAX_ROW_WEIGHT; - ldpc.max_col_weight = HRA_112_112_MAX_COL_WEIGHT; - ldpc.H_rows = (uint16_t *)HRA_112_112_H_rows; - ldpc.H_cols = (uint16_t *)HRA_112_112_H_cols; - - /* Main Loop ---------------------------------------------------------------------*/ - - for(f=0; f<NFRAMES; f++) { - - /* --------------------------------------------------------*\ - Mod - \*---------------------------------------------------------*/ - - /* See CML startup code in tofdm.m */ - - for(i=0; i<ofdm_nuwbits; i++) { - tx_bits[i] = ofdm->tx_uw[i]; - } - for(i=ofdm_nuwbits; i<ofdm_nuwbits+ofdm_ntxtbits; i++) { - tx_bits[i] = 0; - } + /* See CML startup code in tofdm.m */ - if (ldpc_enable) { - unsigned char ibits[HRA_112_112_NUMBERROWSHCOLS]; - unsigned char pbits[HRA_112_112_NUMBERPARITYBITS]; - - assert(HRA_112_112_NUMBERROWSHCOLS == ldpc.CodeLength/2); - for(i=0; i<ldpc.CodeLength/2; i++) { - ibits[i] = payload_data_bits[i]; - } - encode(&ldpc, ibits, pbits); - for(j=0, i=ofdm_nuwbits+ofdm_ntxtbits; j<ldpc.CodeLength/2; i++,j++) { - tx_bits[i] = ibits[j]; - } - for(j=0; j<ldpc.CodeLength/2; i++,j++) { - tx_bits[i] = pbits[j]; - } - assert(i == ofdm_bitsperframe); - } else { - int Npayloadbits = ofdm_bitsperframe - (ofdm_nuwbits + ofdm_ntxtbits); - uint16_t r[Npayloadbits]; - uint8_t payload_bits[Npayloadbits]; - - ofdm_rand(r, Npayloadbits); - for (i = 0; i < Npayloadbits; i++) - payload_bits[i] = r[i] > 16384; - uint8_t txt_bits[ofdm_ntxtbits]; - for (i = 0; i < ofdm_ntxtbits; i++) - txt_bits[i] = 0; - - uint8_t tx_bits_char[ofdm_bitsperframe]; - ofdm_assemble_qpsk_modem_packet(ofdm, tx_bits_char, payload_bits, txt_bits); - for(i=0; i<ofdm_bitsperframe; i++) - tx_bits[i] = tx_bits_char[i]; - } + for (i = 0; i < ofdm_nuwbits; i++) { + tx_bits[i] = ofdm->tx_uw[i]; + } + for (i = ofdm_nuwbits; i < ofdm_nuwbits + ofdm_ntxtbits; i++) { + tx_bits[i] = 0; + } - ofdm_mod(ofdm, (COMP*)tx, tx_bits); + if (ldpc_enable) { + unsigned char ibits[HRA_112_112_NUMBERROWSHCOLS]; + unsigned char pbits[HRA_112_112_NUMBERPARITYBITS]; + + assert(HRA_112_112_NUMBERROWSHCOLS == ldpc.CodeLength / 2); + for (i = 0; i < ldpc.CodeLength / 2; i++) { + ibits[i] = payload_data_bits[i]; + } + encode(&ldpc, ibits, pbits); + for (j = 0, i = ofdm_nuwbits + ofdm_ntxtbits; j < ldpc.CodeLength / 2; + i++, j++) { + tx_bits[i] = ibits[j]; + } + for (j = 0; j < ldpc.CodeLength / 2; i++, j++) { + tx_bits[i] = pbits[j]; + } + assert(i == ofdm_bitsperframe); + } else { + int Npayloadbits = ofdm_bitsperframe - (ofdm_nuwbits + ofdm_ntxtbits); + uint16_t r[Npayloadbits]; + uint8_t payload_bits[Npayloadbits]; + + ofdm_rand(r, Npayloadbits); + for (i = 0; i < Npayloadbits; i++) payload_bits[i] = r[i] > 16384; + uint8_t txt_bits[ofdm_ntxtbits]; + for (i = 0; i < ofdm_ntxtbits; i++) txt_bits[i] = 0; + + uint8_t tx_bits_char[ofdm_bitsperframe]; + ofdm_assemble_qpsk_modem_packet(ofdm, tx_bits_char, payload_bits, + txt_bits); + for (i = 0; i < ofdm_bitsperframe; i++) tx_bits[i] = tx_bits_char[i]; + } - /* tx vector logging */ + ofdm_mod(ofdm, (COMP *)tx, tx_bits); - memcpy(&tx_bits_log[ofdm_bitsperframe*f], tx_bits, sizeof(int)*ofdm_bitsperframe); - memcpy(&tx_log[ofdm_samplesperframe*f], tx, sizeof(COMP)*ofdm_samplesperframe); - } + /* tx vector logging */ - /* --------------------------------------------------------*\ - Channel - \*---------------------------------------------------------*/ + memcpy(&tx_bits_log[ofdm_bitsperframe * f], tx_bits, + sizeof(int) * ofdm_bitsperframe); + memcpy(&tx_log[ofdm_samplesperframe * f], tx, + sizeof(COMP) * ofdm_samplesperframe); + } - fs_offset(rx_log, tx_log, ofdm_samplesperframe*NFRAMES, SAMPLE_CLOCK_OFFSET_PPM); + /* --------------------------------------------------------*\ + Channel + \*---------------------------------------------------------*/ - COMP foff_phase_rect = {1.0f, 0.0f}; + fs_offset(rx_log, tx_log, ofdm_samplesperframe * NFRAMES, + SAMPLE_CLOCK_OFFSET_PPM); - freq_shift(rx_log, rx_log, FOFF_HZ, &foff_phase_rect, ofdm_samplesperframe * NFRAMES); + COMP foff_phase_rect = {1.0f, 0.0f}; - /* --------------------------------------------------------*\ - Demod - \*---------------------------------------------------------*/ + freq_shift(rx_log, rx_log, FOFF_HZ, &foff_phase_rect, + ofdm_samplesperframe * NFRAMES); - /* Init/pre-load rx with ideal timing so we can test with timing estimation disabled */ + /* --------------------------------------------------------*\ + Demod + \*---------------------------------------------------------*/ - int Nsam = ofdm_samplesperframe*NFRAMES; - int prx = 0; - int nin = ofdm_samplesperframe + 2*ofdm_samplespersymbol; + /* Init/pre-load rx with ideal timing so we can test with timing estimation + * disabled */ - int lnew; - COMP rxbuf_in[ofdm_max_samplesperframe]; + int Nsam = ofdm_samplesperframe * NFRAMES; + int prx = 0; + int nin = ofdm_samplesperframe + 2 * ofdm_samplespersymbol; + + int lnew; + COMP rxbuf_in[ofdm_max_samplesperframe]; #define FRONT_LOAD #ifdef FRONT_LOAD - for (i=0; i<nin; i++,prx++) { - ofdm->rxbuf[ofdm_nrxbuf-nin+i] = rx_log[prx].real + rx_log[prx].imag * I; - } + for (i = 0; i < nin; i++, prx++) { + ofdm->rxbuf[ofdm_nrxbuf - nin + i] = + rx_log[prx].real + rx_log[prx].imag * I; + } #endif - int nin_tot = 0; + int nin_tot = 0; - /* disable estimators for initial testing */ + /* disable estimators for initial testing */ - ofdm_set_verbose(ofdm, false); - ofdm_set_timing_enable(ofdm, true); - ofdm_set_foff_est_enable(ofdm, true); - ofdm_set_phase_est_enable(ofdm, true); + ofdm_set_verbose(ofdm, false); + ofdm_set_timing_enable(ofdm, true); + ofdm_set_foff_est_enable(ofdm, true); + ofdm_set_phase_est_enable(ofdm, true); //#define TESTING_FILE #ifdef TESTING_FILE - FILE *fin=fopen("~/codec2-dev/octave/ofdm_test.raw", "rb"); - assert(fin != NULL); - int Nbitsperframe = ofdm_bitsperframe; - int Nmaxsamperframe = ofdm_max_samplesperframe; - short rx_scaled[Nmaxsamperframe]; + FILE *fin = fopen("~/codec2-dev/octave/ofdm_test.raw", "rb"); + assert(fin != NULL); + int Nbitsperframe = ofdm_bitsperframe; + int Nmaxsamperframe = ofdm_max_samplesperframe; + short rx_scaled[Nmaxsamperframe]; #endif - /* start this with something sensible otherwise LDPC decode fails in tofdm.m */ + /* start this with something sensible otherwise LDPC decode fails in tofdm.m + */ - ofdm->mean_amp = 1.0; + ofdm->mean_amp = 1.0; - for(f=0; f<NFRAMES; f++) { - /* For initial testing, timing est is off, so nin is always - fixed. TODO: we need a constant for rxbuf_in[] size that - is the maximum possible nin */ + for (f = 0; f < NFRAMES; f++) { + /* For initial testing, timing est is off, so nin is always + fixed. TODO: we need a constant for rxbuf_in[] size that + is the maximum possible nin */ - nin = ofdm_get_nin(ofdm); - assert(nin <= ofdm_max_samplesperframe); + nin = ofdm_get_nin(ofdm); + assert(nin <= ofdm_max_samplesperframe); - /* Insert samples at end of buffer, set to zero if no samples - available to disable phase estimation on future pilots on - last frame of simulation. */ + /* Insert samples at end of buffer, set to zero if no samples + available to disable phase estimation on future pilots on + last frame of simulation. */ - if ((Nsam-prx) < nin) { - lnew = Nsam-prx; - } else { - lnew = nin; - } - //printf("nin: %d prx: %d lnew: %d\n", nin, prx, lnew); - for(i=0; i<nin; i++) { - rxbuf_in[i].real = 0.0; - rxbuf_in[i].imag = 0.0; - } + if ((Nsam - prx) < nin) { + lnew = Nsam - prx; + } else { + lnew = nin; + } + // printf("nin: %d prx: %d lnew: %d\n", nin, prx, lnew); + for (i = 0; i < nin; i++) { + rxbuf_in[i].real = 0.0; + rxbuf_in[i].imag = 0.0; + } - if (lnew) { - for(i=0; i<lnew; i++, prx++) { - rxbuf_in[i] = rx_log[prx]; - } - } - assert(prx <= ofdm_max_samplesperframe*NFRAMES); + if (lnew) { + for (i = 0; i < lnew; i++, prx++) { + rxbuf_in[i] = rx_log[prx]; + } + } + assert(prx <= ofdm_max_samplesperframe * NFRAMES); #ifdef TESTING_FILE - fread(rx_scaled, sizeof(short), nin, fin); + fread(rx_scaled, sizeof(short), nin, fin); - for(i=0; i<nin; i++) { - rxbuf_in[i].real = (float)rx_scaled[i]/ASCALE; - rxbuf_in[i].imag = 0.0; - } + for (i = 0; i < nin; i++) { + rxbuf_in[i].real = (float)rx_scaled[i] / ASCALE; + rxbuf_in[i].imag = 0.0; + } #endif - /* uncoded OFDM modem ---------------------------------------*/ + /* uncoded OFDM modem ---------------------------------------*/ - ofdm_demod(ofdm, rx_bits, rxbuf_in); + ofdm_demod(ofdm, rx_bits, rxbuf_in); #ifdef TESTING_FILE - int Nerrs = 0; - for(i=0; i<Nbitsperframe; i++) { - if (test_bits_ofdm[i] != rx_bits[i]) { - Nerrs++; - } - } - printf("f: %d Nerr: %d\n", f, Nerrs); + int Nerrs = 0; + for (i = 0; i < Nbitsperframe; i++) { + if (test_bits_ofdm[i] != rx_bits[i]) { + Nerrs++; + } + } + printf("f: %d Nerr: %d\n", f, Nerrs); #endif - float symbol_likelihood[ (CODED_BITSPERFRAME/ofdm_bps) * (1<<ofdm_bps) ]; - float bit_likelihood[CODED_BITSPERFRAME]; - uint8_t out_char[CODED_BITSPERFRAME]; + float symbol_likelihood[(CODED_BITSPERFRAME / ofdm_bps) * (1 << ofdm_bps)]; + float bit_likelihood[CODED_BITSPERFRAME]; + uint8_t out_char[CODED_BITSPERFRAME]; - if (ldpc_enable) { - /* LDPC functions --------------------------------------*/ + if (ldpc_enable) { + /* LDPC functions --------------------------------------*/ - float EsNo = 10; + float EsNo = 10; - /* first few symbols are used for UW and txt bits, find start of (224,112) LDPC codeword */ + /* first few symbols are used for UW and txt bits, find start of (224,112) + * LDPC codeword */ - assert((ofdm_nuwbits+ofdm_ntxtbits+CODED_BITSPERFRAME) == ofdm_bitsperframe); + assert((ofdm_nuwbits + ofdm_ntxtbits + CODED_BITSPERFRAME) == + ofdm_bitsperframe); - COMP ldpc_codeword_symbols[(CODED_BITSPERFRAME/ofdm_bps)]; + COMP ldpc_codeword_symbols[(CODED_BITSPERFRAME / ofdm_bps)]; - for(i=0, j=(ofdm_nuwbits+ofdm_ntxtbits)/ofdm_bps; i<(CODED_BITSPERFRAME/ofdm_bps); i++,j++) { - ldpc_codeword_symbols[i].real = crealf(ofdm->rx_np[j]); - ldpc_codeword_symbols[i].imag = cimagf(ofdm->rx_np[j]); - } + for (i = 0, j = (ofdm_nuwbits + ofdm_ntxtbits) / ofdm_bps; + i < (CODED_BITSPERFRAME / ofdm_bps); i++, j++) { + ldpc_codeword_symbols[i].real = crealf(ofdm->rx_np[j]); + ldpc_codeword_symbols[i].imag = cimagf(ofdm->rx_np[j]); + } - float *ldpc_codeword_symbol_amps = &ofdm->rx_amp[(ofdm_nuwbits+ofdm_ntxtbits)/ofdm_bps]; + float *ldpc_codeword_symbol_amps = + &ofdm->rx_amp[(ofdm_nuwbits + ofdm_ntxtbits) / ofdm_bps]; - Demod2D(symbol_likelihood, ldpc_codeword_symbols, S_matrix, EsNo, ldpc_codeword_symbol_amps, ofdm->mean_amp, CODED_BITSPERFRAME/ofdm_bps); - Somap(bit_likelihood, symbol_likelihood, 1<<ofdm_bps, ofdm_bps, CODED_BITSPERFRAME/ofdm_bps); + Demod2D(symbol_likelihood, ldpc_codeword_symbols, S_matrix, EsNo, + ldpc_codeword_symbol_amps, ofdm->mean_amp, + CODED_BITSPERFRAME / ofdm_bps); + Somap(bit_likelihood, symbol_likelihood, 1 << ofdm_bps, ofdm_bps, + CODED_BITSPERFRAME / ofdm_bps); - float llr[CODED_BITSPERFRAME]; - int parityCheckCount; + float llr[CODED_BITSPERFRAME]; + int parityCheckCount; + // fprintf(stderr, "\n"); + for (i = 0; i < CODED_BITSPERFRAME; i++) { + llr[i] = -bit_likelihood[i]; + // fprintf(stderr, "%f ", llr[i]); + } - // fprintf(stderr, "\n"); - for(i=0; i<CODED_BITSPERFRAME; i++) { - llr[i] = -bit_likelihood[i]; - // fprintf(stderr, "%f ", llr[i]); - } + // fprintf(stderr, "\n"); - //fprintf(stderr, "\n"); - - run_ldpc_decoder(&ldpc, out_char, llr, &parityCheckCount); - /* - fprintf(stderr, "iter: %d parityCheckCount: %d\n", iter, parityCheckCount); - for(i=0; i<CODED_BITSPERFRAME; i++) { - fprintf(stderr, "%d ", out_char[i]); - } - */ + run_ldpc_decoder(&ldpc, out_char, llr, &parityCheckCount); + /* + fprintf(stderr, "iter: %d parityCheckCount: %d\n", iter, + parityCheckCount); for(i=0; i<CODED_BITSPERFRAME; i++) { fprintf(stderr, + "%d ", out_char[i]); } + */ + } - /* rx vector logging -----------------------------------*/ - - assert(nin_tot < ofdm_samplesperframe*NFRAMES); - memcpy(&rxbuf_in_log[nin_tot], rxbuf_in, sizeof(COMP)*nin); - nin_tot += nin; + /* rx vector logging -----------------------------------*/ - for(i=0; i<ofdm_nrxbuf; i++) { - rxbuf_log[ofdm_nrxbuf*f+i].real = crealf(ofdm->rxbuf[i]); - rxbuf_log[ofdm_nrxbuf*f+i].imag = cimagf(ofdm->rxbuf[i]); - } + assert(nin_tot < ofdm_samplesperframe * NFRAMES); + memcpy(&rxbuf_in_log[nin_tot], rxbuf_in, sizeof(COMP) * nin); + nin_tot += nin; - for (i = 0; i < (ofdm_ns + 3); i++) { - for (j = 0; j < (ofdm_nc + 2); j++) { - rx_sym_log[(ofdm_ns + 3)*f+i][j].real = crealf(ofdm->rx_sym[i][j]); - rx_sym_log[(ofdm_ns + 3)*f+i][j].imag = cimagf(ofdm->rx_sym[i][j]); - } - } + for (i = 0; i < ofdm_nrxbuf; i++) { + rxbuf_log[ofdm_nrxbuf * f + i].real = crealf(ofdm->rxbuf[i]); + rxbuf_log[ofdm_nrxbuf * f + i].imag = cimagf(ofdm->rxbuf[i]); + } - /* note corrected phase (rx no phase) is one big linear array for frame */ + for (i = 0; i < (ofdm_ns + 3); i++) { + for (j = 0; j < (ofdm_nc + 2); j++) { + rx_sym_log[(ofdm_ns + 3) * f + i][j].real = crealf(ofdm->rx_sym[i][j]); + rx_sym_log[(ofdm_ns + 3) * f + i][j].imag = cimagf(ofdm->rx_sym[i][j]); + } + } - for (i = 0; i < ofdm_rowsperframe*ofdm_nc; i++) { - rx_np_log[ofdm_rowsperframe*ofdm_nc*f + i].real = crealf(ofdm->rx_np[i]); - rx_np_log[ofdm_rowsperframe*ofdm_nc*f + i].imag = cimagf(ofdm->rx_np[i]); - } + /* note corrected phase (rx no phase) is one big linear array for frame */ - /* note phase/amp ests the same for each col, but check them all anyway */ + for (i = 0; i < ofdm_rowsperframe * ofdm_nc; i++) { + rx_np_log[ofdm_rowsperframe * ofdm_nc * f + i].real = + crealf(ofdm->rx_np[i]); + rx_np_log[ofdm_rowsperframe * ofdm_nc * f + i].imag = + cimagf(ofdm->rx_np[i]); + } - for (i = 0; i < ofdm_rowsperframe; i++) { - for (j = 0; j < ofdm_nc; j++) { - phase_est_pilot_log[ofdm_rowsperframe*f+i][j] = ofdm->aphase_est_pilot_log[ofdm_nc*i+j]; - rx_amp_log[ofdm_rowsperframe*ofdm_nc*f+ofdm_nc*i+j] = ofdm->rx_amp[ofdm_nc*i+j]; - } - } + /* note phase/amp ests the same for each col, but check them all anyway */ - foff_hz_log[f] = ofdm->foff_est_hz; - timing_est_log[f] = ofdm->timing_est + 1; /* offset by 1 to match Octave */ - timing_valid_log[f] = ofdm->timing_valid; - timing_mx_log[f] = ofdm->timing_mx; - coarse_foff_est_hz_log[f] = ofdm->coarse_foff_est_hz; - sample_point_log[f] = ofdm->sample_point + 1; /* offset by 1 to match Octave */ - float EsNodB = ofdm_esno_est_calc(ofdm->rx_np, ofdm_rowsperframe*ofdm_nc); - snr_log[f] = ofdm_snr_from_esno(ofdm, EsNodB); - mean_amp_log[f] = ofdm->mean_amp; - - memcpy(&rx_bits_log[ofdm_bitsperframe*f], rx_bits, sizeof(rx_bits)); - - if (ldpc_enable) { - for(i=0; i<(CODED_BITSPERFRAME/ofdm_bps) * (1<<ofdm_bps); i++) { - symbol_likelihood_log[ (CODED_BITSPERFRAME/ofdm_bps) * (1<<ofdm_bps) * f + i] = symbol_likelihood[i]; - } - for(i=0; i<CODED_BITSPERFRAME; i++) { - bit_likelihood_log[CODED_BITSPERFRAME*f + i] = bit_likelihood[i]; - detected_data_log[CODED_BITSPERFRAME*f + i] = out_char[i]; - } - } + for (i = 0; i < ofdm_rowsperframe; i++) { + for (j = 0; j < ofdm_nc; j++) { + phase_est_pilot_log[ofdm_rowsperframe * f + i][j] = + ofdm->aphase_est_pilot_log[ofdm_nc * i + j]; + rx_amp_log[ofdm_rowsperframe * ofdm_nc * f + ofdm_nc * i + j] = + ofdm->rx_amp[ofdm_nc * i + j]; + } } - /*---------------------------------------------------------*\ - Dump logs to Octave file for evaluation - by tofdm.m Octave script - \*---------------------------------------------------------*/ - - fout = fopen("tofdm_out.txt","wt"); - assert(fout != NULL); - fprintf(fout, "# Created by tofdm.c\n"); - octave_save_complex(fout, "pilot_samples_c", (COMP*)ofdm->pilot_samples, 1, ofdm_samplespersymbol, ofdm_samplespersymbol); - octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, ofdm_bitsperframe*NFRAMES); - octave_save_complex(fout, "tx_log_c", (COMP*)tx_log, 1, ofdm_samplesperframe*NFRAMES, ofdm_samplesperframe*NFRAMES); - octave_save_complex(fout, "rx_log_c", (COMP*)rx_log, 1, ofdm_samplesperframe*NFRAMES, ofdm_samplesperframe*NFRAMES); - octave_save_complex(fout, "rxbuf_in_log_c", (COMP*)rxbuf_in_log, 1, nin_tot, nin_tot); - octave_save_complex(fout, "rxbuf_log_c", (COMP*)rxbuf_log, 1, ofdm_nrxbuf*NFRAMES, ofdm_nrxbuf*NFRAMES); - octave_save_complex(fout, "rx_sym_log_c", (COMP*)rx_sym_log, (ofdm_ns + 3)*NFRAMES, ofdm_nc + 2, ofdm_nc + 2); - octave_save_float(fout, "phase_est_pilot_log_c", (float*)phase_est_pilot_log, ofdm_rowsperframe*NFRAMES, ofdm_nc, ofdm_nc); - octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, 1, ofdm_rowsperframe*ofdm_nc*NFRAMES, ofdm_rowsperframe*ofdm_nc*NFRAMES); - octave_save_float(fout, "foff_hz_log_c", foff_hz_log, NFRAMES, 1, 1); - octave_save_int(fout, "timing_est_log_c", timing_est_log, NFRAMES, 1); - octave_save_int(fout, "timing_valid_log_c", timing_valid_log, NFRAMES, 1); - octave_save_float(fout, "timing_mx_log_c", timing_mx_log, NFRAMES, 1, 1); - octave_save_float(fout, "coarse_foff_est_hz_log_c", coarse_foff_est_hz_log, NFRAMES, 1, 1); - octave_save_int(fout, "sample_point_log_c", sample_point_log, NFRAMES, 1); - octave_save_complex(fout, "rx_np_log_c", (COMP*)rx_np_log, 1, ofdm_rowsperframe*ofdm_nc*NFRAMES, ofdm_rowsperframe*ofdm_nc*NFRAMES); - octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, ofdm_bitsperframe*NFRAMES); - octave_save_float(fout, "symbol_likelihood_log_c", symbol_likelihood_log, (CODED_BITSPERFRAME/ofdm_bps) * (1<<ofdm_bps) * NFRAMES, 1, 1); - octave_save_float(fout, "bit_likelihood_log_c", bit_likelihood_log, CODED_BITSPERFRAME * NFRAMES, 1, 1); - octave_save_int(fout, "detected_data_log_c", detected_data_log, 1, CODED_BITSPERFRAME*NFRAMES); - octave_save_float(fout, "snr_log_c", snr_log, NFRAMES, 1, 1); - octave_save_float(fout, "mean_amp_log_c", mean_amp_log, NFRAMES, 1, 1); - fclose(fout); + foff_hz_log[f] = ofdm->foff_est_hz; + timing_est_log[f] = ofdm->timing_est + 1; /* offset by 1 to match Octave */ + timing_valid_log[f] = ofdm->timing_valid; + timing_mx_log[f] = ofdm->timing_mx; + coarse_foff_est_hz_log[f] = ofdm->coarse_foff_est_hz; + sample_point_log[f] = + ofdm->sample_point + 1; /* offset by 1 to match Octave */ + float EsNodB = ofdm_esno_est_calc(ofdm->rx_np, ofdm_rowsperframe * ofdm_nc); + snr_log[f] = ofdm_snr_from_esno(ofdm, EsNodB); + mean_amp_log[f] = ofdm->mean_amp; + + memcpy(&rx_bits_log[ofdm_bitsperframe * f], rx_bits, sizeof(rx_bits)); + + if (ldpc_enable) { + for (i = 0; i < (CODED_BITSPERFRAME / ofdm_bps) * (1 << ofdm_bps); i++) { + symbol_likelihood_log[(CODED_BITSPERFRAME / ofdm_bps) * + (1 << ofdm_bps) * f + + i] = symbol_likelihood[i]; + } + for (i = 0; i < CODED_BITSPERFRAME; i++) { + bit_likelihood_log[CODED_BITSPERFRAME * f + i] = bit_likelihood[i]; + detected_data_log[CODED_BITSPERFRAME * f + i] = out_char[i]; + } + } + } + + /*---------------------------------------------------------*\ + Dump logs to Octave file for evaluation + by tofdm.m Octave script + \*---------------------------------------------------------*/ + + fout = fopen("tofdm_out.txt", "wt"); + assert(fout != NULL); + fprintf(fout, "# Created by tofdm.c\n"); + octave_save_complex(fout, "pilot_samples_c", (COMP *)ofdm->pilot_samples, 1, + ofdm_samplespersymbol, ofdm_samplespersymbol); + octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, + ofdm_bitsperframe * NFRAMES); + octave_save_complex(fout, "tx_log_c", (COMP *)tx_log, 1, + ofdm_samplesperframe * NFRAMES, + ofdm_samplesperframe * NFRAMES); + octave_save_complex(fout, "rx_log_c", (COMP *)rx_log, 1, + ofdm_samplesperframe * NFRAMES, + ofdm_samplesperframe * NFRAMES); + octave_save_complex(fout, "rxbuf_in_log_c", (COMP *)rxbuf_in_log, 1, nin_tot, + nin_tot); + octave_save_complex(fout, "rxbuf_log_c", (COMP *)rxbuf_log, 1, + ofdm_nrxbuf * NFRAMES, ofdm_nrxbuf * NFRAMES); + octave_save_complex(fout, "rx_sym_log_c", (COMP *)rx_sym_log, + (ofdm_ns + 3) * NFRAMES, ofdm_nc + 2, ofdm_nc + 2); + octave_save_float(fout, "phase_est_pilot_log_c", (float *)phase_est_pilot_log, + ofdm_rowsperframe * NFRAMES, ofdm_nc, ofdm_nc); + octave_save_float(fout, "rx_amp_log_c", (float *)rx_amp_log, 1, + ofdm_rowsperframe * ofdm_nc * NFRAMES, + ofdm_rowsperframe * ofdm_nc * NFRAMES); + octave_save_float(fout, "foff_hz_log_c", foff_hz_log, NFRAMES, 1, 1); + octave_save_int(fout, "timing_est_log_c", timing_est_log, NFRAMES, 1); + octave_save_int(fout, "timing_valid_log_c", timing_valid_log, NFRAMES, 1); + octave_save_float(fout, "timing_mx_log_c", timing_mx_log, NFRAMES, 1, 1); + octave_save_float(fout, "coarse_foff_est_hz_log_c", coarse_foff_est_hz_log, + NFRAMES, 1, 1); + octave_save_int(fout, "sample_point_log_c", sample_point_log, NFRAMES, 1); + octave_save_complex(fout, "rx_np_log_c", (COMP *)rx_np_log, 1, + ofdm_rowsperframe * ofdm_nc * NFRAMES, + ofdm_rowsperframe * ofdm_nc * NFRAMES); + octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, + ofdm_bitsperframe * NFRAMES); + octave_save_float(fout, "symbol_likelihood_log_c", symbol_likelihood_log, + (CODED_BITSPERFRAME / ofdm_bps) * (1 << ofdm_bps) * NFRAMES, + 1, 1); + octave_save_float(fout, "bit_likelihood_log_c", bit_likelihood_log, + CODED_BITSPERFRAME * NFRAMES, 1, 1); + octave_save_int(fout, "detected_data_log_c", detected_data_log, 1, + CODED_BITSPERFRAME * NFRAMES); + octave_save_float(fout, "snr_log_c", snr_log, NFRAMES, 1, 1); + octave_save_float(fout, "mean_amp_log_c", mean_amp_log, NFRAMES, 1, 1); + fclose(fout); #ifdef TESTING_FILE - fclose(fin); + fclose(fin); #endif - ofdm_destroy(ofdm); + ofdm_destroy(ofdm); - return 0; + return 0; } |
