diff options
author | tracierenea <tracie.perez@mavs.uta.edu> | 2014-06-30 16:17:18 -0500 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2015-10-15 10:40:21 -0400 |
commit | 3d3ab6009246e2348c46acc692eb0147b82af0ea (patch) | |
tree | c18da3c033c7d6949f96746bd81da818db18f147 /gr-fec | |
parent | 6f0cc2616674c3a0bb77cf657724f23a8260dae5 (diff) |
fec: LDPC: Adding LDPC encoder variable.
Diffstat (limited to 'gr-fec')
-rw-r--r-- | gr-fec/include/gnuradio/fec/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/ldpc_R_U_encoder.h | 71 | ||||
-rw-r--r-- | gr-fec/lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-fec/lib/ldpc_R_U_encoder_impl.cc | 136 | ||||
-rw-r--r-- | gr-fec/lib/ldpc_R_U_encoder_impl.h | 55 | ||||
-rw-r--r-- | gr-fec/swig/fec_swig.i | 4 |
6 files changed, 268 insertions, 0 deletions
diff --git a/gr-fec/include/gnuradio/fec/CMakeLists.txt b/gr-fec/include/gnuradio/fec/CMakeLists.txt index 93143e4ed5..861c4c2beb 100644 --- a/gr-fec/include/gnuradio/fec/CMakeLists.txt +++ b/gr-fec/include/gnuradio/fec/CMakeLists.txt @@ -54,6 +54,7 @@ install(FILES polar_decoder_common.h ldpc_par_chk_mtrx.h ldpc_bit_flip_decoder.h + ldpc_R_U_encoder.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fec COMPONENT "fec_devel" ) diff --git a/gr-fec/include/gnuradio/fec/ldpc_R_U_encoder.h b/gr-fec/include/gnuradio/fec/ldpc_R_U_encoder.h new file mode 100644 index 0000000000..90378d56c1 --- /dev/null +++ b/gr-fec/include/gnuradio/fec/ldpc_R_U_encoder.h @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013-2014 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 3, or (at your + * option) any later version. + * + * This software 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 General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FEC_LDPC_R_U_ENCODER_H +#define INCLUDED_FEC_LDPC_R_U_ENCODER_H + +#include <gnuradio/fec/api.h> +#include <gnuradio/fec/generic_encoder.h> +#include <gnuradio/fec/ldpc_par_chk_mtrx.h> + +namespace gr { + namespace fec { + namespace code { + + /*! + * \brief LDPC Generic Encoder (method by Richardson & Urbanke) + * \ingroup error_coding_blk + * + * \details + * A generic LDPC encoder class. This encoding method is + * described by Richardson and Urbanke in Appendix A of their + * book Modern Coding Theory (ISBN 978-0-521-85229-6). + */ + class FEC_API ldpc_R_U_encoder : virtual public generic_encoder + { + public: + /*! + * Build an encoding FEC API object. + * + * \param H_obj The LDPC parity check matrix object to use + * for encoding. This is the same matrix used for + * decoding. + */ + static generic_encoder::sptr make(ldpc_par_chk_mtrx *H_obj); + + /*! + * Sets the uncoded frame size to \p frame_size. If \p + * frame_size is greater than the value given to the + * constructor, the frame size will be capped by that initial + * value and this function will return false. Otherwise, it + * returns true. + */ + virtual bool set_frame_size(unsigned int frame_size) = 0; + + /*! + * Returns the coding rate of this encoder. + */ + virtual double rate() = 0; + }; + } /* namespace code */ + } /* namespace fec */ +} /* namespace gr */ + +#endif /* INCLUDED_FEC_LDPC_R_U_ENCODER_H */
\ No newline at end of file diff --git a/gr-fec/lib/CMakeLists.txt b/gr-fec/lib/CMakeLists.txt index f5872f9f03..5e4bf72b64 100644 --- a/gr-fec/lib/CMakeLists.txt +++ b/gr-fec/lib/CMakeLists.txt @@ -91,6 +91,7 @@ list(APPEND gnuradio_fec_sources ldpc_par_chk_mtrx_impl.cc ldpc_par_chk_mtrx.cc ldpc_bit_flip_decoder_impl.cc + ldpc_R_U_encoder_impl.cc ) #Add Windows DLL resource file if using MSVC diff --git a/gr-fec/lib/ldpc_R_U_encoder_impl.cc b/gr-fec/lib/ldpc_R_U_encoder_impl.cc new file mode 100644 index 0000000000..7da8e12094 --- /dev/null +++ b/gr-fec/lib/ldpc_R_U_encoder_impl.cc @@ -0,0 +1,136 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013-2014 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 3, or (at your + * option) any later version. + * + * This software 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 General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <ldpc_R_U_encoder_impl.h> +#include <sstream> + +namespace gr { + namespace fec { + namespace code { + generic_encoder::sptr + ldpc_R_U_encoder::make(ldpc_par_chk_mtrx *H_obj) + { + return generic_encoder::sptr + (new ldpc_R_U_encoder_impl(H_obj)); + } + + ldpc_R_U_encoder_impl::ldpc_R_U_encoder_impl(ldpc_par_chk_mtrx *H_obj) + : generic_encoder("ldpc_R_U_encoder") + { + // LDPC parity check matrix to use for encoding + d_H = H_obj; + // Set frame size to k, the # of bits in the information word + // All buffers and settings will be based on this value. + set_frame_size(d_H->k()); + } + + ldpc_R_U_encoder_impl::~ldpc_R_U_encoder_impl() + { + } + + int + ldpc_R_U_encoder_impl::get_output_size() + { + return d_H->n(); + } + + int + ldpc_R_U_encoder_impl::get_input_size() + { + return d_frame_size; + } + + bool + ldpc_R_U_encoder_impl::set_frame_size(unsigned int frame_size) + { + bool ret = true; + // TODO add some bounds check here? The frame size is + // constant and specified by the size of the parity check + // matrix used for encoding. + d_frame_size = frame_size; + + return ret; + } + + double + ldpc_R_U_encoder_impl::rate() + { + return (d_H->n())/static_cast<double>(d_frame_size); + } + + void + ldpc_R_U_encoder_impl::generic_work(void *inbuffer, + void *outbuffer) + { + // Populate the information word + const unsigned char *in = (const unsigned char *)inbuffer; + unsigned int index, k = d_H->k(); + gsl_matrix *s = gsl_matrix_alloc(k, 1); + for (index = 0; index < k; index++) { + double value = static_cast<double>(in[index]); + gsl_matrix_set(s, index, 0, value); + } + + // Solve for p2 (parity part) + const gsl_matrix *A = d_H->A(); + const gsl_matrix *B = d_H->B(); + const gsl_matrix *D = d_H->D(); + const gsl_matrix *E = d_H->E(); + const gsl_matrix *inv_T = d_H->T_inverse(); + const gsl_matrix *inv_p = d_H->phi_inverse(); + const gsl_matrix *temp1 = d_H->mult_matrices_mod2(B, s); + const gsl_matrix *temp2 = d_H->mult_matrices_mod2(inv_T, + temp1); + const gsl_matrix *temp3 = d_H->mult_matrices_mod2(E, temp2); + const gsl_matrix *temp4 = d_H->mult_matrices_mod2(D, s); + const gsl_matrix *temp5 = d_H->add_matrices_mod2(temp4, + temp3); + const gsl_matrix *p2 = d_H->mult_matrices_mod2(inv_p, temp5); + + // Solve for p1 (parity part) + const gsl_matrix *temp6 = d_H->mult_matrices_mod2(A, p2); + const gsl_matrix *temp7 = d_H->add_matrices_mod2(temp6, + temp1); + const gsl_matrix *p1 = d_H->mult_matrices_mod2(inv_T, temp7); + + // Populate the codeword to be output + unsigned int p1_length = (*p1).size1; + unsigned int p2_length = (*p2).size1; + unsigned char *out = (unsigned char*)outbuffer; + for (index = 0; index < p1_length; index++) { + int value = gsl_matrix_get(p1, index, 0); + out[index] = value; + } + for (index = 0; index < p2_length; index++) { + int value = gsl_matrix_get(p2, index, 0); + out[p1_length+index] = value; + } + for (index = 0; index < k; index++) { + int value = gsl_matrix_get(s, index, 0); + out[p1_length+p2_length+index] = value; + } + } + } /* namespace code */ + } /* namespace fec */ +} /* namespace gr */
\ No newline at end of file diff --git a/gr-fec/lib/ldpc_R_U_encoder_impl.h b/gr-fec/lib/ldpc_R_U_encoder_impl.h new file mode 100644 index 0000000000..97102c0cd4 --- /dev/null +++ b/gr-fec/lib/ldpc_R_U_encoder_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013-2014 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 3, or (at your + * option) any later version. + * + * This software 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 General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_FEC_LDPC_R_U_ENCODER_IMPL_H +#define INCLUDED_FEC_LDPC_R_U_ENCODER_IMPL_H + +#include <map> +#include <string> +#include <gnuradio/fec/ldpc_R_U_encoder.h> +#include <gnuradio/fec/ldpc_par_chk_mtrx.h> + +namespace gr { + namespace fec { + namespace code { + class FEC_API ldpc_R_U_encoder_impl : public ldpc_R_U_encoder + { + private: + void generic_work(void *inbuffer, void *outbuffer); + int get_output_size(); + int get_input_size(); + + // Number of bits in the information word + unsigned int d_frame_size; + // LDPC parity check matrix to use for encoding + ldpc_par_chk_mtrx *d_H; + + public: + ldpc_R_U_encoder_impl(ldpc_par_chk_mtrx *H_obj); + ~ldpc_R_U_encoder_impl(); + + bool set_frame_size(unsigned int frame_size); + double rate(); + }; + } /* namespace code */ + } /* namespace fec */ +} /* namespace gr */ + +#endif /* INCLUDED_FEC_LDPC_R_U_ENCODER_IMPL_H */
\ No newline at end of file diff --git a/gr-fec/swig/fec_swig.i b/gr-fec/swig/fec_swig.i index 0194cde92a..20fdc8af4e 100644 --- a/gr-fec/swig/fec_swig.i +++ b/gr-fec/swig/fec_swig.i @@ -68,6 +68,8 @@ #include "gnuradio/fec/polar_decoder_sc_list.h" #include "gnuradio/fec/polar_decoder_common.h" #include "gnuradio/fec/ldpc_par_chk_mtrx.h" +#include "gnuradio/fec/ldpc_bit_flip_decoder.h" +#include "gnuradio/fec/ldpc_R_U_encoder.h" %} %include "gnuradio/fec/generic_decoder.h" @@ -97,6 +99,8 @@ %include "gnuradio/fec/tpc_encoder.h" %include "gnuradio/fec/tpc_decoder.h" %include "gnuradio/fec/ldpc_par_chk_mtrx.h" +%include "gnuradio/fec/ldpc_bit_flip_decoder.h" +%include "gnuradio/fec/ldpc_R_U_encoder.h" GR_SWIG_BLOCK_MAGIC2(fec, decoder); GR_SWIG_BLOCK_MAGIC2(fec, encoder); |