1 /* -*- c++ -*- */
2 /*
3 * Copyright 2014 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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "repetition_decoder_impl.h"
28 #include <math.h>
29 #include <stdio.h>
30 #include <volk/volk.h>
31 #include <boost/assign/list_of.hpp>
32 #include <sstream>
33 #include <vector>
34
35 namespace gr {
36 namespace fec {
37 namespace code {
38
make(int frame_size,int rep,float ap_prob)39 generic_decoder::sptr repetition_decoder::make(int frame_size, int rep, float ap_prob)
40 {
41 return generic_decoder::sptr(new repetition_decoder_impl(frame_size, rep, ap_prob));
42 }
43
repetition_decoder_impl(int frame_size,int rep,float ap_prob)44 repetition_decoder_impl::repetition_decoder_impl(int frame_size, int rep, float ap_prob)
45 : generic_decoder("repetition_decoder")
46 {
47 // Set max frame size here; all buffers and settings will be
48 // based on this value.
49 d_max_frame_size = frame_size;
50 set_frame_size(frame_size);
51
52 if (rep < 0)
53 throw std::runtime_error("repetition_encoder: repetition rate must be >= 0");
54 if ((ap_prob < 0) || (ap_prob > 1.0))
55 throw std::runtime_error(
56 "repetition_encoder: a priori probability rate must be in [0, 1]");
57
58 d_rep = rep;
59 d_ap_prob = ap_prob;
60 d_trials.resize(d_rep);
61 }
62
~repetition_decoder_impl()63 repetition_decoder_impl::~repetition_decoder_impl() {}
64
get_output_size()65 int repetition_decoder_impl::get_output_size()
66 {
67 // unpacked bits
68 return d_frame_size;
69 }
70
get_input_size()71 int repetition_decoder_impl::get_input_size() { return d_frame_size * d_rep; }
72
get_input_item_size()73 int repetition_decoder_impl::get_input_item_size() { return sizeof(float); }
74
get_input_conversion()75 const char* repetition_decoder_impl::get_input_conversion() { return "none"; }
76
get_shift()77 float repetition_decoder_impl::get_shift() { return 0; }
78
set_frame_size(unsigned int frame_size)79 bool repetition_decoder_impl::set_frame_size(unsigned int frame_size)
80 {
81 bool ret = true;
82 if (frame_size > d_max_frame_size) {
83 GR_LOG_INFO(d_logger,
84 boost::format("tried to set frame to %1%; max possible is %2%") %
85 frame_size % d_max_frame_size);
86 frame_size = d_max_frame_size;
87 ret = false;
88 }
89
90 d_frame_size = frame_size;
91
92 return ret;
93 }
94
rate()95 double repetition_decoder_impl::rate() { return 1.0 / static_cast<double>(d_rep); }
96
generic_work(void * inbuffer,void * outbuffer)97 void repetition_decoder_impl::generic_work(void* inbuffer, void* outbuffer)
98 {
99 const float* in = (const float*)inbuffer;
100 unsigned char* out = (unsigned char*)outbuffer;
101
102 for (unsigned int i = 0; i < d_frame_size; i++) {
103 for (unsigned int r = 0; r < d_rep; r++) {
104 d_trials[r] = (in[d_rep * i + r] > 0) ? 1.0f : 0.0f;
105 }
106 float res = std::count(d_trials.begin(), d_trials.end(), 1.0f);
107 if ((res / static_cast<float>(d_rep)) > d_ap_prob)
108 out[i] = 1;
109 else
110 out[i] = 0;
111 }
112 }
113
114 } /* namespace code */
115 } /* namespace fec */
116 } /* namespace gr */
117