1 /* -*- c++ -*- */
2 /*
3  * Copyright 2015 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include "ldpc_par_mtrx_encoder_impl.h"
24 #include <math.h>
25 #include <stdio.h>
26 #include <string.h> // for memcpy
27 #include <volk/volk.h>
28 #include <boost/assign/list_of.hpp>
29 #include <algorithm> // for std::reverse
30 #include <sstream>
31 #include <vector>
32 
33 namespace gr {
34 namespace fec {
35 namespace code {
36 
make(std::string alist_file,unsigned int gap)37 generic_encoder::sptr ldpc_par_mtrx_encoder::make(std::string alist_file,
38                                                   unsigned int gap)
39 {
40     code::ldpc_H_matrix::sptr H_obj = code::ldpc_H_matrix::make(alist_file, gap);
41     return make_H(H_obj);
42 }
43 
make_H(const code::ldpc_H_matrix::sptr H_obj)44 generic_encoder::sptr ldpc_par_mtrx_encoder::make_H(const code::ldpc_H_matrix::sptr H_obj)
45 {
46     return generic_encoder::sptr(new ldpc_par_mtrx_encoder_impl(H_obj));
47 }
48 
ldpc_par_mtrx_encoder_impl(const code::ldpc_H_matrix::sptr H_obj)49 ldpc_par_mtrx_encoder_impl::ldpc_par_mtrx_encoder_impl(
50     const code::ldpc_H_matrix::sptr H_obj)
51     : generic_encoder("ldpc_par_mtrx_encoder")
52 {
53     // LDPC parity check matrix to use for encoding
54     d_H = H_obj;
55 
56     d_rate = static_cast<double>(d_H->n()) / static_cast<double>(d_H->k());
57 
58     // Set frame size to k, the # of bits in the information word
59     // All buffers and settings will be based on this value.
60     set_frame_size(d_H->k());
61 }
62 
~ldpc_par_mtrx_encoder_impl()63 ldpc_par_mtrx_encoder_impl::~ldpc_par_mtrx_encoder_impl() {}
64 
get_output_size()65 int ldpc_par_mtrx_encoder_impl::get_output_size()
66 {
67     // return outputSize;
68     return d_output_size;
69 }
70 
get_input_size()71 int ldpc_par_mtrx_encoder_impl::get_input_size()
72 {
73     // return inputSize;
74     return d_frame_size;
75 }
76 
set_frame_size(unsigned int frame_size)77 bool ldpc_par_mtrx_encoder_impl::set_frame_size(unsigned int frame_size)
78 {
79     bool ret = true;
80 
81     if (frame_size % d_H->k() != 0) {
82         GR_LOG_ERROR(d_logger,
83                      boost::format("Frame size (%1% bits) must be a "
84                                    "multiple of the information word "
85                                    "size of the LDPC matrix (%2%).") %
86                          frame_size % (d_H->k()));
87         throw std::runtime_error("ldpc_par_mtrx_encoder: cannot use frame size.");
88     }
89 
90     d_frame_size = frame_size;
91 
92     d_output_size = static_cast<int>(d_rate * d_frame_size);
93 
94     return ret;
95 }
96 
rate()97 double ldpc_par_mtrx_encoder_impl::rate() { return d_rate; }
98 
generic_work(void * inbuffer,void * outbuffer)99 void ldpc_par_mtrx_encoder_impl::generic_work(void* inbuffer, void* outbuffer)
100 {
101     // Populate the information word
102     const unsigned char* in = (const unsigned char*)inbuffer;
103     unsigned char* out = (unsigned char*)outbuffer;
104 
105     int j = 0;
106     for (int i = 0; i < get_input_size(); i += d_H->k()) {
107         d_H->encode(&out[j], &in[i]);
108         j += d_H->n();
109     }
110 }
111 
112 } /* namespace code */
113 } /* namespace fec */
114 } /* namespace gr */
115