From: drowe67 Date: Sat, 14 Apr 2018 10:06:54 +0000 (+0000) Subject: LDPC encoded test frame, measuring uncoded and coded errors for single interleaver... X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=87aab74cdd1e6e476aaf994bf8d8f7a436a6f57b;p=freetel-svn-tracking.git LDPC encoded test frame, measuring uncoded and coded errors for single interleaver frame on ofdm_demod, but perf a bit poor cf ofdm_lpc_rx git-svn-id: https://svn.code.sf.net/p/freetel/code@3489 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/ofdm_ldpc_rx.m b/codec2-dev/octave/ofdm_ldpc_rx.m index 9e6bf6da..1fa5fcb1 100644 --- a/codec2-dev/octave/ofdm_ldpc_rx.m +++ b/codec2-dev/octave/ofdm_ldpc_rx.m @@ -56,10 +56,10 @@ function ofdm_ldpc_rx(filename, interleave_frames = 1, error_pattern_filename) % OK generate tx frame for BER calcs - rand('seed', 100); + rand('seed', 1); + atx_bits = round(rand(1,code_param.data_bits_per_frame)); tx_bits = []; tx_codewords = []; for f=1:interleave_frames - atx_bits = round(rand(1,code_param.data_bits_per_frame)); tx_bits = [tx_bits atx_bits]; acodeword = LdpcEncode(atx_bits, code_param.H_rows, code_param.P_matrix); tx_codewords = [tx_codewords acodeword]; diff --git a/codec2-dev/octave/ofdm_ldpc_tx.m b/codec2-dev/octave/ofdm_ldpc_tx.m index bcebb39f..55e4154a 100644 --- a/codec2-dev/octave/ofdm_ldpc_tx.m +++ b/codec2-dev/octave/ofdm_ldpc_tx.m @@ -64,10 +64,15 @@ function ofdm_ldpc_tx(filename, Nsec, interleave_frames = 1, EbNodB=100, channel % OK generate an interleaver frame of codewords from random data bits - rand('seed', 100); + % use single frame of test bits with seed of 1 + % to keep compatable with ofdm_test_bits.c and friends + % as per create_ldpc_test_frame + + rand('seed', 1); + atx_bits = round(rand(1,code_param.data_bits_per_frame)); + tx_bits = tx_symbols = []; for f=1:interleave_frames - atx_bits = round(rand(1,code_param.data_bits_per_frame)); tx_bits = [tx_bits atx_bits]; codeword = LdpcEncode(atx_bits, code_param.H_rows, code_param.P_matrix); for b=1:2:code_param.code_bits_per_frame diff --git a/codec2-dev/octave/ofdm_lib.m b/codec2-dev/octave/ofdm_lib.m index 0b2921b9..05644be3 100644 --- a/codec2-dev/octave/ofdm_lib.m +++ b/codec2-dev/octave/ofdm_lib.m @@ -510,6 +510,52 @@ function [rx_bits states aphase_est_pilot_log rx_np rx_amp] = ofdm_demod(states, endfunction +% generate a test frame of ldpc encoded bits, used for raw and +% coded BER testing. Includes UW and txt files + +function [tx_bits payload_data_bits] = create_ldpc_test_frame + Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 17; Ns = 8; + states = ofdm_init(bps, Rs, Tcp, Ns, Nc); + ofdm_load_const; + + % Set up LDPC code + + mod_order = 4; bps = 2; modulation = 'QPSK'; mapping = 'gray'; + + init_cml('/home/david/Desktop/cml/'); % TODO: make this path sensible and portable + load HRA_112_112.txt + [code_param framesize rate] = ldpc_init_user(HRA_112_112, modulation, mod_order, mapping); + assert(Nbitsperframe == (code_param.code_bits_per_frame + Nuwbits + Ntxtbits)); + + rand('seed',1); + payload_data_bits = round(rand(1,code_param.data_bits_per_frame)); + codeword = LdpcEncode(payload_data_bits, code_param.H_rows, code_param.P_matrix); + Nsymbolsperframe = length(codeword)/bps; + + % need all these steps to get actual raw codeword bits at demod + % note this will only work for single interleaver frame case, + % but that's enough for initial quick tests + + tx_symbols = []; + for s=1:Nsymbolsperframe + tx_symbols = [tx_symbols qpsk_mod( codeword(2*(s-1)+1:2*s) )]; + end + + tx_symbols = gp_interleave(tx_symbols); + + codeword_raw = []; + for s=1:Nsymbolsperframe + codeword_raw = [codeword_raw qpsk_demod(tx_symbols(s))]; + end + + % insert UW and txt bits + + tx_bits = [zeros(1,Nuwbits) zeros(1,Ntxtbits) codeword_raw]; + assert(Nbitsperframe == length(tx_bits)); + +endfunction + + % Save test bits frame to a text file in the form of a C array % % usage: @@ -517,15 +563,8 @@ endfunction % function test_bits_ofdm_file - - Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 17; Ns = 8; - states = ofdm_init(bps, Rs, Tcp, Ns, Nc); - ofdm_load_const; - - rand('seed',1); - test_bits_ofdm = round(rand(1,Nbitsperframe)); - test_bits_ofdm(1:states.Ntxtbits) = 0; % insert Unique Word - printf("%d test bits\n", Nbitsperframe); + [test_bits_ofdm payload_data_bits] = create_ldpc_test_frame; + printf("%d test bits\n", length(test_bits_ofdm)); f=fopen("../src/test_bits_ofdm.h","wt"); fprintf(f,"/* Generated by test_bits_ofdm_file() Octave function */\n\n"); @@ -533,7 +572,13 @@ function test_bits_ofdm_file for m=1:length(test_bits_ofdm)-1 fprintf(f," %d,\n",test_bits_ofdm(m)); endfor - fprintf(f," %d\n};\n",test_bits_ofdm(length(test_bits_ofdm))); + fprintf(f," %d\n};\n",test_bits_ofdm(length(payload_data_bits))); + + fprintf(f,"\nconst int payload_data_bits[]={\n"); + for m=1:length(payload_data_bits)-1 + fprintf(f," %d,\n",payload_data_bits(m)); + endfor + fprintf(f," %d\n};\n",payload_data_bits(length(payload_data_bits))); fclose(f); endfunction diff --git a/codec2-dev/octave/ofdm_rx.m b/codec2-dev/octave/ofdm_rx.m index 8ef93ce0..c5eebf72 100644 --- a/codec2-dev/octave/ofdm_rx.m +++ b/codec2-dev/octave/ofdm_rx.m @@ -25,10 +25,8 @@ function ofdm_rx(filename, error_pattern_filename) % OK re-generate tx frame for BER calcs - rand('seed', 1); - tx_bits = round(rand(1,Nbitsperframe)); - tx_bits(1:states.Nuwbits) = 0; % insert UW - + tx_bits = create_ldpc_test_frame; + % init logs and BER stats rx_bits = []; rx_np_log = []; timing_est_log = []; delta_t_log = []; foff_est_hz_log = []; diff --git a/codec2-dev/octave/ofdm_tx.m b/codec2-dev/octave/ofdm_tx.m index 371922a5..9571d788 100644 --- a/codec2-dev/octave/ofdm_tx.m +++ b/codec2-dev/octave/ofdm_tx.m @@ -30,9 +30,7 @@ function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0, d Nrows = Nsec*Rs; Nframes = floor((Nrows-1)/Ns); - rand('seed', 1); - tx_bits = round(rand(1,Nbitsperframe)); - tx_bits(1:states.Nuwbits) = 0; % insert UW + tx_bits = create_ldpc_test_frame; tx = []; for f=1:Nframes diff --git a/codec2-dev/src/ofdm_demod.c b/codec2-dev/src/ofdm_demod.c index 959e6a31..37b8b4aa 100644 --- a/codec2-dev/src/ofdm_demod.c +++ b/codec2-dev/src/ofdm_demod.c @@ -5,8 +5,13 @@ DATE CREATED: Mar 2018 Given an input file of raw file (8kHz, 16 bit shorts) of OFDM modem - samples. Optionally outputs one char per bit (hard decision), or - soft decision rx_np and rx_amp QPSK symbols information for LDPC decoder. + samples. Optionally: + + 1/ outputs one char per bit (hard decision) + 2/ bit LLRS, one double per bir, for external LDPC decoder like ldpc_dec + 3/ LDPC decoded bits, one char per bit + + Also has test frame modes for uncoded and coded operation. \*---------------------------------------------------------------------------*/ @@ -41,10 +46,11 @@ #include "mpdecode_core.h" #include "gp_interleaver.h" -#define ASCALE (2E5*1.1491/2.0) /* scale from shorts back to floats */ -#define NFRAMES 100 /* just log the first 100 frames */ -#define NDISCARD 20 /* BER2measure disctrds first 20 frames */ -#define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */ +#define ASCALE (2E5*1.1491/2.0) /* scale from shorts back to floats */ +#define NFRAMES 100 /* just log the first 100 frames */ +#define NDISCARD 20 /* BER2measure disctrds first 20 frames */ +#define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */ +#define DATA_BITSPERFRAME 112 /* number of LDPC payload data bits/frame */ #include "HRA_112_112.h" /* generated by ldpc_fsk_lib.m:ldpc_decode() */ #define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */ @@ -73,6 +79,7 @@ int main(int argc, char *argv[]) int i, j, f, oct, logframes, arg, llr_en; int Nerrs, Terrs, Tbits, Terrs2, Tbits2, testframes, frame_count; + int ldpc_en, Nerrs_coded, Tbits_coded, Terrs_coded; struct LDPC ldpc; ldpc.max_iter = HRA_112_112_MAX_ITER; @@ -92,10 +99,12 @@ int main(int argc, char *argv[]) printf("usage: %s InputModemRawFile OutputFile [-o OctaveLogFile] [--llr] [-v VerboseLevel]\n", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, " Default output file format is one byte per bit hard decision\n"); + fprintf(stderr, " --llr LLR output, one double per bit, %d doubles/frame\n", CODED_BITSPERFRAME); fprintf(stderr, " -t Receive test frames and count errors\n"); + fprintf(stderr, " --ldpc Run (224,112) LDPC decoder. This forces 112, one char/bit output values\n" + " per frame. In testframe mode (-t) raw and coded errors will be counted\n"); fprintf(stderr, " -v Verbose info the stderr\n"); fprintf(stderr, " -o Octave log file for testing\n"); - fprintf(stderr, " --llr LLR output, one double per bit, %d doubles/frame\n", CODED_BITSPERFRAME); fprintf(stderr, "\n"); exit(1); } @@ -136,11 +145,17 @@ int main(int argc, char *argv[]) testframes = 1; } + ldpc_en = 0; + if (opt_exists(argv, argc, "--ldpc")) { + ldpc_en = 1; + llr_en = 1; + } + ofdm = ofdm_create(OFDM_CONFIG_700D); assert(ofdm != NULL); if ((arg = opt_exists(argv, argc, "-v")) != 0) { - ofdm_set_verbose(ofdm, atoi(argv[arg+1])); + ofdm_set_verbose(ofdm, 1); } int Nbitsperframe = ofdm_get_bits_per_frame(ofdm); @@ -151,10 +166,11 @@ int main(int argc, char *argv[]) int rx_bits[Nbitsperframe]; char rx_bits_char[Nbitsperframe]; int rx_uw[OFDM_NUWBITS]; - f = 0; Nerrs = Terrs = Tbits = Terrs2 = Tbits2 = frame_count = 0; + f = 0; Nerrs = Terrs = Tbits = Terrs2 = Tbits2 = Terrs_coded = Tbits_coded = frame_count = 0; + int parityCheckCount, iter; float EsNo = 10; - fprintf(stderr,"Warning EsNo: %f hard coded", EsNo); + fprintf(stderr,"Warning EsNo: %f hard coded\n", EsNo); nin_frame = ofdm_get_nin(ofdm); while(fread(rx_scaled, sizeof(short), nin_frame, fin) == nin_frame) { @@ -201,40 +217,33 @@ int main(int argc, char *argv[]) llr[i] = -bit_likelihood[i]; } - int iter; char out_char[CODED_BITSPERFRAME]; - int parityCheckCount; for(i=0; i= NDISCARD) { - Terrs2 += Nerrs; - Tbits2 += Nbitsperframe; + if (testframes) { + Nerrs_coded = 0; + for(i=0; iverbose) { - fprintf(stderr, "f: %2d state: %-10s uw_errors: %2d %1d Nerrs: %3d foff: %3.1f\n", + fprintf(stderr, "f: %2d state: %-10s uw_errors: %2d %1d Nerrs: %3d foff: %3.1f", f, ofdm->last_sync_state, ofdm->uw_errors, ofdm->sync_counter, Nerrs, ofdm->foff_est_hz); + if (ldpc_en) { + fprintf(stderr, " Nerrs_coded: %3d iter: %3d pCC: %3d", Nerrs_coded, iter, parityCheckCount); + } + fprintf(stderr, "\n"); } /* optional logging of states */ @@ -323,8 +336,12 @@ int main(int argc, char *argv[]) fclose(fout); if (testframes) { - fprintf(stderr, "BER..: %5.4f Tbits: %5d Terrs: %5d\n", (float)Terrs/Tbits, Tbits, Terrs); - fprintf(stderr, "BER2.: %5.4f Tbits: %5d Terrs: %5d\n", (float)Terrs2/Tbits2, Tbits2, Terrs2); + fprintf(stderr, "BER......: %5.4f Tbits: %5d Terrs: %5d\n", (float)Terrs/Tbits, Tbits, Terrs); + fprintf(stderr, "BER2.....: %5.4f Tbits: %5d Terrs: %5d\n", (float)Terrs2/Tbits2, Tbits2, Terrs2); + if (ldpc_en) { + fprintf(stderr, "Coded BER: %5.4f Tbits: %5d Terrs: %5d\n", + (float)Terrs_coded/Tbits_coded, Tbits_coded, Terrs_coded); + } } /* optionally dump Octave files */ diff --git a/codec2-dev/src/test_bits_ofdm.h b/codec2-dev/src/test_bits_ofdm.h index 456a9be1..02120097 100644 --- a/codec2-dev/src/test_bits_ofdm.h +++ b/codec2-dev/src/test_bits_ofdm.h @@ -11,23 +11,40 @@ const int test_bits_ofdm[]={ 0, 0, 0, - 1, 0, 0, 0, 0, + 1, + 1, 0, + 1, + 1, 0, + 1, 0, 0, 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 1, 0, 1, + 1, + 0, 0, 1, 0, + 1, 0, + 1, 0, 0, 0, @@ -39,52 +56,77 @@ const int test_bits_ofdm[]={ 1, 0, 0, - 0, + 1, + 1, 0, 0, 1, 1, 1, 1, + 0, + 0, 1, 1, - 0, 1, 0, - 1, 0, 1, 1, 0, + 0, + 1, + 1, + 1, + 1, 1, 0, 0, + 1, 0, 0, 1, - 0, 1, 0, 1, 0, 1, 1, + 0, 1, 0, 1, 0, + 0, + 0, + 0, 1, 0, + 0, 1, 1, 0, + 0, + 0, + 0, 1, 1, 0, + 0, + 0, + 0, + 0, + 0, + 1, 1, 0, 0, 1, + 1, + 1, + 1, + 0, + 1, 0, 1, 0, @@ -93,9 +135,11 @@ const int test_bits_ofdm[]={ 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, @@ -104,8 +148,14 @@ const int test_bits_ofdm[]={ 1, 0, 0, + 0, + 0, + 0, 1, + 0, + 0, 1, + 0, 1, 0, 0, @@ -122,17 +172,21 @@ const int test_bits_ofdm[]={ 1, 1, 1, + 0, + 0, 1, - 1, - 1, + 0, + 0, 1, 0, + 0, 1, 1, 1, 0, 0, - 1, + 0, + 0, 1, 0, 0, @@ -144,56 +198,91 @@ const int test_bits_ofdm[]={ 0, 0, 0, + 0, 1, 0, 0, - 1, - 1, - 1, + 0, + 0, + 0, 1, 0, + 0, + 0, 1, 0, + 0, + 0, + 0, + 0, + 0, 1, 1, 0, + 0, 1, 1, 1, 1, 0, 1, + 0, 1, 1, 1, - 1, - 0, 0, 1, 1, 1, 0, - 1, 0, - 1, 0, + 0, + 0 +}; + +const int payload_data_bits[]={ 1, 1, + 0, + 0, 1, 1, 1, + 0, 1, + 0, 1, 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, 1, 1, + 0, 1, + 0, 1, 0, 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 1, + 0, + 0, + 0, + 0, + 0, 1, 1, 1, @@ -201,13 +290,23 @@ const int test_bits_ofdm[]={ 1, 1, 0, + 1, 0, + 1, 0, + 1, + 1, 0, 1, + 0, + 0, + 0, + 0, 1, 0, + 1, 0, + 1, 0, 1, 1, @@ -215,6 +314,7 @@ const int test_bits_ofdm[]={ 0, 1, 0, + 1, 0, 1, 1, @@ -222,14 +322,25 @@ const int test_bits_ofdm[]={ 1, 1, 0, + 1, 0, 0, 1, + 0, 1, 0, 0, 0, 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, 1, 0, @@ -238,5 +349,9 @@ const int test_bits_ofdm[]={ 1, 1, 0, + 0, + 1, + 1, + 1, 0 };