Houston, we have a trunk.
[debian/gnuradio] / gr-error-correcting-codes / src / lib / gr_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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gr_metrics_decode_viterbi_full_block.h>
28 #include <gr_io_signature.h>
29 #include <assert.h>
30 #include <iostream>
31
32 gr_metrics_decode_viterbi_full_block_sptr
33 gr_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 gr_metrics_decode_viterbi_full_block_sptr
44     (new gr_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 gr_metrics_decode_viterbi_full_block_feedback_sptr
56 gr_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 gr_metrics_decode_viterbi_full_block_feedback_sptr
68     (new gr_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 gr_metrics_decode_viterbi_full_block::gr_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_ic1_ic1 (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 gr_metrics_decode_viterbi_full_block::gr_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_ic1_ic1 (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 gr_metrics_decode_viterbi_full_block::~gr_metrics_decode_viterbi_full_block
131 ()
132 {
133   delete d_decoder;
134   delete d_encoder;
135 }
136
137 void
138 gr_metrics_decode_viterbi_full_block::setup_io_signatures
139 (int sample_precision,
140  int n_code_inputs,
141  int n_code_outputs)
142 {
143   // create the decoder using:
144   //
145   // the "i1" input model: individual input streams; two per metric
146   // type (0-bit, 1-bit), single metric per input item (char, short, long)
147   //
148   // the "ic1" output model:
149   // individual output streams per decoded code input stream;
150   // each item is a 'char' type with 1 bit aligned on the LSB.
151
152   d_decoder = new decoder_viterbi_full_block_i1_ic1 (sample_precision,
153                                                      d_encoder);
154
155   // error checking is done in the encoder and decoder classes
156   // so just use the parameters as given; will be correct!
157
158   d_n_code_inputs = n_code_inputs;
159   d_n_code_outputs = n_code_outputs;
160
161   // output signature is always the same:
162   // sizeof (char) with 1 bit per char as the LSB
163
164   set_output_signature (gr_make_io_signature (d_n_code_inputs,
165                                               d_n_code_inputs,
166                                               sizeof (char)));
167
168   // determine the input signature element size
169   size_t l_input_item_size_bytes;
170
171   if (sample_precision == 0) {
172     // float
173     l_input_item_size_bytes = sizeof (float);
174   } else if (sample_precision <= 8) {
175     // use char
176     l_input_item_size_bytes = sizeof (char);
177   } else if (sample_precision <= 16) {
178     // use short
179     l_input_item_size_bytes = sizeof (short);
180   } else {
181     // use long
182     l_input_item_size_bytes = sizeof (long);
183   }
184
185   set_input_signature (gr_make_io_signature (2*d_n_code_outputs,
186                                              2*d_n_code_outputs,
187                                              l_input_item_size_bytes));
188 }
189
190 void gr_metrics_decode_viterbi_full_block::forecast
191 (int noutput_items,
192  gr_vector_int &ninput_items_required)
193 {
194   int ninput_items = d_decoder->compute_n_input_metrics (noutput_items);
195   size_t ninputs = ninput_items_required.size();
196   for (size_t n = 0; n < ninputs; n++)
197     ninput_items_required[n] = ninput_items;
198 }
199
200 int
201 gr_metrics_decode_viterbi_full_block::general_work
202 (int noutput_items,
203  gr_vector_int &ninput_items,
204  gr_vector_const_void_star &input_items,
205  gr_vector_void_star &output_items)
206 {
207   // FIXME: compute the actual number of output items (1 bit char's) created.
208
209   size_t t_n_input_items = d_decoder->compute_n_input_metrics (noutput_items);
210   size_t t_n_output_items = d_decoder->compute_n_output_bits (t_n_input_items);
211
212   assert (t_n_output_items == ((size_t)noutput_items));
213
214   // "work" is handled by the decoder; which returns the actual number
215   // of input items (metrics) used.
216
217   t_n_input_items = d_decoder->decode ((const char**)(&input_items[0]),
218                                        (char**)(&output_items[0]),
219                                        noutput_items);
220
221   // consume the number of used input items on all input streams
222
223   consume_each (t_n_input_items);
224
225   // returns number of items written to each output stream
226
227   return (noutput_items);
228 }