[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] gr-error-correcting-codes/src lib/libecc/encode...
From: |
Michael Dickens |
Subject: |
[Commit-gnuradio] gr-error-correcting-codes/src lib/libecc/encode... |
Date: |
Wed, 12 Jul 2006 23:43:38 +0000 |
CVSROOT: /sources/gnuradio
Module name: gr-error-correcting-codes
Changes by: Michael Dickens <michaelld> 06/07/12 23:43:38
Modified files:
src/lib/libecc : encoder.h encoder_convolutional.cc
encoder_convolutional.h
encoder_convolutional_ic1_ic1.cc
encoder_convolutional_ic1_ic1.h
src/python : qa_test_encoder_convolutional_1.py
Log message:
Still a work in progress; likely won't function properly as a block,
but at least instantiates correctly and can provide debugging
comments to check for correctness.
Initial changes to allow for correct # delays required;
added checking of the 2 primary realizations, and selecting
the better of the 2. Revised the encoding programming to
make use of the selected realization, as well as if doing
feedback or not (thus, 4 possible encoders).
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder.h?cvsroot=gnuradio&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.cc?cvsroot=gnuradio&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.h?cvsroot=gnuradio&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.cc?cvsroot=gnuradio&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.h?cvsroot=gnuradio&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_1.py?cvsroot=gnuradio&r1=1.1&r2=1.2
Patches:
Index: lib/libecc/encoder.h
===================================================================
RCS file: /sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- lib/libecc/encoder.h 9 Jul 2006 16:15:17 -0000 1.4
+++ lib/libecc/encoder.h 12 Jul 2006 23:43:38 -0000 1.5
@@ -55,10 +55,17 @@
inline size_t n_code_outputs () {return (d_n_code_outputs);};
protected:
+ /* encode_private: encode the given in_buf and write the output bits
+ * to the out_buf, using internal class variables. This function is
+ * called from the publically available "encode()" methods, which
+ * first set the internal class variables before executing.
+ */
+
virtual void encode_private (const char** in_buf, char** out_buf) = 0;
- virtual char get_next_bit (const char** in_buf, size_t code_input_n) = 0;
- virtual void output_bit (char t_out_bit, char** out_buf,
- size_t t_output_stream) = 0;
+
+ /* inheriting methods need to figure out what makes the most sense
+ * for them in terms of getting new inputs and writing outputs.
+ */
size_t d_block_size_bits, d_n_code_inputs, d_n_code_outputs;
size_t d_n_enc_bits, d_total_n_enc_bits;
Index: lib/libecc/encoder_convolutional.cc
===================================================================
RCS file:
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- lib/libecc/encoder_convolutional.cc 9 Jul 2006 18:40:42 -0000 1.5
+++ lib/libecc/encoder_convolutional.cc 12 Jul 2006 23:43:38 -0000 1.6
@@ -40,6 +40,7 @@
static const int g_max_block_size_bits = 10000000;
static const int g_max_num_streams = 10;
+static const int g_num_bits_per_byte = 8;
void encoder_convolutional::encoder_convolutional_init
(int block_size_bits,
@@ -98,6 +99,10 @@
d_do_feedback = (code_feedback != NULL);
+ // set the initial FSM state to 'init'
+
+ d_fsm_state = fsm_enc_conv_init;
+
// create the class block variables
d_block_size_bits = block_size_bits;
@@ -123,7 +128,7 @@
// interger type, at least 32 bits) bits to represent memory and the
// code, as it makes the operations quite simple the state vectors.
- // d_states is a "matrix" [#input by #outputs] containing pointers
+ // d_states is a "matrix" [#input by #outputs] containing indices
// to memory_t's; this is done to make feedback function properly,
// and doesn't effect the computation time for feedforward. The
// issue is that any code with the same feedback can use the same
@@ -134,7 +139,7 @@
// encoder uses the correct memory.
// reference the matrix using "maoi(i,o)" ... see .h file.
- d_states.assign (d_n_code_inputs * d_n_code_outputs, NULL);
+ d_states_ndx.assign (d_n_code_inputs * d_n_code_outputs, 0);
// code generators (feedforward part) are [#inputs x #outputs],
// always - one for each I/O combination.
@@ -171,48 +176,13 @@
}
}
- if (d_do_feedback == true) {
- // resize the memory and states to the max size, worst case;
-
- // d_n_memories will define how many of these are actually used;
-
- // d_input_num and d_states will be set separately depending on
- // the actual feedback parameters.
-
- d_memory.assign (d_n_code_inputs * d_n_code_outputs, 0);
- d_init_states.assign (d_n_code_inputs * d_n_code_outputs, 0);
- d_term_states.assign (d_n_code_inputs * d_n_code_outputs, 0);
d_code_feedback.assign (d_n_code_inputs * d_n_code_outputs, 0);
- d_input_num.assign (d_n_code_inputs * d_n_code_outputs, 0);
- } else {
- // Setup for No Feedback;
- // 1 memory per input; same for init and term states;
-
- d_n_memories = d_n_code_inputs;
- d_memory.assign (d_n_memories, 0);
- d_init_states.assign (d_n_memories, 0);
- d_term_states.assign (d_n_memories, 0);
- d_code_feedback.assign (d_n_code_inputs * d_n_code_outputs, 0);
- d_input_num.assign (d_n_code_inputs * d_n_code_outputs, 0);
-
- // assign input numbers, one per memory
-
- for (size_t n = 0; n < d_n_code_inputs; n++)
- d_input_num[n] = n;
-
- // assign d_states' pointers correctly
- // loop over all I/O streams
-
- for (size_t n = 0; n < d_n_code_outputs; n++)
- for (size_t m = 0; m < d_n_code_inputs; m++)
- d_states[maoi(m,n)] = &(d_memory[m]);
- }
// copy over the FF code generators
for (size_t n = 0; n < d_n_code_outputs; n++)
for (size_t m = 0; m < d_n_code_inputs; m++)
- d_code_generators[maoi(m,n)] = code_generators[maoi(m,n)];
+ d_code_generators[maio(m,n)] = code_generators[maio(m,n)];
// check the input FF (and FB) code generators for correctness, and
// find the minimum memory configuration: combining via a single
@@ -236,7 +206,7 @@
for (size_t n = 0; n < d_n_code_outputs; n++) {
memory_t t_all_inputs_zero = 0;
for (size_t m = 0; m < d_n_code_inputs; m++)
- t_all_inputs_zero |= d_code_generators[maoi(m,n)];
+ t_all_inputs_zero |= d_code_generators[maio(m,n)];
// check this input to see if all encoders were '0'; this might be
// OK for some codes, but warn the user just in case
@@ -253,7 +223,7 @@
for (size_t m = 0; m < d_n_code_inputs; m++) {
memory_t t_all_outputs_zero = 0;
for (size_t n = 0; n < d_n_code_outputs; n++)
- t_all_outputs_zero |= d_code_generators[maoi(m,n)];
+ t_all_outputs_zero |= d_code_generators[maio(m,n)];
// check this input to see if all encoders were '0'; this might be
// OK for some codes, but warn the user just in case
@@ -265,193 +235,117 @@
}
}
-#if 0
-I GOT TO HERE!
-
- // single output, all inputs (SOAI) realization check
-
- std::vector<size_t> t_memories;
- size_t oa_max_mem, t_total_mem;
-
- t_memories.assign (d_n_code_outputs, 0);
- oa_max_mem = t_total_mem = 0;
- for (size_t n = 0; n < d_n_code_outputs; n++) {
- size_t t_max_mem = 0;
- for (size_t m = 0; m < d_n_code_inputs; m++) {
- size_t t_in_code = d_code_generators[maoi(m,n)];
-
- // find the memory requirement for this code generator
-
- size_t t_code_mem = 0;
- while (t_in_code != 0) {
- t_in_code >>= 1;
- t_code_mem++;
- }
- if (t_code_mem > t_max_mem)
- t_max_mem = t_code_mem;
-
- // check the feedback portion, if it exists;
- // for soai, check all the inputs which generate this output for
- // uniqueness; duplicate entries can be combined to reduce total
- // # of memories as well as required computations.
-
- if (d_do_feedback == true) {
- size_t t_save_code = t_in_code = (*d_code_feedback)[maoi(m,n)];;
-
- // find the memory requirement for this code generator
-
- t_code_mem = 0;
- while (t_in_code != 0) {
- t_in_code >>= 1;
- t_code_mem++;
- }
- if (t_code_mem > t_max_mem)
- t_max_mem = t_code_mem;
-
-
-
- // find if this feedback is unique for this input;
-
- size_t l_n_unique_fb = t_n_unique_fb_prev_start;
- while (l_n_unique_fb < d_n_memories) {
- if (d_code_feedback[l_n_unique_fb] == t_save_code)
- break;
- l_n_unique_fb++;
- }
- if (l_n_unique_fb == d_n_memories) {
-
- // this is a unique feedback;
- // create new entries for it in d_code_feedback and d_input_num
+ // create the inputs and outputs buffers
- d_code_feedback[l_n_unique_fb] = t_save_code;
- d_input_num[l_n_unique_fb] = m;
+ d_current_inputs.assign (d_n_code_inputs, 0);
+ d_current_outputs.assign (d_n_code_outputs, 0);
- // update the "or" of all unique memories
- t_all_inputs_one |= t_save_code;
- // find the memory requirement for this code feedback
+ // still need to fill in:
+ // d_max_delay, d_n_memories, d_total_n_delays,
+ // d_code_feedback (if FB), d_io_num, d_max_mem_masks (if SIAO),
+ // d_states_ndx, d_do_encode_soai
- size_t t_code_mem = 0;
- t_in_code = t_save_code;
- while (t_in_code != 0) {
- t_in_code >>= 1;
- t_code_mem++;
- }
- if (t_code_mem > t_max_mem)
- t_max_mem = t_code_mem;
+ // check and compute memory requirements in order to determine which
+ // realization uses the least memory; create and save findings to
+ // not have to re-do these computations later.
- // increase the number of unique feedback codes
-
- d_n_memories++;
- }
-
-
-
- }
+ // single output, all inputs (SOAI) realization:
+ // reset the global parameters
+ d_code_feedback.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_n_delays.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_io_num.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_states_ndx.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_max_delay = d_total_n_delays = d_n_memories = 0;
+ d_do_encode_soai = true;
+ for (size_t n = 0; n < d_n_code_outputs; n++) {
+ size_t t_max_mem = 0;
+ size_t t_n_unique_fb_prev_start = d_n_memories;
+ for (size_t m = 0; m < d_n_code_inputs; m++)
+ get_memory_requirements (m, n, t_max_mem,
+ t_n_unique_fb_prev_start, code_feedback);
+ if (d_do_feedback == false) {
+ // not feedback; just store memory requirements for this output
+ d_total_n_delays += t_max_mem;
}
-
- // store memory requirements for this output
-
- t_total_mem += t_max_mem;
- t_memories[n] = t_max_mem;
- if (oa_max_mem < t_max_mem)
- oa_max_mem = t_max_mem;
}
// store the parameters for SOAI
- std::vector<size_t> t_memories_soai = t_memories;
- size_t t_max_mem_soai = oa_max_mem;
- size_t t_total_mem_soai = t_total_mem;
+ std::vector<size_t> t_fb_generators_soai, t_n_delays_soai, t_io_num_soai;
+ std::vector<size_t> t_states_ndx_soai;
+ size_t t_max_delay_soai, t_total_n_delays_soai, t_n_memories_soai;
+
+ t_fb_generators_soai = d_code_feedback;
+ t_n_delays_soai = d_n_delays;
+ t_io_num_soai = d_io_num;
+ t_states_ndx_soai = d_states_ndx;
+ t_n_memories_soai = d_n_memories;
+ t_total_n_delays_soai = d_total_n_delays;
+ t_max_delay_soai = d_max_delay;
- // single input, all outputs (siao)
+ // single input, all outputs (SIAO) realization
+ // reset the global parameters
+
+ d_code_feedback.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_n_delays.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_io_num.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_states_ndx.assign (d_n_code_inputs * d_n_code_outputs, 0);
+ d_max_delay = d_total_n_delays = d_n_memories = 0;
+ d_do_encode_soai = false;
- t_memories.assign (d_n_code_inputs, 0);
- oa_max_mem = t_total_mem = 0;
for (size_t m = 0; m < d_n_code_inputs; m++) {
size_t t_max_mem = 0;
- for (size_t n = 0; n < d_n_code_outputs; n++) {
- size_t t_in_code = d_code_generators[maoi(m,n)];
-
- // find the memory requirement for this code generator
-
- size_t t_code_mem = 0;
- while (t_in_code != 0) {
- t_in_code >>= 1;
- t_code_mem++;
- }
- if (t_code_mem > t_max_mem)
- t_max_mem = t_code_mem;
-
- // check the feedback portion, if it exists
-
- if (d_do_feedback == true) {
- t_in_code = (*d_code_feedback)[maoi(m,n)];
+ size_t t_n_unique_fb_prev_start = d_n_memories;
- // find the memory requirement for this code generator
+ for (size_t n = 0; n < d_n_code_outputs; n++)
+ get_memory_requirements (m, n, t_max_mem,
+ t_n_unique_fb_prev_start, code_feedback);
- t_code_mem = 0;
- while (t_in_code != 0) {
- t_in_code >>= 1;
- t_code_mem++;
- }
- if (t_code_mem > t_max_mem)
- t_max_mem = t_code_mem;
+ if (d_do_feedback == false) {
+ // not feedback; just store memory requirements for this output
+ d_total_n_delays += t_max_mem;
}
}
- // store memory requirements for this output
-
- t_total_mem += t_max_mem;
- t_memories[n] = t_max_mem;
- if (oa_max_mem < t_max_mem)
- oa_max_mem = t_max_mem;
- }
-
- // store the parameters for SOAI
-
- std::vector<size_t> t_memories_siao = t_memories;
- size_t t_max_mem_siao = oa_max_mem;
- size_t t_total_mem_siao = t_total_mem;
-
if (DO_PRINT_DEBUG) {
- std::cout << "Parameters:\n"
- " max_mem_siao = " << t_max_mem_siao << "\n"
- " total_mem_siao = " << t_total_mem_siao << "\n"
- " max_mem_soai = " << t_max_mem_soai << "\n"
- " total_mem_soai = " << t_total_mem_soai << "\n";
+ std::cout <<
+ " t_total_n_delays_siao = " << d_total_n_delays << "\n"
+ " t_total_n_delays_soai = " << t_total_n_delays_soai << "\n";
}
// pick which realization to use; soai is preferred since it's faster
// ... but unfortunately it's also less likely
- if (t_max_mem_soai <= t_max_mem_soai) {
- // use soai
- d_do_encode_soai = true;
- d_memories_siao = t_memories;
- size_t t_max_mem_siao = t_max_mem;
- size_t t_total_mem_siao = t_total_mem;
+ if (d_total_n_delays < t_total_n_delays_soai) {
+ // use siao
+ d_do_encode_soai = false;
+ // nothing else to do yet, since the global variables already hold
+ // the correct values.
} else {
// use soai
d_do_encode_soai = true;
- d_memories_siao = t_memories;
- size_t t_max_mem_siao = t_max_mem;
- size_t t_total_mem_siao = t_total_mem;
+ d_code_feedback = t_fb_generators_soai;
+ d_n_delays = t_n_delays_soai;
+ d_io_num = t_io_num_soai;
+ d_states_ndx = t_states_ndx_soai;
+ d_n_memories = t_n_memories_soai;
+ d_total_n_delays = t_total_n_delays_soai;
+ d_max_delay = t_max_delay_soai;
}
- // store this maximum memory order (e.g. "2" -> D^2)
-
- d_max_delay = t_max_mem - 1;
-
if (DO_PRINT_DEBUG) {
std::cout <<
- "d_max_delay = " << d_max_delay << "\n";
+ " d_total_n_delays = " << d_total_n_delays << "\n"
+ " d_max_delay = " << d_max_delay << "\n"
+ " d_do_encode_soai = " <<
+ ((d_do_encode_soai == true) ? "true" : "false") << "\n";
}
// make sure the block length makes sense, #2
@@ -466,130 +360,126 @@
assert (0);
}
+ if (d_do_encode_soai == false) {
+ // create the max_mem_mask to be used in encoding
+ d_max_mem_masks.assign (d_n_memories, 0);
+ for (size_t m = 0; m < d_n_memories; m++) {
+ if (d_n_delays[m] == sizeof (memory_t) * g_num_bits_per_byte)
+ d_max_mem_masks[m] = -1;
+ else
+ d_max_mem_masks[m] = (2 << d_n_delays[m]) - 1;
+ }
+ }
- // check feedback portion, if it exists,
- // for correctness & # of memories
+// FIXME: STILL NEED TO parse START AND END MEMORY STATES;
+}
- if (d_do_feedback == true) {
- // need to check the code_feedback to make sure it's valid; need to
- // update the "d_max_delay" and comment back to the user if
- // feedback is longer than feedforward.
+void
+encoder_convolutional::get_memory_requirements
+(size_t m, // input number
+ size_t n, // output number
+ size_t& t_max_mem,
+ size_t& t_n_unique_fb_prev_start,
+ const std::vector<int>* code_feedback)
+{
+ size_t t_in_code = d_code_generators[maio(m,n)];
- if (d_do_feedback == true) {
+ // find the memory requirement for this code generator
- // check the code_feedback for correctness & find the memory order
- // t_max_mem will be the mamimum number of memories used by the
- // feedback; code_feedback will be in "input" first order, which is
- // what is required internally.
+ size_t t_code_mem_ff = max_bit_position (t_in_code);
- size_t t_max_mem = d_n_memories = 0;
- memory_t t_all_inputs_one = 0;
+ // check to see if this is bigger than any others in this row/column
- for (size_t n = 0; n < d_n_code_outputs; n++) {
- size_t t_n_unique_fb_prev_start = d_n_memories;
+ if (t_code_mem_ff > t_max_mem)
+ t_max_mem = t_code_mem_ff;
- for (size_t m = 0; m < d_n_code_inputs; m++) {
- size_t t_save_code = code_feedback[maio(m,n)];
- size_t t_in_code = t_save_code;
+ if (DO_PRINT_DEBUG) {
+ std::cout << "c_g[" << m << "][" << n << "]{" <<
+ maio(m,n) << "} = " << n2bs(t_in_code, 8) <<
+ ", code_mem = " << t_code_mem_ff;
+ }
- // check to make sure (code & 1) == 1; can't do this type of
- // convolutional encoder without it!
+ // check the feedback portion, if it exists;
+ // for soai, check all the inputs which generate this output for
+ // uniqueness; duplicate entries can be combined to reduce total
+ // # of memories as well as required computations.
- if ((t_in_code & 1) != 1) {
- std::cerr << "encoder_convolutional: " <<
- "All feedback codes must contain a '1' for the least "
- "significant bit.\n";
- assert (0);
+ if (d_do_feedback == true) {
+ if (DO_PRINT_DEBUG) {
+ std::cout << "\n";
}
- // find if this feedback is unique for this input;
+ // get the FB code, and OR with 1 to make sure it's valid
+
+ t_in_code = ((*code_feedback)[maio(m,n)]) | 1;
+
+ // find the memory requirement
+
+ size_t t_code_mem_fb = max_bit_position (t_in_code);
+
+ if (DO_PRINT_DEBUG) {
+ std::cout << "c_f[" << m << "][" << n << "]{" <<
+ maio(m,n) << "} = " << n2bs(t_in_code, 8) <<
+ ", code_mem = " << t_code_mem_fb;
+ }
+
+ // check to see if this feedback is unique
size_t l_n_unique_fb = t_n_unique_fb_prev_start;
while (l_n_unique_fb < d_n_memories) {
- if (d_code_feedback[l_n_unique_fb] == t_save_code)
+ if (d_code_feedback[l_n_unique_fb] == t_in_code)
break;
l_n_unique_fb++;
}
if (l_n_unique_fb == d_n_memories) {
// this is a unique feedback;
- // create new entries for it in d_code_feedback and d_input_num
- d_code_feedback[l_n_unique_fb] = t_save_code;
- d_input_num[l_n_unique_fb] = m;
-
- // update the "or" of all unique memories
-
- t_all_inputs_one |= t_save_code;
-
- // find the memory requirement for this code feedback
-
- size_t t_code_mem = 0;
- t_in_code = t_save_code;
- while (t_in_code != 0) {
- t_in_code >>= 1;
- t_code_mem++;
- }
- if (t_code_mem > t_max_mem)
- t_max_mem = t_code_mem;
+ d_code_feedback[l_n_unique_fb] = t_in_code;
+ d_n_delays[l_n_unique_fb] = t_code_mem_fb;
// increase the number of unique feedback codes
d_n_memories++;
- }
-
- // create the new entry in d_states
- d_states[maio(m,n)] = &(d_memory[l_n_unique_fb]);
- }
- }
-
- // check to see if the feedback's memory requirements are
- // greater than the feedforward's; warn the user (not sure why,
- // but it seems like a good idea).
+ // store memory requirements for this output
- if (--t_max_mem > d_max_delay) {
- std::cout << "encoder_convolutional: Warning: " <<
- "Feedback using more memory than feedforward.\n";
- d_max_delay = t_max_mem;
+ if (t_max_mem < t_code_mem_fb)
+ t_max_mem = t_code_mem_fb;
+ d_total_n_delays += t_max_mem;
- // make sure the block length makes sense, #2
+ if (DO_PRINT_DEBUG) {
+ std::cout << ", uq # " << l_n_unique_fb <<
+ ", tot_mem = " << d_total_n_delays;
+ }
+ } else {
+ // not a unique feedback, but the FF might require more memory
- if ((d_do_streaming == false) & (d_block_size_bits < d_max_delay)) {
- std::cerr << "encoder_convolutional: " <<
- "Requested block length (" << d_block_size_bits <<
- " bit" << (d_block_size_bits > 1 ? "s" : "") <<
- ") must be at least 1 memory length (" << d_max_delay <<
- " bit" << (d_max_delay > 1 ? "s" : "") <<
- " for this code) when doing block coding.\n";
- assert (0);
+ if (DO_PRINT_DEBUG) {
+ std::cout << ", !uq # " << l_n_unique_fb <<
+ " = " << d_n_delays[l_n_unique_fb];
}
- // create the memory mask for this code generator
+ if (d_n_delays[l_n_unique_fb] < t_code_mem_ff) {
+ d_total_n_delays += (t_code_mem_ff - d_n_delays[l_n_unique_fb]);
+ d_n_delays[l_n_unique_fb] = t_code_mem_ff;
- d_max_mem_mask = (2 << d_max_delay) - 1;
+ if (DO_PRINT_DEBUG) {
+ std::cout << " => " << d_n_delays[l_n_unique_fb] <<
+ ", tot_mem = " << d_total_n_delays;
}
}
}
-
- // create the memory mask for this code generator
-
- d_max_mem_mask = (2 << d_max_delay) - 1;
-
-// FIXME: STILL NEED TO parse START AND END MEMORY STATES;
-
- // set the initial FSM state to 'init'
-
- d_fsm_state = fsm_enc_conv_init;
-
+ d_io_num[l_n_unique_fb] = ((d_do_encode_soai == true) ? n : m);
+ d_states_ndx[maio(m,n)] = l_n_unique_fb;
+ }
if (DO_PRINT_DEBUG) {
- std::cout << "Encoder:\n Mask = " <<
- n2bs (d_max_mem_mask, d_max_delay+2) <<
- "\n Max_Mem = " << d_max_delay << "\n.";
+ std::cout << "\n";
}
-#endif
+ if (d_max_delay < t_max_mem)
+ d_max_delay = t_max_mem;
}
void
@@ -720,29 +610,16 @@
}
void
-encoder_convolutional::encode_loop
-(const char** in_buf,
- char** out_buf,
- size_t* which_counter,
- size_t how_many)
-{
- if (d_do_encode_soai == true)
- encode_loop_soai (in_buf, out_buf, which_counter, how_many);
- else
- encode_loop_siao (in_buf, out_buf, which_counter, how_many);
-}
-
-void
encoder_convolutional::encode_loop_soai
(const char** in_buf,
char** out_buf,
size_t* which_counter,
size_t how_many)
{
- // single-output, all inputs
+ // single-output, all inputs; no feedback
if (DO_PRINT_DEBUG) {
- std::cout << "starting encode_loop_soai.\n";
+ std::cout << "Starting encode_loop_soai.\n";
}
while (((*which_counter) > 0) & (d_n_enc_bits < how_many)) {
@@ -752,50 +629,45 @@
"Getting new inputs.\n";
}
- // get a new input bit per stream, and update the memory;
- // loop over all inputs, push the current state bit into d_memory
- // (which is pointed to by d_states, and thus both are updated).
+ // get the next set of input bits from all streams;
+ // written into d_current_inputs
+ get_next_inputs (in_buf);
-#if 0
- for (m = 0; m < d_n_code_outputs; m++) {
- memory_t t_mem = ??? >> 1;
- for (n = 0; n < d_n_code_inputs; n++) {
- if (get_next_bit (in_buf, d_input_num[???]))
- t_mem ^= d_code_generator[maoi(n,m)];
- }
- char t_out_bit = t_mem & 1;
-
- if ((d_do_feedback == true) & t_out_bit)
- t_mem ^= (d_code_feedback (??[m]) & (d_mem_mask - 1));
+ // shift memories down by 1 bit to make room for feedback; no
+ // masking required.
- ??? = t_mem;
+ for (size_t p = 0; p < d_n_memories; p++) {
+ d_memory[p] >>= 1;
+ }
- // output this particular bit on this output stream
+ // for each input bit, if that bit's a '1', then XOR the code
+ // generators into the correct state's memory.
- output_bit (t_out_bit, out_buf, m);
+ for (size_t m = 0; m < d_n_code_inputs; m++) {
+ if (d_current_inputs[m] == 1) {
+ for (size_t n = 0; n < d_n_code_outputs; n++) {
+ d_memory[d_states_ndx[maio(m,n)]] ^= d_code_generators[maio(m,n)];
+ }
+ }
+ }
- // increment the input and output indices, if necessary, between
- // output bits
+ // create the output bits, by XOR'ing the individual unique
+ // memory(ies) into the correct output bit
- increment_io_indices (true);
+ for (size_t p = 0; p < d_n_memories; p++) {
+ d_current_outputs[d_io_num[p]] ^= ((char)(d_memory[p] & 1));
}
-#endif
- // increment the input and output counters, if necessary, between
- // input bits
- increment_io_indices (false);
+ // write the bits in d_current_outputs into the output buffer
+
+ write_output_bits (out_buf);
// increment the number of encoded bits for the current block, and
// the total number of bits for this running of "encode()"
d_n_enc_bits++;
d_total_n_enc_bits++;
-
- // decrement the number of input and output bits left
-
- d_n_input_bits_left--;
- d_n_output_bits_left--;
}
if (DO_PRINT_DEBUG) {
@@ -804,17 +676,18 @@
}
void
-encoder_convolutional::encode_loop_siao
+encoder_convolutional::encode_loop_soai_fb
(const char** in_buf,
char** out_buf,
size_t* which_counter,
size_t how_many)
{
- // single input, all outputs
+ // single-output, all inputs; with feedback
if (DO_PRINT_DEBUG) {
- std::cout << "starting encode_loop_siao.\n";
+ std::cout << "Starting encode_loop_soai_fb.\n";
}
+
while (((*which_counter) > 0) & (d_n_enc_bits < how_many)) {
if (DO_PRINT_DEBUG) {
std::cout << "*w_c = " << (*which_counter) << ", "
@@ -822,209 +695,219 @@
"Getting new inputs.\n";
}
- // get a new input bit per stream, and update the memory;
- // loop over all inputs, push the current state bit into d_memory
- // (which is pointed to by d_states, and thus both are updated).
+ // get the next set of input bits from all streams;
+ // written into d_current_inputs
+
+ get_next_inputs (in_buf);
+
+ // shift memories down by 1 bit to make room for feedback; no
+ // masking required.
for (size_t p = 0; p < d_n_memories; p++) {
- if (DO_PRINT_DEBUG) {
- std::cout << "mem_in[" << p << "] = " <<
- n2bs (d_memory[p], d_max_delay+2) << "\n";
+ d_memory[p] >>= 1;
}
- d_memory[p] |= get_next_bit (in_buf, d_input_num[p]);
+ // for each input bit, if that bit's a '1', then XOR the code
+ // generators into the correct state's memory.
- if (DO_PRINT_DEBUG) {
- std::cout << "mem_out[" << p << "] = " <<
- n2bs (d_memory[p], d_max_delay+2) << "\n";
+ for (size_t m = 0; m < d_n_code_inputs; m++) {
+ if (d_current_inputs[m] == 1) {
+ for (size_t n = 0; n < d_n_code_outputs; n++) {
+ d_memory[d_states_ndx[maio(m,n)]] ^= d_code_generators[maio(m,n)];
+ }
}
}
- // now encode those inputs using the code generators,
- // and output a single bit per output stream
+ // create the output bits, by XOR'ing the individual unique
+ // memory(ies) into the correct output bit
- // loop over all outputs
+ for (size_t p = 0; p < d_n_memories; p++) {
+ d_current_outputs[d_io_num[p]] ^= ((char)(d_memory[p] & 1));
+ }
- for (size_t q = 0; q < d_n_code_outputs; q++) {
- memory_t t_out_result = 0;
+ // now that the output bits are fully created, XOR the FB back
+ // into the memories; the feedback bits have the LSB (&1) masked
+ // off already so that it doesn't contribute.
- // loop over all inputs, xor'ing the result each time
+ for (size_t p = 0; p < d_n_memories; p++) {
+ if (d_current_outputs[d_io_num[p]] == 1) {
+ d_memory[p] ^= d_code_feedback[p];
+ }
+ }
- for (size_t p = 0; p < d_n_code_inputs; p++) {
- memory_t t_c_g = d_code_generators[maoi(p,q)];
- memory_t t_mem = (*(d_states[maoi(p,q)]));
+ // write the bits in d_current_outputs into the output buffer
- if (DO_PRINT_DEBUG) {
- std::cout << "b_i = " <<
- n2bs (t_out_result, d_max_delay+2) <<
- ", st[" << p << "," << q << "] = " <<
- n2bs (t_mem, d_max_delay+2) <<
- ", cg[" << p << "," << q << "] = " <<
- n2bs (t_c_g, d_max_delay+2) <<
- ", st[] & cg[] = " <<
- n2bs (t_mem & t_c_g, d_max_delay+2);
- }
+ write_output_bits (out_buf);
- t_out_result ^= (t_mem & t_c_g);
+ // increment the number of encoded bits for the current block, and
+ // the total number of bits for this running of "encode()"
- if (DO_PRINT_DEBUG) {
- std::cout << ", b_o = " <<
- n2bs (t_out_result, d_max_delay+2) << '\n';
- }
+ d_n_enc_bits++;
+ d_total_n_enc_bits++;
}
+
if (DO_PRINT_DEBUG) {
- std::cout << "b_r = " << n2bs (t_out_result, d_max_delay+2);
+ std::cout << "ending encode_loop_soai.\n";
}
+}
- // sum the number of set bits, mod 2, for the output bit
-
- char t_out_bit = sum_bits_mod2 (t_out_result, d_max_delay);
+void
+encoder_convolutional::encode_loop_siao
+(const char** in_buf,
+ char** out_buf,
+ size_t* which_counter,
+ size_t how_many)
+{
+ // single input, all outputs; no feedback
if (DO_PRINT_DEBUG) {
- std::cout << "t_out_bit = mo2_sum (b_o) = " <<
- n2bs (t_out_result, 2);
+ std::cout << "starting encode_loop_siao.\n";
}
- // output this particular bit on this output stream
-
- output_bit (t_out_bit, out_buf, q);
-
- // increment the input and output indices, if necessary, between
- // output bits
-
- increment_io_indices (true);
+ while (((*which_counter) > 0) & (d_n_enc_bits < how_many)) {
+ if (DO_PRINT_DEBUG) {
+ std::cout << "*w_c = " << (*which_counter) << ", "
+ "# enc_bits = " << d_n_enc_bits << " of " << how_many << ".\n"
+ "Getting new inputs.\n";
}
- // do post-encoding memory mods (e.g. feedback); at a minimum:
- // must shift memory to get ready for a new input bit, and mask
- // off any extra bit from shifting (beyond a particular input's
- // memory bits).
+ // get the next set of input bits from all streams;
+ // written into d_current_inputs
- // update memory with any feedback, then shift up (left) by 1 bit
- // and mask the memory state to be ready for the next input
+ get_next_inputs (in_buf);
- // loop over all memories, shift the memory left (up) by 1 bit and
- // mask off any high non-memory bit(s)
+ // update the memories with the current input bits;
+ // pre-shift delays instead of post-shift to gather loops.
- if (DO_PRINT_DEBUG) {
- std::cout << " doing memory shift and mask:\n";
- }
+ // for each unique memory (1 per input), shift the delays and mask
+ // off the extra high bits; then XOR in the input bit.
for (size_t p = 0; p < d_n_memories; p++) {
- if (DO_PRINT_DEBUG) {
- std::cout << " mem_in[" << p << "] = " <<
- n2bs (d_memory[p], d_max_delay+2) << "\n";
+ memory_t t_mem = (d_memory[p] << 1) & d_max_mem_masks[p];
+ d_memory[p] = t_mem ^ ((memory_t)(d_current_inputs[d_io_num[p]]));
}
- d_memory[p] = (d_memory[p] << 1) & d_max_mem_mask;
+ // create the output bits: for each output, loop over all inputs,
+ // find the output bits for each encoder, and XOR each together
+ // then sum (would usually be sum then XOR, but they're mutable in
+ // base-2 and it's faster this way).
- if (DO_PRINT_DEBUG) {
- std::cout << " mem_out[" << p << "] = " <<
- n2bs (d_memory[p], d_max_delay+2) << "\n";
+ for (size_t n = 0; n < d_n_code_outputs; n++) {
+ memory_t t_mem = 0;
+ for (size_t m = 0; m < d_n_code_inputs; m++) {
+ t_mem ^= ((d_memory[d_states_ndx[maio(m,n)]]) &
+ d_code_generators[maio(m,n)]);
}
+ d_current_outputs[n] = sum_bits_mod2 (t_mem, d_max_delay);
}
- if (d_do_feedback == true) {
-
- if (DO_PRINT_DEBUG) {
- std::cout << " doing feedback:\n";
+#if 0
+ for (size_t p = 0; p < d_n_memories; p++) {
+ memory_t t_mem = (d_memory[p] << 1);
+ d_memory[p] = (t_mem & d_max_mem_masks[p]);
}
+#endif
- // loop over all unique memories, creating the feedback bit for each
- // and placing those bits in the state's second bit location
+ // write the bits in d_current_outputs into the output buffer
- for (size_t p = 0; p < d_n_memories; p++) {
- if (DO_PRINT_DEBUG) {
- std::cout << " mem_in[" << p << "] = " <<
- n2bs (d_memory[p], d_max_delay+2) << "\n";
- }
+ write_output_bits (out_buf);
- // do feedback with current memory
- // get the memory, and zero out the second bit
+ // increment the number of encoded bits for the current block, and
+ // the total number of bits for this running of "encode()"
- memory_t t_state = d_memory[p] & (d_max_mem_mask ^ 2);
+ d_n_enc_bits++;
+ d_total_n_enc_bits++;
+ }
if (DO_PRINT_DEBUG) {
- std::cout << " t_state = mem[] & (" << d_max_mem_mask <<
- " xor 2) = " << n2bs (t_state, d_max_delay+2) << "\n";
+ std::cout << "ending encode_loop_siao.\n";
}
+}
- // create the code feedback state
+void
+encoder_convolutional::encode_loop_siao_fb
+(const char** in_buf,
+ char** out_buf,
+ size_t* which_counter,
+ size_t how_many)
+{
+ // single input, all outputs; with feedback
- memory_t t_fb_state = t_state & (d_code_feedback[p]);
+ if (DO_PRINT_DEBUG) {
+ std::cout << "starting encode_loop_siao_fb.\n";
+ }
+ while (((*which_counter) > 0) & (d_n_enc_bits < how_many)) {
if (DO_PRINT_DEBUG) {
- std::cout << " t_fb_state = t_state & {fb[" << p << "] == " <<
- d_code_feedback[p] << "} = " <<
- n2bs (t_fb_state, d_max_delay+2) << "\n";
+ std::cout << "*w_c = " << (*which_counter) << ", "
+ "# enc_bits = " << d_n_enc_bits << " of " << how_many << ".\n"
+ "Getting new inputs.\n";
}
- // mod2 sum the feedback state to get the feedback bit value
+ // get the next set of input bits from all streams;
+ // written into d_current_inputs
- char t_fb_bit = sum_bits_mod2 (t_fb_state, d_max_delay);
+ get_next_inputs (in_buf);
- if (DO_PRINT_DEBUG) {
- std::cout << " t_fb_bit = mod2_sum (t_fb_state) = " <<
- n2bs (t_fb_bit, 2) << "\n";
- }
+ // update the memories with the current input bits;
+ // pre-shift delays instead of post-shift to gather loops.
- // place the feedback bit into the second state bit
+ // for each unique memory (1 per input), shift the delays and mask
+ // off the extra high bits; then XOR in the input bit.
+ // with FB: find the feedback bit, and OR it into the input bit's slot;
- d_memory[p] = t_state | (t_fb_bit << 1);
+ for (size_t p = 0; p < d_n_memories; p++) {
+ memory_t t_mem = (d_memory[p] << 1) & d_max_mem_masks[p];
+ memory_t t_fb = t_mem & d_code_feedback[p];
+ char t_fb_bit = sum_bits_mod2 (t_fb, d_max_delay);
+ t_mem |= ((memory_t) t_fb_bit);
+ d_memory[p] = t_mem ^ ((memory_t)(d_current_inputs[d_io_num[p]]));
+ }
- if (DO_PRINT_DEBUG) {
- std::cout << " mem_out[" << p << "] = t_state | (fb_bit << 1) = "
<<
- n2bs (d_memory[p], d_max_delay+2) << "\n";
+ // create the output bits: for each output, loop over all inputs,
+ // find the output bits for each encoder, and XOR each together
+ // then sum (would usually be sum then XOR, but they're mutable in
+ // base-2 and it's faster this way).
+
+ for (size_t n = 0; n < d_n_code_outputs; n++) {
+ memory_t t_mem = 0;
+ for (size_t m = 0; m < d_n_code_inputs; m++) {
+ t_mem ^= ((d_memory[d_states_ndx[maio(m,n)]]) &
+ d_code_generators[maio(m,n)]);
}
+ d_current_outputs[n] = sum_bits_mod2 (t_mem, d_max_delay);
}
+
+#if 0
+ for (size_t p = 0; p < d_n_memories; p++) {
+ memory_t t_mem = (d_memory[p] << 1);
+ d_memory[p] = (t_mem & d_max_mem_masks[p]);
}
+#endif
- // increment the input and output counters, if necessary, between
- // input bits
+ // write the bits in d_current_outputs into the output buffer
- increment_io_indices (false);
+ write_output_bits (out_buf);
// increment the number of encoded bits for the current block, and
// the total number of bits for this running of "encode()"
d_n_enc_bits++;
d_total_n_enc_bits++;
-
- // decrement the number of input and output bits left
-
- d_n_input_bits_left--;
- d_n_output_bits_left--;
}
if (DO_PRINT_DEBUG) {
- std::cout << "ending encode_loop_siao.\n";
- }
-}
-
-char
-encoder_convolutional::get_next_bit
-(const char** in_buf,
- size_t code_input_n)
-{
- char ret_val = 0;
- switch (d_fsm_state) {
- case fsm_enc_conv_doing_input:
- ret_val = get_next_bit__input (in_buf, code_input_n);
- break;
- case fsm_enc_conv_doing_term:
- ret_val = get_next_bit__term (code_input_n);
- break;
- default:
- assert (0);
- break;
+ std::cout << "ending encode_loop_siao_fb.\n";
}
- return (ret_val);
}
-char
-encoder_convolutional::get_next_bit__term
-(size_t code_input_n)
+void
+encoder_convolutional::get_next_inputs__term
+()
{
// FIXME: how to figure out which term bit to get?
- return (d_term_states[code_input_n] & 1);
+ // loop to set each entry of "d_current_inputs"
+
+ d_current_inputs.assign (d_n_code_inputs, 0);
+ // return (d_term_states[code_input_n] & 1);
}
Index: lib/libecc/encoder_convolutional.h
===================================================================
RCS file:
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- lib/libecc/encoder_convolutional.h 9 Jul 2006 16:15:17 -0000 1.4
+++ lib/libecc/encoder_convolutional.h 12 Jul 2006 23:43:38 -0000 1.5
@@ -176,6 +176,24 @@
inline size_t maoi(size_t i, size_t o) {return ((i*d_n_code_outputs) + o);};
+/*
+ * max_bit_position (x): returns the bit-number of the highest "1" bit
+ * in the provided value, such that the LSB would return 0 and the MSB
+ * of a long would return 31.
+ */
+
+ inline size_t max_bit_position (memory_t x)
+ {
+ size_t t_code_mem = 0;
+ memory_t t_in_code = x >> 1;
+ while (t_in_code != 0) {
+ t_in_code >>= 1;
+ t_code_mem++;
+ }
+
+ return (t_code_mem);
+ }
+
// methods defined in this class
void encoder_convolutional_init (int block_size_bits,
@@ -188,52 +206,134 @@
int end_memory_state);
virtual void encode_private (const char** in_buf, char** out_buf);
- virtual void encode_loop (const char** in_buf, char** out_buf,
- size_t* which_counter, size_t how_many);
+
+ inline void encode_loop (const char** in_buf, char** out_buf,
+ size_t* which_counter, size_t how_many) {
+ if (d_do_encode_soai == true) {
+ if (d_do_feedback == true) {
+ encode_loop_soai_fb (in_buf, out_buf, which_counter, how_many);
+ } else {
+ encode_loop_soai (in_buf, out_buf, which_counter, how_many);
+ }
+ } else {
+ if (d_do_feedback == true) {
+ encode_loop_siao (in_buf, out_buf, which_counter, how_many);
+ } else {
+ encode_loop_siao (in_buf, out_buf, which_counter, how_many);
+ }
+ }
+ };
+
virtual void encode_loop_soai (const char** in_buf, char** out_buf,
size_t* which_counter, size_t how_many);
virtual void encode_loop_siao (const char** in_buf, char** out_buf,
size_t* which_counter, size_t how_many);
- virtual char get_next_bit (const char** in_buf, size_t code_input_n);
- virtual char get_next_bit__term (size_t code_input_n);
+ virtual void encode_loop_soai_fb (const char** in_buf, char** out_buf,
+ size_t* which_counter, size_t how_many);
+ virtual void encode_loop_siao_fb (const char** in_buf, char** out_buf,
+ size_t* which_counter, size_t how_many);
+
+ inline void get_next_inputs (const char** in_buf) {
+ switch (d_fsm_state) {
+ case fsm_enc_conv_doing_input:
+ get_next_inputs__input (in_buf);
+ break;
+ case fsm_enc_conv_doing_term:
+ get_next_inputs__term ();
+ break;
+ default:
+ assert (0);
+ break;
+ }
+ };
+
+ virtual void get_next_inputs__term ();
+
+ void get_memory_requirements (size_t m,
+ size_t n,
+ size_t& t_max_mem,
+ size_t& t_n_unique_fb_prev_start,
+ const std::vector<int>* code_feedback);
// methods which are required by classes which inherit from this
// one; primarily just the parts which deal with getting input bits
// and writing output bits, changing the indices for those buffers.
- virtual char get_next_bit__input (const char** in_buf,
- size_t code_input_n) = 0;
- virtual void increment_io_indices (bool while_encoding) = 0;
+ virtual void write_output_bits (char** out_buf) = 0;
+ virtual void get_next_inputs__input (const char** in_buf) = 0;
// variables
fsm_enc_conv_t d_fsm_state;
bool d_do_streaming, d_do_termination, d_do_feedback, d_do_encode_soai;
- memory_t d_max_mem_mask;
- // max_delay is the max # of delays for all unique generators (ff and fb),
+ // "max_delay" is the max # of delays for all unique generators (ff and fb),
// needed to determine (e.g.) termination
size_t d_max_delay;
- // n_memories is the number of unique memories as determined by
- // either the feedforward or feedback generators (not both).
+ // "n_memories" is the number of unique memories as determined by
+ // either the feedforward or feedback generators (not both). For
+ // FF, this number equals either the number of code inputs (for
+ // SIAO) or outputs (for SOAI).
size_t d_n_memories;
- // total_n_delays is the total # of delays, needed to determine the
+ // "total_n_delays" is the total # of delays, needed to determine the
// # of states in the decoder
size_t d_total_n_delays;
- // code generators and feedback are stored internally in "maXY(i,o)"
- // order this allows for looping over all a single output and
- // computing all input parts sequentially.
+ // "code generators" are stored internally in "maXY(i,o)" order this
+ // allows for looping over all a single output and computing all
+ // input parts sequentially.
+
+ std::vector<memory_t> d_code_generators;
+
+ // "feedback" are found as "d_n_memories" unique entries, and stored
+ // in at most 1 entry per I/O combination. Listed in the same order
+ // as "d_io_num" entries show.
+
+ std::vector<memory_t> d_code_feedback;
+
+ // "n_delays" is a vector, the number of delays for the FB generator
+ // in the same [] location; also relates directly to the
+ // "max_mem_masks" in the same [] location.
+
+ std::vector<size_t> d_n_delays;
+
+ // "io_num" is a vector, mapping which FB in SIAO goes with which
+ // input, or which FB in SOAI goes with which output
+
+ std::vector<size_t> d_io_num;
+
+ // "max_mem_masks" are the memory masks, one per unique FB for SIAO;
+ // otherwise not used.
+
+ std::vector<memory_t> d_max_mem_masks;
+
+ // "states_ndx" is a "matrix" whose contents are the indices into
+ // the "io_num" vector, telling which input goes with which
+ // state; uses the same "maXY(i,o)" as the code generators.
+
+ std::vector<size_t> d_states_ndx;
+
+ // "memory" are the actual stored delay bits, one memory for each
+ // unique FF or FB code generator;
+ // "init_states" are the user-provided init states - and
+ // "term_states" are the user-provided termination states -
+ // interpreted w/r.t. the actual FF and FB code generators and SOAI
+ // / SIAO realization;
- std::vector<memory_t> d_code_generators, d_code_feedback;
- std::vector<memory_ptr_t> d_states;
std::vector<memory_t> d_memory, d_init_states, d_term_states;
- std::vector<size_t> d_input_num;
+
+ // "inputs" are the current input bits, in the LSB (&1) of each "char"
+
+ std::vector<char> d_current_inputs;
+
+ // "outputs" are the current output bits, in the LSB (&1) of each "char"
+
+ std::vector<char> d_current_outputs;
};
#endif /* INCLUDED_ENCODER_CONVOLUTIONAL_H */
Index: lib/libecc/encoder_convolutional_ic1_ic1.cc
===================================================================
RCS file:
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- lib/libecc/encoder_convolutional_ic1_ic1.cc 9 Jul 2006 18:40:42 -0000
1.3
+++ lib/libecc/encoder_convolutional_ic1_ic1.cc 12 Jul 2006 23:43:38 -0000
1.4
@@ -113,57 +113,69 @@
}
void
-encoder_convolutional_ic1_ic1::increment_io_indices
-(bool while_encoding)
+encoder_convolutional_ic1_ic1::write_output_bits
+(char** out_buf)
{
- // increment the buffer index only (not the internal bit shift
- // indices) for "ic1" type, only after encoding is done and all
- // resulting outputs are stored on the output streams; nothing to do
- // while encoding
+ // write all the outputs bits in d_current_outputs LSB (&1) to the
+ // given output buffer.
- if (while_encoding == false) {
- d_out_buf_ndx++;
- d_in_buf_ndx++;
- }
-}
-
-void
-encoder_convolutional_ic1_ic1::output_bit
-(char t_out_bit,
- char** out_buf,
- size_t t_output_stream)
-{
- // store the result for this particular output stream
- // one bit per output item for "ic1" type output
+ // one bit per output 'char' for "ic1" type output
+ for (size_t n = 0; n < d_n_code_outputs; n++) {
if (DO_PRINT_DEBUG) {
std::cout << "Starting output_bit:\n"
- " O_i[" << t_output_stream << "][" << d_out_buf_ndx << "] = " <<
- n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte) <<
- ", b_out = " << n2bs (t_out_bit, 2) << ", ";
+ " O_i[" << n << "][" << d_out_buf_ndx << "] = " <<
+ n2bs (out_buf[n][d_out_buf_ndx], g_num_bits_per_byte) <<
+ ", b_out = " << n2bs (d_current_outputs[n], 2) << ", ";
}
- out_buf[t_output_stream][d_out_buf_ndx] = t_out_bit;
+ out_buf[n][d_out_buf_ndx] = d_current_outputs[n];
if (DO_PRINT_DEBUG) {
std::cout << "O_o[][] = " <<
- n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte) <<
- "\nEnding output_bit.\n";
+ n2bs (out_buf[n][d_out_buf_ndx], g_num_bits_per_byte) <<
+ "\n";
+ }
+ }
+
+ if (DO_PRINT_DEBUG) {
+ std::cout << "Ending write_output_bits.\n";
}
+
+ // decrement the number of output bits left on all streams
+
+ d_n_output_bits_left--;
+
+ // increment the output index (not the bit shift index) for the next
+ // write
+
+ d_out_buf_ndx++;
}
-char
-encoder_convolutional_ic1_ic1::get_next_bit__input
-(const char** in_buf,
- size_t code_input_n)
+void
+encoder_convolutional_ic1_ic1::get_next_inputs__input
+(const char** in_buf)
{
- // get a bit from this particular input stream
- // one bit per output item for "ic1" type input
+ // get the next set of input bits, moved into the LSB (&1) of
+ // d_current_inputs
+
+ // one bit per input 'char' for "ic1" type input
+
+ for (size_t m = 0; m < d_n_code_inputs; m++) {
+ d_current_inputs[m] = ((in_buf[m][d_in_buf_ndx]) & 1);
if (DO_PRINT_DEBUG) {
- std::cout << "I[" << code_input_n << "][" << d_in_buf_ndx << "] = " <<
- n2bs (in_buf[code_input_n][d_in_buf_ndx], 2) << "\n";
+ std::cout << "I[" << m << "][" << d_in_buf_ndx << "] = " <<
+ n2bs (d_current_inputs[m], 2) << "\n";
+ }
}
- return (in_buf[code_input_n][d_in_buf_ndx] & 1);
+ // decrement the number of bits left on all streams
+
+ d_n_input_bits_left--;
+
+ // increment the input index (not the bit shift index) for the next
+ // read
+
+ d_in_buf_ndx++;
}
Index: lib/libecc/encoder_convolutional_ic1_ic1.h
===================================================================
RCS file:
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- lib/libecc/encoder_convolutional_ic1_ic1.h 9 Jul 2006 16:15:17 -0000
1.3
+++ lib/libecc/encoder_convolutional_ic1_ic1.h 12 Jul 2006 23:43:38 -0000
1.4
@@ -84,11 +84,8 @@
virtual size_t compute_n_output_bits (size_t n_input_bits);
protected:
- virtual char get_next_bit__input (const char** in_buf,
- size_t code_input_n);
- virtual void output_bit (char t_out_bit, char** out_buf,
- size_t t_output_stream);
- virtual void increment_io_indices (bool while_encoding);
+ virtual void get_next_inputs__input (const char** in_buf);
+ virtual void write_output_bits (char** out_buf);
};
#endif /* INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_H */
Index: python/qa_test_encoder_convolutional_1.py
===================================================================
RCS file:
/sources/gnuradio/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_1.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- python/qa_test_encoder_convolutional_1.py 9 Jul 2006 16:15:17 -0000
1.1
+++ python/qa_test_encoder_convolutional_1.py 12 Jul 2006 23:43:38 -0000
1.2
@@ -24,15 +24,11 @@
from gnuradio.eng_option import eng_option
def main ():
- frame_size = 10
- enc_code_in_chan = 2
- code_generators = [05, 04] #, 03, 04] # , 0, 07]
- enc_code_out_chan = len (code_generators) / enc_code_in_chan
+ e1 = ecc.streams_encode_convolutional (100, 3, 2, [1, 0, 5, 0, 1, 6])
- ss_enc = ecc.streams_encode_convolutional (frame_size,
- enc_code_in_chan,
- enc_code_out_chan,
- code_generators)
+ e2 = ecc.streams_encode_convolutional (100, 2, 3, [1, 0, 0, 1, 5, 6])
+
+ e3 = ecc.streams_encode_convolutional_feedback (100, 2, 3, [1, 7, 0, 1,
5, 6], [1, 1, 1, 1, 017, 017])
if __name__ == '__main__':
main ()
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] gr-error-correcting-codes/src lib/libecc/encode...,
Michael Dickens <=