3 * Copyright 2006 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
27 #include <encoder_convolutional_ic8_ic8.h>
31 #define DO_TIME_THOUGHPUT 1
32 #define DO_PRINT_DEBUG 1
35 #include <mld/mld_timer.h>
41 // FIXME: when doing packed, should probably allow user to select how
42 // bits are selected, so-as to make sure it's always the same
43 // no matter the CPU endianness
47 encoder_convolutional_ic8_ic8::compute_n_output_bits
55 * Compute the number of input bits needed to produce
56 * 'n_output' bits. For convolutional encoders, there is
57 * 1 bit output per bit input per stream, with the addition of a some
58 * bits for trellis termination if selected. Thus the input:output
61 * if (streaming | no termination), 1:1
63 * if (not streaming & termination), roughly 1:(1+X), where "X" is the
64 * total memory size of the code divided by the block length in bits.
65 * But this also depends on the state of the FSM ... how many bits are
66 * left before termination.
68 * The returned value will also depend on whether bits are packed, as
69 * well as whether streams are mux'ed together.
73 encoder_convolutional_ic8_ic8::compute_n_input_bits
74 (size_t n_output_bits)
76 size_t t_n_output_bits, t_n_input_bits;
77 t_n_output_bits = t_n_input_bits = n_output_bits;
79 if (d_do_termination == true) {
81 // not streaming, doing termination; find the number of bits
82 // currently available with no required inputs, if any
85 if (d_fsm_state == fsm_enc_conv_doing_term) {
86 n_extra = d_max_memory - d_n_enc_bits;
89 // check to see if this is enough; return 0 if it is.
91 if (n_extra >= t_n_output_bits)
94 // remove those which require no input
96 t_n_output_bits -= n_extra;
98 // find the number of frames of data which could be processed
100 size_t t_n_output_bits_per_frame = d_frame_size_bits + d_max_memory;
102 // get the base number of input items required for the given
103 // number of frames to be generated
105 size_t t_n_frames = t_n_output_bits / t_n_output_bits_per_frame;
106 t_n_input_bits = t_n_frames * d_frame_size_bits;
108 // add to that the number of leftover inputs needed to generate
109 // the remainder of the outputs within the remaining frame, up to
110 // the given frame size (since anything beyond that within this
111 // frame requires no inputs)
113 size_t t_leftover_bits = t_n_output_bits % t_n_output_bits_per_frame;
114 t_n_input_bits += ((t_leftover_bits > d_frame_size_bits) ?
115 d_frame_size_bits : t_leftover_bits);
118 return (t_n_input_bits);
122 encoder_convolutional_ic8_ic8::increment_io_indices
123 (bool while_encoding)
125 // increment the buffer index only for this version, only after
126 // encoding is done and all resulting outputs are stored on the
129 if (while_encoding == false) {
134 // nothing to do while encoding, so no else
137 // move counters to the next input bit, wrapping to the next input
139 if (++d_in_bit_shift % g_num_bits_per_byte == 0) {
143 // move counters to the next output bit, wrapping to the next output
145 if (++d_out_bit_shift % g_num_bits_per_byte == 0) {
153 encoder_convolutional_ic8_ic8::output_bit
156 size_t t_output_stream)
158 // store the result for this particular output stream
159 // one bit per output item for "ic8" type output
161 if (DO_PRINT_DEBUG) {
162 std::cout << ", O_i[" << t_output_stream <<
163 "][" << d_out_buf_ndx << "] = " <<
164 n2bs (out_buf[t_output_stream][d_out_buf_ndx], 2);
167 out_buf[t_output_stream][d_out_buf_ndx] = t_out_bit;
169 if (DO_PRINT_DEBUG) {
170 std::cout << ", b_out = " << t_out_bit <<
171 ", O_o[" << t_output_stream << "][" << d_out_buf_ndx << "][" <<
172 d_out_bit_shift << "] = " <<
173 n2bs (out_buf[t_output_stream][d_out_buf_ndx], 2) << '\n';
178 std::cout << ", O_i[" << t_output_stream <<
179 "][" << d_out_buf_ndx << "] = " <<
180 n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte);
183 // packed bits in each output item
184 out_buf[t_output_stream][d_out_buf_ndx] |=
185 (t_out_bit << d_out_bit_shift);
188 std::cout << ", b_out = " << t_out_bit <<
189 ", O_o[" << t_output_stream << "][" << d_out_buf_ndx << "][" <<
190 d_out_bit_shift << "] = " <<
191 n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte) << '\n';
197 encoder_convolutional_ic8_ic8::get_next_bit__input
198 (const char** in_buf,
201 // get a bit from this particular input stream
202 // one bit per output item for "ic8" type input
204 if (DO_PRINT_DEBUG) {
205 std::cout << "I[" << p << "][" << d_in_buf_ndx << "] = ";
206 cout_binary (t_next_bit, g_num_bits_per_byte);
207 std::cout << ", st_i[" << p << "] = ";
208 cout_binary ((*t_states_ptr), d_max_memory+2);
209 std::cout << ", I[" << p << "][" << d_in_buf_ndx << "][" <<
210 d_in_bit_shift << "] = " << t_next_bit <<
211 ", st_o[" << p << "] = ";
212 cout_binary (t_state, d_max_memory+2);
216 return ((in_buf[code_input_n][d_in_buf_ndx] >> d_in_bit_shift) & 1);
220 encoder_convolutional_ic8_ic8::get_next_bit__term
221 (size_t code_input_n)
223 return ((d_term_states[code_input_n] >> d_in_bit_shift) & 1);