Updated FSF address in all files. Fixes ticket:51
[debian/gnuradio] / gr-error-correcting-codes / src / lib / ecc_streams_encode_turbo.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_streams_encode_turbo.h>
28 #include <gr_io_signature.h>
29 #include <assert.h>
30 #include <iostream>
31
32 ecc_streams_encode_turbo_sptr 
33 ecc_make_streams_encode_turbo
34 (int n_code_inputs,
35  int n_code_outputs,
36  const std::vector<ecc_streams_encode_convolutional_sptr> &encoders,
37  const std::vector<size_t> &interleavers)
38 {
39   return ecc_streams_encode_turbo_sptr
40     (new ecc_streams_encode_turbo (n_code_inputs,
41                                    n_code_outputs,
42                                    encoders,
43                                    interleavers));
44 }
45
46 ecc_streams_encode_turbo::ecc_streams_encode_turbo
47 (int n_code_inputs,
48  int n_code_outputs,
49  const std::vector<ecc_streams_encode_convolutional_sptr> &encoders,
50  const std::vector<size_t> &interleavers)
51   : gr_block ("streams_encode_turbo",
52               gr_make_io_signature (0, 0, 0),
53               gr_make_io_signature (0, 0, 0))
54 {
55   // error checking is done by the encoder class itself; just pass
56   // items on here.  But ... check out individual encoders, to make
57   // sure the total I/O matches those specified by the user.
58
59   d_n_encoders = encoders.size ();
60
61   if (d_n_encoders < 2) {
62     std::cerr << "ecc_streams_encode_turbo: Error: "
63       "too few (" << d_n_encoders << ") encoders specified; a Turbo "
64       "code requires at least 2 constituent encoders.\n";
65     assert (0);
66   }
67
68   // make sure that the block size and termination are consistent for
69   // all encoders; warn the user if not, since it doesn't really
70   // matter to the encoder (but it might to the decoder; remains to be
71   // seen).
72
73   encoder_convolutional* t_ec = encoders[0]->encoder ();
74   d_block_size_bits = t_ec->block_size_bits ();
75   d_do_termination = t_ec->do_termination ();
76   bool t_diff_block_size, t_diff_termination;
77   t_diff_block_size = t_diff_termination = false;
78
79   for (size_t m = 1; m < d_n_encoders; m++) {
80     t_ec = encoders[0]->encoder ();
81     size_t t_block_size_bits = t_ec->block_size_bits ();
82     if (t_block_size_bits != d_block_size_bits)
83       t_diff_block_size = true;
84     bool t_do_termination = t_ec->do_termination ();
85     if (t_do_termination != d_do_termination)
86       t_do_termination = true;
87   }
88
89   if (t_diff_block_size == true) {
90     std::cout << "ecc_streams_encode_turbo: Warning: "
91       "Some constituent encoders have different block size (bits).\n";
92   }
93   if (t_diff_termination == true) {
94     std::cout << "ecc_streams_encode_turbo: Warning: "
95       "Some constituent encoders are differently terminationed.\n";
96   }
97
98   std::cout << "ecc_streams_encode_turbo: setup:\n"
99     "d_n_encoders = " << d_n_encoders << "\n"
100     "n_code_inputs = " << n_code_inputs << "\n"
101     "n_code_outputs = " << n_code_outputs << "\n\n"
102     "Individual Encoders:\n";
103
104   for (size_t m = 0; m < d_n_encoders; m++) {
105     t_ec = encoders[m]->encoder ();
106     std::cout << "  [" << (m+1) << "]:\n"
107       "n_code_inputs = " << (t_ec->n_code_inputs()) << "\n"
108       "n_code_outputs = " << (t_ec->n_code_outputs()) << "\n"
109       "block_size_bits = " << (t_ec->block_size_bits()) << "\n"
110       "do_termination = " <<
111       ((t_ec->do_termination()==true)?"true":"false") << "\n";
112   }
113
114 #if 1
115   assert (0);
116 #else
117   if (d_n_encoders != (interleavers.size())) {}
118
119   d_encoder = new encoder_turbo (n_code_inputs,
120                                  n_code_outputs,
121                                  code_generators,
122                                  do_termination,
123                                  start_memory_state,
124                                  end_memory_state);
125 #endif
126
127   // create the correct input signature; 1 bit per input char
128
129   d_in_buf = new code_input_ic1l (n_code_inputs);
130   set_input_signature (gr_make_io_signature (n_code_inputs,
131                                              n_code_inputs,
132                                              sizeof (char)));
133
134   // create the correct output signature; 1 bit per output char
135
136   d_out_buf = new code_output_ic1l (n_code_outputs);
137   set_output_signature (gr_make_io_signature (n_code_outputs,
138                                               n_code_outputs,
139                                               sizeof (char)));
140 }
141
142 ecc_streams_encode_turbo::~ecc_streams_encode_turbo
143 ()
144 {
145   delete d_encoder;
146   d_encoder = 0;
147   delete d_in_buf;
148   d_in_buf = 0;
149   delete d_out_buf;
150   d_out_buf = 0;
151 }
152
153 void ecc_streams_encode_turbo::forecast
154 (int noutput_items,
155  gr_vector_int &ninput_items_required)
156 {
157   int ninput_items = d_encoder->compute_n_input_bits (noutput_items);
158   size_t ninputs = ninput_items_required.size();
159   for (size_t n = 0; n < ninputs; n++)
160     ninput_items_required[n] = ninput_items;
161 }
162
163 int
164 ecc_streams_encode_turbo::general_work
165 (int noutput_items,
166  gr_vector_int &ninput_items,
167  gr_vector_const_void_star &input_items,
168  gr_vector_void_star &output_items)
169 {
170   // compute the actual number of output items (1 bit char's) created.
171
172   size_t t_n_input_items = d_encoder->compute_n_input_bits (noutput_items);
173 #if 1
174   size_t t_n_output_items = d_encoder->compute_n_output_bits (t_n_input_items);
175   assert (t_n_output_items == ((size_t)noutput_items));
176 #endif
177   // setup the i/o buffers
178
179   d_in_buf->set_buffer ((void**)(&input_items[0]), t_n_input_items);
180   d_out_buf->set_buffer ((void**)(&output_items[0]), noutput_items);
181
182   // "work" is handled by the encoder; which returns the actual number
183   // of input items (1-bit char's) used.
184
185   t_n_input_items = d_encoder->encode (d_in_buf, d_out_buf,
186                                        (size_t) noutput_items);
187
188   assert (0);
189
190   // consume the number of used input items on all input streams
191
192   consume_each (t_n_input_items);
193
194   // returns number of items written to each output stream
195
196   return (noutput_items);
197 }