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., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
23 #ifndef INCLUDED_ENCODER_CONVOLUTIONAL_H
24 #define INCLUDED_ENCODER_CONVOLUTIONAL_H
27 #include "code_convolutional_trellis.h"
29 class encoder_convolutional : public encoder
32 * class encoder_convolutional : public encoder
34 * Encode the incoming streams using a convolutional encoder; This is
35 * a virtual class which defines the basics of a convolutional
36 * encoder, but not how input and output bits are handled, nor
37 * feedback in the encoder. These features are all defined by
38 * overriding methods appropriately.
40 * block_size_bits: if == 0, then do streaming encoding ("infinite"
41 * trellis); otherwise this is the block size in bits to encode
42 * before terminating the trellis. This value -does not- include
43 * any termination bits.
47 * code_generator: vector of integers (32 bit) representing the code
48 * to be implemented. E.g. "4" in binary is "100", which would be
49 * "D^2" for code generation. "6" == 110b == "D^2 + D"
50 * ==> The vector is listed in order for each output stream, so if there
51 * are 2 input streams (I1, I2) [specified in "n_code_inputs"]
52 * and 2 output streams (O1, O2) [specified in "n_code_outputs"],
53 * then the vector would be the code generator for:
54 * [I1->O1, I2->O1, I1->O2, I2->O2]
55 * with each element being an integer representation of the code.
56 * The "octal" representation is used frequently in the literature
57 * (e.g. [015, 06] == [1101, 0110] in binary) due to its close
58 * relationship with binary (each number is 3 binary digits)
59 * ... but any integer representation will suffice.
61 * do_termination: valid only if block_size_bits != 0, and defines
62 * whether or not to use trellis termination. Default is to use
63 * termination when doing block coding.
65 * start_memory_state: when starting a new block, the starting memory
66 * state to begin encoding; there will be a helper function to
67 * assist in creating this value for a given set of inputs;
68 * default is the "all zero" state.
70 * end_memory_state: when terminating a block, the ending memory
71 * state to stop encoding; there will be a helper function to
72 * assist in creating this value for a given set of inputs;
73 * default is the "all zero" state.
77 inline encoder_convolutional
81 const std::vector<int> &code_generators,
82 bool do_termination = true,
83 int start_memory_state = 0,
84 int end_memory_state = 0)
85 {encoder_convolutional_init (block_size_bits,
95 * Encoder with feedback.
97 * code_feedback: vector of integers (32 bit) representing the code
98 * feedback to be implemented (same as for the code_generator).
99 * For this feedback type, the LSB ("& 1") is ignored (set to "1"
100 * internally, since it's always 1) ... this (effectively)
101 * represents the input bit for the given encoder, without which
102 * there would be no encoding! Each successive higher-order bit
103 * represents the output of that delay block; for example "6" ==
104 * 110b == "D^2 + D" means use the current input bit + the output
105 * of the second delay block. Listing order is the same as for
106 * the code_generator.
109 inline encoder_convolutional
110 (int block_size_bits,
113 const std::vector<int>& code_generators,
114 const std::vector<int>& code_feedback,
115 bool do_termination = true,
116 int start_memory_state = 0,
117 int end_memory_state = 0)
118 {encoder_convolutional_init (block_size_bits,
127 virtual ~encoder_convolutional () {delete d_trellis;};
130 * Compute the number of input bits needed to produce 'n_output' bits,
131 * and the number of output bits which will be produced by 'n_input'
132 * bits ... for a single stream only.
134 * For convolutional encoders, there is 1 bit output per bit input per
135 * stream, with the addition of a some bits for trellis termination if
136 * selected. Thus the input:output bit ratio will be:
138 * if (streaming | no termination), 1:1 exactly;
140 * if (not streaming & termination), depends on the state of the FSM,
141 * and needs to include the number of termination bits (the total # of
142 * delays); ratio is roughly (1:(1+X)), where "X" is the number of
143 * termination bits divided by the (unterminated) block length in bits.
145 * It's up to the caller to change 'bits' to 'items' ... to know if
146 * bits are packed (see e.g. code_io "ic8l") or not ("ic1l"), or all
147 * streams are mux'ed together into one stream.
150 virtual size_t compute_n_input_bits (size_t n_output_bits);
151 virtual size_t compute_n_output_bits (size_t n_input_bits);
153 /* for remote access to internal info */
155 inline const bool do_termination () {return (d_do_termination);};
156 inline const bool do_feedback () {return (d_trellis->do_feedback());};
157 inline const bool do_encode_soai () {return (d_trellis->do_encode_soai());};
158 inline const bool do_streaming () {return (d_do_streaming);};
159 inline const size_t total_n_delays () {return (d_total_n_delays);};
160 inline const size_t n_bits_to_term () {return (d_n_bits_to_term);};
161 inline const code_convolutional_trellis* trellis() {return (d_trellis);};
165 * fsm_enc_conv_t: finite state machine for the convolutional encoder;
166 * output happens all the time, so that's built-in to each state.
168 * fsm_enc_conv_init: initialize for a new block / block; this is already
169 * done at instantiation, so do it only at the end of a block.
171 * fsm_enc_conv_doing_input: doing encoding inside the trellis
173 * fsm_enc_conv_doing_term: termination trellis, if requested
176 enum fsm_enc_conv_t {
177 fsm_enc_conv_init, fsm_enc_conv_doing_input, fsm_enc_conv_doing_term
180 // methods defined in this class
182 void encoder_convolutional_init (int block_size_bits,
185 const std::vector<int>& code_generators,
186 const std::vector<int>* code_generators,
188 int start_memory_state,
189 int end_memory_state);
191 virtual void encode_private ();
192 virtual void encode_loop (size_t& which_counter, size_t how_many);
194 inline void get_next_inputs () {
195 switch (d_fsm_state) {
196 case fsm_enc_conv_doing_input:
197 get_next_inputs__input ();
199 case fsm_enc_conv_doing_term:
200 get_next_inputs__term ();
208 inline virtual void get_next_inputs__input () {
209 d_in_buf->read_items ((void*)(&(d_current_inputs[0])));
210 d_in_buf->increment_indices ();
214 inline virtual void get_next_inputs__term () {
215 d_trellis->get_termination_inputs (d_term_state,
220 inline virtual void write_output_bits () {
221 d_out_buf->write_items ((const void*)(&(d_current_outputs[0])));
222 d_out_buf->increment_indices ();
223 d_n_bits_to_output--;
226 void get_memory_requirements (size_t m,
229 size_t& t_n_unique_fb_prev_start,
230 const std::vector<int>* code_feedback);
234 fsm_enc_conv_t d_fsm_state;
235 bool d_do_streaming, d_do_termination;
237 // "total_n_delays" is the total # of delays, needed to determine the
238 // # of states in the decoder
240 size_t d_total_n_delays, d_n_enc_bits;
242 // the current state of the encoder (all delays / memories)
246 // "inputs" are the current input bits, in the LSB (&1) of each "char"
248 std::vector<char> d_current_inputs;
250 // "outputs" are the current output bits, in the LSB (&1) of each "char"
252 std::vector<char> d_current_outputs;
254 // "n_bits_to_term" is the number of bits to terminate the trellis
255 // to the desired state, as determined by the termination table.
256 // d_max_delay <= d_n_bits_to_term <= d_total_n_delays
257 // These numbers will vary depending on the realization.
259 size_t d_n_bits_to_term;
261 // "trellis" is the code trellis for the given input parameters
263 code_convolutional_trellis* d_trellis;
265 // "init_states" are the user-provided init states,
266 // interpreted w/r.t. the actual trellis;
268 memory_t d_init_state;
270 // "term_state" is the ending state before termination, used by the
271 // trellis to determine the correct input-bit sequences needed to
272 // properly terminate the trellis to the desired end-state;
273 // used only if doing termination.
275 memory_t d_term_state;
278 #endif /* INCLUDED_ENCODER_CONVOLUTIONAL_H */