From 873efe1fe5b57cee090e43e8197fec7e8a1a0e3c Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sat, 24 Mar 2018 22:25:52 +0000 Subject: [PATCH] added acquisition function ofdm_search_sync to C and Octave and tofdm framewor, todsm passes git-svn-id: https://svn.code.sf.net/p/freetel/code@3432 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/ofdm_lib.m | 49 ++++++++++++++++++++++++- codec2-dev/octave/ofdm_rx.m | 63 +++++++++----------------------- codec2-dev/octave/ofdm_tx.m | 2 +- codec2-dev/src/ofdm.c | 70 ++++++++++++++++++++++++++++++++++-- codec2-dev/src/ofdm_mod.c | 14 ++++---- codec2-dev/unittest/tofdm.c | 19 ++++++++-- 6 files changed, 157 insertions(+), 60 deletions(-) diff --git a/codec2-dev/octave/ofdm_lib.m b/codec2-dev/octave/ofdm_lib.m index 2cf282bc..38452686 100644 --- a/codec2-dev/octave/ofdm_lib.m +++ b/codec2-dev/octave/ofdm_lib.m @@ -202,7 +202,10 @@ function states = ofdm_init(bps, Rs, Tcp, Ns, Nc) states.foff_est_hz = 0; states.sample_point = states.timing_est = 1; states.nin = states.Nsamperframe; - + states.timing_valid = 0; + states.timing_mx = 0; + states.coarse_foff_est_hz = 0; + % generate OFDM pilot symbol, used for timing and freq offset est rate_fs_pilot_samples = states.pilots * W/states.M; @@ -219,6 +222,10 @@ function states = ofdm_init(bps, Rs, Tcp, Ns, Nc) states.rate = 1.0; states.ldpc_en = 0; + % init some output states for logging + + states.rx_sym = zeros(1+Ns+1+1, Nc+2); + endfunction @@ -289,6 +296,46 @@ function tx = ofdm_txframe(states, tx_sym_lin) endfunction +% ---------------------------------------------------------------------------------- +% ofdm_sync_search - attempts to find coarse sync parameters for modem initial sync +% ---------------------------------------------------------------------------------- + +function [timing_valid states] = ofdm_sync_search(states, rxbuf_in) + ofdm_load_const; + + % insert latest input samples into rxbuf so it is primed for when we have to call ofdm_demod() + + states.rxbuf(1:Nrxbuf-states.nin) = states.rxbuf(states.nin+1:Nrxbuf); + states.rxbuf(Nrxbuf-states.nin+1:Nrxbuf) = rxbuf_in; + + % Attempt coarse timing estimate (i.e. detect start of frame) + + st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe; + [ct_est foff_est timing_valid timing_mx] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples); + if states.verbose + printf(" ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx: %d\n", ct_est, foff_est, timing_valid, timing_mx); + end + + if timing_valid + % potential candidate found .... + + % calculate number of samples we need on next buffer to get into sync + + states.nin = Nsamperframe + ct_est - 1; + + % reset modem states + + states.sample_point = states.timing_est = 1; + states.foff_est_hz = foff_est; + else + states.nin = Nsamperframe; + end + states.timing_valid = timing_valid; + states.timing_mx = timing_mx; + states.coarse_foff_est_hz = foff_est; +endfunction + + % ------------------------------------------ % ofdm_demod - Demodulates one frame of bits % ------------------------------------------ diff --git a/codec2-dev/octave/ofdm_rx.m b/codec2-dev/octave/ofdm_rx.m index ccd854c7..e8785598 100644 --- a/codec2-dev/octave/ofdm_rx.m +++ b/codec2-dev/octave/ofdm_rx.m @@ -74,66 +74,34 @@ function ofdm_rx(filename, error_pattern_filename) end prx += states.nin; - printf(" states.nin: %d\n", states.nin); - [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in); - - errors = xor(tx_bits, rx_bits); - Nerrs = sum(errors); - aber = Nerrs/Nbitsperframe; - - frame_count++; - - printf("f: %d state: %s Nerrs: %d aber: %3.2f\n", f, state, Nerrs, aber); - + printf("f: %d state: %s nin: %d\n", f, state, nin); + % If looking for sync: check raw BER on frame just received % against all possible positions in the interleaver frame. % iterate state machine ------------------------------------ next_state = state; - if strcmp(state,'searching') - % If looking for sync: check raw BER on frame just received - % against all possible positions in the interleaver frame. + if strcmp(state,'searching') + [timing_valid states] = ofdm_sync_search(states, rxbuf_in); - if aber < 0.1 + if timing_valid next_state = 'synced'; - % make sure we get an interleave frame with correct freq offset - % note this introduces a lot of delay, a better idea would be to - % run demod again from interleave_frames back with now-known freq offset - end - end - - if strcmp(state,'synced') - if Nerrs/Nbitsperframe > 0.2 - %next_state = 'searching'; end end + + if strcmp(state,'synced') - state = next_state; - - if strcmp(state,'searching') - - % still searching? Attempt coarse timing estimate (i.e. detect start of frame) - - st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe; - [ct_est foff_est] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples); - if states.verbose - printf(" Nerrs: %d ct_est: %4d foff_est: %3.1f\n", Nerrs, ct_est, foff_est); - end - - % calculate number of samples we need on next buffer to get into sync - - states.nin = Nsamperframe + ct_est - 1; - - % reset modem states + printf(" states.nin: %d\n", states.nin); + [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in); - states.sample_point = states.timing_est = 1; - states.foff_est_hz = foff_est; - end + errors = xor(tx_bits, rx_bits); + Nerrs = sum(errors); + aber = Nerrs/Nbitsperframe; - if strcmp(state,'synced') - + frame_count++; + % we are in sync so log states rx_np_log = [rx_np_log arx_np]; @@ -150,6 +118,9 @@ function ofdm_rx(filename, error_pattern_filename) Tbits += Nbitsperframe; end end + + state = next_state; + end printf("BER..: %5.4f Tbits: %5d Terrs: %5d\n", Terrs/Tbits, Tbits, Terrs); diff --git a/codec2-dev/octave/ofdm_tx.m b/codec2-dev/octave/ofdm_tx.m index 174743e5..67cd5658 100644 --- a/codec2-dev/octave/ofdm_tx.m +++ b/codec2-dev/octave/ofdm_tx.m @@ -9,7 +9,7 @@ i) 10 seconds, AWGN channel at Eb/No=3dB - octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw', 10,3); + octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw', 10, 3); ii) 10 seconds, HF channel at Eb/No=6dB diff --git a/codec2-dev/src/ofdm.c b/codec2-dev/src/ofdm.c index bc87943a..f110c5de 100644 --- a/codec2-dev/src/ofdm.c +++ b/codec2-dev/src/ofdm.c @@ -163,7 +163,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length, float * complex float acc = 0.0f + 0.0f * I; for (i = 0; i < length; i++) { - acc += rx[i] * conjf(rx[i]); + acc += crealf(rx[i]) * crealf(rx[i]) + cimagf(rx[i]) * cimagf(rx[i]); } av_level = 2.0*sqrt(ofdm->timing_norm*crealf(acc)/length) + 1E-12; @@ -243,7 +243,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length, float * */ static void ofdm_txframe(struct OFDM *ofdm, complex float tx[OFDM_SAMPLESPERFRAME], - complex float *tx_sym_lin) { + complex float *tx_sym_lin) { complex float aframe[OFDM_NS][OFDM_NC + 2]; complex float asymbol[OFDM_M]; complex float asymbol_cp[OFDM_M + OFDM_NCP]; @@ -355,6 +355,17 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) { } } + for (i = 0; i < OFDM_ROWSPERFRAME*OFDM_NC; i++) { + ofdm->rx_np[i] = 0.0f + 0.0f * I; + } + + for (i = 0; i < OFDM_ROWSPERFRAME; i++) { + for (j = 0; j < OFDM_NC; j++) { + ofdm->aphase_est_pilot_log[OFDM_NC*i+j] = 0.0f + 0.0f * I; + ofdm->rx_amp[OFDM_NC*i+j] = 0.0f + 0.0f * I; + } + } + /* default settings of options and states */ ofdm->verbose = 0; @@ -490,6 +501,61 @@ void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *t } } + +/* + * ---------------------------------------------------------------------------------- + * ofdm_sync_search - attempts to find coarse sync parameters for modem initial sync + * ---------------------------------------------------------------------------------- + */ + +int ofdm_sync_search(struct OFDM *ofdm, COMP *rxbuf_in) +{ + int i,j; + + /* insert latest input samples into rxbuf so it is primed for when + we have to call ofdm_demod() */ + + for (i = 0, j = ofdm->nin; i < (OFDM_RXBUF - ofdm->nin); i++, j++) { + ofdm->rxbuf[i] = ofdm->rxbuf[j]; + } + + /* insert latest input samples onto tail of rxbuf */ + + for (i = (OFDM_RXBUF - ofdm->nin), j = 0; i < OFDM_RXBUF; i++, j++) { + ofdm->rxbuf[i] = rxbuf_in[j].real + rxbuf_in[j].imag * I; + } + + /* Attempt coarse timing estimate (i.e. detect start of frame) */ + + int st = OFDM_M + OFDM_NCP + OFDM_SAMPLESPERFRAME; + int en = st + 2*OFDM_SAMPLESPERFRAME; + int ct_est = coarse_sync(ofdm, &ofdm->rxbuf[st], (en - st), &ofdm->coarse_foff_est_hz); + if (ofdm->verbose) { + fprintf(stderr, " ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx: %f\n", + ct_est, ofdm->coarse_foff_est_hz, ofdm->timing_valid, ofdm->timing_mx); + } + + if (ofdm->timing_valid) { + /* potential candidate found .... */ + + /* calculate number of samples we need on next buffer to get into sync */ + + ofdm->nin = OFDM_SAMPLESPERFRAME + ct_est; + + /* reset modem states */ + + ofdm->sample_point = ofdm->timing_est = 0; + ofdm->foff_est_hz = ofdm->coarse_foff_est_hz; + } + else { + ofdm->nin = OFDM_SAMPLESPERFRAME; + } + + return ofdm->timing_valid; +} + + + /* * ------------------------------------------ * ofdm_demod - Demodulates one frame of bits diff --git a/codec2-dev/src/ofdm_mod.c b/codec2-dev/src/ofdm_mod.c index 67735c98..626d0ac8 100644 --- a/codec2-dev/src/ofdm_mod.c +++ b/codec2-dev/src/ofdm_mod.c @@ -64,18 +64,18 @@ int main(int argc, char *argv[]) if (strcmp(argv[1], "-") == 0) fin = stdin; else if ( (fin = fopen(argv[1],"rb")) == NULL ) { - fprintf(stderr, "Error opening input file: %s: %s.\n", - argv[1], strerror(errno)); - exit(1); + fprintf(stderr, "Error opening input file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); } if (strcmp(argv[2], "-") == 0) fout = stdout; else if ( (fout = fopen(argv[2],"wb")) == NULL ) { - fprintf(stderr, "Error opening output modem sample file: %s: %s.\n", - argv[2], strerror(errno)); - exit(1); + fprintf(stderr, "Error opening output modem sample file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); } - + ofdm = ofdm_create(OFDM_CONFIG_700D); assert(ofdm != NULL); int Nbitsperframe = ofdm_get_bits_per_frame(ofdm); diff --git a/codec2-dev/unittest/tofdm.c b/codec2-dev/unittest/tofdm.c index ce97a9aa..19aeda99 100644 --- a/codec2-dev/unittest/tofdm.c +++ b/codec2-dev/unittest/tofdm.c @@ -149,11 +149,13 @@ int main(int argc, char *argv[]) int sample_point_log[NFRAMES]; FILE *fout; - int f,i,j; + int f,i,j, state, next_state; ofdm = ofdm_create(OFDM_CONFIG_700D); assert(ofdm != NULL); + state = OFDM_SEARCH; + /* Main Loop ---------------------------------------------------------------------*/ for(f=0; f