From: drowe67 Date: Fri, 13 Apr 2018 06:28:07 +0000 (+0000) Subject: some LDPC frames decoding from ofdm_demod, need to do some cleanup X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=8b171bbe7d023aa677bbcde8344209a4330e0f2e;p=freetel-svn-tracking.git some LDPC frames decoding from ofdm_demod, need to do some cleanup git-svn-id: https://svn.code.sf.net/p/freetel/code@3474 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/CMakeLists.txt b/codec2-dev/src/CMakeLists.txt index b071a9a5..2cb6fc79 100644 --- a/codec2-dev/src/CMakeLists.txt +++ b/codec2-dev/src/CMakeLists.txt @@ -340,7 +340,7 @@ target_link_libraries(ofdm_put_test_bits ${CMAKE_REQUIRED_LIBRARIES} codec2) add_executable(ofdm_mod ofdm_mod.c) target_link_libraries(ofdm_mod ${CMAKE_REQUIRED_LIBRARIES} codec2) -add_executable(ofdm_demod ofdm_demod.c octave.c mpdecode_core.c) +add_executable(ofdm_demod ofdm_demod.c octave.c mpdecode_core.c gp_interleaver.c) target_link_libraries(ofdm_demod ${CMAKE_REQUIRED_LIBRARIES} codec2) add_executable(fmfsk_mod fmfsk_mod.c) diff --git a/codec2-dev/src/gp_interleaver.c b/codec2-dev/src/gp_interleaver.c new file mode 100644 index 00000000..c138e167 --- /dev/null +++ b/codec2-dev/src/gp_interleaver.c @@ -0,0 +1,98 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: gp_interleaver.c + AUTHOR......: David Rowe + DATE CREATED: April 2018 + + Golden Prime Interleaver. My interprestation of "On the Analysis and + Design of Good Algebraic Interleavers", Xie et al,eq (5). + + See also octvae/gp_interleaver.m + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2018 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#include +#include "gp_interleaver.h" + +/* + Choose b for Golden Prime Interleaver. b is chosen to be the + closest integer, which is relatively prime to N, to the Golden + section of N. + + Implemented with a LUT in C for convenience, Octave version + has a more complete implementation. +*/ + +int b_table[] = { + 112,71, + 224,139, + 448,277, + 672,419, + 896,557, + 1120,701, + 1344,839, + 1568,971, + 1792,1109, + 2016,1249, + 2240,1399, + 2464,1523, + 2688,1663, + 2912,1801, + 3136,1949, + 3360,2081, + 3584,2213 +}; + +int choose_interleaver_b(int Nbits) +{ + int i; + + for(i=0; i. +*/ + +#ifndef __GP_INTERLEAVER__ +#define __GP_INTERLEAVER__ + +#include "comp.h" + +void gp_interleave_comp(COMP interleaved_frame[], COMP frame[], int Nbits); +void gp_interleave_float(float frame[], float interleaved_frame[], int Nbits); + +#endif diff --git a/codec2-dev/src/ldpc_dec.c b/codec2-dev/src/ldpc_dec.c index 479771a8..e14b58a2 100644 --- a/codec2-dev/src/ldpc_dec.c +++ b/codec2-dev/src/ldpc_dec.c @@ -85,6 +85,7 @@ int main(int argc, char *argv[]) fprintf(stderr, " InOneSymbolPerDouble Input file of double LLRs, use - for the \n"); fprintf(stderr, " file names to use stdin/stdout\n"); fprintf(stderr, " --code Use LDPC code CodeName\n"); + fprintf(stderr, " --listcodes List available LDPC codes\n"); fprintf(stderr, " --sd Treat input file samples as Soft Decision\n"); fprintf(stderr, " demod outputs rather than LLRs\n"); fprintf(stderr, " --half Load framesize/2 input samples for each decode\n"); @@ -220,6 +221,7 @@ int main(int argc, char *argv[]) input_double[i] = 0.0; } } + fprintf(stderr, "CodeLength: %d offset: %d\n", CodeLength, offset); while(fread(&input_double[offset], sizeof(double), nread, fin) == nread) { if (sdinput) { @@ -232,7 +234,7 @@ int main(int argc, char *argv[]) // Output data bits if decoder converged, or was // within 10% of all parity checks converging (10% est - // BER). usefule for real world operation as it can + // BER). useful for real world operation as it can // resync and won't send crappy packets to the decoder float ber_est = (float)(ldpc.NumberParityBits - parityCheckCount)/ldpc.NumberParityBits; @@ -265,7 +267,7 @@ int main(int argc, char *argv[]) break; } state = next_state; - //fprintf(stderr, "state: %d iter: %d\n", state, iter); + fprintf(stderr, "state: %d iter: %d\n", state, iter); } for(i=0; iH_rows; - - for (p=0; pNumberParityBits; p++) { - par = 0; - - for (i=0; imax_row_weight; i++) { - ind = (int)H_rows[p + i*ldpc->NumberParityBits]; - par = par + ibits[ind-1]; - } - - tmp = par + prev; - - tmp &= 1; // only retain the lsb - prev = tmp; - pbits[p] = tmp; - } -} - int main(int argc, char *argv[]) { unsigned char ibits[NUMBERROWSHCOLS]; diff --git a/codec2-dev/src/mpdecode_core.c b/codec2-dev/src/mpdecode_core.c index 28d1609b..5cda6795 100644 --- a/codec2-dev/src/mpdecode_core.c +++ b/codec2-dev/src/mpdecode_core.c @@ -15,6 +15,27 @@ int extract_output(char out_char[], int DecodedBits[], int ParityCheckCount[], int max_iter, int CodeLength, int NumberParityBits); +void encode(struct LDPC *ldpc, unsigned char ibits[], unsigned char pbits[]) { + unsigned int p, i, tmp, par, prev=0; + int ind; + double *H_rows = ldpc->H_rows; + + for (p=0; pNumberParityBits; p++) { + par = 0; + + for (i=0; imax_row_weight; i++) { + ind = (int)H_rows[p + i*ldpc->NumberParityBits]; + par = par + ibits[ind-1]; + } + + tmp = par + prev; + + tmp &= 1; // only retain the lsb + prev = tmp; + pbits[p] = tmp; + } +} + /* Phi function */ static float phi0( float x ) diff --git a/codec2-dev/src/mpdecode_core.h b/codec2-dev/src/mpdecode_core.h index 82d27a44..6fd202db 100644 --- a/codec2-dev/src/mpdecode_core.h +++ b/codec2-dev/src/mpdecode_core.h @@ -27,6 +27,8 @@ struct LDPC { double *H_cols; }; +void encode(struct LDPC *ldpc, unsigned char ibits[], unsigned char pbits[]); + int run_ldpc_decoder(struct LDPC *ldpc, char out_char[], double input[], int *parityCheckCount); void sd_to_llr(double llr[], double sd[], int n); diff --git a/codec2-dev/src/ofdm_demod.c b/codec2-dev/src/ofdm_demod.c index 8905e236..40d4b1c6 100644 --- a/codec2-dev/src/ofdm_demod.c +++ b/codec2-dev/src/ofdm_demod.c @@ -11,7 +11,7 @@ \*---------------------------------------------------------------------------*/ /* - Copyright (C) 2015 David Rowe + Copyright (C) 2018 David Rowe All rights reserved. @@ -39,12 +39,16 @@ #include "octave.h" #include "test_bits_ofdm.h" #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 */ +#include "HRA_112_112.h" /* generated by ldpc_fsk_lib.m:ldpc_decode() */ +#define CODED_BITSPERFRAME 224 /* number of LDPC codeword bits/frame */ + int opt_exists(char *argv[], int argc, char opt[]) { int i; for (i=0; irx_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]; + + COMP codeword_symbols_de[CODED_BITSPERFRAME/OFDM_BPS]; + float codeword_amps_de[CODED_BITSPERFRAME/OFDM_BPS]; + + gp_interleave_comp(codeword_symbols_de, ldpc_codeword_symbols, CODED_BITSPERFRAME/OFDM_BPS); + gp_interleave_float(codeword_amps_de, ldpc_codeword_symbol_amps, CODED_BITSPERFRAME/OFDM_BPS); - Demod2D(symbol_likelihood, ldpc_codeword_symbols, S_matrix, EsNo, ldpc_codeword_symbol_amps, CODED_BITSPERFRAME/OFDM_BPS); + Demod2D(symbol_likelihood, codeword_symbols_de, S_matrix, EsNo, codeword_amps_de, CODED_BITSPERFRAME/OFDM_BPS); Somap(bit_likelihood, symbol_likelihood, CODED_BITSPERFRAME/OFDM_BPS); + for(i=0; i