commit-gnuradio
[Top][All Lists]
Advanced

[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: Tue, 04 Jul 2006 01:55:56 +0000

CVSROOT:        /sources/gnuradio
Module name:    gr-error-correcting-codes
Changes by:     Michael Dickens <michaelld>     06/07/04 01:55:56

Added files:
        src/lib/libecc : encoder_convolutional_ic1_ic1_ff.cc 
                         encoder_convolutional_ic1_ic1_ff.h 

Log message:
        The new "ic1" encoders mentioned before.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1_ff.cc?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1_ff.h?cvsroot=gnuradio&rev=1.1

Patches:
Index: encoder_convolutional_ic1_ic1_ff.cc
===================================================================
RCS file: encoder_convolutional_ic1_ic1_ff.cc
diff -N encoder_convolutional_ic1_ic1_ff.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ encoder_convolutional_ic1_ic1_ff.cc 4 Jul 2006 01:55:56 -0000       1.1
@@ -0,0 +1,250 @@
+/* -*- c++ -*- */
+/*
+ * Copyright @ 2006 Michael Dickens
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this library; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <encoder_convolutional_ic1_ic1_ff.h>
+#include <assert.h>
+#include <iostream>
+
+#define DO_TIME_THOUGHPUT 1
+#define DO_PRINT_DEBUG 1
+
+#if DO_TIME_THOUGHPUT
+#include <mld/mld_timer.h>
+#endif
+#if DO_PRINT_DEBUG
+#include <mld/n2bs.h>
+#endif
+
+encoder_convolutional_ic1_ic1_ff::encoder_convolutional_ic1_ic1_ff
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ std::vector<int> &code_generators,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : encoder_convolutional_base
+    (frame_size_bits,
+     n_code_inputs,
+     n_code_outputs,
+     code_generators,
+     do_termination,
+     start_memory_state,
+     end_memory_state) {}
+
+size_t
+encoder_convolutional_ic1_ic1_ff::compute_n_output_bits
+(size_t n_input_bits)
+{
+  assert (0);
+  return (0);
+}
+
+/*
+ * Compute the number of input bits needed to produce
+ * 'n_output' bits.  For convolutional encoders, there is
+ * 1 bit output per bit input per stream, with the addition of a some
+ * bits for trellis termination if selected.  Thus the input:output
+ * bit ratio will be:
+ * 
+ * if (streaming | no termination), 1:1
+ *
+ * if (not streaming & termination), roughly 1:(1+X), where "X" is the
+ * total memory size of the code divided by the block length in bits.
+ * But this also depends on the state of the FSM ... how many bits are
+ * left before termination.
+ *
+ * The returned value will also depend on whether bits are packed, as
+ * well as whether streams are mux'ed together.
+ */
+
+size_t
+encoder_convolutional_ic1_ic1_ff::compute_n_input_bits
+(size_t n_output_bits)
+{
+  size_t t_n_output_bits, t_n_input_bits;
+  t_n_output_bits = t_n_input_bits = n_output_bits;
+
+  if (d_do_termination == true) {
+// not streaming, doing termination
+// find the number of bits currently available with no required inputs, if any
+    size_t n_extra = 0;
+    if (d_fsm_state == fsm_enc_conv_doing_term) {
+      n_extra = d_max_memory - d_n_enc_bits;
+    }
+
+// check to see if this is enough; return 0 if it is.
+    if (n_extra >= t_n_output_bits)
+      return (0);
+
+// remove those which require no input
+    t_n_output_bits -= n_extra;
+
+// find the number of frames of data which could be processed
+    size_t t_n_output_bits_per_frame = d_frame_size_bits + d_max_memory;
+
+// get the base number of input items required for the given number of
+// frames to be generated
+    size_t t_n_frames = t_n_output_bits / t_n_output_bits_per_frame;
+    t_n_input_bits = t_n_frames * d_frame_size_bits;
+
+// add to that the number of leftover inputs needed to generate the
+// remainder of the outputs within the remaining frame, up to the
+// given frame size (since anything beyond that within this frame
+// requires no inputs)
+    size_t t_leftover_bits = t_n_output_bits % t_n_output_bits_per_frame;
+    t_n_input_bits += ((t_leftover_bits > d_frame_size_bits) ?
+                      d_frame_size_bits : t_leftover_bits);
+  }
+
+  return (t_n_input_bits);
+}
+
+void
+encoder_convolutional_ic1_ic1_ff::update_memory_post_encode
+()
+{
+// update memory with any feedback, then shift up (left) by 1 bit and
+// mask the memory state to be ready for the next input
+
+// loop over all inputs, push the current state bit into d_states
+  memory_ptr_t t_states_ptr = &(d_states[0]);
+  for (size_t p = 0; p < d_n_code_inputs; p++) {
+    memory_t t_state = ((*t_states_ptr) << 1) & d_max_mem_mask;
+    (*t_states_ptr++) = t_state;
+  }
+
+#if 0
+// loop over all inputs, push the current state bit into d_states
+    memory_ptr_t t_states_ptr = &(d_states[0]);
+    memory_ptr_t t_fb_ptr = &(d_code_feedback[0]);
+    for (size_t p = 0; p < d_n_code_inputs; p++) {
+// do feedback with current memory
+      memory_t t_state = (*t_states_ptr);
+      memory_t t_fd = t_state & (*t_fb_ptr++);
+      t_state |= sum_bits_mod2 (t_state, d_max_memory);
+      t_state <<= 1;
+      t_state &= d_max_mem_mask;
+      (*t_states_ptr++) = t_state;
+    }
+  }
+#endif
+}
+
+void
+encoder_convolutional_ic1_ic1_ff::increment_io_indices
+(bool while_encoding)
+{
+// increment the buffer index only for this version, only after encoding
+// is done and all resulting outputs are stored on the output streams
+  if (while_encoding == false) {
+    d_out_buf_ndx++;
+// increment the input buffer index only for this version
+    d_in_buf_ndx++;
+  }
+#if 0
+// move counters to the next input bit, wrapping to the next input
+// byte as necessary
+  if (++d_in_bit_shift % g_num_bits_per_byte == 0) {
+    d_in_bit_shift = 0;
+    d_in_buf_ndx++;
+  }
+// move counters to the next output bit, wrapping to the next output
+// byte as necessary
+    if (++d_out_bit_shift % g_num_bits_per_byte == 0) {
+      d_out_bit_shift = 0;
+      d_out_buf_ndx++;
+    }
+#endif
+}
+
+void
+encoder_convolutional_ic1_ic1_ff::output_bit
+(char t_out_bit,
+ char** out_buf,
+ size_t t_output_stream)
+{
+// store the result for this particular output stream
+
+#if DO_PRINT_DEBUG
+  std::cout << ", O_i[" << t_output_stream <<
+    "][" << d_out_buf_ndx << "] = " <<
+    n2bs (out_buf[t_output_stream][d_out_buf_ndx], 2);
+#endif
+
+// one bit per output item
+  out_buf[t_output_stream][d_out_buf_ndx] = t_out_bit;
+
+#if DO_PRINT_DEBUG
+  std::cout << ", b_out = " << t_out_bit <<
+    ", O_o[" << t_output_stream << "][" << d_out_buf_ndx << "][" <<
+    d_out_bit_shift << "] = " <<
+    n2bs (out_buf[t_output_stream][d_out_buf_ndx], 2) << '\n';
+#endif
+
+#if 0
+#if DO_PRINT_DEBUG
+  std::cout << ", O_i[" << t_output_stream <<
+    "][" << d_out_buf_ndx << "] = " <<
+    n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte);
+#endif
+
+// packed bits in each output item
+  out_buf[t_output_stream][d_out_buf_ndx] |=
+    (t_out_bit << d_out_bit_shift);
+
+#if DO_PRINT_DEBUG
+  std::cout << ", b_out = " << t_out_bit <<
+    ", O_o[" << t_output_stream << "][" << d_out_buf_ndx << "][" <<
+    d_out_bit_shift << "] = " <<
+    n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte) << 
'\n';
+#endif
+#endif
+}
+
+char
+encoder_convolutional_ic1_ic1_ff::get_next_bit__input
+(const char** in_buf,
+ size_t code_input_n)
+{
+  return (in_buf[code_input_n][d_in_buf_ndx] & 1);
+
+#if 0
+// if doing packed, should probably allow user to select how
+// bits are selected, so-as to make sure it's always the same
+// no matter the CPU endianness
+   return ((in_buf[code_input_n][d_in_buf_ndx] >> d_in_bit_shift) & 1);
+#endif
+}
+
+char
+encoder_convolutional_ic1_ic1_ff::get_next_bit__term
+(size_t code_input_n)
+{
+  return (d_term_states[code_input_n] & 1);
+
+#if 0
+  return ((d_term_states[code_input_n] >> d_in_bit_shift) & 1);
+#endif
+}

Index: encoder_convolutional_ic1_ic1_ff.h
===================================================================
RCS file: encoder_convolutional_ic1_ic1_ff.h
diff -N encoder_convolutional_ic1_ic1_ff.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ encoder_convolutional_ic1_ic1_ff.h  4 Jul 2006 01:55:56 -0000       1.1
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright @ 2006 Michael Dickens
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this library; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_FF_H
+#define INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_FF_H
+
+#include <vector>
+#include "encoder_convolutional_base.h"
+
+/*!
+ * Encode the incoming streams using a convolutional encoder,
+ *     "feedforward" only ... meaning no feedback.  Optional
+ *     termination and streaming.
+ *
+ * input is "ic1": streams of char, one stream per input as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single input bit per input item.
+ *
+ * output is "ic1": streams of char, one stream per output as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single output bit per output item.
+ */
+
+class encoder_convolutional_ic1_ic1_ff : public encoder_convolutional_base
+{
+public:
+/*
+ * frame_size_bits: if == 0, then do streaming encoding ("infinite"
+ *     trellis); otherwise this is the frame size in bits to encode
+ *     before terminating the trellis.  This value -does not- include
+ *     any termination bits.
+ *
+ * n_code_inputs:
+ * n_code_outputs:
+ * code_generator: vector of integers (32 bit) representing the code
+ *     to be implemented in octal form.  E.g. "04" in binary is "100",
+ *     which would be "D^2" for code generation.  "06" == 110b == "D^2 + D"
+ *  ==> The vector is listed in order for each input stream, so if there
+ *     are 2 input streams (I1, I2) [specified in "n_code_inputs"]
+ *     and 2 output streams (O1, O2) [specified in "n_code_outputs"],
+ *     then the vector would be the code generator for:
+ *       [I1->O1, I1->O2, I2->O1, I2->O2]
+ *     with each element being the octal representation of the code.
+ *
+ * do_termination: valid only if frame_size_bits != 0, and defines
+ *     whether or not to use trellis termination.  Default is to use
+ *     termination when doing block coding.
+ *
+ * start_memory_state: when starting a new block, the starting memory
+ *     state to begin encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ * 
+ * end_memory_state: when terminating a block, the ending memory
+ *     state to stop encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ */
+
+  encoder_convolutional_ic1_ic1_ff (int frame_size_bits,
+                                   int n_code_inputs,
+                                   int n_code_outputs,
+                                   std::vector<int> &code_generators,
+                                   bool do_termination = true,
+                                   int start_memory_state = 0,
+                                   int end_memory_state = 0);
+
+  virtual ~encoder_convolutional_ic1_ic1_ff () {};
+
+  virtual size_t compute_n_input_bits (size_t n_output_bits);
+  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 char get_next_bit__term (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 update_memory_post_encode ();
+};
+
+#endif /* INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_FF_H */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]