Statistics
| Branch: | Tag: | Revision:

root / gr-error-correcting-codes / src / lib / ecc_metrics_decode_viterbi_full_block.cc @ c5b588b8

History | View | Annotate | Download (6.9 kB)

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 <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
}