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 <gnuradio/fec/decoder.h>
24 #include <gnuradio/fec/ldpc_decoder.h>
25 #include <gnuradio/fec/maxstar.h>
26 #include <math.h>
27 #include <stdio.h>
28 #include <string.h> // for memcpy
29 #include <volk/volk.h>
30 #include <boost/assign/list_of.hpp>
31 #include <algorithm> // for std::reverse
32 #include <sstream>
33 #include <vector>
34
35
36 namespace gr {
37 namespace fec {
38
39 generic_decoder::sptr
make(std::string alist_file,float sigma,int max_iterations)40 ldpc_decoder::make(std::string alist_file, float sigma, int max_iterations)
41 {
42 return generic_decoder::sptr(new ldpc_decoder(alist_file, sigma, max_iterations));
43 }
44
ldpc_decoder(std::string alist_file,float sigma,int max_iterations)45 ldpc_decoder::ldpc_decoder(std::string alist_file, float sigma, int max_iterations)
46 : generic_decoder("ldpc_decoder")
47 {
48 if (!boost::filesystem::exists(alist_file))
49 throw std::runtime_error("Bad AList file name!");
50
51 d_list.read(alist_file.c_str());
52 d_code.set_alist(d_list);
53 d_spa.set_alist_sigma(d_list, sigma);
54
55 d_rate =
56 static_cast<double>(d_code.dimension()) / static_cast<double>(d_code.get_N());
57 set_frame_size(d_code.dimension());
58
59 d_spa.set_K(d_output_size);
60 d_spa.set_max_iterations(max_iterations);
61 }
62
get_output_size()63 int ldpc_decoder::get_output_size() { return d_output_size; }
64
get_input_size()65 int ldpc_decoder::get_input_size() { return d_input_size; }
66
rate()67 double ldpc_decoder::rate() { return d_rate; }
68
set_frame_size(unsigned int frame_size)69 bool ldpc_decoder::set_frame_size(unsigned int frame_size)
70 {
71 if (frame_size % d_code.dimension() != 0) {
72 GR_LOG_ERROR(d_logger,
73 boost::format("Frame size (%1% bits) must be a "
74 "multiple of the information word "
75 "size of the LDPC matrix, %2%") %
76 frame_size % (d_code.dimension()));
77 throw std::runtime_error("ldpc_decoder: cannot use frame size.");
78 }
79
80 d_output_size = frame_size;
81 d_input_size = static_cast<int>(round(frame_size / d_rate));
82
83 return true;
84 }
85
generic_work(void * inBuffer,void * outBuffer)86 void ldpc_decoder::generic_work(void* inBuffer, void* outBuffer)
87 {
88 const float* in = (const float*)inBuffer;
89 unsigned char* out = (unsigned char*)outBuffer;
90
91 int j = 0;
92 std::vector<float> rx(d_code.get_N());
93 for (int i = 0; i < d_input_size; i += d_code.get_N()) {
94 for (int k = 0; k < d_code.get_N(); k++) {
95 rx[k] = in[i + k] * (-1);
96 }
97
98 int n_iterations = 0;
99 std::vector<char> estimate(d_spa.decode(rx, &n_iterations));
100 std::vector<char> data(d_code.get_systematic_bits(estimate));
101 memcpy(&out[j], &data[0], d_code.dimension());
102 d_iterations = n_iterations;
103
104 j += d_code.dimension();
105 }
106 }
107
get_input_item_size()108 int ldpc_decoder::get_input_item_size() { return sizeof(INPUT_DATATYPE); }
109
get_output_item_size()110 int ldpc_decoder::get_output_item_size() { return sizeof(OUTPUT_DATATYPE); }
111
get_history()112 int ldpc_decoder::get_history() { return 0; }
113
get_shift()114 float ldpc_decoder::get_shift() { return 0.0; }
115
get_conversion()116 const char* ldpc_decoder::get_conversion() { return "none"; }
117
~ldpc_decoder()118 ldpc_decoder::~ldpc_decoder() {}
119
120 } // namespace fec
121 } // namespace gr
122