Updated FSF address in all files. Fixes ticket:51
[debian/gnuradio] / gr-error-correcting-codes / src / lib / ecc_metrics_decode_viterbi_full_block.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006 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 2, 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 <ecc_metrics_decode_viterbi_full_block.h>
28 #include <gr_io_signature.h>
29 #include <assert.h>
30 #include <iostream>
31
32 ecc_metrics_decode_viterbi_full_block_sptr
33 ecc_make_metrics_decode_viterbi_full_block
34 (int sample_precision,
35  int frame_size_bits,
36  int n_code_inputs,
37  int n_code_outputs,
38  const std::vector<int>& code_generator,
39  bool do_termination,
40  int start_memory_state,
41  int end_memory_state)
42 {
43   return ecc_metrics_decode_viterbi_full_block_sptr
44     (new ecc_metrics_decode_viterbi_full_block
45      (sample_precision,
46       frame_size_bits,
47       n_code_inputs,
48       n_code_outputs,
49       code_generator,
50       do_termination,
51       start_memory_state,
52       end_memory_state));
53 }
54
55 ecc_metrics_decode_viterbi_full_block_feedback_sptr
56 ecc_make_metrics_decode_viterbi_full_block_feedback
57 (int sample_precision,
58  int frame_size_bits,
59  int n_code_inputs,
60  int n_code_outputs,
61  const std::vector<int>& code_generator,
62  const std::vector<int>& code_feedback,
63  bool do_termination,
64  int start_memory_state,
65  int end_memory_state)
66 {
67   return ecc_metrics_decode_viterbi_full_block_feedback_sptr
68     (new ecc_metrics_decode_viterbi_full_block
69      (sample_precision,
70       frame_size_bits,
71       n_code_inputs,
72       n_code_outputs,
73       code_generator,
74       code_feedback,
75       do_termination,
76       start_memory_state,
77       end_memory_state));
78 }
79
80 ecc_metrics_decode_viterbi_full_block::ecc_metrics_decode_viterbi_full_block
81 (int sample_precision,
82  int frame_size_bits,
83  int n_code_inputs,
84  int n_code_outputs,
85  const std::vector<int>& code_generator,
86  bool do_termination,
87  int start_memory_state,
88  int end_memory_state)
89   : gr_block ("metrics_decode_viterbi_full_block",
90               gr_make_io_signature (0, 0, 0),
91               gr_make_io_signature (0, 0, 0))
92 {
93   d_encoder = new encoder_convolutional (frame_size_bits,
94                                          n_code_inputs,
95                                          n_code_outputs,
96                                          code_generator,
97                                          do_termination,
98                                          start_memory_state,
99                                          end_memory_state);
100
101   setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
102 }
103
104 ecc_metrics_decode_viterbi_full_block::ecc_metrics_decode_viterbi_full_block
105 (int sample_precision,
106  int frame_size_bits,
107  int n_code_inputs,
108  int n_code_outputs,
109  const std::vector<int>& code_generator,
110  const std::vector<int>& code_feedback,
111  bool do_termination,
112  int start_memory_state,
113  int end_memory_state)
114   : gr_block ("metrics_decode_viterbi_full_block_feedback",
115               gr_make_io_signature (0, 0, 0),
116               gr_make_io_signature (0, 0, 0))
117 {
118   d_encoder = new encoder_convolutional (frame_size_bits,
119                                          n_code_inputs,
120                                          n_code_outputs,
121                                          code_generator,
122                                          code_feedback,
123                                          do_termination,
124                                          start_memory_state,
125                                          end_memory_state);
126
127   setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
128 }
129
130 ecc_metrics_decode_viterbi_full_block::~ecc_metrics_decode_viterbi_full_block
131 ()
132 {
133   delete d_decoder;
134   d_decoder = 0;
135   delete d_encoder;
136   d_encoder = 0;
137   delete d_in_buf;
138   d_in_buf = 0;
139   delete d_out_buf;
140   d_out_buf = 0;
141 }
142
143 void
144 ecc_metrics_decode_viterbi_full_block::setup_io_signatures
145 (int sample_precision,
146  int n_code_inputs,
147  int n_code_outputs)
148 {
149   // create the decoder
150   //
151   // the input model: individual input streams; two per metric type
152   // (0-bit, 1-bit), single metric per input item (float, char, short,
153   // long)
154   //
155   // the "ic1l" output model:
156   // individual output streams per decoded code input stream;
157   // each item is a 'char' type with 1 bit aligned on the LSB.
158
159   d_decoder = new decoder_viterbi_full_block (sample_precision,
160                                               d_encoder);
161   d_out_buf = new code_output_ic1l (n_code_inputs);
162
163   // error checking is done in the encoder and decoder classes
164   // so just use the parameters as given; will be correct!
165
166   d_n_code_inputs = n_code_inputs;
167   d_n_code_outputs = n_code_outputs;
168
169   // output signature is always the same:
170   // sizeof (char) with 1 bit per char as the LSB
171
172   set_output_signature (gr_make_io_signature (d_n_code_inputs,
173                                               d_n_code_inputs,
174                                               sizeof (char)));
175
176   // determine the input signature element size
177   size_t l_input_item_size_bytes;
178
179   if (sample_precision == 0) {
180     // float
181     l_input_item_size_bytes = sizeof (float);
182     d_in_buf = new code_input_if (n_code_outputs);
183   } else if (sample_precision <= 8) {
184     // use char
185     l_input_item_size_bytes = sizeof (char);
186     d_in_buf = new code_input_ic (n_code_outputs);
187   } else if (sample_precision <= 16) {
188     // use short
189     l_input_item_size_bytes = sizeof (short);
190     d_in_buf = new code_input_is (n_code_outputs);
191   } else {
192     // use long
193     l_input_item_size_bytes = sizeof (long);
194     d_in_buf = new code_input_il (n_code_outputs);
195   }
196
197   set_input_signature (gr_make_io_signature (2*d_n_code_outputs,
198                                              2*d_n_code_outputs,
199                                              l_input_item_size_bytes));
200 }
201
202 void ecc_metrics_decode_viterbi_full_block::forecast
203 (int noutput_items,
204  gr_vector_int &ninput_items_required)
205 {
206   int ninput_items = d_decoder->compute_n_input_items (noutput_items);
207   size_t ninputs = ninput_items_required.size();
208   for (size_t n = 0; n < ninputs; n++)
209     ninput_items_required[n] = ninput_items;
210 }
211
212 int
213 ecc_metrics_decode_viterbi_full_block::general_work
214 (int noutput_items,
215  gr_vector_int &ninput_items,
216  gr_vector_const_void_star &input_items,
217  gr_vector_void_star &output_items)
218 {
219   // compute the actual number of output items (1 bit char's) created.
220
221   size_t t_n_input_items = d_decoder->compute_n_input_items (noutput_items);
222 #if 1
223   size_t t_n_output_items = d_decoder->compute_n_output_bits (t_n_input_items);
224   assert (t_n_output_items == ((size_t)noutput_items));
225 #endif
226
227   // setup the i/o buffers
228
229   d_in_buf->set_buffer ((void**)(&input_items[0]), t_n_input_items);
230   d_out_buf->set_buffer ((void**)(&output_items[0]), noutput_items);
231
232   // "work" is handled by the decoder; which returns the actual number
233   // of input items (metrics) used.
234
235   t_n_input_items = d_decoder->decode (d_in_buf, d_out_buf,
236                                        (size_t) noutput_items);
237
238   // consume the number of used input items on all input streams
239
240   consume_each (t_n_input_items);
241
242   // returns number of items written to each output stream
243
244   return (noutput_items);
245 }