From 5e850c44d27feef9400f7643a03f212a894b4da7 Mon Sep 17 00:00:00 2001 From: baobrien Date: Wed, 10 Jan 2018 22:32:41 +0000 Subject: [PATCH] Deconstantized OFDM git-svn-id: https://svn.code.sf.net/p/freetel/code@3390 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/src/ofdm.c | 184 +++++++++++++++++++-------------- codec2-dev/src/ofdm_internal.h | 65 ++++++------ codec2-dev/unittest/tofdm.c | 39 ++++++- 3 files changed, 177 insertions(+), 111 deletions(-) diff --git a/codec2-dev/src/ofdm.c b/codec2-dev/src/ofdm.c index cdaa9c0b..a3d5c1a2 100644 --- a/codec2-dev/src/ofdm.c +++ b/codec2-dev/src/ofdm.c @@ -43,8 +43,8 @@ /* Concrete definition of 700D parameters */ const struct OFDM_CONFIG OFDM_CONFIG_700D_C = { .Nc = 16, - .Ts = -1, - .Rs = -1, + .Ts = 0.018f, + .Rs = (1.0/0.018), .Fs = 8000, .bps = 2, .Tcp = -1, @@ -69,7 +69,7 @@ static void idft(struct OFDM *, complex float *, complex float *); static complex float vector_sum(complex float *, int); static complex float qpsk_mod(int *); static void qpsk_demod(complex float, int *); -static void ofdm_txframe(struct OFDM *, complex float [OFDM_SAMPLESPERFRAME], complex float *); +static void ofdm_txframe(struct OFDM *, complex float [], complex float *); static int coarse_sync(struct OFDM *, complex float *, int); /* Defines */ @@ -170,19 +170,12 @@ static complex float vector_sum(complex float *a, int num_elements) { static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) { complex float csam; - int Fs = ofdm->config.Fs; - int Rs = ofdm->config.Rs; - int Bps = ofdm->config.bps; - int Nc = ofdm->config.Nc; - int M = ofdm->config.M; - int Ncp = ofdm->config.Ncp; - int Ns = ofdm->config.Ns; - int RowsPerFrame = ofdm->config.RowsPerFrame; - int SampsPerFrame = ofdm->config.SampsPerFrame; - int Fcenter = ofdm->config.Fcenter; - int Ncorr = length - (SampsPerFrame + (M + Ncp)); - - int SFrame = SampsPerFrame; + const int Fs = ofdm->config.Fs; + const int M = ofdm->config.M; + const int Ncp = ofdm->config.Ncp; + const int SampsPerFrame = ofdm->config.SampsPerFrame; + const int Ncorr = length - (SampsPerFrame + (M + Ncp)); + float corr[Ncorr]; int NPSamp = M + Ncp; int i, j; @@ -193,7 +186,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) { for (j = 0; j < (M + Ncp); j++) { csam = conjf(ofdm->pilot_samples[j]); temp = temp + (rx[i + j] * csam); - temp = temp + (rx[i + j + SFrame] * csam); + temp = temp + (rx[i + j + SampsPerFrame] * csam); } corr[i] = cabsf(temp); @@ -213,7 +206,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) { /* Coarse frequency estimation */ /* TODO: Move FFT config to ofdm init and ofdm struct */ - kiss_fft_cfg fftcfg = kiss_fft_alloc(Fs,0,NULL,NULL); + kiss_fft_cfg fftcfg = ofdm->sync_fft_cfg; complex float fft_in[Fs]; complex float fft_out[Fs]; float C[Fs]; @@ -235,7 +228,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) { /* shift and copy in NPsam samples to front of buffer for FFT'ing */ for(i = 0; i < NPSamp; i++){ - fft_in[i] = rx[i + t_est + SFrame] * conjf(ofdm->pilot_samples[i]); + fft_in[i] = rx[i + t_est + SampsPerFrame] * conjf(ofdm->pilot_samples[i]); } kiss_fft(fftcfg,(kiss_fft_cpx*)fft_in,(kiss_fft_cpx*)fft_out); @@ -262,7 +255,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) { } } foff_est = (pmax > nmax) ? pmax_i : (nmax_i - fmax); - fprintf(stderr,"foff_est is %f\n",foff_est); + //fprintf(stderr,"foff_est is %f\n",foff_est); return t_est; } @@ -273,19 +266,14 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) { * ---------------------------------------------- */ -static void ofdm_txframe(struct OFDM *ofdm, complex float tx[OFDM_SAMPLESPERFRAME], +static void ofdm_txframe(struct OFDM *ofdm, complex float tx[], complex float *tx_sym_lin) { - int Fs = ofdm->config.Fs; - int Rs = ofdm->config.Rs; - int Bps = ofdm->config.bps; - int Nc = ofdm->config.Nc; - int M = ofdm->config.M; - int Ncp = ofdm->config.Ncp; - int Ns = ofdm->config.Ns; - int RowsPerFrame = ofdm->config.RowsPerFrame; - int SampsPerFrame = ofdm->config.SampsPerFrame; - int Fcenter = ofdm->config.Fcenter; + const int Nc = ofdm->config.Nc; + const int M = ofdm->config.M; + const int Ncp = ofdm->config.Ncp; + const int Ns = ofdm->config.Ns; + const int RowsPerFrame = ofdm->config.RowsPerFrame; complex float aframe[Ns][Nc + 2]; complex float asymbol[M]; @@ -364,6 +352,10 @@ void **alloc_doubleary(size_t sx,size_t sy,size_t elem){ return (void**) ary; } +/* + * Utility function to free array allocated with alloc_doubleary() + * Performs null check before freeing anything + */ void free_doubleary(void ** ary){ if(ary == NULL){ return; @@ -374,10 +366,16 @@ void free_doubleary(void ** ary){ } free(*ary); - free(ary); } +/* Utility function to null-check before freeing */ +static void free_nc(void * ptr){ + if(ptr != NULL){ + free(ptr); + } +} + /* * ------------ * ofdm_create @@ -397,25 +395,39 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) { /* Copy config structure */ /* TODO: validate config structure */ memcpy((void*)&ofdm->config,(void*)config,sizeof(struct OFDM_CONFIG)); - int Fs = ofdm->config.Fs; - int Rs = ofdm->config.Rs; - int Bps = ofdm->config.bps; - int Nc = ofdm->config.Nc; - int M = ofdm->config.M; - int Ncp = ofdm->config.Ncp; - int Ns = ofdm->config.Ns; - int RowsPerFrame = ofdm->config.RowsPerFrame; - int SampsPerFrame = ofdm->config.SampsPerFrame; - int Fcenter = ofdm->config.Fcenter; + const int Fs = ofdm->config.Fs; + const int Rs = ofdm->config.Rs; + const int Nc = ofdm->config.Nc; + const int M = ofdm->config.M; + const int Ncp = ofdm->config.Ncp; + const int Ns = ofdm->config.Ns; + const int RowsPerFrame = ofdm->config.RowsPerFrame; + const int SampsPerFrame = ofdm->config.SampsPerFrame; + const int Fcenter = ofdm->config.Fcenter; + complex float temp[M]; /* Allocate various buffers */ /* TODO: cleanup after failed malloc */ ofdm->pilot_samples = malloc(sizeof(complex float) * (M + Ncp)); + if(ofdm->pilot_samples == NULL) goto ofdm_fail_cleanup; + ofdm->pilots = malloc(sizeof(complex float) * (Nc+2)); + if(ofdm->pilots == NULL) goto ofdm_fail_cleanup; + ofdm->rxbuf = malloc(sizeof(complex float) * ofdm->config.RxBufSize); + if(ofdm->rxbuf == NULL) goto ofdm_fail_cleanup; + ofdm->w = malloc(sizeof(float) * (Nc+2)); + if(ofdm->w == NULL) goto ofdm_fail_cleanup; + ofdm->rx_amp = malloc(sizeof(float) * RowsPerFrame * Nc); + if(ofdm->rx_amp == NULL) goto ofdm_fail_cleanup; + ofdm->aphase_est_pilot_log = malloc(sizeof(float) * RowsPerFrame * Nc); + if(ofdm->aphase_est_pilot_log == NULL) goto ofdm_fail_cleanup; + + ofdm->sync_fft_cfg = kiss_fft_alloc(Fs,0,NULL,NULL); + if(ofdm->sync_fft_cfg == NULL) goto ofdm_fail_cleanup; /* store complex BPSK pilot symbols */ @@ -425,7 +437,7 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) { /* carrier tables for up and down conversion */ - int Nlower = floorf((OFDM_CENTRE - OFDM_RS * (Nc / 2)) / OFDM_RS); + int Nlower = floorf(( (float)(Fcenter) - Rs * ((float)Nc / 2)) / Rs); for (i = 0, j = Nlower; i < (Nc + 2); i++, j++) { /* @@ -433,11 +445,14 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) { * j = 1 kHz to 2 kHz (1.5 kHz center) */ - ofdm->w[i] = TAU * (float) j / (OFDM_FS / OFDM_RS); + ofdm->w[i] = TAU * (float) j / ((float)Fs / Rs); } ofdm->W = (complex float **) alloc_doubleary(Nc+2,M,sizeof(complex float)); + if(ofdm->W == NULL) goto ofdm_fail_cleanup; + ofdm->rx_sym = (complex float **) alloc_doubleary(Ns+3,Nc+2,sizeof(complex float)); + if(ofdm->rx_sym == NULL) goto ofdm_fail_cleanup; for (i = 0; i < (Nc + 2); i++) { @@ -467,8 +482,6 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) { /* create the OFDM waveform */ - complex float temp[M]; - idft(ofdm, temp, ofdm->pilots); /* @@ -488,10 +501,41 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) { } return ofdm; /* Success */ + + /* Deal with a failed malloc or something */ + ofdm_fail_cleanup: + /* Make sure ofdm points to a vaild struct */ + if(ofdm == NULL) + return NULL; + + free_nc(ofdm->pilots); + free_nc(ofdm->pilot_samples); + free_nc(ofdm->rxbuf); + free_nc(ofdm->w); + free_nc(ofdm->rx_amp); + free_nc(ofdm->aphase_est_pilot_log); + free_doubleary((void**)ofdm->W); + free_doubleary((void**)ofdm->rx_sym); + if(ofdm->sync_fft_cfg!=NULL) kiss_fft_free(ofdm->sync_fft_cfg); + free_nc(ofdm); + + return NULL; } void ofdm_destroy(struct OFDM *ofdm) { - free(ofdm); + if(ofdm == NULL) + return; + + free_nc(ofdm->pilots); + free_nc(ofdm->pilot_samples); + free_nc(ofdm->rxbuf); + free_nc(ofdm->w); + free_nc(ofdm->rx_amp); + free_nc(ofdm->aphase_est_pilot_log); + free_doubleary((void**)ofdm->W); + free_doubleary((void**)ofdm->rx_sym); + if(ofdm->sync_fft_cfg!=NULL) kiss_fft_free(ofdm->sync_fft_cfg); + free_nc(ofdm); } int ofdm_get_nin(struct OFDM *ofdm) { @@ -537,19 +581,11 @@ void ofdm_set_off_est_hz(struct OFDM *ofdm, float val) { * -------------------------------------- */ -void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *tx_bits) { +void ofdm_mod(struct OFDM *ofdm, COMP result[], const int *tx_bits) { - int Fs = ofdm->config.Fs; - int Rs = ofdm->config.Rs; - int Bps = ofdm->config.bps; - int Nc = ofdm->config.Nc; - int M = ofdm->config.M; - int Ncp = ofdm->config.Ncp; - int Ns = ofdm->config.Ns; - int RowsPerFrame = ofdm->config.RowsPerFrame; - int SampsPerFrame = ofdm->config.SampsPerFrame; - int BitsPerFrame = ofdm->config.BitsPerFrame; - int Fcenter = ofdm->config.Fcenter; + const int Bps = ofdm->config.bps; + const int SampsPerFrame = ofdm->config.SampsPerFrame; + const int BitsPerFrame = ofdm->config.BitsPerFrame; int length = BitsPerFrame / Bps; complex float tx[SampsPerFrame]; @@ -592,19 +628,17 @@ void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *t void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) { complex float aphase_est_pilot_rect; - int Fs = ofdm->config.Fs; - int Rs = ofdm->config.Rs; - int Bps = ofdm->config.bps; - int Nc = ofdm->config.Nc; - int M = ofdm->config.M; - int Ncp = ofdm->config.Ncp; - int Ns = ofdm->config.Ns; - int RowsPerFrame = ofdm->config.RowsPerFrame; - int SampsPerFrame = ofdm->config.SampsPerFrame; - int FtWindowWidth = ofdm->config.FtWindowWidth; - int BitsPerFrame = ofdm->config.BitsPerFrame; - int Fcenter = ofdm->config.Fcenter; - int RxBufSize = ofdm->config.RxBufSize; + const int Fs = ofdm->config.Fs; + const float Rs = ofdm->config.Rs; + const int Bps = ofdm->config.bps; + const int Nc = ofdm->config.Nc; + const int M = ofdm->config.M; + const int Ncp = ofdm->config.Ncp; + const int Ns = ofdm->config.Ns; + const int RowsPerFrame = ofdm->config.RowsPerFrame; + const int SampsPerFrame = ofdm->config.SampsPerFrame; + const int FtWindowWidth = ofdm->config.FtWindowWidth; + const int RxBufSize = ofdm->config.RxBufSize; float aphase_est_pilot[Nc + 2]; float aamp_est_pilot[Nc + 2]; @@ -843,7 +877,7 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) { freq_err_rect = freq_err_rect + 1E-6f; - freq_err_hz = cargf(freq_err_rect) * OFDM_RS / (TAU * Ns); + freq_err_hz = cargf(freq_err_rect) * Rs / (TAU * Ns); ofdm->foff_est_hz += (ofdm->foff_est_gain * freq_err_hz); } @@ -942,9 +976,9 @@ void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) { ofdm->aphase_est_pilot_log[(rr * Nc) + (i - 1)] = aphase_est_pilot[i]; - if (OFDM_BPS == 1) { + if (Bps == 1) { rx_bits[bit_index++] = crealf(rx_corr) > 0.0f; - } else if (OFDM_BPS == 2) { + } else if (Bps == 2) { /* * Only one final task, decode what quadrant the phase * is in, and return the dibits diff --git a/codec2-dev/src/ofdm_internal.h b/codec2-dev/src/ofdm_internal.h index 8ea4fc90..8f886207 100644 --- a/codec2-dev/src/ofdm_internal.h +++ b/codec2-dev/src/ofdm_internal.h @@ -37,6 +37,7 @@ extern "C" { #include #include "codec2_ofdm.h" +#include "kiss_fft.h" #ifndef M_PI #define M_PI 3.14159265358979323846f /* math constant */ @@ -44,45 +45,45 @@ extern "C" { #define TAU (2.0f * M_PI) /* mathematical constant */ -#define OFDM_NCX 16 /* N Carriers */ -#define OFDM_TS 0.018f /* Symbol time */ -#define OFDM_RS (1.0f / OFDM_TS) /* Symbol rate */ -#define OFDM_FS 8000.0f /* Sample rate */ -#define OFDM_BPS 2 /* Bits per symbol */ -#define OFDM_TCP 0.002f /* ? */ -#define OFDM_NS 8 /* Symbols per frame (number of rows incl pilot) */ -#define OFDM_CENTRE 1500.0f /* Center frequency */ +//#define OFDM_NCX 16 /* N Carriers */ +//#define OFDM_TS 0.018f /* Symbol time */ +//#define OFDM_RS (1.0f / OFDM_TS) /* Symbol rate */ +//#define OFDM_FS 8000.0f /* Sample rate */ +//#define OFDM_BPS 2 /* Bits per symbol */ +//#define OFDM_TCP 0.002f /* ? */ +//#define OFDM_NS 8 /* Symbols per frame (number of rows incl pilot) */ +//#define OFDM_CENTRE 1500.0f /* Center frequency */ /* To prevent C99 warning */ -#define OFDM_M 144 /* Samples per bare symbol (?) */ -#define OFDM_NCP 16 /* Samples per cyclic prefix */ - -#ifdef OLD_STYLE -/* This will produce a warning in C99 as (int) makes these variable */ - -#define OFDM_M ((int)(OFDM_FS / OFDM_RS)) -#define OFDM_NCP ((int)(OFDM_TCP * OFDM_FS)) -#endif - -/* ? */ -#define OFDM_FTWINDOWWIDTH 11 -/* Bits per frame (duh) */ -#define OFDM_BITSPERFRAME ((OFDM_NS - 1) * (OFDM_NCX * OFDM_BPS)) -/* Rows per frame */ -#define OFDM_ROWSPERFRAME (OFDM_BITSPERFRAME / (OFDM_NCX * OFDM_BPS)) -/* Samps per frame */ -#define OFDM_SAMPLESPERFRAME (OFDM_NS * (OFDM_M + OFDM_NCP)) - -#define OFDM_MAX_SAMPLESPERFRAME (OFDM_SAMPLESPERFRAME + (OFDM_M + OFDM_NCP)/4) -#define OFDM_RXBUF (3 * OFDM_SAMPLESPERFRAME + 3 * (OFDM_M + OFDM_NCP)) +//#define OFDM_M 144 /* Samples per bare symbol (?) */ +//#define OFDM_NCP 16 /* Samples per cyclic prefix */ +// +//#ifdef OLD_STYLE +///* This will produce a warning in C99 as (int) makes these variable */ +// +//#define OFDM_M ((int)(OFDM_FS / OFDM_RS)) +//#define OFDM_NCP ((int)(OFDM_TCP * OFDM_FS)) +//#endif + +///* ? */ +//#define OFDM_FTWINDOWWIDTH 11 +///* Bits per frame (duh) */ +//#define OFDM_BITSPERFRAME ((OFDM_NS - 1) * (OFDM_NCX * OFDM_BPS)) +///* Rows per frame */ +//#define OFDM_ROWSPERFRAME (OFDM_BITSPERFRAME / (OFDM_NCX * OFDM_BPS)) +///* Samps per frame */ +//#define OFDM_SAMPLESPERFRAME (OFDM_NS * (OFDM_M + OFDM_NCP)) +// +//#define OFDM_MAX_SAMPLESPERFRAME (OFDM_SAMPLESPERFRAME + (OFDM_M + OFDM_NCP)/4) +//#define OFDM_RXBUF (3 * OFDM_SAMPLESPERFRAME + 3 * (OFDM_M + OFDM_NCP)) /* Dummy struct for now, will contain constant configuration for OFDM modem */ struct OFDM_CONFIG{ int32_t Nc; - int32_t Ts; - int32_t Rs; + float Ts; + float Rs; int32_t Fs; int32_t bps; int32_t Tcp; @@ -123,7 +124,7 @@ struct OFDM { complex float * pilot_samples; complex float * rxbuf; float * w; - + kiss_fft_cfg sync_fft_cfg; /* Demodulator data */ diff --git a/codec2-dev/unittest/tofdm.c b/codec2-dev/unittest/tofdm.c index 21e52ae2..61c16de3 100644 --- a/codec2-dev/unittest/tofdm.c +++ b/codec2-dev/unittest/tofdm.c @@ -50,6 +50,36 @@ //#define SAMPLE_CLOCK_OFFSET_PPM 100 //#define FOFF_HZ 5.0f + +#define OFDM_NCX 16 /* N Carriers */ +#define OFDM_TS 0.018f /* Symbol time */ +#define OFDM_RS (1.0f / OFDM_TS) /* Symbol rate */ +#define OFDM_FS 8000.0f /* Sample rate */ +#define OFDM_BPS 2 /* Bits per symbol */ +#define OFDM_TCP 0.002f /* ? */ +#define OFDM_NS 8 /* Symbols per frame (number of rows incl pilot) */ +#define OFDM_CENTRE 1500.0f /* Center frequency */ + +/* ? */ +#define OFDM_FTWINDOWWIDTH 11 +/* Bits per frame (duh) */ +#define OFDM_BITSPERFRAME ((OFDM_NS - 1) * (OFDM_NCX * OFDM_BPS)) +/* Rows per frame */ +#define OFDM_ROWSPERFRAME (OFDM_BITSPERFRAME / (OFDM_NCX * OFDM_BPS)) +/* Samps per frame */ +#define OFDM_SAMPLESPERFRAME (OFDM_NS * (OFDM_M + OFDM_NCP)) + +#define OFDM_MAX_SAMPLESPERFRAME (OFDM_SAMPLESPERFRAME + (OFDM_M + OFDM_NCP)/4) +#define OFDM_RXBUF (3 * OFDM_SAMPLESPERFRAME + 3 * (OFDM_M + OFDM_NCP)) + + + +/* To prevent C99 warning */ + +#define OFDM_M 144 /* Samples per bare symbol (?) */ +#define OFDM_NCP 16 /* Samples per cyclic prefix */ + + /*---------------------------------------------------------------------------*\ FUNCTION....: fs_offset() @@ -122,10 +152,12 @@ static void freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *fof int main(int argc, char *argv[]) { - int samples_per_frame = ofdm_get_samples_per_frame(); - int max_samples_per_frame = ofdm_get_max_samples_per_frame(); - struct OFDM *ofdm; + + struct OFDM *ofdm = ofdm_create(OFDM_CONFIG_700D); + int samples_per_frame = ofdm_get_samples_per_frame(ofdm); + int max_samples_per_frame = ofdm_get_max_samples_per_frame(ofdm); + COMP tx[samples_per_frame]; /* one frame of tx samples */ int rx_bits[OFDM_BITSPERFRAME]; /* one frame of rx bits */ @@ -153,7 +185,6 @@ int main(int argc, char *argv[]) float foff_hz = 0.1; int nframes = 30; - ofdm = ofdm_create(OFDM_CONFIG_700D); assert(ofdm != NULL); /* Main Loop ---------------------------------------------------------------------*/ -- 2.25.1