diff options
Diffstat (limited to 'gr-fec/lib/ldpc_R_U_encoder_impl.cc')
-rw-r--r-- | gr-fec/lib/ldpc_R_U_encoder_impl.cc | 136 |
1 files changed, 136 insertions, 0 deletions
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 |