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.
23 #ifndef INCLUDED_DECODER_VITERBI_H
24 #define INCLUDED_DECODER_VITERBI_H
27 #include "encoder_convolutional.h"
29 class decoder_viterbi : public decoder
33 * \brief Decode the incoming metrics streams using the Viterbi algorithm.
35 * input: streams of metrics, 2 streams per n_code_outputs - one each for
36 * a 0- and 1-bit metric.
38 * output: streams of char, one stream per n_code_inputs, using only
39 * the right-most justified bit as the single bit per output item.
41 * sample_precision: precision of the incoming metrics
42 * if == 0, then use soft precision (32 bit float);
43 * otherwise, use an integer up to 32 bits, already sign-extended
44 * to the nearest power-of-2-sized type (char, short, long).
46 * l_encoder: pointer to an encoder class from which to determine the
47 * trellis transitions (states and i/o bits).
50 decoder_viterbi (int sample_precision,
51 encoder_convolutional* l_encoder);
53 virtual ~decoder_viterbi ();
59 * connection_t: describes an output connection from the current
60 * time-bit memory state to the next time-bit memory state
62 * d_to: state pointer to which this connection going
64 * d_to_ndx: index of the "to" state
66 * d_output_bits: what are the output bits, coverted into
67 * 1->+1.0, 0->-1.0, for this connection
70 typedef struct connection_t {
74 } connection_t, *connection_t_ptr;
77 * state_t: describes a given memory state
79 * d_connections: a pointer to an array of these structures
80 * will be used to describes a given time-bit's memory state;
81 * an entry will be referenced via "state_add_to", to find the
82 * connections to the next time-bit memory states. There is
83 * one entry per each input bit combination -> 2^#I connections in all.
84 * e.g. [0] means the all 0 input;
85 * [1] means that input #1 was 1 while all the others were 0;
86 * [2] means that input #2 was 1, while all the others were 0;
87 * [3] means that inputs #1 and #2 were 1, while the others were 0.
89 * d_max_metric: the maximum metric thus far for this state
91 * d_max_state: the state from which the maximum metric was attained
93 * d_max_input: the input bits from which the maximum metric was attained
96 typedef struct state_t {
97 connection_t_ptr d_connections;
101 } state_t, *state_t_ptr;
104 * state_get_from(v,i,k): use to retrieve a given bit-memory state,
107 * memory_t v: the value from which to retrieve the given state
108 * size_t i: for which input stream (0 to #I-1)
109 * size_t k: the number of memory slots per input (e.g. 1+D^2 -> 2)
112 inline memory_t state_get_from (memory_t v,
115 {return (((v)>>((i)*(k)))&((1<<(k))-1));};
118 * state_add_to(s,v,i,k): use to create a given bit-memory state,
121 * memory_t s: the state value to modify
122 * memory_t v: value to set the state to for this input
123 * size_t i: for which input stream (0 to #I-1)
124 * size_t k: the number of memory slots per input (e.g. 1+D^2 -> 2)
127 inline void state_add_to (memory_t s,
131 {(s)|=(((v)&((1<<(k))-1))<<((i)*(k)));};
134 * fsm_dec_viterbi_t: finite state machine for the Viterbi decoder
136 * fsm_dec_viterbi_init: initialize for a new block / block; this is
137 * already done at instantiation, so do it only at the end of a
140 * fsm_dec_viterbi_doing_up: encoding at the start of a block
142 * fsm_dec_viterbi_doing_middle: doing encoding inside the trellis
144 * fsm_dec_viterbi_doing_term: termination trellis, if requested
147 enum fsm_dec_viterbi_t {
148 fsm_dec_viterbi_init, fsm_dec_viterbi_doing_up,
149 fsm_dec_viterbi_doing_middle, fsm_dec_viterbi_doing_term
152 virtual void decode_private (const char** in_buf, char** out_buf);
153 virtual char get_next_input (const char** in_buf, size_t code_input_n);
155 virtual void decode_loop (const char** in_buf, char** out_buf,
156 size_t* which_counter, size_t how_many);
158 virtual char get_next_input__up (const char** in_buf,
159 size_t code_input_n) = 0;
160 virtual char get_next_input__middle (const char** in_buf,
161 size_t code_input_n) = 0;
162 virtual char get_next_input__term (size_t code_input_n) = 0;
164 virtual void increment_input_indices (bool while_decoding) = 0;
165 virtual void increment_output_indices (bool while_decoding) = 0;
166 virtual void update_traceback__up (size_t from_state_ndx,
169 virtual void update_traceback__middle () = 0;
170 virtual void update_traceback__term () = 0;
172 void reset_metrics (u_char which);
173 void zero_metrics (u_char which);
175 encoder_convolutional* d_encoder;
176 fsm_dec_viterbi_t d_fsm_state;
177 size_t d_max_memory, d_total_memory;
178 size_t d_time_count, d_n_total_inputs_per_stream;
179 size_t d_n_saved_bits, d_n_saved_bits_start_ndx, d_n_traceback_els;
180 size_t d_n_states, d_n_input_combinations;
181 size_t d_states_ndx, d_up_term_ndx;
182 bool d_do_streaming, d_do_termination;
183 std::vector<memory_t> d_init_states, d_term_states;
184 char **d_save_buffer;
185 state_t_ptr d_states[2];
186 size_t* d_up_term_states_ndx[2];
189 #endif /* INCLUDED_DECODER_VITERBI_H */