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 Makefile.am e...


From: Michael Dickens
Subject: [Commit-gnuradio] gr-error-correcting-codes/src/lib Makefile.am e...
Date: Tue, 01 Aug 2006 19:02:36 +0000

CVSROOT:        /sources/gnuradio
Module name:    gr-error-correcting-codes
Changes by:     Michael Dickens <michaelld>     06/08/01 19:02:35

Modified files:
        src/lib        : Makefile.am ecc.i 
        src/lib/libecc : Makefile.am code_convolutional_trellis.cc 
                         code_convolutional_trellis.h code_metrics.cc 
                         code_metrics.h decoder.cc decoder.h 
                         decoder_viterbi.cc decoder_viterbi.h 
                         decoder_viterbi_full_block.cc 
                         decoder_viterbi_full_block.h encoder.cc 
                         encoder.h encoder_convolutional.cc 
                         encoder_convolutional.h encoder_turbo.cc 
                         encoder_turbo.h 
        src/lib/libecc/tests: qa_encoder_convolutional_ic1_ic1.cc 
                              qa_encoder_convolutional_ic1_ic1.h 
Added files:
        src/lib        : ecc_metrics_decode_viterbi_full_block.cc 
                         ecc_metrics_decode_viterbi_full_block.h 
                         ecc_metrics_decode_viterbi_full_block.i 
                         ecc_streams_encode_convolutional.cc 
                         ecc_streams_encode_convolutional.h 
                         ecc_streams_encode_convolutional.i 
                         ecc_streams_encode_turbo.cc 
                         ecc_streams_encode_turbo.h 
                         ecc_streams_encode_turbo.i 
                         ecc_syms_to_metrics.cc ecc_syms_to_metrics.h 
                         ecc_syms_to_metrics.i 
        src/lib/libecc : code_io.cc code_io.h 
Removed files:
        src/lib        : gr_metrics_decode_viterbi_full_block.cc 
                         gr_metrics_decode_viterbi_full_block.h 
                         gr_metrics_decode_viterbi_full_block.i 
                         gr_streams_encode_convolutional.cc 
                         gr_streams_encode_convolutional.h 
                         gr_streams_encode_convolutional.i 
                         gr_streams_encode_turbo.cc 
                         gr_streams_encode_turbo.h 
                         gr_streams_encode_turbo.i gr_syms_to_metrics.cc 
                         gr_syms_to_metrics.h gr_syms_to_metrics.i 
        src/lib/libecc : decoder_viterbi_full_block_i1_ic1.cc 
                         decoder_viterbi_full_block_i1_ic1.h 
                         encoder_convolutional_ic1_ic1.cc 
                         encoder_convolutional_ic1_ic1.h 
                         encoder_convolutional_ic8_ic8.cc 
                         encoder_convolutional_ic8_ic8.h 

Log message:
        Changed gr_block names from "gr_" to "ecc_".
        
        Moved I/O to its own class ("code_io"), and thus removed the need for
        the odd naming of files (e.g. "ic1").  Updated all the programming to
        work with this new I/O model.  Rewrote the code_metrics for as
        templates, for more robust functionality.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/Makefile.am?cvsroot=gnuradio&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc.i?cvsroot=gnuradio&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_metrics_decode_viterbi_full_block.cc?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_metrics_decode_viterbi_full_block.h?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_metrics_decode_viterbi_full_block.i?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_streams_encode_convolutional.cc?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_streams_encode_convolutional.h?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_streams_encode_convolutional.i?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_streams_encode_turbo.cc?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_streams_encode_turbo.h?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_streams_encode_turbo.i?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_syms_to_metrics.cc?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_syms_to_metrics.h?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/ecc_syms_to_metrics.i?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.cc?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.h?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.i?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.cc?cvsroot=gnuradio&r1=1.4&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.h?cvsroot=gnuradio&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.i?cvsroot=gnuradio&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.cc?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.h?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.i?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.cc?cvsroot=gnuradio&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.h?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.i?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/Makefile.am?cvsroot=gnuradio&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.cc?cvsroot=gnuradio&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.h?cvsroot=gnuradio&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/code_metrics.cc?cvsroot=gnuradio&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/code_metrics.h?cvsroot=gnuradio&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder.cc?cvsroot=gnuradio&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder.h?cvsroot=gnuradio&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.cc?cvsroot=gnuradio&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.h?cvsroot=gnuradio&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.cc?cvsroot=gnuradio&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.h?cvsroot=gnuradio&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder.cc?cvsroot=gnuradio&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder.h?cvsroot=gnuradio&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.cc?cvsroot=gnuradio&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.h?cvsroot=gnuradio&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.cc?cvsroot=gnuradio&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.h?cvsroot=gnuradio&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/code_io.cc?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/code_io.h?cvsroot=gnuradio&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.cc?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.h?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.cc?cvsroot=gnuradio&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.h?cvsroot=gnuradio&r1=1.6&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.cc?cvsroot=gnuradio&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.h?cvsroot=gnuradio&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.cc?cvsroot=gnuradio&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.h?cvsroot=gnuradio&r1=1.3&r2=1.4

Patches:
Index: Makefile.am
===================================================================
RCS file: /sources/gnuradio/gr-error-correcting-codes/src/lib/Makefile.am,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- Makefile.am 14 Jul 2006 19:49:25 -0000      1.4
+++ Makefile.am 1 Aug 2006 19:02:35 -0000       1.5
@@ -43,10 +43,10 @@
        $(GNURADIO_CORE_INCLUDEDIR)/swig/gnuradio.i
 
 LOCAL_IFILES =                                                 \
-       gr_syms_to_metrics.i                            \
-       gr_metrics_decode_viterbi_full_block.i          \
-       gr_streams_encode_convolutional.i               \
-       gr_streams_encode_turbo.i                       \
+       ecc_syms_to_metrics.i                           \
+       ecc_metrics_decode_viterbi_full_block.i         \
+       ecc_streams_encode_convolutional.i              \
+       ecc_streams_encode_turbo.i                      \
        ecc.i
 
 # These files are built by SWIG.  The first is the C++ glue.
@@ -66,10 +66,10 @@
 
 # These are the source files that go into the shared library
 _ecc_la_SOURCES =                                      \
-       gr_syms_to_metrics.cc                           \
-       gr_metrics_decode_viterbi_full_block.cc         \
-       gr_streams_encode_convolutional.cc              \
-       gr_streams_encode_turbo.cc                      \
+       ecc_syms_to_metrics.cc                          \
+       ecc_metrics_decode_viterbi_full_block.cc        \
+       ecc_streams_encode_convolutional.cc             \
+       ecc_streams_encode_turbo.cc                     \
        ecc.cc
 
 # magic flags
@@ -83,10 +83,10 @@
 
 # These headers get installed in ${prefix}/include/gnuradio
 grinclude_HEADERS =                                    \
-       gr_syms_to_metrics.h                            \
-       gr_metrics_decode_viterbi_full_block.h          \
-       gr_streams_encode_convolutional.h               \
-       gr_streams_encode_turbo.h
+       ecc_syms_to_metrics.h                           \
+       ecc_metrics_decode_viterbi_full_block.h         \
+       ecc_streams_encode_convolutional.h              \
+       ecc_streams_encode_turbo.h
 
 # These swig headers get installed in ${prefix}/include/gnuradio/swig
 swiginclude_HEADERS = $(LOCAL_IFILES)

Index: ecc.i
===================================================================
RCS file: /sources/gnuradio/gr-error-correcting-codes/src/lib/ecc.i,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- ecc.i       9 Jul 2006 21:02:44 -0000       1.4
+++ ecc.i       1 Aug 2006 19:02:35 -0000       1.5
@@ -27,15 +27,15 @@
 %{
 
 #include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
-#include <gr_streams_encode_convolutional.h>
-#include <gr_streams_encode_turbo.h>
-#include <gr_metrics_decode_viterbi_full_block.h>
-#include <gr_syms_to_metrics.h>
+#include <ecc_streams_encode_convolutional.h>
+#include <ecc_streams_encode_turbo.h>
+#include <ecc_metrics_decode_viterbi_full_block.h>
+#include <ecc_syms_to_metrics.h>
 #include <stdexcept>
 
 %}
 
-%include "gr_streams_encode_convolutional.i"
-%include "gr_streams_encode_turbo.i"
-%include "gr_metrics_decode_viterbi_full_block.i"
-%include "gr_syms_to_metrics.i"
+%include "ecc_streams_encode_convolutional.i"
+%include "ecc_streams_encode_turbo.i"
+%include "ecc_metrics_decode_viterbi_full_block.i"
+%include "ecc_syms_to_metrics.i"

Index: libecc/Makefile.am
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- libecc/Makefile.am  20 Jul 2006 17:42:54 -0000      1.9
+++ libecc/Makefile.am  1 Aug 2006 19:02:35 -0000       1.10
@@ -29,25 +29,21 @@
 
 libecc_la_SOURCES =                            \
        code_convolutional_trellis.cc           \
-       code_metrics.cc                         \
+       code_metrics.cc code_io.cc              \
        encoder.cc                              \
        encoder_convolutional.cc                \
-       encoder_convolutional_ic1_ic1.cc        \
        encoder_turbo.cc                        \
        decoder.cc                              \
        decoder_viterbi.cc                      \
-       decoder_viterbi_full_block.cc           \
-       decoder_viterbi_full_block_i1_ic1.cc
+       decoder_viterbi_full_block.cc
 
 noinst_HEADERS =                               \
-       code_types.h code_metrics.h             \
+       code_types.h code_metrics.h code_io.h   \
        code_convolutional_trellis.h            \
        encoder.h encoder_turbo.h               \
        encoder_convolutional.h                 \
-       encoder_convolutional_ic1_ic1.h         \
        decoder.h decoder_viterbi.h             \
-       decoder_viterbi_full_block.h            \
-       decoder_viterbi_full_block_i1_ic1.h
+       decoder_viterbi_full_block.h
 
 # link the library against the c++ standard library
 libecc_la_LIBADD =             \

Index: libecc/code_convolutional_trellis.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libecc/code_convolutional_trellis.cc        20 Jul 2006 17:42:54 -0000      
1.1
+++ libecc/code_convolutional_trellis.cc        1 Aug 2006 19:02:35 -0000       
1.2
@@ -29,8 +29,8 @@
 #include <iostream>
 
 #define DO_TIME_THOUGHPUT 0
-#define DO_PRINT_DEBUG 1
-#define DO_PRINT_DEBUG_ENCODE 1
+#define DO_PRINT_DEBUG 0
+#define DO_PRINT_DEBUG_ENCODE 0
 
 #include <mld/mld_timer.h>
 #include <mld/n2bs.h>
@@ -704,10 +704,13 @@
  size_t bit_num,
  std::vector<char>& inputs)
 {
-  inputs.resize (d_n_code_inputs);
+#if 1
+  inputs.assign (d_n_code_inputs, 0);
+#else
   for (size_t m = 0; m < d_n_code_inputs; m++) {
     inputs[m] = ((d_term_inputs[term_start_state][m]) >> bit_num) & 1;
   }
+#endif
 }
 
 void

Index: libecc/code_convolutional_trellis.h
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libecc/code_convolutional_trellis.h 20 Jul 2006 17:42:54 -0000      1.1
+++ libecc/code_convolutional_trellis.h 1 Aug 2006 19:02:35 -0000       1.2
@@ -152,9 +152,11 @@
 
 /* for remote access to internal info */
 
-  inline size_t block_size_bits () {return (d_block_size_bits);};
-  inline size_t n_code_inputs () {return (d_n_code_inputs);};
-  inline size_t n_code_outputs () {return (d_n_code_outputs);};
+  inline const size_t block_size_bits () {return (d_block_size_bits);};
+  inline const size_t n_code_inputs () {return (d_n_code_inputs);};
+  inline const size_t n_code_outputs () {return (d_n_code_outputs);};
+  inline const size_t n_states () {return (d_n_states);};
+  inline const size_t n_input_combinations () {return 
(d_n_input_combinations);};
   inline const bool do_termination () {return (d_do_termination);};
   inline const bool do_feedback () {return (d_do_feedback);};
   inline const bool do_streaming () {return (d_do_streaming);};

Index: libecc/code_metrics.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/code_metrics.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- libecc/code_metrics.cc      9 Jul 2006 15:37:00 -0000       1.4
+++ libecc/code_metrics.cc      1 Aug 2006 19:02:35 -0000       1.5
@@ -29,274 +29,261 @@
 #include <math.h>
 #include <assert.h>
 
-code_metric_ff::code_metric_ff
+template<typename pdf_fcn_io_t>
+code_metrics<pdf_fcn_io_t>*
+code_metrics<pdf_fcn_io_t>::create
 (pdf_fcn_t pdf_fcn_0_bit,
  pdf_fcn_t pdf_fcn_1_bit,
  size_t n_samples,
  pdf_fcn_io_t min_sample,
- pdf_fcn_io_t max_sample)
+ pdf_fcn_io_t max_sample,
+ int sample_precision)
 {
-  if (n_samples < 2) {
-    fprintf (stderr, "code_metric_f32:: n_samples "
-            "must be at least 2.\n");
+  if (! pdf_fcn_0_bit) {
+    std::cerr << "code_metrics_table::create: Error: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n";
     assert (0);
   }
-  if (min_sample >= max_sample) {
-    fprintf (stderr, "code_metric_f32:: min_sample must be "
-            "less than max_sample.\n");
+  if (! pdf_fcn_1_bit) {
+    std::cerr << "code_metrics_table::create: Error: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n";
     assert (0);
   }
-  if (! pdf_fcn_0_bit) {
-    fprintf (stderr, "code_metric_f32:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
+  if (n_samples < 2) {
+    std::cerr << "code_metrics_table::create: Error: n_samples "
+            "must be at least 2.\n";
     assert (0);
   }
-  if (! pdf_fcn_1_bit) {
-    fprintf (stderr, "code_metric_f32:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
+  if (min_sample >= max_sample) {
+    std::cerr << "code_metrics_table::create: Error: min_sample must be "
+            "less than max_sample.\n";
     assert (0);
   }
-
-  d_n_samples = n_samples;
-  d_max_sample = max_sample;
-  d_min_sample = min_sample;
-  d_delta = (max_sample - min_sample) / (n_samples - 1);
-  d_pdf_fcn_0_bit = pdf_fcn_0_bit;
-  d_pdf_fcn_1_bit = pdf_fcn_1_bit;
-  d_metric_table_0_bit.assign (n_samples, 0);
-  d_metric_table_1_bit.assign (n_samples, 0);
-
-  pdf_fcn_io_t l_val = min_sample;
-  for (size_t m = 0; m < n_samples; m++) {
-    d_metric_table_0_bit[m] = logf ((*pdf_fcn_0_bit)(l_val));
-    d_metric_table_1_bit[m] = logf ((*pdf_fcn_1_bit)(l_val));
-    l_val += d_delta;
+  if ((sample_precision < 0) | (sample_precision > 32)) {
+    std::cerr << "code_metrics_table::create: Error: sample_precision "
+      "must be between 0 and 32.\n";
+    assert (0);
   }
-}
 
-void code_metric_ff::lookup
-(pdf_fcn_io_t sym,
- void* bit_0,
- void* bit_1)
-{
-  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
-  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
-
-  if (sym <= d_min_sample) {
-    *l_bit_0 = d_metric_table_0_bit[0];
-    *l_bit_1 = d_metric_table_1_bit[0];
-    return;
-  }
-  if (sym >= d_max_sample) {
-    *l_bit_0 = d_metric_table_0_bit.back ();
-    *l_bit_1 = d_metric_table_1_bit.back ();
-    return;
+  code_metrics<pdf_fcn_io_t>* t_code_metrics;
+
+  if (sample_precision == 0) {
+    // float
+    t_code_metrics = new code_metric_table
+      <pdf_fcn_io_t, float>(pdf_fcn_0_bit,
+                           pdf_fcn_1_bit,
+                           n_samples,
+                           min_sample,
+                           max_sample);
+  } else if (sample_precision <= 8) {
+    // use char
+    t_code_metrics = new code_metric_table
+      <pdf_fcn_io_t, unsigned char>(pdf_fcn_0_bit,
+                                   pdf_fcn_1_bit,
+                                   n_samples,
+                                   min_sample,
+                                   max_sample,
+                                   sample_precision);
+  } else if (sample_precision <= 16) {
+    // use short
+    t_code_metrics = new code_metric_table
+      <pdf_fcn_io_t, unsigned short>(pdf_fcn_0_bit,
+                                    pdf_fcn_1_bit,
+                                    n_samples,
+                                    min_sample,
+                                    max_sample,
+                                    sample_precision);
+  } else {
+    // use long
+    t_code_metrics = new code_metric_table
+      <pdf_fcn_io_t, unsigned long>(pdf_fcn_0_bit,
+                                   pdf_fcn_1_bit,
+                                   n_samples,
+                                   min_sample,
+                                   max_sample,
+                                   sample_precision);
   }
 
-  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
-  *l_bit_0 = d_metric_table_0_bit[l_ndx];
-  *l_bit_1 = d_metric_table_1_bit[l_ndx];
-}
-
-void code_metric_ff::convert
-(size_t n_syms,
- pdf_fcn_io_t* sym,
- void* bit_0,
- void* bit_1)
-{
-  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
-  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
-
-  for (size_t m = n_syms; m > 0; m--)
-    lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
+  return (t_code_metrics);
 }
 
-code_metric_fl::code_metric_fl
+template<typename pdf_fcn_io_t>
+code_metrics<pdf_fcn_io_t>::code_metrics
 (pdf_fcn_t pdf_fcn_0_bit,
  pdf_fcn_t pdf_fcn_1_bit,
  size_t n_samples,
  pdf_fcn_io_t min_sample,
- pdf_fcn_io_t max_sample,
- int sample_precision)
+ pdf_fcn_io_t max_sample)
 {
-  if (n_samples < 2) {
-    fprintf (stderr, "code_metric_fl:: n_samples "
-            "must be at least 2.\n");
-    assert (0);
-  }
-  if (min_sample >= max_sample) {
-    fprintf (stderr, "code_metric_fl:: min_sample must be "
-            "less than max_sample.\n");
-    assert (0);
-  }
-  if (! pdf_fcn_0_bit) {
-    fprintf (stderr, "code_metric_fl:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
-    assert (0);
-  }
-  if (! pdf_fcn_1_bit) {
-    fprintf (stderr, "code_metric_fl:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
-    assert (0);
-  }
-  if (sample_precision < 16 || sample_precision > 32) {
-    fprintf (stderr, "code_metric_fl:: sample_precision must be "
-            "between 16 and 32 for this class.\n");
-    assert (0);
-  }
+  // internally, all samples are taken as pdf_fcn_io_t initially, and
+  // only converted to other values by their specific constructors.
 
-  d_sample_precision = sample_precision;
   d_n_samples = n_samples;
   d_max_sample = max_sample;
   d_min_sample = min_sample;
-  d_delta = (max_sample - min_sample) / (n_samples - 1);
+  d_delta = (max_sample - min_sample) / ((pdf_fcn_io_t) n_samples);
   d_pdf_fcn_0_bit = pdf_fcn_0_bit;
   d_pdf_fcn_1_bit = pdf_fcn_1_bit;
-  d_metric_table_0_bit.assign (n_samples, 0);
-  d_metric_table_1_bit.assign (n_samples, 0);
 
-  // get the scale factor for converting from float to sample_precision
-  // maps:
-  //    logf (pdf_fcn_0_bit->eval (d_min_sample))  ->  l_min_map
-  //    logf (pdf_fcn_0_bit->eval (d_max_sample))  ->  l_max_map
-
-  metric_t l_min_map = - (1 << (sample_precision - 1));
-
-  pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
-  pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
-  pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
-                           (l_max_log_val_0 - l_min_log_val_0));
-  pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
-  pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
-  pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
-                           (l_max_log_val_1 - l_min_log_val_1));
-
-  pdf_fcn_io_t l_val = d_min_sample;
-  for (size_t m = 0; m < d_n_samples; m++) {
-    d_metric_table_0_bit[m] =
-      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
-                        (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
-                                      l_min_log_val_0)));
-    d_metric_table_1_bit[m] =
-      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
-                        (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
-                                      l_min_log_val_1)));
-    l_val += d_delta;
+  // use a sub-sample by 100 to better determine the actual "bin"
+  // probability values for each actual sample.  Each "bin" is 100
+  // delta's less than the min_sample up to the min_sample+delta; then
+  // each delta; then from the max_sample-delta to 100 delta's more
+  // than the max sample.  Once normalized, these give a reasonable
+  // interpretation of the PDF function.
+
+  pdf_fcn_io_t d_sub_delta = d_delta / ((pdf_fcn_io_t) 100);
+  pdf_fcn_io_t d_sub_min_sample = d_min_sample - ((pdf_fcn_io_t) 100)*d_delta;
+  pdf_fcn_io_t d_sup_max_sample = d_max_sample + ((pdf_fcn_io_t) 100)*d_delta;
+
+  d_pdf_fcn_0_samples.assign (d_n_samples, 0);
+  d_pdf_fcn_1_samples.assign (d_n_samples, 0);
+
+  pdf_fcn_io_t t_val, t_sum_0, t_sum_1, t_max_0, t_max_1, t_min_0, t_min_1;
+  t_sum_0 = t_sum_1 = t_max_0 = t_max_1 = t_min_0 = t_min_1 = 0;
+  size_t m = 0;
+  t_val = d_sub_min_sample;
+  for (; m < (d_n_samples - 1); m++) {
+    pdf_fcn_io_t t_sample_0 = 1;
+    pdf_fcn_io_t t_sample_1 = 1;
+    for (; t_val < (d_min_sample+d_delta); t_val += d_sub_delta) {
+      t_sample_0 += ((*d_pdf_fcn_0_bit)(t_val));
+      t_sample_1 += ((*d_pdf_fcn_1_bit)(t_val));
+    }
+    d_pdf_fcn_0_samples[m] = t_sample_0;
+    d_pdf_fcn_0_samples[m] = t_sample_1;
+    t_sum_0 += t_sample_0;
+    t_sum_1 += t_sample_1;
+    if (m == 0) {
+      t_max_0 = t_min_0 = t_sample_0;
+      t_max_1 = t_min_1 = t_sample_1;
+    } else {
+      if (t_max_0 < t_sample_0)
+       t_max_0 = t_sample_0;
+      else if (t_min_0 > t_sample_0)
+       t_min_0 = t_sample_0;
+      if (t_max_1 < t_sample_1)
+       t_max_1 = t_sample_1;
+      else if (t_min_1 > t_sample_1)
+       t_min_1 = t_sample_1;
+    }
+  }
+
+  pdf_fcn_io_t t_sample_0 = 1;
+  pdf_fcn_io_t t_sample_1 = 1;
+  for (; t_val < d_sup_max_sample; t_val += d_sub_delta) {
+    t_sample_0 += ((*d_pdf_fcn_0_bit)(t_val));
+    t_sample_1 += ((*d_pdf_fcn_1_bit)(t_val));
+  }
+  d_pdf_fcn_0_samples[m] = t_sample_0;
+  d_pdf_fcn_0_samples[m] = t_sample_1;
+  t_sum_0 += t_sample_0;
+  t_sum_1 += t_sample_1;
+  if (t_max_0 < t_sample_0)
+    t_max_0 = t_sample_0;
+  else if (t_min_0 > t_sample_0)
+    t_min_0 = t_sample_0;
+  if (t_max_1 < t_sample_1)
+    t_max_1 = t_sample_1;
+  else if (t_min_1 > t_sample_1)
+    t_min_1 = t_sample_1;
+
+  // normalize to the sum, so that these are "real" probabilities.
+
+  for (m = 0; m < d_n_samples; m++) {
+    d_pdf_fcn_0_samples[m] /= t_sum_0;
+    d_pdf_fcn_1_samples[m] /= t_sum_1;
+  }
+  t_max_0 /= t_sum_0;
+  t_min_0 /= t_sum_0;
+  t_max_1 /= t_sum_1;
+  t_min_1 /= t_sum_1;
+
+  // take the logf so that metrics can add
+
+  for (m = 0; m < d_n_samples; m++) {
+    d_pdf_fcn_0_samples[m] = logf (d_pdf_fcn_0_samples[m]);
+    d_pdf_fcn_1_samples[m] = logf (d_pdf_fcn_1_samples[m]);
+  }
+  t_max_0 = logf (t_max_0);
+  t_min_0 = logf (t_min_0);
+  t_max_1 = logf (t_max_1);
+  t_min_1 = logf (t_min_1);
+
+  // higher (less negative) log-probabilities mean more likely; lower
+  // (more negative) mean less likely.  Want metrics which are 0 when
+  // most likely and more positive when less likely.  So subtract the
+  // max, then negate and normalize to the min (new max) so that the
+  // max value is 1 and the min value is 0.
+
+  for (m = 0; m < d_n_samples; m++) {
+    d_pdf_fcn_0_samples[m] = ((d_pdf_fcn_0_samples[m] - t_max_0) /
+                             (t_min_0 - t_max_0));
+    d_pdf_fcn_1_samples[m] = ((d_pdf_fcn_1_samples[m] - t_max_1) /
+                             (t_min_1 - t_max_1));
   }
-}
-
-void code_metric_fl::lookup
-(pdf_fcn_io_t sym,
- void* bit_0,
- void* bit_1)
-{
-  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
-  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
 
-  if (sym <= d_min_sample) {
-    *l_bit_0 = d_metric_table_0_bit[0];
-    *l_bit_1 = d_metric_table_1_bit[0];
-    return;
-  }
-  if (sym >= d_max_sample) {
-    *l_bit_0 = d_metric_table_0_bit.back ();
-    *l_bit_1 = d_metric_table_1_bit.back ();
-    return;
-  }
+  // correct the delta to the lookup computations
 
-  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
-  *l_bit_0 = d_metric_table_0_bit[l_ndx];
-  *l_bit_1 = d_metric_table_1_bit[l_ndx];
+  d_delta = (max_sample - min_sample) / ((pdf_fcn_io_t)(n_samples-1));
 }
 
-void code_metric_fl::convert
-(size_t n_syms,
- pdf_fcn_io_t* sym,
- void* bit_0,
- void* bit_1)
-{
-  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
-  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
-
-  for (size_t m = n_syms; m > 0; m--)
-    lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
-}
-
-code_metric_fs::code_metric_fs
+template<typename pdf_fcn_io_t, typename metric_t>
+code_metric_table<pdf_fcn_io_t,metric_t>::code_metric_table
 (pdf_fcn_t pdf_fcn_0_bit,
  pdf_fcn_t pdf_fcn_1_bit,
  size_t n_samples,
  pdf_fcn_io_t min_sample,
  pdf_fcn_io_t max_sample,
  int sample_precision)
-{
-  if (n_samples < 2) {
-    fprintf (stderr, "code_metric_fs:: n_samples "
-            "must be at least 2.\n");
-    assert (0);
-  }
-  if (min_sample >= max_sample) {
-    fprintf (stderr, "code_metric_fs:: min_sample must be "
-            "less than max_sample.\n");
-    assert (0);
-  }
-  if (! pdf_fcn_0_bit) {
-    fprintf (stderr, "code_metric_fs:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
-    assert (0);
-  }
-  if (! pdf_fcn_1_bit) {
-    fprintf (stderr, "code_metric_fs:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
-    assert (0);
-  }
-  if (sample_precision < 9 || sample_precision > 16) {
-    fprintf (stderr, "code_metric_fs:: sample_precision must be "
-            "between 9 and 16 for this class.\n");
-    assert (0);
-  }
+  : code_metrics<pdf_fcn_io_t>
+    (pdf_fcn_0_bit,
+     pdf_fcn_1_bit,
+     n_samples,
+     min_sample,
+     max_sample)
+{
+  code_metrics<pdf_fcn_io_t>::d_out_item_size_bytes = sizeof (metric_t);
+  code_metrics<pdf_fcn_io_t>::d_sample_precision = sample_precision;
+
+  // get the scale factor for converting from float to
+  // sample_precision maps: 0 -> 0, 1 -> (2^sample_precision)-1 for
+  // integers; there is no need for a mapping for float types, since
+  // those are already in [0,1].
 
-  d_sample_precision = sample_precision;
-  d_n_samples = n_samples;
-  d_max_sample = max_sample;
-  d_min_sample = min_sample;
-  d_delta = (max_sample - min_sample) / (n_samples - 1);
-  d_pdf_fcn_0_bit = pdf_fcn_0_bit;
-  d_pdf_fcn_1_bit = pdf_fcn_1_bit;
-  d_metric_table_0_bit.assign (n_samples, 0);
-  d_metric_table_1_bit.assign (n_samples, 0);
+  pdf_fcn_io_t t_mult = ((sample_precision == 0) ? 1 :
+                        ((pdf_fcn_io_t)((2^sample_precision)-1)));
 
-  // get the scale factor for converting from float to sample_precision
-  // maps:
-  //    logf (pdf_fcn_0_bit->eval (d_min_sample))  ->  l_min_map
-  //    logf (pdf_fcn_0_bit->eval (d_max_sample))  ->  l_max_map
-
-  metric_t l_min_map = - (1 << (sample_precision - 1));
-
-  pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
-  pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
-  pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
-                           (l_max_log_val_0 - l_min_log_val_0));
-  pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
-  pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
-  pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
-                           (l_max_log_val_1 - l_min_log_val_1));
+  // convert the 0 bit metrics from float to integer
 
-  pdf_fcn_io_t l_val = d_min_sample;
-  for (size_t m = 0; m < d_n_samples; m++) {
+  d_metric_table_0_bit.assign (n_samples, 0);
+  for (size_t m = 0; m < n_samples; m++) {
     d_metric_table_0_bit[m] =
-      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
-                        (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
-                                      l_min_log_val_0)));
+      (metric_t)((code_metrics<pdf_fcn_io_t>::d_pdf_fcn_0_samples[m]) *
+                t_mult);
+  }
+
+  // clear the old float sample vectors to free memory
+
+  code_metrics<pdf_fcn_io_t>::d_pdf_fcn_0_samples.resize (0);
+
+  // convert the 1 bit metrics from float to integer
+
+  d_metric_table_1_bit.assign (n_samples, 0);
+  for (size_t m = 0; m < n_samples; m++) {
     d_metric_table_1_bit[m] =
-      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
-                        (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
-                                      l_min_log_val_1)));
-    l_val += d_delta;
+      (metric_t)((code_metrics<pdf_fcn_io_t>::d_pdf_fcn_1_samples[m]) *
+                t_mult);
   }
+
+  // clear the old float sample vectors to free memory
+
+  code_metrics<pdf_fcn_io_t>::d_pdf_fcn_1_samples.resize (0);
 }
 
-void code_metric_fs::lookup
+template<typename pdf_fcn_io_t, typename metric_t>
+void
+code_metric_table<pdf_fcn_io_t,metric_t>::lookup
 (pdf_fcn_io_t sym,
  void* bit_0,
  void* bit_1)
@@ -304,23 +291,27 @@
   metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
   metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
 
-  if (sym <= d_min_sample) {
+  if (sym <= code_metrics<pdf_fcn_io_t>::d_min_sample) {
     *l_bit_0 = d_metric_table_0_bit[0];
     *l_bit_1 = d_metric_table_1_bit[0];
     return;
   }
-  if (sym >= d_max_sample) {
+  if (sym >= code_metrics<pdf_fcn_io_t>::d_max_sample) {
     *l_bit_0 = d_metric_table_0_bit.back ();
     *l_bit_1 = d_metric_table_1_bit.back ();
     return;
   }
 
-  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
+  size_t l_ndx = (size_t) round
+    ((double)((sym - code_metrics<pdf_fcn_io_t>::d_min_sample) /
+             code_metrics<pdf_fcn_io_t>::d_delta));
   *l_bit_0 = d_metric_table_0_bit[l_ndx];
   *l_bit_1 = d_metric_table_1_bit[l_ndx];
 }
 
-void code_metric_fs::convert
+template<typename pdf_fcn_io_t, typename metric_t>
+void
+code_metric_table<pdf_fcn_io_t,metric_t>::convert
 (size_t n_syms,
  pdf_fcn_io_t* sym,
  void* bit_0,
@@ -333,113 +324,88 @@
     lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
 }
 
-code_metric_fb::code_metric_fb
-(pdf_fcn_t pdf_fcn_0_bit,
- pdf_fcn_t pdf_fcn_1_bit,
- size_t n_samples,
- pdf_fcn_io_t min_sample,
- pdf_fcn_io_t max_sample,
- int sample_precision)
-{
-  if (n_samples < 2) {
-    fprintf (stderr, "code_metric_fb:: n_samples "
-            "must be at least 2.\n");
-    assert (0);
-  }
-  if (min_sample >= max_sample) {
-    fprintf (stderr, "code_metric_fb:: min_sample must be "
-            "less than max_sample.\n");
-    assert (0);
-  }
-  if (! pdf_fcn_0_bit) {
-    fprintf (stderr, "code_metric_fb:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
-    assert (0);
-  }
-  if (! pdf_fcn_1_bit) {
-    fprintf (stderr, "code_metric_fb:: pdf_fcn_0_bit must be "
-            "a non-null pointer to function.\n");
-    assert (0);
-  }
-  if (sample_precision < 1 || sample_precision > 8) {
-    fprintf (stderr, "code_metric_fb:: sample_precision must be "
-            "between 1 and 8 for this class.\n");
-    assert (0);
-  }
+#if 0
+  // for compute_all_outputs
 
-  d_sample_precision = sample_precision;
-  d_n_samples = n_samples;
-  d_max_sample = max_sample;
-  d_min_sample = min_sample;
-  d_delta = (max_sample - min_sample) / (n_samples - 1);
-  d_pdf_fcn_0_bit = pdf_fcn_0_bit;
-  d_pdf_fcn_1_bit = pdf_fcn_1_bit;
-  d_metric_table_0_bit.assign (n_samples, 0);
-  d_metric_table_1_bit.assign (n_samples, 0);
+  d_n_code_outputs = n_code_outputs;
 
-  // get the scale factor for converting from float to sample_precision
-  // maps:
-  //    logf (pdf_fcn_0_bit->eval (d_min_sample))  ->  l_min_map
-  //    logf (pdf_fcn_0_bit->eval (d_max_sample))  ->  l_max_map
-
-  metric_t l_min_map = - (1 << (sample_precision - 1));
-
-  pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
-  pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
-  pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
-                           (l_max_log_val_0 - l_min_log_val_0));
-  pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
-  pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
-  pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
-                           (l_max_log_val_1 - l_min_log_val_1));
+  in_l[0].resize (d_n_code_outputs);
+  in_l[1].resize (d_n_code_outputs);
+  in_f[0].resize (d_n_code_outputs);
+  in_f[1].resize (d_n_code_outputs);
 
-  pdf_fcn_io_t l_val = d_min_sample;
-  for (size_t m = 0; m < d_n_samples; m++) {
-    d_metric_table_0_bit[m] =
-      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
-                        (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
-                                      l_min_log_val_0)));
-    d_metric_table_1_bit[m] =
-      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
-                        (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
-                                      l_min_log_val_1)));
-    l_val += d_delta;
+
+
+  if (n_code_outputs == 0) {
+    std::cerr << "code_metrics::create: Error: # of code outputs "
+      "must be positive.\n";
+    assert (0);
   }
-}
 
-void code_metric_fb::lookup
-(pdf_fcn_io_t sym,
- void* bit_0,
- void* bit_1)
+
+template<typename pdf_fcn_io_t>
+void
+code_metrics<pdf_fcn_io_t>::compute_all_outputs
+(pdf_fcn_io_t* syms,
+ std::vector<unsigned long>& out)
 {
-  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
-  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+  // use the first 'n_code_output' symbols, convert them into metrics,
+  // then compute all possible (summation) combinations of them and
+  // return those in the provided vector.
 
-  if (sym <= d_min_sample) {
-    *l_bit_0 = d_metric_table_0_bit[0];
-    *l_bit_1 = d_metric_table_1_bit[0];
-    return;
-  }
-  if (sym >= d_max_sample) {
-    *l_bit_0 = d_metric_table_0_bit.back ();
-    *l_bit_1 = d_metric_table_1_bit.back ();
-    return;
+  convert (d_n_code_outputs, syms,
+          (void*)(&(in_l[0][0])), (void*)(&in_l[1][0]));
+
+  // assign the starting minimum metric to 0.  This is safe because
+  // metrics are always non-negative.
+
+  unsigned long min_metric = 0;
+  for (size_t m = 0; m < (((size_t)2) << d_n_code_outputs); m++) {
+    size_t t_out_ndx = m;
+    unsigned long t_metric = 0;
+    for (size_t n = 0; n < d_n_code_outputs; n++, t_out_ndx >>= 1)
+      t_metric += in_l[t_out_ndx&1][n];
+    if (t_metric < min_metric)
+      min_metric = t_metric;
+    out[m] = t_metric;
   }
 
-  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
-  *l_bit_0 = d_metric_table_0_bit[l_ndx];
-  *l_bit_1 = d_metric_table_1_bit[l_ndx];
+  // normalize so that the minimum metric equals 0
+
+  for (size_t m = 0; m < d_n_code_outputs; m++)
+    out[m] -= min_metric;
 }
 
-void code_metric_fb::convert
-(size_t n_syms,
- pdf_fcn_io_t* sym,
- void* bit_0,
- void* bit_1)
+template<typename pdf_fcn_io_t>
+void
+code_metrics<pdf_fcn_io_t>::compute_all_outputs
+(pdf_fcn_io_t* syms,
+ std::vector<float>& out)
 {
-  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
-  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+  // use the first 'n_code_output' symbols, convert them into metrics,
+  // then compute all possible (summation) combinations of them and
+  // return those in the provided vector.
 
-  for (size_t m = n_syms; m > 0; m--)
-    lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
+  convert (d_n_code_outputs, syms,
+          (void*)(&(in_f[0][0])), (void*)(&in_f[1][0]));
+
+  // assign the starting minimum metric to 0.  This is safe because
+  // metrics are always non-negative.
+
+  float min_metric = 0;
+  for (size_t m = 0; m < (((size_t)2) << d_n_code_outputs); m++) {
+    size_t t_out_ndx = m;
+    float t_metric = 0;
+    for (size_t n = 0; n < d_n_code_outputs; n++, t_out_ndx >>= 1)
+      t_metric += in_f[t_out_ndx&1][n];
+    if (t_metric < min_metric)
+      min_metric = t_metric;
+    out[m] = t_metric;
+  }
+
+  // normalize so that the minimum metric equals 0
+
+  for (size_t m = 0; m < d_n_code_outputs; m++)
+    out[m] -= min_metric;
 }
+#endif

Index: libecc/code_metrics.h
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/code_metrics.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- libecc/code_metrics.h       4 Jul 2006 20:57:32 -0000       1.3
+++ libecc/code_metrics.h       1 Aug 2006 19:02:35 -0000       1.4
@@ -20,136 +20,142 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#ifndef INCLUDED_CODE_METRIC_H
-#define INCLUDED_CODE_METRIC_H
+#ifndef INCLUDED_CODE_METRICS_H
+#define INCLUDED_CODE_METRICS_H
 
-#include <sys/types.h>
+#include "code_types.h"
 #include <vector>
 
+template<typename pdf_fcn_io_t>
 class code_metrics
 {
+/*
+ * class code_metrics_table: metrics table for convolutional codes.
+ * Pre-compute a lookup table upon instantiation, which makes for
+ * quick conversion from soft-float symbol value ('sym') to metric
+ * value.  The symbol value probability is defined by the arguments
+ * 'pdf_fcn_0_bit' and 'pdf_fcn_1_bit' for p(0|sym) and p(1|sym)
+ * respectively.  Internally, the PDF's are sampled and normalized to
+ * always have a minimum value of 0.  For float-precision, the maximum
+ * value is 1.0, while for integer M-bits the maximum value is
+ * (2^M)-1.  Smaller metric values indicate that the received symbols
+ * are closer to the given output bits; larger values indicate greater
+ * differences.  The only constraint on the PDF functions are that
+ * they are piecewise continuous; otherwise, they don't even have to
+ * be a true PDF in terms of the integral from -inf to +inf being
+ * equal to 1 due to the normalization.
+ *
+ * Storage type for the tables is determined by the "sample_precision"
+ * argument.  When the precision equals 0, 32-bit float storage is
+ * used; otherwise, the next largest standard integer type is used
+ * unsigned (char for 1 to 8 bits, short for 9 to 16 bits, and long
+ * for 17 to 32 bits).  For the purposes of coding gain, any
+ * sample_precision larger than about 9 will have minimal added
+ * benefit under most conditions where communications are possible.
+ * Trellis computations are performed in either 32-bit float (for
+ * float storage) or 32-bit unsigned long (for all integer storage).
+ *
+ * The number of samples to store is determined by the "n_samples"
+ * argument, which must be at least 2 but is otherwise not limited
+ * except by the memory of the host computer.
+ *
+ * Samples of the PDF functions are taken from "min_sample" to
+ * "max_sample", which represent the floor and ceiling on input symbol
+ * values below and above which symbol values are truncated.
+ * Internally, a sub-n_samples value is determined and used to "sum"
+ * the PDF functions to divide the probabilities into "bins".
+ *
+ * The "n_code_outputs" is needed to compute the trellis combined
+ * metric for the given received code-output values (including any
+ * noise and other channel effects) and all possible bit-output values.
+ */
+
 public:
-  typedef float pdf_fcn_io_t;
+  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
 
-  code_metrics () {};
   virtual ~code_metrics () {};
 
-// lookup() returns either a float, or a sign-extended
-// 'sample_precision'-bit integer value.
+  // lookup() returns either a float, or a sign-extended
+  // 'sample_precision'-bit integer value.
 
   virtual void lookup (pdf_fcn_io_t sym,
                       void* bit_0,
                       void* bit_1) = 0;
 
+  // convert does a lookup on 'n_syms' input symbols
+
   virtual void convert (size_t n_syms,
                        pdf_fcn_io_t* syms,
                        void* bit_0,
                        void* bit_1) = 0;
-};
 
-class code_metric_ff : public code_metrics
-{
-  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
-  typedef float metric_t, *metric_ptr_t;
+  inline const unsigned char out_item_size_bytes ()
+  {return(d_out_item_size_bytes);};
 
-private:
-  size_t d_n_samples;
-  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
-  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
-  std::vector<metric_t> d_metric_table_0_bit;
-  std::vector<metric_t> d_metric_table_1_bit;
+  // code_metrics are not "new"d directly, but rather created by this
+  // static function - which automatically determines the correct
+  // storage class type and creates the new instantiation.
 
-public:
-  code_metric_ff (pdf_fcn_t pdf_fcn_0_bit,
+  static code_metrics* create (pdf_fcn_t pdf_fcn_0_bit,
                  pdf_fcn_t pdf_fcn_1_bit,
                  size_t n_samples,
                  pdf_fcn_io_t min_sample,
-                 pdf_fcn_io_t max_sample);
-  ~code_metric_ff () {};
-
-  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
-  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
-};
-
-class code_metric_fl : public code_metrics
-{
-  typedef float pdf_fcn_io_t;
-  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
-  typedef long metric_t, *metric_ptr_t;
-
-private:
-  char d_sample_precision;
-  size_t d_n_samples, d_sample_mask;
-  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
-  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
-  std::vector<metric_t> d_metric_table_0_bit;
-  std::vector<metric_t> d_metric_table_1_bit;
+                              pdf_fcn_io_t max_sample,
+                              int sample_precision = 0);
 
-public:
-  code_metric_fl (pdf_fcn_t pdf_fcn_0_bit,
+protected:
+  code_metrics (pdf_fcn_t pdf_fcn_0_bit,
                  pdf_fcn_t pdf_fcn_1_bit,
                  size_t n_samples,
                  pdf_fcn_io_t min_sample,
-                 pdf_fcn_io_t max_sample,
-                 int sample_precision = 32);
-  ~code_metric_fl () {};
+               pdf_fcn_io_t max_sample);
 
-  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
-  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
+  unsigned char d_out_item_size_bytes, d_sample_precision;
+  size_t d_n_samples;
+  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
+  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
+  std::vector<pdf_fcn_io_t> d_pdf_fcn_0_samples, d_pdf_fcn_1_samples;
 };
 
-class code_metric_fs : public code_metrics
+template<typename pdf_fcn_io_t, typename metric_t>
+class code_metric_table : public code_metrics<pdf_fcn_io_t>
 {
-  typedef float pdf_fcn_io_t;
+public:
+  typedef metric_t *metric_ptr_t;
   typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
-  typedef short metric_t, *metric_ptr_t;
 
-private:
-  char d_sample_precision;
-  size_t d_n_samples, d_sample_mask;
-  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
-  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
-  std::vector<metric_t> d_metric_table_0_bit;
-  std::vector<metric_t> d_metric_table_1_bit;
+  ~code_metric_table () {};
 
-public:
-  code_metric_fs (pdf_fcn_t pdf_fcn_0_bit,
+  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
+  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
+
+protected:
+  code_metric_table (pdf_fcn_t pdf_fcn_0_bit,
                  pdf_fcn_t pdf_fcn_1_bit,
                  size_t n_samples,
                  pdf_fcn_io_t min_sample,
                  pdf_fcn_io_t max_sample,
-                 int sample_precision = 16);
-  ~code_metric_fs () {};
+                    int sample_precision = 0);
 
-  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
-  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
-};
-
-class code_metric_fb : public code_metrics
-{
-  typedef float pdf_fcn_io_t;
-  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
-  typedef char metric_t, *metric_ptr_t;
-
-private:
-  char d_sample_precision;
-  size_t d_n_samples, d_sample_mask;
-  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
-  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
-  std::vector<metric_t> d_metric_table_0_bit;
-  std::vector<metric_t> d_metric_table_1_bit;
-
-public:
-  code_metric_fb (pdf_fcn_t pdf_fcn_0_bit,
+  friend code_metrics<pdf_fcn_io_t>*
+  code_metrics<pdf_fcn_io_t>::create
+  (pdf_fcn_t pdf_fcn_0_bit,
                  pdf_fcn_t pdf_fcn_1_bit,
                  size_t n_samples,
                  pdf_fcn_io_t min_sample,
                  pdf_fcn_io_t max_sample,
-                 int sample_precision = 8);
-  ~code_metric_fb () {};
+   int sample_precision);
 
-  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
-  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
+  std::vector<metric_t> d_metric_table_0_bit, d_metric_table_1_bit;
 };
+#if 0
+  // compute all output-bit combinations of the incoming symbols' metrics
+
+  void compute_all_outputs (pdf_fcn_io_t* syms, std::vector<unsigned long>& 
out);
+  void compute_all_outputs (pdf_fcn_io_t* syms, std::vector<float>& out);
 
-#endif /* INCLUDED_CODE_METRIC_H */
+  size_t d_n_code_outputs;
+  std::vector<unsigned long> in_l[2];
+  std::vector<float> in_f[2];
+#endif
+#endif /* INCLUDED_CODE_METRICS_H */

Index: libecc/decoder.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/decoder.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- libecc/decoder.cc   9 Jul 2006 16:15:17 -0000       1.2
+++ libecc/decoder.cc   1 Aug 2006 19:02:35 -0000       1.3
@@ -25,93 +25,180 @@
 #endif
 
 #include <decoder.h>
-#include <assert.h>
 #include <iostream>
 
-#define DO_PRINT_DEBUG 1
-
-#if DO_PRINT_DEBUG
-#include <mld/n2bs.h>
-#endif
+#define DO_PRINT_DEBUG 0
 
 /*
  * decode a certain number of output bits
  *
  * the 'in_buf' and 'out_buf' must have enough memory to handle the
- *     number of input metrics and output bits; no error checking is done!
+ *     number of input items and output bits; no error checking is done!
  *
- * n_bits_to_output: the number of bits per output stream to output.
+ * n_bits_to_output: the number of bits per output stream to decode.
  *
- * returns the actual number of metrics used per input stream.
+ * returns the actual number of items used per input stream.
  */
 
 size_t
 decoder::decode
-(const char** in_buf,
- char** out_buf,
+(const code_input_ptr in_buf,
+ code_output_ptr out_buf,
  size_t n_bits_to_output)
 {
+  if (in_buf == 0) {
+    std::cerr << "decoder::decode: Error: input buffer is NULL.\n";
+    assert (0);
+  }
+  if (out_buf == 0) {
+    std::cerr << "decoder::decode: Error: output buffer is NULL.\n";
+    assert (0);
+  }
+  if (n_bits_to_output == 0) {
+    std::cerr << "decoder::decode: Warning: no output bits requested.\n";
+    return (0);
+  }
+
   // set the class-internal number of input metrics
   // and output bits left to decode
 
-  size_t saved_n_input_metrics;
-  saved_n_input_metrics = d_n_input_metrics_left =
-    compute_n_input_metrics (n_bits_to_output);
-  d_n_output_bits_left = n_bits_to_output;
+  d_in_buf = in_buf;
+  d_out_buf = out_buf;
+
+  // check that there are enough output buffer items
+
+  if (d_out_buf->n_items_left() < n_bits_to_output) {
+    std::cerr << "encoder::encode: Warning: output buffer size (" <<
+      d_out_buf->n_items_left() << "is less than the desired number "
+      "of output items (" << n_bits_to_output <<
+      ") ... using lower number.\n";
+    n_bits_to_output = d_out_buf->n_items_left();
+  }
+
+  // check that there are enough input buffer items
+
+  size_t n_items_to_input = compute_n_input_items (n_bits_to_output);
+
+  if (d_in_buf->n_items_left() < n_items_to_input) {
+    std::cerr << "encoder::encode: Warning: input buffer size (" <<
+      d_in_buf->n_items_left() << "is less than the computed number "
+      "of required input items (" << n_items_to_input <<
+      ") ... using lower number.\n";
+    n_items_to_input = d_in_buf->n_items_left();
+    n_bits_to_output = compute_n_output_bits (n_items_to_input);
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "# output bits = " << n_bits_to_output << "\n"
+      "# input items = " << n_items_to_input << "\n";
+  }
 
   // call the private decode function
 
-  decode_private (in_buf, out_buf);
+  decode_private ();
 
   if (DO_PRINT_DEBUG) {
-    std::cout << "n_input_metrics_used = " <<
-      (saved_n_input_metrics - d_n_input_metrics_left) << "\n"
-      "n_output_bits_used = " <<
-      (n_bits_to_output - d_n_output_bits_left) << '\n';
+    std::cout <<
+      "# input items used = " << d_in_buf->n_items_used() << "\n"
+      "# output bits used = " << d_out_buf->n_items_used() << "\n";
   }
 
-  // return the actual number of input metrics used
+  size_t n_items_used = d_in_buf->n_items_used ();
+
+  // clear these buffers, just in case
+
+  d_in_buf = 0;
+  d_out_buf = 0;
+
+  // return the actual number of input bits used
 
-  return (saved_n_input_metrics - d_n_input_metrics_left);
+  return (n_items_used);
 }
 
 /*
  * decode a certain number of input metrics
  *
  * the 'in_buf' and 'out_buf' must have enough memory to handle the
- *     number of input metrics and output bits; no error checking is done!
+ *     number of input items and output bits; no error checking is done!
  *
- * n_metrics_to_input: the number of metrics per input stream to decode
+ * n_items_to_input: the number of items per input stream to decode
  *
  * returns the actual number of bits written per output stream
  */
 
 size_t
 decoder::decode
-(const char** in_buf,  
- size_t n_metrics_to_input,
- char** out_buf)
+(const code_input_ptr in_buf,
+ size_t n_items_to_input,
+ code_output_ptr out_buf)
 {
+  if (in_buf == 0) {
+    std::cerr << "encoder::encode: Error: input buffer is NULL.\n";
+    assert (0);
+  }
+  if (out_buf == 0) {
+    std::cerr << "encoder::encode: Error: output buffer is NULL.\n";
+    assert (0);
+  }
+  if (n_items_to_input == 0) {
+    std::cerr << "encoder::encode: Warning: no input items requested.\n";
+    return (0);
+  }
+
   // set the class-internal number of input metrics and
   // output bits left to decode
 
-  size_t saved_n_output_bits;
-  saved_n_output_bits = d_n_output_bits_left =
-    compute_n_output_bits (n_metrics_to_input);
-  d_n_input_metrics_left = n_metrics_to_input;
+  d_in_buf = in_buf;
+  d_out_buf = out_buf;
+
+  // check that there are enough input buffer items
+
+  if (d_in_buf->n_items_left() < n_items_to_input) {
+    std::cerr << "encoder::encode: Warning: input buffer size (" <<
+      d_in_buf->n_items_left() << "is less than the desired number "
+      "of input items (" << n_items_to_input <<
+      ") ... using lower number.\n";
+    n_items_to_input = d_in_buf->n_items_left();
+  }
+
+  // check that there are enough output buffer items
+
+  size_t n_bits_to_output = compute_n_output_bits (n_items_to_input);
+
+  if (d_out_buf->n_items_left() < n_bits_to_output) {
+    std::cerr << "encoder::encode: Warning: output buffer size (" <<
+      d_out_buf->n_items_left() << "is less than the computed number "
+      "of required output items (" << n_bits_to_output <<
+      ") ... using lower number.\n";
+    n_bits_to_output = d_out_buf->n_items_left();
+    n_items_to_input = compute_n_input_items (n_bits_to_output);
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "# output bits = " << n_bits_to_output << "\n"
+      "# input items = " << n_items_to_input << "\n";
+  }
 
   // call the private decode function
 
-  decode_private (in_buf, out_buf);
+  decode_private ();
 
   if (DO_PRINT_DEBUG) {
-    std::cout << "n_input_metrics_used = " <<
-      (n_metrics_to_input - d_n_input_metrics_left) << '\n';
-    std::cout << "n_output_bits_used = " <<
-      (saved_n_output_bits - d_n_output_bits_left) << '\n';
+    std::cout <<
+      "# input items used = " << d_in_buf->n_items_used() << "\n"
+      "# output bits used = " << d_out_buf->n_items_used() << "\n";
   }
 
+  size_t n_items_used = d_out_buf->n_items_used();
+
+  // clear these buffers, just in case
+
+  d_in_buf = 0;
+  d_out_buf = 0;
+
   // return the actual number of output bits written
 
-  return (saved_n_output_bits - d_n_output_bits_left);
+  return (n_items_used);
 }

Index: libecc/decoder.h
===================================================================
RCS file: /sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/decoder.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- libecc/decoder.h    20 Jul 2006 17:42:54 -0000      1.5
+++ libecc/decoder.h    1 Aug 2006 19:02:35 -0000       1.6
@@ -23,37 +23,69 @@
 #ifndef INCLUDED_DECODER_H
 #define INCLUDED_DECODER_H
 
-#include "code_types.h"
-
-// the 'decoder' class is a virtual class upon which all decoder types
-// can be built.
+#include "code_io.h"
 
 class decoder
 {
+  /*
+   * class decoder
+   * A virtual class upon which all decoder types can be built.
+   * This class provides the basic methods and variables
+   * generic for all decoders.
+   */
 public:
   decoder () {};
   virtual ~decoder () {};
 
-  virtual size_t compute_n_input_metrics (size_t n_output_bits) = 0;
-  virtual size_t compute_n_output_bits (size_t n_input_metrics) = 0;
-  virtual size_t decode (const char** in_buf,
-                        char** out_buf,
+  /*
+   * compute_n_...: to be defined by inheriting classes, in order to
+   * allow for user-functions to figure out how many inputs are
+   * required to generate a given number of outputs, and vice versa.
+   * Can't define them without knowing the decoder type.
+   *
+   * Compute the number of input items (metrics, floats, whatevers)
+   * needed to produce 'n_output' bits, and the number of output bits
+   * which will be produced by 'n_input' items ... for a single stream
+   * only.
+   */
+
+  virtual size_t compute_n_input_items (size_t n_output_bits) = 0;
+  virtual size_t compute_n_output_bits (size_t n_input_items) = 0;
+
+  /*
+   * decode: given the input and output buffers, either decode up to
+   * the number of output bits or decode the number of input items
+   * ... if the buffers support either decoding amounts.
+   */
+
+  virtual size_t decode (const code_input_ptr in_buf,
+                        code_output_ptr out_buf,
                         size_t n_bits_to_output);
-  virtual size_t decode (const char** in_buf,
-                        size_t n_metrics_to_input,
-                        char** out_buf);
+  virtual size_t decode (const code_input_ptr in_buf,
+                        size_t n_items_to_input,
+                        code_output_ptr out_buf);
+
+/* for remote access to internal info */
+
+  inline const size_t block_size_bits () {return (d_block_size_bits);};
+  inline const size_t n_code_inputs () {return (d_n_code_inputs);};
+  inline const size_t n_code_outputs () {return (d_n_code_outputs);};
+  inline const size_t total_n_dec_bits () {return (d_total_n_dec_bits);};
 
 protected:
-  virtual void decode_private (const char** in_buf, char** out_buf) = 0;
-  virtual char get_next_input (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;
+  /*
+   * decode_private: decode 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 decode_private () = 0;
 
   size_t d_block_size_bits, d_n_code_inputs, d_n_code_outputs;
-  size_t d_n_dec_bits;
-  size_t d_in_buf_ndx, d_out_buf_ndx;
-  size_t d_in_bit_shift, d_out_bit_shift;
-  size_t d_n_input_metrics_left, d_n_output_bits_left;
+  size_t d_total_n_dec_bits;
+  code_input_ptr d_in_buf;
+  code_output_ptr d_out_buf;
 };
 
 #endif /* INCLUDED_DECODER_H */

Index: libecc/decoder_viterbi.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- libecc/decoder_viterbi.cc   9 Jul 2006 16:15:17 -0000       1.2
+++ libecc/decoder_viterbi.cc   1 Aug 2006 19:02:35 -0000       1.3
@@ -52,55 +52,45 @@
 #define DO_PRINT_DEBUG_EXIT 0
 #define DO_PRINT_DEBUG 0
 
-#if DO_TIME_THOUGHPUT
 #include <mld/mld_timer.h>
-#endif
-#if DO_PRINT_DEBUG
 #include <mld/n2bs.h>
-#endif
 
 decoder_viterbi::decoder_viterbi
 (int sample_precision,
- encoder_convolutional* l_encoder)
+ const encoder_convolutional* l_encoder)
 {
-  // make sure the sample precitions makes sense
+  // make sure that the encoder is "valid"
 
-  if ((sample_precision < 0) | (sample_precision > 32)) {
-    std::cerr << "decoder_viterbi: "
-      "Requested sample_precision (" << sample_precision <<
-      "must be between 0 and 32.\n";
+  if (! l_encoder) {
+    std::cerr << "decoder_viterbi: Error: Encoder is NULL.\n";
     assert (0);
   }
 
-  // make sure that the encoder is "valid"
+  // make the metrics converter
 
-  if (! l_encoder) {
-    std::cerr << "decoder_viterbi: Error: Encoder is a NULL pointer.\n";
+  //  d_code_metrics = new code_metrics (
+
+  if ((sample_precision < 0) | (sample_precision > 32)) {
+    std::cerr << "decoder_viterbi: "
+      "Requested sample_precision (" << sample_precision <<
+      ") must be between 0 and 32.\n";
     assert (0);
   }
 
-  // keep around a pointer to the encoder
+  // get the trellis
 
-  d_encoder = l_encoder;
+  d_encoder = (encoder_convolutional*) l_encoder;
+  d_trellis = (code_convolutional_trellis*) d_encoder->trellis ();
 
   // fill the class variables
 
   d_block_size_bits = d_encoder->block_size_bits ();
-  d_do_streaming = (d_block_size_bits == 0);
   d_n_code_inputs = d_encoder->n_code_inputs ();
   d_n_code_outputs = d_encoder->n_code_outputs ();
   d_do_termination = d_encoder->do_termination ();
-#if 0
-  d_total_memory = d_encoder->total_memory ();
-#endif
-
-  // NOTE: d_n_states is a 'long', and thus is quite limited in terms
-  // of max memory and # of input streams to 2^32 states This is OK,
-  // since that many states would be impossibly slow to decode!  might
-  // make this a "long long" (64 bits) in the future
-
-  d_n_states = 1 << d_total_memory;
-  d_n_input_combinations = 1 << d_n_code_inputs;
+  d_total_n_delays = d_encoder->total_n_delays ();
+  d_n_states = d_trellis->n_states ();
+  d_n_input_combinations = d_trellis->n_input_combinations ();
 
   // really nothing else to do here, since this class doesn't "know"
   // how to process streaming versus block decoding, or partial
@@ -112,11 +102,9 @@
       "d_block_size_bits          = " << d_block_size_bits << "\n" <<
       "d_n_code_inputs            = " << d_n_code_inputs << "\n" <<
       "d_n_code_outputs           = " << d_n_code_outputs << "\n" <<
-      "d_do_streaming             = " <<
-      ((d_do_streaming == true) ? "true" : "false") << "\n" <<
       "d_do_termination           = " <<
       ((d_do_termination == true) ? "true" : "false") << "\n" <<
-      "d_total_memory             = " << d_total_memory << "\n" <<
+      "d_total_n_delays           = " << d_total_n_delays << "\n" <<
       "d_n_states                 = " << d_n_states << "\n" <<
       "d_n_input_combinations     = " << d_n_input_combinations << "\n";
   }
@@ -134,17 +122,14 @@
 
   d_n_total_inputs_per_stream = d_block_size_bits;
   if (d_do_termination == true)
-    d_n_total_inputs_per_stream += d_max_memory;
-
-
-
+    d_n_total_inputs_per_stream += d_total_n_delays;
 }
 
 decoder_viterbi::~decoder_viterbi
 ()
 {
   // reverse over from allocation
-
+#if 0
   delete [] d_up_term_states_ndx[0];
   delete [] d_up_term_states_ndx[1];
 
@@ -177,6 +162,7 @@
     delete [] (*t_save_buffer++);
   }
   delete [] d_save_buffer;
+#endif
 }
 
 void
@@ -209,20 +195,9 @@
   }
 }
 
-//FIXME 
-
-char
-decoder_viterbi::get_next_input
-(const char** in_buf,
-size_t code_input_n)
-{
-  return (0);
-}
-
 void
 decoder_viterbi::decode_private
-(const char** in_buf,
- char** out_buf)
+()
 {
 #if 0
 
@@ -231,8 +206,8 @@
   start_timer (&t_tp);
 #endif
 #if DO_PRINT_DEBUG
-  size_t t_state_print_bits = d_total_memory + 1;
-  size_t t_mem_print_bits = d_max_memory + 2;
+  size_t t_state_print_bits = d_total_n_delays;
+  size_t t_mem_print_bits = d_total_n_delays;
 #endif
 // setup variables for quicker access
   const char **in_buf = (const char **) &input_items[0];
@@ -319,148 +294,8 @@
 // jump to the correct state in the fsm
     switch (d_fsm_state) {
     case fsm_dec_viterbi_doing_up:
-#if DO_PRINT_DEBUG_FSM
-      std::cout << "Starting fsm_dec_viterbi_doing_up\n";
-#endif
-// set the number of up_down indices
-      size_t t_n_up_down_ndx = 1 << (d_n_code_inputs *
-                                    d_time_count);
-// stay in this state until the correct number of input symbols are
-// reached; exit also if we run out of input symbols to process
-      while ((d_time_count < d_max_memory) &
-            (t_in_buf_ndx < t_ninput_items)) {
-#if DO_PRINT_DEBUG_UP_0
-       std::cout << "Doing 'while' loop:\n" <<
-         "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
-         "d_time_count       = " << d_time_count << "\n" <<
-         "d_max_memory       = " << d_max_memory << "\n" <<
-         "t_in_buf_ndx       = " << t_in_buf_ndx << "\n" <<
-         "t_ninput_items     = " << t_ninput_items << "\n";
-#endif
-// use the "from" states, loop over all inputs and compute the metric for
-// each & store it in the "to" state at the end of the connection.
-// no need to compare metrics yet, since none join into any given state
-
 #if 0
-// reset the "to" state's metrics
-// probably don't need to do this; try removing later
-        reset_metrics (d_states_ndx ^ 1);
-#if DO_PRINT_DEBUG_UP
-       std::cout << "Reset Metrics\n";
-#endif
-#endif
-
-// reset the state's index for each set of new inputs
-       size_t* t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
-       size_t* t_next_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx ^ 1];
-// loop over all current stored "up" states
-       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
-         size_t t_state_ndx = *t_state_ndx_ptr++;
-// get a pointer to this state's structure
-         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
-// get the connections for all inputs
-         connection_t_ptr t_connection = t_state->d_connections;
-#if DO_PRINT_DEBUG_UP_0
-         std::cout << "Looping over all 'up' states:\n" <<
-           "n                  = " << n << "\n" <<
-           "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
-           "d_states_ndx       = " << d_states_ndx << "\n" <<
-           "t_state_ndx        = " << t_state_ndx << "\n" <<
-           "d_n_input_combs    = " << d_n_input_combinations << "\n" <<
-           "t_state            = " << t_state << "\n" <<
-           "t_connection       = " << t_connection << "\n";
-#endif
-// loop over all possible input values, 1 bit per input stream
-         for (size_t q = 0; q < d_n_input_combinations; q++, t_connection++) {
-// find the "to" state for this connection
-           state_t_ptr t_to_state = t_connection->d_to;
-// get the output bits for this connection
-           float* t_output_bit = t_connection->d_output_bits;
-// start with this state's metric
-           float t_metric = t_state->d_max_metric;
-#if DO_PRINT_DEBUG_UP_0
-           std::cout <<
-             "to state index     = " << t_connection->d_to_ndx << "\n" <<
-             "current metric     = " << t_metric << "\n";
-#endif
-           if (d_do_mux_inputs == true) {
-// if using mux'ed input streams, handle differently
-              const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
-// loop over all encoder-output values
-             for (size_t r = d_n_code_outputs; r > 0; r--) {
-#if DO_PRINT_DEBUG_UP
-               std::cout << "in_sym = " << *t_in_buf << ", code_out_bit = " <<
-                 *t_output_bit << " ==> metric -> ";
-#endif
-               t_metric += ((*t_in_buf++) * (*t_output_bit++));
-#if DO_PRINT_DEBUG_UP
-               std::cout << t_metric << "\n";
-#endif
-             }
-           } else {
-// loop over all encoder-output values
-             for (size_t r = 0; r < d_n_code_outputs; r++) {
-#if DO_PRINT_DEBUG_UP
-               std::cout << "in_sym = " << in_buf[r][t_in_buf_ndx] <<
-                 ", code_out_bit = " << *t_output_bit << " ==> metric -> ";
-#endif
-               t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
-#if DO_PRINT_DEBUG_UP
-               std::cout << t_metric << "\n";
-#endif
-             }
-           }
-// get the "to" state index
-           size_t t_to_ndx = t_connection->d_to_ndx;
-// store the metric in the "to" state; should not have been used before
-           t_to_state->d_max_metric = t_metric;
-// add the "to" state index to the "up" state list
-           *t_next_state_ndx_ptr++ = t_to_ndx;
-// update the traceback structure, depending on which variety it is
-// doing full trellis before decoding; use d_out_buf
-// simple: get the current state & output state
-           traceback_t_ptr t_out_buf = &(d_out_buf[d_time_count]
-                                         [t_state_ndx]);
-           traceback_t_ptr t_next_out_buf = &(d_out_buf[d_time_count+1]
-                                              [t_to_ndx]);
-#if DO_PRINT_DEBUG_UP_1
-           std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n" <<
-             "ndx[" << n << "] == " << t_state_ndx <<
-             ", s[" << n2bs(t_state_ndx,t_state_print_bits) <<
-             "]: max_ndx = " <<
-             n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
-             ", input = " << n2bs(q, d_n_code_inputs+1) <<
-             ": " << t_next_out_buf << " => " << t_out_buf << "\n";
-#endif
-// and connect output to the current, set inputs on output
-           t_next_out_buf->d_prev = t_out_buf;
-           t_next_out_buf->d_inputs = q;
-// finished (for) this input value
-         }
-// finished (for) this "up_term" state
-       }
-// increment the in_buf index, depending on mux'ing or not
-       t_in_buf_ndx += (d_do_mux_inputs == false) ? 1 : d_n_code_outputs;
-// increment the time counter
-        d_time_count++;
-// update the number of "up_term" states
-        d_up_term_ndx ^= 1;
-// increase the number of using states
-        t_n_up_down_ndx <<= d_n_code_inputs;
-// change which d_states' index to use as starting
-        d_states_ndx ^= 1;
-// finished (while) staying in this fsm state or not
-      }
-// if reached the end of doing the "up" part of the trellis,
-// switch states into the middle
-      if (d_time_count == d_max_memory) {
-#if DO_PRINT_DEBUG_FSM
-       std::cout << "Setting FSM to fsm_dec_viterbi_doing_middle\n";
-#endif
-        d_fsm_state = fsm_dec_viterbi_doing_middle;
-      }
-#if DO_PRINT_DEBUG_FSM
-      std::cout << "Exited fsm_dec_viterbi_doing_up\n";
+      encode_loop_up ();
 #endif
       break;
     case (fsm_dec_viterbi_doing_middle):
@@ -486,7 +321,7 @@
 #if DO_PRINT_DEBUG_MIDDLE
        std::cout << "Time Count " << (d_time_count+1) << " of " <<
          d_block_size_bits << "\n" <<
-         "d_states_ndx = " << d_states_ndx << "\n";;
+         "d_states_ndx = " << d_states_ndx << "\n";
 #endif
 // loop over all current states
        for (size_t n = 0; n < d_n_states; n++, t_state++) {
@@ -621,15 +456,15 @@
       std::cout << "Entered fsm_dec_viterbi_doing_term\n";
 #endif
 // set the "next" up_down index to the end of their states
-      size_t t_time_count = d_max_memory - (d_time_count - d_block_size_bits);
+      size_t t_time_count = d_total_n_delays - (d_time_count - 
d_block_size_bits);
       t_n_up_down_ndx = 1 << (d_n_code_inputs * t_time_count);
 // stay in this state until the correct number of input symbols are
 // reached; exit also if we run out of input symbols to process
       while ((t_time_count > 0) &
             (t_in_buf_ndx < t_ninput_items)) {
 #if DO_PRINT_DEBUG_TERM
-       std::cout << "Doing time " << (d_max_memory - t_time_count + 1) <<
-         " of " << d_max_memory << "; starting buf[" << t_in_buf_ndx <<
+       std::cout << "Doing time " << (d_total_n_delays - t_time_count + 1) <<
+         " of " << d_total_n_delays << "; starting buf[" << t_in_buf_ndx <<
          "] of [" << t_ninput_items << "]\n";
 #endif
 // use the "to" states,
@@ -800,15 +635,15 @@
 // FIXME: assume termination state == 0
 #if DO_PRINT_DEBUG_OUTPUT_0
        std::cout << "Using termination; going through trellis for " <<
-         d_max_memory << " bit" <<
-         ((d_max_memory != 1) ? "s" : "") << "\n";
+         d_total_n_delays << " bit" <<
+         ((d_total_n_delays != 1) ? "s" : "") << "\n";
 #endif
        t_out_buf = &(d_out_buf[d_time_count][0]);
 #if DO_PRINT_DEBUG_OUTPUT_0
        std::cout << "Starting traceback ptr " << t_out_buf << "\n";
 #endif
 // skip over the termination bits
-       for (size_t n = d_max_memory; n > 0; n--) {
+       for (size_t n = d_total_n_delays; n > 0; n--) {
          t_out_buf = t_out_buf->d_prev;
 #if DO_PRINT_DEBUG_OUTPUT_0
          std::cout << "Next traceback ptr " << t_out_buf << "\n";
@@ -1058,3 +893,157 @@
     " b/s\n";
 #endif
 }
+
+#if 0
+
+void
+decoder_viterbi::encode_loop_up ()
+{
+#if DO_PRINT_DEBUG_FSM
+  std::cout << "Starting fsm_dec_viterbi_doing_up\n";
+#endif
+
+  // set the number of up_down indices
+
+  size_t t_n_up_down_ndx = 1 << (d_n_code_inputs *
+                                d_time_count);
+
+// stay in this state until the correct number of input symbols are
+// reached; exit also if we run out of input symbols to process
+      while ((d_time_count < d_total_n_delays) &
+            (t_in_buf_ndx < t_ninput_items)) {
+#if DO_PRINT_DEBUG_UP_0
+       std::cout << "Doing 'while' loop:\n" <<
+         "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
+         "d_time_count       = " << d_time_count << "\n" <<
+         "d_total_n_delays   = " << d_total_n_delays << "\n" <<
+         "t_in_buf_ndx       = " << t_in_buf_ndx << "\n" <<
+         "t_ninput_items     = " << t_ninput_items << "\n";
+#endif
+// use the "from" states, loop over all inputs and compute the metric for
+// each & store it in the "to" state at the end of the connection.
+// no need to compare metrics yet, since none join into any given state
+
+#if 0
+// reset the "to" state's metrics
+// probably don't need to do this; try removing later
+        reset_metrics (d_states_ndx ^ 1);
+#if DO_PRINT_DEBUG_UP
+       std::cout << "Reset Metrics\n";
+#endif
+#endif
+
+// reset the state's index for each set of new inputs
+       size_t* t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
+       size_t* t_next_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx ^ 1];
+// loop over all current stored "up" states
+       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
+         size_t t_state_ndx = *t_state_ndx_ptr++;
+// get a pointer to this state's structure
+         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
+// get the connections for all inputs
+         connection_t_ptr t_connection = t_state->d_connections;
+#if DO_PRINT_DEBUG_UP_0
+         std::cout << "Looping over all 'up' states:\n" <<
+           "n                  = " << n << "\n" <<
+           "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
+           "d_states_ndx       = " << d_states_ndx << "\n" <<
+           "t_state_ndx        = " << t_state_ndx << "\n" <<
+           "d_n_input_combs    = " << d_n_input_combinations << "\n" <<
+           "t_state            = " << t_state << "\n" <<
+           "t_connection       = " << t_connection << "\n";
+#endif
+// loop over all possible input values, 1 bit per input stream
+         for (size_t q = 0; q < d_n_input_combinations; q++, t_connection++) {
+// find the "to" state for this connection
+           state_t_ptr t_to_state = t_connection->d_to;
+// get the output bits for this connection
+           float* t_output_bit = t_connection->d_output_bits;
+// start with this state's metric
+           float t_metric = t_state->d_max_metric;
+#if DO_PRINT_DEBUG_UP_0
+           std::cout <<
+             "to state index     = " << t_connection->d_to_ndx << "\n" <<
+             "current metric     = " << t_metric << "\n";
+#endif
+           if (d_do_mux_inputs == true) {
+// if using mux'ed input streams, handle differently
+              const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
+// loop over all encoder-output values
+             for (size_t r = d_n_code_outputs; r > 0; r--) {
+#if DO_PRINT_DEBUG_UP
+               std::cout << "in_sym = " << *t_in_buf << ", code_out_bit = " <<
+                 *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += ((*t_in_buf++) * (*t_output_bit++));
+#if DO_PRINT_DEBUG_UP
+               std::cout << t_metric << "\n";
+#endif
+             }
+           } else {
+// loop over all encoder-output values
+             for (size_t r = 0; r < d_n_code_outputs; r++) {
+#if DO_PRINT_DEBUG_UP
+               std::cout << "in_sym = " << in_buf[r][t_in_buf_ndx] <<
+                 ", code_out_bit = " << *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
+#if DO_PRINT_DEBUG_UP
+               std::cout << t_metric << "\n";
+#endif
+             }
+           }
+// get the "to" state index
+           size_t t_to_ndx = t_connection->d_to_ndx;
+// store the metric in the "to" state; should not have been used before
+           t_to_state->d_max_metric = t_metric;
+// add the "to" state index to the "up" state list
+           *t_next_state_ndx_ptr++ = t_to_ndx;
+// update the traceback structure, depending on which variety it is
+// doing full trellis before decoding; use d_out_buf
+// simple: get the current state & output state
+           traceback_t_ptr t_out_buf = &(d_out_buf[d_time_count]
+                                         [t_state_ndx]);
+           traceback_t_ptr t_next_out_buf = &(d_out_buf[d_time_count+1]
+                                              [t_to_ndx]);
+#if DO_PRINT_DEBUG_UP_1
+           std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n" <<
+             "ndx[" << n << "] == " << t_state_ndx <<
+             ", s[" << n2bs(t_state_ndx,t_state_print_bits) <<
+             "]: max_ndx = " <<
+             n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
+             ", input = " << n2bs(q, d_n_code_inputs+1) <<
+             ": " << t_next_out_buf << " => " << t_out_buf << "\n";
+#endif
+// and connect output to the current, set inputs on output
+           t_next_out_buf->d_prev = t_out_buf;
+           t_next_out_buf->d_inputs = q;
+// finished (for) this input value
+         }
+// finished (for) this "up_term" state
+       }
+// increment the in_buf index, depending on mux'ing or not
+       t_in_buf_ndx += (d_do_mux_inputs == false) ? 1 : d_n_code_outputs;
+// increment the time counter
+        d_time_count++;
+// update the number of "up_term" states
+        d_up_term_ndx ^= 1;
+// increase the number of using states
+        t_n_up_down_ndx <<= d_n_code_inputs;
+// change which d_states' index to use as starting
+        d_states_ndx ^= 1;
+// finished (while) staying in this fsm state or not
+      }
+// if reached the end of doing the "up" part of the trellis,
+// switch states into the middle
+      if (d_time_count == d_total_n_delays) {
+#if DO_PRINT_DEBUG_FSM
+       std::cout << "Setting FSM to fsm_dec_viterbi_doing_middle\n";
+#endif
+        d_fsm_state = fsm_dec_viterbi_doing_middle;
+      }
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_viterbi_doing_up\n";
+#endif
+}
+#endif

Index: libecc/decoder_viterbi.h
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- libecc/decoder_viterbi.h    9 Jul 2006 16:15:17 -0000       1.2
+++ libecc/decoder_viterbi.h    1 Aug 2006 19:02:35 -0000       1.3
@@ -48,31 +48,11 @@
  */
 
   decoder_viterbi (int sample_precision,
-                  encoder_convolutional* l_encoder);
+                  const encoder_convolutional* l_encoder);
 
   virtual ~decoder_viterbi ();
 
 protected:
-  struct state_t;
-
-/*
- * connection_t: describes an output connection from the current
- *     time-bit memory state to the next time-bit memory state
- *
- * d_to: state pointer to which this connection going
- *
- * d_to_ndx: index of the "to" state
- *
- * d_output_bits: what are the output bits, coverted into
- *     1->+1.0, 0->-1.0, for this connection
- */
-
-  typedef struct connection_t {
-    struct state_t *d_to;
-    int d_to_ndx;
-    float* d_output_bits;
-  } connection_t, *connection_t_ptr;
-
 /*
  * state_t: describes a given memory state
  *
@@ -94,7 +74,7 @@
  */
 
   typedef struct state_t {
-    connection_t_ptr d_connections;
+    struct state_t* d_connections;
     float d_max_metric;
     int d_max_state_ndx;
     int d_max_input;
@@ -149,20 +129,21 @@
     fsm_dec_viterbi_doing_middle, fsm_dec_viterbi_doing_term
   };
 
-  virtual void decode_private (const char** in_buf, char** out_buf);
-  virtual char get_next_input (const char** in_buf, size_t code_input_n);
+  virtual void decode_private ();
 #if 0
-  virtual void decode_loop (const char** in_buf, char** out_buf,
-                           size_t* which_counter, size_t how_many);
-
-  virtual char get_next_input__up (const char** in_buf,
-                                     size_t code_input_n) = 0;
-  virtual char get_next_input__middle (const char** in_buf,
-                                         size_t code_input_n) = 0;
-  virtual char get_next_input__term (size_t code_input_n) = 0;
+  virtual void decode_loop (size_t* which_counter, size_t how_many);
 #endif
-  virtual void increment_input_indices (bool while_decoding) = 0;
-  virtual void increment_output_indices (bool while_decoding) = 0;
+  virtual void get_next_inputs () {
+    d_in_buf->read_items ((void*)(&(d_current_inputs[0])));
+    d_in_buf->increment_indices ();
+  };
+  virtual void write_output_bits () {
+    d_out_buf->write_items ((void*)(&(d_current_outputs[0])));
+    d_out_buf->increment_indices ();
+  };
+
+  void encode_loop_up ();
+
   virtual void update_traceback__up (size_t from_state_ndx,
                                     size_t to_state_ndx,
                                     size_t l_input) = 0;
@@ -173,17 +154,32 @@
   void zero_metrics (u_char which);
 
   encoder_convolutional* d_encoder;
+  code_convolutional_trellis* d_trellis;
   fsm_dec_viterbi_t d_fsm_state;
-  size_t d_max_memory, d_total_memory;
+
   size_t d_time_count, d_n_total_inputs_per_stream;
   size_t d_n_saved_bits, d_n_saved_bits_start_ndx, d_n_traceback_els;
-  size_t d_n_states, d_n_input_combinations;
+  size_t d_n_states, d_n_input_combinations, d_total_n_delays;
   size_t d_states_ndx, d_up_term_ndx;
-  bool d_do_streaming, d_do_termination;
-  std::vector<memory_t> d_init_states, d_term_states;
-  char **d_save_buffer;
+  bool d_do_termination;
+#if 1
   state_t_ptr d_states[2];
   size_t* d_up_term_states_ndx[2];
+  char **d_save_buffer;
+#else
+  std::vector<state_t> d_states[2];
+  std::vector<size_t> d_up_term_states_ndx[2];
+  std::vector<char **> d_save_buffer;  ???
+#endif
+
+  // "inputs" are the current input symbols as soft-floats, to be
+  // converted to metrics internally
+
+  std::vector<float> d_current_inputs;
+
+  // "outputs" are the current output bits, in the LSB (&1) of each "char"
+
+  std::vector<char> d_current_outputs;
 };
 
 #endif /* INCLUDED_DECODER_VITERBI_H */

Index: libecc/decoder_viterbi_full_block.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libecc/decoder_viterbi_full_block.cc        9 Jul 2006 16:15:17 -0000       
1.1
+++ libecc/decoder_viterbi_full_block.cc        1 Aug 2006 19:02:35 -0000       
1.2
@@ -127,6 +127,20 @@
   delete [] d_out_buf;
 }
 
+size_t
+compute_n_input_items
+(size_t n_output_bits)
+{
+  return (0);
+}
+
+size_t
+compute_n_output_bits
+(size_t n_input_items)
+{
+  return (0);
+}
+
 void
 decoder_viterbi_full_block::update_traceback__up
 (size_t from_state_ndx,
@@ -272,8 +286,7 @@
 
 void
 decoder_viterbi_full_block::decode_private
-(const char** in_buf,
- char** out_buf)
+()
 {
 #if 0
 

Index: libecc/decoder_viterbi_full_block.h
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libecc/decoder_viterbi_full_block.h 9 Jul 2006 16:15:17 -0000       1.1
+++ libecc/decoder_viterbi_full_block.h 1 Aug 2006 19:02:35 -0000       1.2
@@ -29,8 +29,8 @@
 {
 /*!
  * \brief Decode the incoming streams using a Viterbi-style decoder,
- *     doing full trellis block decoding before putting out
- *     any bits
+ *     doing full trellis block decoding before putting out any
+ *     decoded bits.
  *
  * input: streams of metrics, two per code output: one for the 0-bit
  *     metrics and the other for the 1-bit metric.
@@ -44,8 +44,11 @@
 
   virtual ~decoder_viterbi_full_block ();
 
+  virtual size_t compute_n_input_items (size_t n_output_bits);
+  virtual size_t compute_n_output_bits (size_t n_input_items);
+
 protected:
-  virtual void decode_private (const char** in_buf, char** out_buf);
+  virtual void decode_private ();
   virtual void update_traceback__up (size_t from_state_ndx,
                                     size_t to_state_ndx,
                                     size_t l_input);

Index: libecc/encoder.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder.cc,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libecc/encoder.cc   20 Jul 2006 17:42:54 -0000      1.6
+++ libecc/encoder.cc   1 Aug 2006 19:02:35 -0000       1.7
@@ -42,43 +42,78 @@
 
 size_t
 encoder::encode
-(const char** in_buf,
- char** out_buf,
+(const code_input_ptr in_buf,
+ code_output_ptr out_buf,
  size_t n_bits_to_output)
 {
-  if (DO_PRINT_DEBUG) {
-    std::cout << "encode{out}(): Starting:";
+  if (in_buf == 0) {
+    std::cerr << "encoder::encode: Error: input buffer is NULL.\n";
+    assert (0);
+  }
+  if (out_buf == 0) {
+    std::cerr << "encoder::encode: Error: output buffer is NULL.\n";
+    assert (0);
+  }
+  if (n_bits_to_output == 0) {
+    std::cerr << "encoder::encode: Warning: no output bits requested.\n";
+    return (0);
   }
 
   // set the class-internal number of input bits and
   // output bits left to encode
 
-  size_t saved_n_input_bits;
-  saved_n_input_bits = d_n_input_bits_left =
-    compute_n_input_bits (n_bits_to_output);
-  d_n_output_bits_left = n_bits_to_output;
+  d_in_buf = in_buf;
+  d_out_buf = out_buf;
+
+  // check that there are enough output buffer items
+
+  if (d_out_buf->n_items_left() < n_bits_to_output) {
+    std::cerr << "encoder::encode: Warning: output buffer size (" <<
+      d_out_buf->n_items_left() << "is less than the desired number "
+      "of output items (" << n_bits_to_output <<
+      ") ... using lower number.\n";
+    n_bits_to_output = d_out_buf->n_items_left();
+  }
+
+  // check that there are enough input buffer items
+
+  size_t n_bits_to_input = compute_n_input_bits (n_bits_to_output);
+
+  if (d_in_buf->n_items_left() < n_bits_to_input) {
+    std::cerr << "encoder::encode: Warning: input buffer size (" <<
+      d_in_buf->n_items_left() << "is less than the computed number "
+      "of required input items (" << n_bits_to_input <<
+      ") ... using lower number.\n";
+    n_bits_to_input = d_in_buf->n_items_left();
+    n_bits_to_output = compute_n_output_bits (n_bits_to_input);
+  }
 
   if (DO_PRINT_DEBUG) {
     std::cout <<
-      "# output bits provided = " << d_n_output_bits_left << "\n"
-      "# input bits computed  = " << d_n_input_bits_left << "\n";
+      "# output bits = " << n_bits_to_output << "\n"
+      "# input bits  = " << n_bits_to_input << "\n";
   }
 
   // call the private encode function
 
-  encode_private (in_buf, out_buf);
+  encode_private ();
 
   if (DO_PRINT_DEBUG) {
     std::cout <<
-      "n_input_bits_used  = " <<
-      (saved_n_input_bits - d_n_input_bits_left) << "\n"
-      "n_output_bits_used = " <<
-      (n_bits_to_output - d_n_output_bits_left) << '\n';
+      "# input bits used  = " << d_in_buf->n_items_used() << "\n"
+      "# output bits used = " << d_out_buf->n_items_used() << "\n";
   }
 
+  size_t n_items_used = d_in_buf->n_items_used ();
+
+  // clear these buffers, just in case
+
+  d_in_buf = 0;
+  d_out_buf = 0;
+
   // return the actual number of input bits used
 
-  return (saved_n_input_bits - d_n_input_bits_left);
+  return (n_items_used);
 }
 
 /*
@@ -94,30 +129,76 @@
 
 size_t
 encoder::encode
-(const char** in_buf,  
+(const code_input_ptr in_buf,
  size_t n_bits_to_input,
- char** out_buf)
+ code_output_ptr out_buf)
 {
+  if (in_buf == 0) {
+    std::cerr << "encoder::encode: Error: input buffer is NULL.\n";
+    assert (0);
+  }
+  if (out_buf == 0) {
+    std::cerr << "encoder::encode: Error: output buffer is NULL.\n";
+    assert (0);
+  }
+  if (n_bits_to_input == 0) {
+    std::cerr << "encoder::encode: Warning: no input bits requested.\n";
+    return (0);
+  }
+
   // set the class-internal number of input and
   // output bits left to encode
 
-  size_t saved_n_output_bits;
-  saved_n_output_bits = d_n_output_bits_left =
-    compute_n_output_bits (n_bits_to_input);
-  d_n_input_bits_left = n_bits_to_input;
+  d_in_buf = in_buf;
+  d_out_buf = out_buf;
+
+  // check that there are enough input buffer items
+
+  if (d_in_buf->n_items_left() < n_bits_to_input) {
+    std::cerr << "encoder::encode: Warning: input buffer size (" <<
+      d_in_buf->n_items_left() << "is less than the desired number "
+      "of input items (" << n_bits_to_input <<
+      ") ... using lower number.\n";
+    n_bits_to_input = d_in_buf->n_items_left();
+  }
+
+  // check that there are enough output buffer items
+
+  size_t n_bits_to_output = compute_n_output_bits (n_bits_to_input);
+
+  if (d_out_buf->n_items_left() < n_bits_to_output) {
+    std::cerr << "encoder::encode: Warning: output buffer size (" <<
+      d_out_buf->n_items_left() << "is less than the computed number "
+      "of required output items (" << n_bits_to_output <<
+      ") ... using lower number.\n";
+    n_bits_to_output = d_out_buf->n_items_left();
+    n_bits_to_input = compute_n_input_bits (n_bits_to_output);
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "# output bits = " << n_bits_to_output << "\n"
+      "# input bits  = " << n_bits_to_input << "\n";
+  }
 
   // call the private encode function
 
-  encode_private (in_buf, out_buf);
+  encode_private ();
 
   if (DO_PRINT_DEBUG) {
-    std::cout << "n_input_bits_used = " <<
-      (n_bits_to_input - d_n_input_bits_left) << '\n';
-    std::cout << "n_output_bits_used = " <<
-      (saved_n_output_bits - d_n_output_bits_left) << '\n';
+    std::cout <<
+      "# input bits used  = " << d_in_buf->n_items_used() << "\n"
+      "# output bits used = " << d_out_buf->n_items_used() << "\n";
   }
 
+  size_t n_items_used = d_out_buf->n_items_used();
+
+  // clear these buffers, just in case
+
+  d_in_buf = 0;
+  d_out_buf = 0;
+
   // return the actual number of output bits written
 
-  return (saved_n_output_bits - d_n_output_bits_left);
+  return (n_items_used);
 }

Index: libecc/encoder.h
===================================================================
RCS file: /sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libecc/encoder.h    20 Jul 2006 17:42:54 -0000      1.6
+++ libecc/encoder.h    1 Aug 2006 19:02:35 -0000       1.7
@@ -23,50 +23,68 @@
 #ifndef INCLUDED_ENCODER_H
 #define INCLUDED_ENCODER_H
 
-#include "code_types.h"
-
-// the 'encoder' class is a virtual class upon which all encoder types
-// can be built.
+#include "code_io.h"
 
 class encoder
 {
+  /*
+   * class encoder
+   * A virtual class upon which all encoder types can be built.
+   * This class provides the basic methods and variables
+   * generic for all encoders.
+   */
 public:
   encoder () {};
   virtual ~encoder () {};
 
+  /*
+   * compute_n_...: to be defined by inheriting classes, in order to
+   * allow for user-functions to figure out how many inputs are
+   * required to generate a given number of outputs, and vice versa.
+   * Can't define them without knowing the encoder type.
+   *
+   * Compute the number of input bits needed to produce 'n_output' bits,
+   * and the number of output bits which will be produced by 'n_input'
+   * bits ... for a single stream only.
+   */
+
   virtual size_t compute_n_input_bits (size_t n_output_bits) = 0;
   virtual size_t compute_n_output_bits (size_t n_input_bits) = 0;
-  virtual size_t encode (const char** in_buf,
-                        char** out_buf,
+
+  /*
+   * encode: given the input and output buffers, either encode up to
+   * the number of output bits or encode the number of input bits
+   * ... if the buffers support either encoding amounts.
+   */
+
+  virtual size_t encode (const code_input_ptr in_buf,
+                        code_output_ptr out_buf,
                         size_t n_bits_to_output);
-  virtual size_t encode (const char** in_buf,
+  virtual size_t encode (const code_input_ptr in_buf,
                         size_t n_bits_to_input,
-                        char** out_buf);
+                        code_output_ptr out_buf);
 
 /* for remote access to internal info */
 
-  inline size_t block_size_bits () {return (d_block_size_bits);};
-  inline size_t n_code_inputs () {return (d_n_code_inputs);};
-  inline size_t n_code_outputs () {return (d_n_code_outputs);};
+  inline const size_t block_size_bits () {return (d_block_size_bits);};
+  inline const size_t n_code_inputs () {return (d_n_code_inputs);};
+  inline const size_t n_code_outputs () {return (d_n_code_outputs);};
+  inline const size_t total_n_enc_bits () {return (d_total_n_enc_bits);};
 
 protected:
-  /* encode_private: encode the given in_buf and write the output bits
+  /*
+   * 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;
-
-  /* inheriting methods need to figure out what makes the most sense
-   * for them in terms of getting new inputs and writing outputs.
-   */
+  virtual void encode_private () = 0;
 
   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;
-  size_t d_in_buf_ndx, d_out_buf_ndx;
-  size_t d_in_bit_shift, d_out_bit_shift;
-  size_t d_n_input_bits_left, d_n_output_bits_left;
+  size_t d_total_n_enc_bits;
+  code_input_ptr d_in_buf;
+  code_output_ptr d_out_buf;
 };
 
 #endif /* INCLUDED_ENCODER_H */

Index: libecc/encoder_convolutional.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.cc,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- libecc/encoder_convolutional.cc     20 Jul 2006 17:42:54 -0000      1.12
+++ libecc/encoder_convolutional.cc     1 Aug 2006 19:02:35 -0000       1.13
@@ -29,16 +29,12 @@
 #include <iostream>
 
 #define DO_TIME_THOUGHPUT 0
-#define DO_PRINT_DEBUG 1
 
 #include <mld/mld_timer.h>
-#include <mld/n2bs.h>
+//#include <mld/n2bs.h>
 
-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
+void
+encoder_convolutional::encoder_convolutional_init
 (int block_size_bits,
  int n_code_inputs,
  int n_code_outputs,
@@ -97,14 +93,16 @@
 
   d_init_state = start_memory_state;
 
+  // reset the inputs and outputs, both to get the correct size() and
+  // for the sake of zeroing them out.
+
   d_current_inputs.assign (d_n_code_inputs, 0);
   d_current_outputs.assign (d_n_code_outputs, 0);
 }
 
 void
 encoder_convolutional::encode_private
-(const char** in_buf,
- char** out_buf)
+()
 {
   struct timeval t_tp;
   if (DO_TIME_THOUGHPUT) {
@@ -113,18 +111,12 @@
 
   // reset buffer indices
 
-  d_total_n_enc_bits = d_in_buf_ndx = d_out_buf_ndx =
-    d_in_bit_shift = d_out_bit_shift = 0;
-
-  if (DO_PRINT_DEBUG) {
-    std::cout << "Beginning this encode() call; starting parameters.\n";
-    std::cout << "d_n_input_bits_left = " << d_n_input_bits_left << '\n';
-    std::cout << "d_n_output_bits_left = " << d_n_output_bits_left << '\n';
-  }
+  d_total_n_enc_bits = 0;
 
   // while there are inputs and outputs left to process ...
 
-  while ((d_n_input_bits_left != 0) & (d_n_output_bits_left != 0)) {
+  while ((d_in_buf->n_items_left() != 0) &
+        (d_out_buf->n_items_left() != 0)) {
 
     // jump to the correct state in the fsm
 
@@ -158,7 +150,7 @@
       // termination bits, if any), counting down the number of
       // available input bits.
 
-      encode_loop (in_buf, out_buf, &d_n_input_bits_left, d_block_size_bits);
+      encode_loop (d_in_buf->n_items_left(), d_block_size_bits);
 
       // finished this loop; check for jumping to the next state
 
@@ -183,7 +175,12 @@
       // number of output bits left
 
       if (d_do_termination == true) {
-       encode_loop (in_buf, out_buf, &d_n_output_bits_left, d_total_n_delays);
+       if (d_n_enc_bits == 0) {
+         // first time through this; save the starting termination state
+         d_term_state = d_memory;
+       }
+
+       encode_loop (d_out_buf->n_items_left(), d_total_n_delays);
 
        // finished this loop; check for jumping to the next state
 
@@ -207,17 +204,6 @@
     // done (while) there are inputs and outputs
   }
 
-  if (DO_PRINT_DEBUG) {
-    std::cout << "Done with this encode() call; ending parameters.\n"
-      "d_in_bit_shift = " << d_in_bit_shift << "\n"
-      "d_out_bit_shift = " << d_out_bit_shift << "\n"
-      "d_in_buf_ndx = " << d_in_buf_ndx << "\n"
-      "d_out_buf_ndx = " << d_out_buf_ndx << "\n"
-      "d_n_input_bits_left = " << d_n_input_bits_left << "\n"
-      "d_n_output_bits_left = " << d_n_output_bits_left << "\n"
-      "d_total_n_enc_bits = " << d_total_n_enc_bits << "\n";
-  }
-
   if (DO_TIME_THOUGHPUT) {
     // compute the throughput for this particular function call
     u_long d_t = end_timer (&t_tp);
@@ -230,28 +216,17 @@
 
 void
 encoder_convolutional::encode_loop
-(const char** in_buf,
- char** out_buf,
- size_t* which_counter,
+(const size_t& which_counter,
  size_t how_many)
 {
   // generic encode_loop
 
-  if (DO_PRINT_DEBUG) {
-    std::cout << "Starting encode_loop.\n";
-  }
-
-  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";
-    }
+  while ((which_counter > 0) & (d_n_enc_bits < how_many)) {
 
     // get the next set of input bits from all streams;
     // written into d_current_inputs
 
-    get_next_inputs (in_buf);
+    get_next_inputs ();
 
     // use the trellis to do the encoding;
     // updates the input memory to the new memory state for the given input
@@ -261,7 +236,7 @@
 
     // write the bits in d_current_outputs into the output buffer
 
-    write_output_bits (out_buf);
+    write_output_bits ();
 
     // increment the number of encoded bits for the current block, and
     // the total number of bits for this running of "encode()"
@@ -269,22 +244,88 @@
     d_n_enc_bits++;
     d_total_n_enc_bits++;
   }
+}
+
+size_t
+encoder_convolutional::compute_n_output_bits
+(size_t n_input_bits)
+{
+  size_t t_n_output_bits, t_n_input_bits;
+  t_n_output_bits = t_n_input_bits = n_input_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_total_n_delays - d_n_enc_bits;
+    }
+
+    t_n_output_bits += n_extra;
 
-  if (DO_PRINT_DEBUG) {
-    std::cout << "ending encode_loop.\n";
+    // find the number of blocks using just input bits,
+    // as well as the number of leftover bits
+
+    size_t t_n_blocks = t_n_input_bits / d_block_size_bits;
+    size_t t_leftover_bits = t_n_input_bits % d_block_size_bits;
+
+    // add the number of bits*blocks to the number of output bits, as
+    // well as the number of leftover bits which are not a whole block
+
+    t_n_output_bits += (t_n_blocks * (d_block_size_bits + d_total_n_delays));
+    t_n_output_bits += t_leftover_bits;
   }
+
+  return (t_n_output_bits);
 }
 
-void
-encoder_convolutional::get_next_inputs__term
-()
+size_t
+encoder_convolutional::compute_n_input_bits
+(size_t n_output_bits)
 {
-  // FIXME: how to figure out which term bit to get?
-  // loop to set each entry of "d_current_inputs"
+  size_t t_n_output_bits, t_n_input_bits;
+  t_n_output_bits = t_n_input_bits = n_output_bits;
 
-  // need to do feedback separately, since it involves determining the
-  // FB bit value & using that as the input value to cancel it out
+  if (d_do_termination == true) {
 
-  d_current_inputs.assign (d_n_code_inputs, 0);
-  //   return (d_term_states[code_input_n] & 1);
+    // 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_total_n_delays - 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 blocks of data which could be processed
+
+    size_t t_n_output_bits_per_block = d_block_size_bits + d_total_n_delays;
+
+    // get the base number of input items required for the given
+    // number of blocks to be generated
+
+    size_t t_n_blocks = t_n_output_bits / t_n_output_bits_per_block;
+    t_n_input_bits = t_n_blocks * d_block_size_bits;
+
+    // add to that the number of leftover inputs needed to generate
+    // the remainder of the outputs within the remaining block, up to
+    // the given block size (since anything beyond that within this
+    // block requires no inputs)
+
+    size_t t_leftover_bits = t_n_output_bits % t_n_output_bits_per_block;
+    t_n_input_bits += ((t_leftover_bits > d_block_size_bits) ?
+                      d_block_size_bits : t_leftover_bits);
+  }
+
+  return (t_n_input_bits);
 }

Index: libecc/encoder_convolutional.h
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- libecc/encoder_convolutional.h      20 Jul 2006 17:42:54 -0000      1.8
+++ libecc/encoder_convolutional.h      1 Aug 2006 19:02:35 -0000       1.9
@@ -126,12 +126,37 @@
 
   virtual ~encoder_convolutional () {delete d_trellis;};
 
+/*
+ * Compute the number of input bits needed to produce 'n_output' bits,
+ * and the number of output bits which will be produced by 'n_input'
+ * bits ... for a single stream only.
+ *
+ * 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 exactly;
+ *
+ * if (not streaming & termination), depends on the state of the FSM,
+ * and needs to include the number of termination bits (the total # of
+ * delays); ratio is roughly (1:(1+X)), where "X" is the number of
+ * termination bits divided by the (unterminated) block length in bits.
+ *
+ * It's up to the caller to change 'bits' to 'items' ... to know if
+ * bits are packed (see e.g. code_io "ic8l") or not ("ic1l"), or all
+ * streams are mux'ed together into one stream.
+*/
+
+  virtual size_t compute_n_input_bits (size_t n_output_bits);
+  virtual size_t compute_n_output_bits (size_t n_input_bits);
+
 /* for remote access to internal info */
 
   inline const bool do_termination () {return (d_do_termination);};
   inline const bool do_feedback () {return (d_trellis->do_feedback());};
   inline const bool do_streaming () {return (d_do_streaming);};
   inline const size_t total_n_delays () {return (d_total_n_delays);};
+  inline const code_convolutional_trellis* trellis() {return (d_trellis);};
 
 protected:
 /*
@@ -161,15 +186,13 @@
                                   int start_memory_state,
                                   int end_memory_state);
 
-  virtual void encode_private (const char** in_buf, char** out_buf);
+  virtual void encode_private ();
+  virtual void encode_loop (const size_t& which_counter, size_t how_many);
 
-  virtual void encode_loop (const char** in_buf, char** out_buf,
-                           size_t* which_counter, size_t how_many);
-
-  inline void get_next_inputs (const char** in_buf) {
+  inline void get_next_inputs () {
     switch (d_fsm_state) {
     case fsm_enc_conv_doing_input:
-      get_next_inputs__input (in_buf);
+      get_next_inputs__input ();
       break;
     case fsm_enc_conv_doing_term:
       get_next_inputs__term ();
@@ -180,7 +203,21 @@
     }
   };
 
-  virtual void get_next_inputs__term ();
+  inline virtual void get_next_inputs__input () {
+    d_in_buf->read_items ((void*)(&(d_current_inputs[0])));
+    d_in_buf->increment_indices ();
+  };
+
+  inline virtual void get_next_inputs__term () {
+    d_trellis->get_termination_inputs (d_term_state,
+                                      d_n_enc_bits,
+                                      d_current_inputs);
+  };
+
+  inline virtual void write_output_bits () {
+    d_out_buf->write_items ((const void*)(&(d_current_outputs[0])));
+    d_out_buf->increment_indices ();
+  };
 
   void get_memory_requirements (size_t m,
                                size_t n,
@@ -188,13 +225,6 @@
                                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 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;
@@ -203,7 +233,7 @@
   // "total_n_delays" is the total # of delays, needed to determine the
   // # of states in the decoder
 
-  size_t d_total_n_delays;
+  size_t d_total_n_delays, d_n_enc_bits;
 
   // the current state of the encoder (all delays / memories)
 
@@ -225,6 +255,13 @@
   // interpreted w/r.t. the actual trellis;
 
   memory_t d_init_state;
+
+  // "term_state" is the ending state before termination, used by the
+  // trellis to determine the correct input-bit sequences needed to
+  // properly terminate the trellis to the desired end-state;
+  // used only if doing termination.
+
+  memory_t d_term_state;
 };
 
 #endif /* INCLUDED_ENCODER_CONVOLUTIONAL_H */

Index: libecc/encoder_turbo.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libecc/encoder_turbo.cc     9 Jul 2006 16:15:17 -0000       1.1
+++ libecc/encoder_turbo.cc     1 Aug 2006 19:02:35 -0000       1.2
@@ -1,52 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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_turbo.h"
 
 encoder_turbo::encoder_turbo
 (int n_code_inputs,
  int n_code_outputs,
- const std::vector<encoder_convolutional*> &encoders,
- const std::vector<size_t> &interleavers)
+ const std::vector<encoder_convolutional*>& encoders,
+ const std::vector<interleaver_t>& interleavers)
 {
-  // need error checking on inputs
+  // need error checking on inputs, not yet.
 
+#if 0
   d_encoders = encoders;
   d_interleavers = interleavers;
-}
-
-// dummy stuff for now to test std::vector<gr_streams_convolutional...> stuff
-
-size_t
-encoder_turbo::compute_n_input_bits
-(size_t n_output_bits)
-{
-  return (0);
-}
-
-size_t
-encoder_turbo::compute_n_output_bits
-(size_t n_input_bits)
-{
-  return (0);
-}
-
-void
-encoder_turbo::encode_private
-(const char** in_buf,
- char** out_buf)
-{
-}
-
-char
-encoder_turbo::get_next_bit
-(const char** in_buf,
- size_t code_input_n)
-{
-  return (0);
-}
-
-void
-encoder_turbo::output_bit
-(char t_out_bit,
- char** out_buf,
- size_t t_output_stream)
-{
+#endif
 }

Index: libecc/encoder_turbo.h
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libecc/encoder_turbo.h      9 Jul 2006 16:15:17 -0000       1.1
+++ libecc/encoder_turbo.h      1 Aug 2006 19:02:35 -0000       1.2
@@ -24,7 +24,8 @@
 #define INCLUDED_ENCODER_TURBO_H
 
 #include "encoder_convolutional.h"
-#include <vector>
+
+typedef std::vector<size_t> interleaver_t;
 
 class encoder_turbo : public encoder
 {
@@ -53,18 +54,19 @@
   encoder_turbo
   (int n_code_inputs,
    int n_code_outputs,
-   const std::vector<encoder_convolutional*> &encoders,
-   const std::vector<size_t> &interleavers);
+   const std::vector<encoder_convolutional*>& encoders,
+   const std::vector<interleaver_t>& interleavers);
 
   virtual ~encoder_turbo () {};
 
 /* for remote access to internal info */
 
-  inline bool do_termination () {return (d_do_termination);};
+  inline const bool do_termination () {return (d_do_termination);};
 
 #if 1
-  virtual size_t compute_n_input_bits (size_t n_output_bits);
-  virtual size_t compute_n_output_bits (size_t n_input_bits);
+  // dummy functions for now
+  virtual size_t compute_n_input_bits (size_t n_output_bits){return(0);};
+  virtual size_t compute_n_output_bits (size_t n_input_bits){return(0);};
 #endif
 
 protected:
@@ -84,44 +86,15 @@
     fsm_enc_turbo_init, fsm_enc_turbo_doing_input, fsm_enc_turbo_doing_term
   };
 
-/*
- * maio(i,o): matrix access into a vector, knowing the # of code
- *     outputs (from inside the class). References into a vector with
- *     code inputs ordered by code output.
- *
- * 'i' is the first dimension - immediate memory order first - the code input
- * 'o' is the second dimension - slower memory order second - the code output
- *
- * returns ((o*n_code_outputs) + i)
- */
-
-  inline size_t maio(size_t i, size_t o) {return ((o*d_n_code_outputs) + i);};
-
-/*
- * maoi(i,o): matrix access into a vector, knowing the # of code
- *     inputs (from inside the class). References into a vector with
- *     code outputs ordered by code input.
- *
- * 'o' is the first dimension - immediate memory order first - the code output
- * 'i' is the second dimension - slower memory order second - the code input
- *
- * returns ((i*n_code_inputs) + o)
- */
-
-  inline size_t maoi(size_t i, size_t o) {return ((i*d_n_code_inputs) + o);};
-
   // methods defined in this class
 #if 1
   // temporary just to get full compilation
 
-  virtual void encode_private (const char** in_buf, char** out_buf);
-  virtual char get_next_bit (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 encode_private () {};
+
 #else
-  virtual void encode_private (const char** in_buf, char** out_buf) = 0;
-  virtual void encode_loop (const char** in_buf, char** out_buf,
-                           size_t* which_counter, size_t how_many) = 0;
+  virtual void encode_private () = 0;
+  virtual void encode_loop (size_t* which_counter, size_t how_many) = 0;
   virtual char get_next_bit (const char** in_buf, size_t code_input_n) = 0;
   virtual char get_next_bit__term (size_t code_input_n) = 0;
 
@@ -131,7 +104,6 @@
 
   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;
 #endif
 
   // variables

Index: libecc/tests/qa_encoder_convolutional_ic1_ic1.cc
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- libecc/tests/qa_encoder_convolutional_ic1_ic1.cc    18 Jul 2006 02:35:44 
-0000      1.4
+++ libecc/tests/qa_encoder_convolutional_ic1_ic1.cc    1 Aug 2006 19:02:35 
-0000       1.5
@@ -20,7 +20,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include "encoder_convolutional_ic1_ic1.h"
+#include "encoder_convolutional.h"
 #include <qa_encoder_convolutional_ic1_ic1.h>
 #include <cppunit/TestAssert.h>
 #include <string.h>
@@ -28,11 +28,12 @@
 #include <iomanip>
 #include <stdio.h>
 
-
 void
 qa_encoder_convolutional_ic1_ic1::do_encoder_check
-(const char** c_in,
+(int test_n,
+ const char** c_in,
  const char** c_res,
+ int n_input_items,
  int n_output_items,
  int block_size_bits,
  int n_code_inputs,
@@ -45,7 +46,7 @@
   for (int m = 0; m < n_code_inputs * n_code_outputs; m++)
     t_code_generators[m] = code_generators[m];
 
-  encoder_convolutional_ic1_ic1* t_encoder;
+  encoder_convolutional* t_encoder;
 
   if (code_feedback) {
     std::vector<int> t_code_feedback;
@@ -53,33 +54,48 @@
     for (int m = 0; m < n_code_inputs * n_code_outputs; m++)
       t_code_feedback[m] = code_feedback[m];
 
-    t_encoder = new encoder_convolutional_ic1_ic1
+    t_encoder = new encoder_convolutional
       (block_size_bits,
        n_code_inputs,
        n_code_outputs,
        t_code_generators,
        t_code_feedback);
   } else {
-    t_encoder = new encoder_convolutional_ic1_ic1
+    t_encoder = new encoder_convolutional
       (block_size_bits,
        n_code_inputs,
        n_code_outputs,
        t_code_generators);
   }
 
+  code_input_ic1l* t_c_in = new code_input_ic1l (n_code_inputs);
+  t_c_in->set_buffer ((void**) c_in, n_input_items);
+
   char** t_out = new char*[n_code_outputs];
   for (int m = 0; m < n_code_outputs; m++) {
     t_out[m] = new char[n_output_items];
   }
 
-  t_encoder->encode (c_in, (char**) t_out, n_output_items);
+  code_output_ic1l* t_c_out = new code_output_ic1l (n_code_outputs);
+  t_c_out->set_buffer ((void**) t_out, n_output_items);
+
+  t_encoder->encode (t_c_in, t_c_out, n_output_items);
 
   for (int m = 0; m < n_code_outputs; m++) {
     for (int n = 0; n < n_output_items; n++) {
+      if (c_res[m][n] != t_out[m][n]) {
+       std::cout << "Test " << test_n << ": Item [" << m <<
+         "][" << n << "] not equal: des = " << (int)(c_res[m][n]) <<
+         ", act = " << (int)(t_out[m][n]) << "\n";
+      }
       CPPUNIT_ASSERT_EQUAL (c_res[m][n], t_out[m][n]);
     }
   }
 
+  delete t_c_out;
+  t_c_out = 0;
+  delete t_c_in;
+  t_c_in = 0;
   delete t_encoder;
   t_encoder = 0;
 
@@ -122,9 +138,10 @@
 qa_encoder_convolutional_ic1_ic1::t0
 ()
 {
-  do_encoder_check ((const char**) t0_in, (const char**) t0_res,
-                   t0_n_output_items, 100, t0_n_code_inputs,
-                   t0_n_code_outputs, (const int*) t0_code_generator);
+  do_encoder_check (0, (const char**) t0_in, (const char**) t0_res,
+                   t0_n_input_items, t0_n_output_items, 100,
+                   t0_n_code_inputs, t0_n_code_outputs,
+                   (const int*) t0_code_generator);
 }
 
 // TEST 1
@@ -158,9 +175,10 @@
 qa_encoder_convolutional_ic1_ic1::t1
 ()
 {
-  do_encoder_check ((const char**) t1_in, (const char**) t1_res,
-                   t1_n_output_items, 100, t1_n_code_inputs,
-                   t1_n_code_outputs, (const int*) t1_code_generator);
+  do_encoder_check (1, (const char**) t1_in, (const char**) t1_res,
+                   t1_n_input_items, t1_n_output_items, 100,
+                   t1_n_code_inputs, t1_n_code_outputs,
+                   (const int*) t1_code_generator);
 }
 
 // TEST 2
@@ -195,9 +213,10 @@
 qa_encoder_convolutional_ic1_ic1::t2
 ()
 {
-  do_encoder_check ((const char**) t2_in, (const char**) t2_res,
-                   t2_n_output_items, 100, t2_n_code_inputs,
-                   t2_n_code_outputs, (const int*) t2_code_generator,
+  do_encoder_check (2, (const char**) t2_in, (const char**) t2_res,
+                   t2_n_input_items, t2_n_output_items, 100,
+                   t2_n_code_inputs, t2_n_code_outputs,
+                   (const int*) t2_code_generator,
                    (const int*) t2_code_feedback);
 }
 
@@ -233,9 +252,10 @@
 qa_encoder_convolutional_ic1_ic1::t3
 ()
 {
-  do_encoder_check ((const char**) t3_in, (const char**) t3_res,
-                   t3_n_output_items, 100, t3_n_code_inputs,
-                   t3_n_code_outputs, (const int*) t3_code_generator,
+  do_encoder_check (3, (const char**) t3_in, (const char**) t3_res,
+                   t3_n_input_items, t3_n_output_items, 100,
+                   t3_n_code_inputs, t3_n_code_outputs,
+                   (const int*) t3_code_generator,
                    (const int*) t3_code_feedback);
 }
 
@@ -271,9 +291,10 @@
 qa_encoder_convolutional_ic1_ic1::t4
 ()
 {
-  do_encoder_check ((const char**) t4_in, (const char**) t4_res,
-                   t4_n_output_items, 100, t4_n_code_inputs,
-                   t4_n_code_outputs, (const int*) t4_code_generator,
+  do_encoder_check (4, (const char**) t4_in, (const char**) t4_res,
+                   t4_n_input_items, t4_n_output_items, 100,
+                   t4_n_code_inputs, t4_n_code_outputs,
+                   (const int*) t4_code_generator,
                    (const int*) t4_code_feedback);
 }
 
@@ -310,9 +331,10 @@
 ()
 {
 #if 0
-  do_encoder_check ((const char**) t5_in, (const char**) t5_res,
-                   t5_n_output_items, 100, t5_n_code_inputs,
-                   t5_n_code_outputs, (const int*) t5_code_generator);
+  do_encoder_check (5, (const char**) t5_in, (const char**) t5_res,
+                   t5_n_input_items, t5_n_output_items, 100,
+                   t5_n_code_inputs, t5_n_code_outputs,
+                   (const int*) t5_code_generator);
 #endif
 }
 
@@ -346,8 +368,8 @@
 qa_encoder_convolutional_ic1_ic1::t6
 ()
 {
-  do_encoder_check ((const char**) t6_in, (const char**) t6_res,
-                   t6_n_output_items, 5, t6_n_code_inputs,
+  do_encoder_check (6, (const char**) t6_in, (const char**) t6_res,
+                   t6_n_input_items, t6_n_output_items, 5, t6_n_code_inputs,
                    t6_n_code_outputs, (const int*) t6_code_generator);
 }
 
@@ -383,8 +405,8 @@
 ()
 {
 #if 0
-  do_encoder_check ((const char**) t7_in, (const char**) t7_res,
-                   t7_n_output_items, 5, t7_n_code_inputs,
+  do_encoder_check (7, (const char**) t7_in, (const char**) t7_res,
+                   t7_n_input_items, t7_n_output_items, 5, t7_n_code_inputs,
                    t7_n_code_outputs, (const int*) t7_code_generator,
                    (const int*) t7_code_feedback);
 #endif
@@ -422,8 +444,8 @@
 ()
 {
 #if 0
-  do_encoder_check ((const char**) t8_in, (const char**) t8_res,
-                   t8_n_output_items, 5, t8_n_code_inputs,
+  do_encoder_check (8, (const char**) t8_in, (const char**) t8_res,
+                   t8_n_input_items, t8_n_output_items, 5, t8_n_code_inputs,
                    t8_n_code_outputs, (const int*) t8_code_generator,
                    (const int*) t8_code_feedback);
 #endif

Index: libecc/tests/qa_encoder_convolutional_ic1_ic1.h
===================================================================
RCS file: 
/sources/gnuradio/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- libecc/tests/qa_encoder_convolutional_ic1_ic1.h     18 Jul 2006 02:35:44 
-0000      1.3
+++ libecc/tests/qa_encoder_convolutional_ic1_ic1.h     1 Aug 2006 19:02:35 
-0000       1.4
@@ -42,8 +42,10 @@
   CPPUNIT_TEST_SUITE_END ();
 
  private:
-  void do_encoder_check (const char** c_t1_in,
+  void do_encoder_check (int test_n,
+                        const char** c_t1_in,
                         const char** c_t1_res,
+                        int n_input_items,
                         int n_output_items,
                         int block_size_bits,
                         int n_code_inputs,

Index: ecc_metrics_decode_viterbi_full_block.cc
===================================================================
RCS file: ecc_metrics_decode_viterbi_full_block.cc
diff -N ecc_metrics_decode_viterbi_full_block.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_metrics_decode_viterbi_full_block.cc    1 Aug 2006 19:02:35 -0000       
1.1
@@ -0,0 +1,245 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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 <ecc_metrics_decode_viterbi_full_block.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+ecc_metrics_decode_viterbi_full_block_sptr
+ecc_make_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return ecc_metrics_decode_viterbi_full_block_sptr
+    (new ecc_metrics_decode_viterbi_full_block
+     (sample_precision,
+      frame_size_bits,
+      n_code_inputs,
+      n_code_outputs,
+      code_generator,
+      do_termination,
+      start_memory_state,
+      end_memory_state));
+}
+
+ecc_metrics_decode_viterbi_full_block_feedback_sptr
+ecc_make_metrics_decode_viterbi_full_block_feedback
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return ecc_metrics_decode_viterbi_full_block_feedback_sptr
+    (new ecc_metrics_decode_viterbi_full_block
+     (sample_precision,
+      frame_size_bits,
+      n_code_inputs,
+      n_code_outputs,
+      code_generator,
+      code_feedback,
+      do_termination,
+      start_memory_state,
+      end_memory_state));
+}
+
+ecc_metrics_decode_viterbi_full_block::ecc_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("metrics_decode_viterbi_full_block",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  d_encoder = new encoder_convolutional (frame_size_bits,
+                                        n_code_inputs,
+                                        n_code_outputs,
+                                        code_generator,
+                                        do_termination,
+                                        start_memory_state,
+                                        end_memory_state);
+
+  setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
+}
+
+ecc_metrics_decode_viterbi_full_block::ecc_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("metrics_decode_viterbi_full_block_feedback",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  d_encoder = new encoder_convolutional (frame_size_bits,
+                                        n_code_inputs,
+                                        n_code_outputs,
+                                        code_generator,
+                                        code_feedback,
+                                        do_termination,
+                                        start_memory_state,
+                                        end_memory_state);
+
+  setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
+}
+
+ecc_metrics_decode_viterbi_full_block::~ecc_metrics_decode_viterbi_full_block
+()
+{
+  delete d_decoder;
+  d_decoder = 0;
+  delete d_encoder;
+  d_encoder = 0;
+  delete d_in_buf;
+  d_in_buf = 0;
+  delete d_out_buf;
+  d_out_buf = 0;
+}
+
+void
+ecc_metrics_decode_viterbi_full_block::setup_io_signatures
+(int sample_precision,
+ int n_code_inputs,
+ int n_code_outputs)
+{
+  // create the decoder
+  //
+  // the input model: individual input streams; two per metric type
+  // (0-bit, 1-bit), single metric per input item (float, char, short,
+  // long)
+  //
+  // the "ic1l" output model:
+  // individual output streams per decoded code input stream;
+  // each item is a 'char' type with 1 bit aligned on the LSB.
+
+  d_decoder = new decoder_viterbi_full_block (sample_precision,
+                                             d_encoder);
+  d_out_buf = new code_output_ic1l (n_code_inputs);
+
+  // error checking is done in the encoder and decoder classes
+  // so just use the parameters as given; will be correct!
+
+  d_n_code_inputs = n_code_inputs;
+  d_n_code_outputs = n_code_outputs;
+
+  // output signature is always the same:
+  // sizeof (char) with 1 bit per char as the LSB
+
+  set_output_signature (gr_make_io_signature (d_n_code_inputs,
+                                             d_n_code_inputs,
+                                             sizeof (char)));
+
+  // determine the input signature element size
+  size_t l_input_item_size_bytes;
+
+  if (sample_precision == 0) {
+    // float
+    l_input_item_size_bytes = sizeof (float);
+    d_in_buf = new code_input_if (n_code_outputs);
+  } else if (sample_precision <= 8) {
+    // use char
+    l_input_item_size_bytes = sizeof (char);
+    d_in_buf = new code_input_ic (n_code_outputs);
+  } else if (sample_precision <= 16) {
+    // use short
+    l_input_item_size_bytes = sizeof (short);
+    d_in_buf = new code_input_is (n_code_outputs);
+  } else {
+    // use long
+    l_input_item_size_bytes = sizeof (long);
+    d_in_buf = new code_input_il (n_code_outputs);
+  }
+
+  set_input_signature (gr_make_io_signature (2*d_n_code_outputs,
+                                            2*d_n_code_outputs,
+                                            l_input_item_size_bytes));
+}
+
+void ecc_metrics_decode_viterbi_full_block::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  int ninput_items = d_decoder->compute_n_input_items (noutput_items);
+  size_t ninputs = ninput_items_required.size();
+  for (size_t n = 0; n < ninputs; n++)
+    ninput_items_required[n] = ninput_items;
+}
+
+int
+ecc_metrics_decode_viterbi_full_block::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  // compute the actual number of output items (1 bit char's) created.
+
+  size_t t_n_input_items = d_decoder->compute_n_input_items (noutput_items);
+#if 1
+  size_t t_n_output_items = d_decoder->compute_n_output_bits (t_n_input_items);
+  assert (t_n_output_items == ((size_t)noutput_items));
+#endif
+
+  // setup the i/o buffers
+
+  d_in_buf->set_buffer ((void**)(&input_items[0]), t_n_input_items);
+  d_out_buf->set_buffer ((void**)(&output_items[0]), noutput_items);
+
+  // "work" is handled by the decoder; which returns the actual number
+  // of input items (metrics) used.
+
+  t_n_input_items = d_decoder->decode (d_in_buf, d_out_buf,
+                                      (size_t) noutput_items);
+
+  // consume the number of used input items on all input streams
+
+  consume_each (t_n_input_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}

Index: ecc_metrics_decode_viterbi_full_block.h
===================================================================
RCS file: ecc_metrics_decode_viterbi_full_block.h
diff -N ecc_metrics_decode_viterbi_full_block.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_metrics_decode_viterbi_full_block.h     1 Aug 2006 19:02:35 -0000       
1.1
@@ -0,0 +1,165 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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_ECC_METRICS_DECODE_VITERBI_FULL_BLOCK_H
+#define INCLUDED_ECC_METRICS_DECODE_VITERBI_FULL_BLOCK_H
+
+#include <gr_block.h>
+#include <libecc/decoder_viterbi_full_block.h>
+#include <libecc/encoder_convolutional.h>
+
+class ecc_metrics_decode_viterbi_full_block;
+
+typedef boost::shared_ptr<ecc_metrics_decode_viterbi_full_block>
+ecc_metrics_decode_viterbi_full_block_sptr,
+ecc_metrics_decode_viterbi_full_block_feedback_sptr;
+
+ecc_metrics_decode_viterbi_full_block_sptr
+ecc_make_metrics_decode_viterbi_full_block
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ std::vector<int> code_generator,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+ecc_metrics_decode_viterbi_full_block_feedback_sptr
+ecc_make_metrics_decode_viterbi_full_block_feedback
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ std::vector<int> code_generator,
+ std::vector<int> code_feedback,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+/*!
+ * \brief Decode the incoming streams using a Viterbi-style decoder,
+ *     full trellis block decoding.
+ *
+ * input: symbol metrics data.
+ *
+ * output: stream(s) of char, single bit stored in the LSB.
+ */
+
+class ecc_metrics_decode_viterbi_full_block : public gr_block
+{
+protected:
+  friend ecc_metrics_decode_viterbi_full_block_sptr
+  ecc_make_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  friend ecc_metrics_decode_viterbi_full_block_feedback_sptr
+  ecc_make_metrics_decode_viterbi_full_block_feedback
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+/*
+ * frame_size_bits: if == 0, then do streaming decoding (infinite
+ *     trellis); otherwise this is the block size to decode before
+ *     terminating the trellis.
+ *
+ * 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 is valid only if frame_size_bits != 0, and defines
+ *     whether or not to to trellis termination.
+ *
+ * do_mux_input: is true, then the one input stream will be
+ *     interpreted as the multiplexing all of the input bits.  For
+ *     example for a 3 input decoder, the input stream would be
+ *     [I1[k], I2[k], I3[k], I1[k+1], I2[k+1], ...], where "k" is the
+ *     input sample time, and "I1" through "I3" are the 3 input
+ *     streams.
+ *
+ * n_code_inputs: the number of decoder-input (encoder-output)
+ *     streams, no matter if separate or mux'ed
+ *
+ * n_code_outputs: the number of decoder-output (encoder-input) streams
+ */
+
+  ecc_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  ecc_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  void setup_io_signatures (int sample_precision,
+                           int n_code_inputs,
+                           int n_code_outputs);
+
+  int d_n_code_inputs, d_n_code_outputs;
+  decoder_viterbi_full_block* d_decoder;
+  encoder_convolutional* d_encoder;
+  code_input_ptr d_in_buf;
+  code_output_ptr d_out_buf;
+
+public:
+  ~ecc_metrics_decode_viterbi_full_block ();
+
+  virtual void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+
+  virtual int general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_ECC_METRICS_DECODE_VITERBI_FULL_BLOCK_H */

Index: ecc_metrics_decode_viterbi_full_block.i
===================================================================
RCS file: ecc_metrics_decode_viterbi_full_block.i
diff -N ecc_metrics_decode_viterbi_full_block.i
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_metrics_decode_viterbi_full_block.i     1 Aug 2006 19:02:35 -0000       
1.1
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(ecc,metrics_decode_viterbi_full_block);
+
+// corrected "class NAME" statement, which uses slightly different NAMEs
+
+typedef boost::shared_ptr<ecc_metrics_decode_viterbi_full_block>
+ecc_metrics_decode_viterbi_full_block_feedback_sptr;
+
+LOCAL_GR_SWIG_BLOCK_MAGIC(ecc,metrics_decode_viterbi_full_block_feedback);
+
+ecc_metrics_decode_viterbi_full_block_sptr
+ecc_make_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state);
+
+ecc_metrics_decode_viterbi_full_block_feedback_sptr
+ecc_make_metrics_decode_viterbi_full_block_feedback
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state);
+
+class ecc_metrics_decode_viterbi_full_block : public gr_block
+{
+  ecc_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  ecc_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+};

Index: ecc_streams_encode_convolutional.cc
===================================================================
RCS file: ecc_streams_encode_convolutional.cc
diff -N ecc_streams_encode_convolutional.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_streams_encode_convolutional.cc 1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,208 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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 <ecc_streams_encode_convolutional.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+ecc_streams_encode_convolutional_sptr 
+ecc_make_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return ecc_streams_encode_convolutional_sptr
+    (new ecc_streams_encode_convolutional (frame_size_bits,
+                                         n_code_inputs,
+                                         n_code_outputs,
+                                         code_generator,
+                                         do_termination,
+                                         start_memory_state,
+                                         end_memory_state));
+}
+
+ecc_streams_encode_convolutional_sptr 
+ecc_make_streams_encode_convolutional_feedback
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return ecc_streams_encode_convolutional_sptr
+    (new ecc_streams_encode_convolutional (frame_size_bits,
+                                         n_code_inputs,
+                                         n_code_outputs,
+                                         code_generator,
+                                         code_feedback,
+                                         do_termination,
+                                         start_memory_state,
+                                         end_memory_state));
+}
+
+ecc_streams_encode_convolutional::ecc_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generators,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("streams_encode_convolutional",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  // error checking is done by the encoder class itself;
+  // just pass items on here.
+
+  d_encoder = new encoder_convolutional (frame_size_bits,
+                                        n_code_inputs,
+                                        n_code_outputs,
+                                        code_generators,
+                                        do_termination,
+                                        start_memory_state,
+                                        end_memory_state);
+
+  setup_io_signatures (n_code_inputs, n_code_outputs);
+}
+
+ecc_streams_encode_convolutional::ecc_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generators,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("streams_encode_convolutional_feedback",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  // error checking is done by the encoder class itself;
+  // just pass items on here.
+
+  d_encoder = new encoder_convolutional (frame_size_bits,
+                                        n_code_inputs,
+                                        n_code_outputs,
+                                        code_generators,
+                                        code_feedback,
+                                        do_termination,
+                                        start_memory_state,
+                                        end_memory_state);
+
+  setup_io_signatures (n_code_inputs, n_code_outputs);
+}
+
+void
+ecc_streams_encode_convolutional::setup_io_signatures
+(int n_code_inputs,
+ int n_code_outputs)
+{
+  // create the correct input signature; 1 bit per input char
+
+  d_in_buf = new code_input_ic1l (n_code_inputs);
+  set_input_signature (gr_make_io_signature (n_code_inputs,
+                                            n_code_inputs,
+                                            sizeof (char)));
+
+  // create the correct output signature; 1 bit per output char
+
+  d_out_buf = new code_output_ic1l (n_code_outputs);
+  set_output_signature (gr_make_io_signature (n_code_outputs,
+                                             n_code_outputs,
+                                             sizeof (char)));
+}
+
+ecc_streams_encode_convolutional::~ecc_streams_encode_convolutional
+()
+{
+  delete d_encoder;
+  d_encoder = 0;
+  delete d_in_buf;
+  d_in_buf = 0;
+  delete d_out_buf;
+  d_out_buf = 0;
+}
+
+/*
+ * Compute the number of input items needed to produce 'n_output'
+ * bits.  Handled internally by the encoder.
+ */
+
+void ecc_streams_encode_convolutional::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  int ninput_items = d_encoder->compute_n_input_bits (noutput_items);
+  size_t ninputs = ninput_items_required.size();
+  for (size_t n = 0; n < ninputs; n++)
+    ninput_items_required[n] = ninput_items;
+}
+
+int
+ecc_streams_encode_convolutional::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  // compute the actual number of output items (1 bit char's) created.
+
+  size_t t_n_input_items = d_encoder->compute_n_input_bits (noutput_items);
+#if 1
+  size_t t_n_output_items = d_encoder->compute_n_output_bits (t_n_input_items);
+  assert (t_n_output_items == ((size_t)noutput_items));
+#endif
+  // setup the i/o buffers
+
+  d_in_buf->set_buffer ((void**)(&input_items[0]), t_n_input_items);
+  d_out_buf->set_buffer ((void**)(&output_items[0]), noutput_items);
+
+  // "work" is handled by the encoder; which returns the actual number
+  // of input items (1-bit char's) used.
+
+  t_n_input_items = d_encoder->encode (d_in_buf, d_out_buf,
+                                      (size_t) noutput_items);
+
+  assert (0);
+
+  // consume the number of used input items on all input streams
+
+  consume_each (t_n_input_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}

Index: ecc_streams_encode_convolutional.h
===================================================================
RCS file: ecc_streams_encode_convolutional.h
diff -N ecc_streams_encode_convolutional.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_streams_encode_convolutional.h  1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,158 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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_ECC_STREAMS_ENCODE_CONVOLUTIONAL_H
+#define INCLUDED_ECC_STREAMS_ENCODE_CONVOLUTIONAL_H
+
+#include <gr_block.h>
+#include <libecc/encoder_convolutional.h>
+
+/*!
+ * \brief Encode the incoming streams using a convolutional encoder
+ *
+ * input: 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: 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.
+ *
+ * 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.  E.g. "4" in binary is "100", which would be
+ *     "D^2" for code generation.  "6" == 110b == "D^2 + D"
+ *  ==> The vector is listed in order for each output 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, I2->O1, I1->O2, I2->O2]
+ *     with each element being an integer 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.
+ */
+
+class ecc_streams_encode_convolutional;
+typedef boost::shared_ptr<ecc_streams_encode_convolutional>
+  ecc_streams_encode_convolutional_sptr;
+
+ecc_streams_encode_convolutional_sptr
+ecc_make_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+ecc_streams_encode_convolutional_sptr
+ecc_make_streams_encode_convolutional_feedback
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+class ecc_streams_encode_convolutional : public gr_block
+{
+protected:
+  friend ecc_streams_encode_convolutional_sptr
+  ecc_make_streams_encode_convolutional
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  friend ecc_streams_encode_convolutional_sptr
+  ecc_make_streams_encode_convolutional_feedback
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  ecc_streams_encode_convolutional (int frame_size_bits,
+                                  int n_code_inputs,
+                                  int n_code_outputs,
+                                  const std::vector<int> &code_generator,
+                                  bool do_termination,
+                                  int start_memory_state,
+                                  int end_memory_state);
+
+  ecc_streams_encode_convolutional (int frame_size_bits,
+                                  int n_code_inputs,
+                                  int n_code_outputs,
+                                  const std::vector<int> &code_generator,
+                                  const std::vector<int> &code_feedback,
+                                  bool do_termination,
+                                  int start_memory_state,
+                                  int end_memory_state);
+
+  void setup_io_signatures (int n_code_inputs, int n_code_outputs);
+
+  encoder_convolutional* d_encoder;
+  code_input_ptr d_in_buf;
+  code_output_ptr d_out_buf;
+
+public:
+  ~ecc_streams_encode_convolutional ();
+
+  inline encoder_convolutional* encoder () {return (d_encoder);};
+
+  virtual void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+
+  virtual int general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_ECC_STREAMS_ENCODE_CONVOLUTIONAL_H */

Index: ecc_streams_encode_convolutional.i
===================================================================
RCS file: ecc_streams_encode_convolutional.i
diff -N ecc_streams_encode_convolutional.i
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_streams_encode_convolutional.i  1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(ecc,streams_encode_convolutional);
+
+// Rename second constructor
+%rename(streams_encode_convolutional_feedback) 
ecc_make_streams_encode_convolutional_feedback;
+
+// support vectors of these ... for use in the convolutional decoder
+// as well as Turbo Codes (both encoder and decoder).
+
+namespace std {
+  %template(x_vector_ecc_streams_encode_convolutional_sptr) 
vector<ecc_streams_encode_convolutional_sptr>;
+};
+
+ecc_streams_encode_convolutional_sptr
+ecc_make_streams_encode_convolutional
+(int block_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+ecc_streams_encode_convolutional_sptr
+ecc_make_streams_encode_convolutional_feedback
+(int block_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+class ecc_streams_encode_convolutional : public gr_block
+{
+private:
+  ecc_streams_encode_convolutional
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  ecc_streams_encode_convolutional
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+};

Index: ecc_streams_encode_turbo.cc
===================================================================
RCS file: ecc_streams_encode_turbo.cc
diff -N ecc_streams_encode_turbo.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_streams_encode_turbo.cc 1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,197 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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 <ecc_streams_encode_turbo.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+ecc_streams_encode_turbo_sptr 
+ecc_make_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<ecc_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers)
+{
+  return ecc_streams_encode_turbo_sptr
+    (new ecc_streams_encode_turbo (n_code_inputs,
+                                  n_code_outputs,
+                                  encoders,
+                                  interleavers));
+}
+
+ecc_streams_encode_turbo::ecc_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<ecc_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers)
+  : gr_block ("streams_encode_turbo",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  // error checking is done by the encoder class itself; just pass
+  // items on here.  But ... check out individual encoders, to make
+  // sure the total I/O matches those specified by the user.
+
+  d_n_encoders = encoders.size ();
+
+  if (d_n_encoders < 2) {
+    std::cerr << "ecc_streams_encode_turbo: Error: "
+      "too few (" << d_n_encoders << ") encoders specified; a Turbo "
+      "code requires at least 2 constituent encoders.\n";
+    assert (0);
+  }
+
+  // make sure that the block size and termination are consistent for
+  // all encoders; warn the user if not, since it doesn't really
+  // matter to the encoder (but it might to the decoder; remains to be
+  // seen).
+
+  encoder_convolutional* t_ec = encoders[0]->encoder ();
+  d_block_size_bits = t_ec->block_size_bits ();
+  d_do_termination = t_ec->do_termination ();
+  bool t_diff_block_size, t_diff_termination;
+  t_diff_block_size = t_diff_termination = false;
+
+  for (size_t m = 1; m < d_n_encoders; m++) {
+    t_ec = encoders[0]->encoder ();
+    size_t t_block_size_bits = t_ec->block_size_bits ();
+    if (t_block_size_bits != d_block_size_bits)
+      t_diff_block_size = true;
+    bool t_do_termination = t_ec->do_termination ();
+    if (t_do_termination != d_do_termination)
+      t_do_termination = true;
+  }
+
+  if (t_diff_block_size == true) {
+    std::cout << "ecc_streams_encode_turbo: Warning: "
+      "Some constituent encoders have different block size (bits).\n";
+  }
+  if (t_diff_termination == true) {
+    std::cout << "ecc_streams_encode_turbo: Warning: "
+      "Some constituent encoders are differently terminationed.\n";
+  }
+
+  std::cout << "ecc_streams_encode_turbo: setup:\n"
+    "d_n_encoders = " << d_n_encoders << "\n"
+    "n_code_inputs = " << n_code_inputs << "\n"
+    "n_code_outputs = " << n_code_outputs << "\n\n"
+    "Individual Encoders:\n";
+
+  for (size_t m = 0; m < d_n_encoders; m++) {
+    t_ec = encoders[m]->encoder ();
+    std::cout << "  [" << (m+1) << "]:\n"
+      "n_code_inputs = " << (t_ec->n_code_inputs()) << "\n"
+      "n_code_outputs = " << (t_ec->n_code_outputs()) << "\n"
+      "block_size_bits = " << (t_ec->block_size_bits()) << "\n"
+      "do_termination = " <<
+      ((t_ec->do_termination()==true)?"true":"false") << "\n";
+  }
+
+#if 1
+  assert (0);
+#else
+  if (d_n_encoders != (interleavers.size())) {}
+
+  d_encoder = new encoder_turbo (n_code_inputs,
+                                n_code_outputs,
+                                code_generators,
+                                do_termination,
+                                start_memory_state,
+                                end_memory_state);
+#endif
+
+  // create the correct input signature; 1 bit per input char
+
+  d_in_buf = new code_input_ic1l (n_code_inputs);
+  set_input_signature (gr_make_io_signature (n_code_inputs,
+                                            n_code_inputs,
+                                            sizeof (char)));
+
+  // create the correct output signature; 1 bit per output char
+
+  d_out_buf = new code_output_ic1l (n_code_outputs);
+  set_output_signature (gr_make_io_signature (n_code_outputs,
+                                             n_code_outputs,
+                                             sizeof (char)));
+}
+
+ecc_streams_encode_turbo::~ecc_streams_encode_turbo
+()
+{
+  delete d_encoder;
+  d_encoder = 0;
+  delete d_in_buf;
+  d_in_buf = 0;
+  delete d_out_buf;
+  d_out_buf = 0;
+}
+
+void ecc_streams_encode_turbo::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  int ninput_items = d_encoder->compute_n_input_bits (noutput_items);
+  size_t ninputs = ninput_items_required.size();
+  for (size_t n = 0; n < ninputs; n++)
+    ninput_items_required[n] = ninput_items;
+}
+
+int
+ecc_streams_encode_turbo::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  // compute the actual number of output items (1 bit char's) created.
+
+  size_t t_n_input_items = d_encoder->compute_n_input_bits (noutput_items);
+#if 1
+  size_t t_n_output_items = d_encoder->compute_n_output_bits (t_n_input_items);
+  assert (t_n_output_items == ((size_t)noutput_items));
+#endif
+  // setup the i/o buffers
+
+  d_in_buf->set_buffer ((void**)(&input_items[0]), t_n_input_items);
+  d_out_buf->set_buffer ((void**)(&output_items[0]), noutput_items);
+
+  // "work" is handled by the encoder; which returns the actual number
+  // of input items (1-bit char's) used.
+
+  t_n_input_items = d_encoder->encode (d_in_buf, d_out_buf,
+                                      (size_t) noutput_items);
+
+  assert (0);
+
+  // consume the number of used input items on all input streams
+
+  consume_each (t_n_input_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}

Index: ecc_streams_encode_turbo.h
===================================================================
RCS file: ecc_streams_encode_turbo.h
diff -N ecc_streams_encode_turbo.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_streams_encode_turbo.h  1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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_ECC_STREAMS_ENCODE_TURBO_H
+#define INCLUDED_ECC_STREAMS_ENCODE_TURBO_H
+
+#include <gr_block.h>
+#include <ecc_streams_encode_convolutional.h>
+
+#if 0
+#include <libecc/encoder_turbo_ic1_ic1.h>
+#else
+#include <libecc/encoder_turbo.h>
+#endif
+
+/*!
+ * \brief Encode the incoming stream(s) using a turbo encoder
+ *
+ * input: 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: 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.
+ *
+ * n_code_inputs:
+ * n_code_outputs: the total number of code inputs and outputs for the
+ *     overall turbo encoder (not just the constituent codes).
+ *
+ * encoders: the constituent encoders to be used; all -should- be
+ *     configured with the same "block_size" and "termination", though
+ *     from this encoder's perspective it doesn't really matter.
+ *
+ * interleavers: the interleavers to use before each encoder,
+ *     respectively, except the first encoder which will not use an
+ *     interleaver.
+ */
+
+class ecc_streams_encode_turbo;
+
+typedef boost::shared_ptr<ecc_streams_encode_turbo>
+ecc_streams_encode_turbo_sptr;
+
+ecc_streams_encode_turbo_sptr
+ecc_make_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<ecc_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers);
+
+class ecc_streams_encode_turbo : public gr_block
+{
+protected:
+  friend ecc_streams_encode_turbo_sptr
+  ecc_make_streams_encode_turbo
+    (int n_code_inputs,
+     int n_code_outputs,
+     const std::vector<ecc_streams_encode_convolutional_sptr> &d_encoders,
+     const std::vector<size_t> &d_interleavers);
+
+  ecc_streams_encode_turbo
+    (int n_code_inputs,
+     int n_code_outputs,
+     const std::vector<ecc_streams_encode_convolutional_sptr> &d_encoders,
+     const std::vector<size_t> &d_interleavers);
+
+  std::vector<ecc_streams_encode_turbo_sptr> d_encoders;
+  std::vector<size_t> d_interleavers;
+  size_t d_n_encoders, d_block_size_bits;
+  bool d_do_termination;
+  encoder_turbo* d_encoder;
+  code_input_ptr d_in_buf;
+  code_output_ptr d_out_buf;
+
+public:
+  ~ecc_streams_encode_turbo ();
+
+  virtual void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+
+  virtual int general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_ECC_STREAMS_ENCODE_TURBO_H */

Index: ecc_streams_encode_turbo.i
===================================================================
RCS file: ecc_streams_encode_turbo.i
diff -N ecc_streams_encode_turbo.i
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_streams_encode_turbo.i  1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(ecc,streams_encode_turbo);
+
+#include <ecc_streams_encode_convolutional.h>
+
+ecc_streams_encode_turbo_sptr
+ecc_make_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<ecc_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers);
+
+class ecc_streams_encode_turbo : public gr_block
+{
+  ecc_streams_encode_turbo
+  (int frame_size_bits,
+   int n_code_inputs,
+   const std::vector<ecc_streams_encode_convolutional_sptr> &encoders,
+   const std::vector<size_t> &interleavers);
+};

Index: ecc_syms_to_metrics.cc
===================================================================
RCS file: ecc_syms_to_metrics.cc
diff -N ecc_syms_to_metrics.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_syms_to_metrics.cc      1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,149 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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 <ecc_syms_to_metrics.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+
+ecc_syms_to_metrics_sptr 
+ecc_make_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                         gr_feval_ff* pdf_fcn_1_bit,
+                         int n_samples,
+                         float min_sample,
+                         float max_sample,
+                         int sample_precision)
+{
+  return ecc_syms_to_metrics_sptr
+    (new ecc_syms_to_metrics (pdf_fcn_0_bit,
+                             pdf_fcn_1_bit,
+                             n_samples,
+                             min_sample,
+                             max_sample,
+                             sample_precision));
+}
+
+/*
+ * dummy functions and variables to get the float(*)(float) function
+ * to work properly with the gr_feval_XX stuff.
+ */
+
+static gr_feval_ff* l_pdf_fcn_0_bit;
+static gr_feval_ff* l_pdf_fcn_1_bit;
+
+static float pdf_fcn_0 (float x)
+{
+  return (l_pdf_fcn_0_bit->eval (x));
+}
+
+static float pdf_fcn_1 (float x)
+{
+  return (l_pdf_fcn_1_bit->eval (x));
+}
+
+ecc_syms_to_metrics::ecc_syms_to_metrics
+(gr_feval_ff* pdf_fcn_0_bit,
+ gr_feval_ff* pdf_fcn_1_bit,
+ int n_samples,
+ float min_sample,
+ float max_sample,
+ int sample_precision)
+  : gr_block ("syms_to_metrics",
+             gr_make_io_signature (1, -1, sizeof (float)),
+             gr_make_io_signature (0, 0, 0))
+{
+  // setup the dummy functions to do the conversion from the
+  // python-provided feval classes to that which is needed by the
+  // libecc's code_metrics classes.
+
+  l_pdf_fcn_0_bit = pdf_fcn_0_bit;
+  l_pdf_fcn_1_bit = pdf_fcn_1_bit;
+
+  // use the static "create" member function to create the actual
+  // code_metrics to use.
+
+  d_code_metrics = code_metrics<float>::create (&pdf_fcn_0,
+                                               &pdf_fcn_1,
+                                               n_samples,
+                                               min_sample,
+                                               max_sample,
+                                               sample_precision);
+
+  // get the output item size in bytes from the new code_metrics.
+
+  d_out_item_size_bytes = d_code_metrics->out_item_size_bytes ();
+
+  // set the output signature to match that which the code_metrics
+  // will generate.
+
+  set_output_signature (gr_make_io_signature (1, -1, d_out_item_size_bytes));
+}
+
+bool ecc_syms_to_metrics::check_topology (int ninputs, int noutputs)
+{
+  // there are 2 output streams per input stream; the first is ~to
+  // log(p(0|x)) = log-probability of a 0-bit given the input symbol
+  // 'x'; the second is ~to log(p(1|x)).
+
+  return ((noutputs == (2*ninputs)) ? true : false);
+}
+
+void
+ecc_syms_to_metrics::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  // always 1:1, for all streams
+  for (size_t n = 0; n < ninput_items_required.size(); n++) {
+    ninput_items_required[n] = noutput_items;
+  }
+}
+
+int
+ecc_syms_to_metrics::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  size_t l_n_output_items = noutput_items;
+
+  for (size_t n = 0; n < input_items.size(); n++) {
+    float* t_in_buf = (float*)(&input_items[n]);
+    void* t_out_buf_0_bit = (void*)(&(output_items[2*n]));
+    void* t_out_buf_1_bit = (void*)(&(output_items[(2*n)+1]));
+
+    d_code_metrics->convert (l_n_output_items, t_in_buf,
+                            t_out_buf_0_bit, t_out_buf_1_bit);
+  }
+
+  // consume the number of used input items on all input streams
+
+  consume_each (noutput_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}

Index: ecc_syms_to_metrics.h
===================================================================
RCS file: ecc_syms_to_metrics.h
diff -N ecc_syms_to_metrics.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_syms_to_metrics.h       1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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_SYMS_TO_METRICS_H
+#define INCLUDED_SYMS_TO_METRICS_H
+
+#include <gr_block.h>
+#include <gr_feval.h>
+#include <vector>
+#include <libecc/code_metrics.h>
+
+class ecc_syms_to_metrics;
+typedef boost::shared_ptr<ecc_syms_to_metrics> ecc_syms_to_metrics_sptr;
+
+ecc_syms_to_metrics_sptr ecc_make_syms_to_metrics
+(gr_feval_ff* pdf_fcn_0_bit,
+ gr_feval_ff* pdf_fcn_1_bit,
+ int n_samples,
+ float min_sample,
+ float max_sample,
+ int sample_precision);
+
+/*!
+ * \brief Convert the input stream(s) of soft (float) symbols to
+ * log-probability metrics of user-specified precision; output is 2
+ * streams per input stream, each stream consisting of the metric for
+ * receiving a 0-bit and 1-bit, respectively, with the lower-numbered
+ * stream being the 0-bit.
+ *
+ * input: stream(s) of float; output: stream(s) of metrics
+ */
+
+class ecc_syms_to_metrics : public gr_block
+{
+  friend ecc_syms_to_metrics_sptr
+  ecc_make_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                           gr_feval_ff* pdf_fcn_1_bit,
+                           int n_samples,
+                           float min_sample,
+                           float max_sample,
+                           int sample_precision);
+
+/*
+ * ecc_syms_to_metrics: Convert the input soft (float) symbols into
+ *     log-probabilities (metrics) for use in the convolutional
+ *     decoder.  Samples the provided PDF function in 'n_samples'
+ *     places from 'min_sample' to 'max_sample', takes the log of that
+ *     value, then converts the result into a given precision and
+ *     stores all results in a "handy dandy" lookup table for much
+ *     faster processing.
+ *
+ * pdf_fcn_0_bit: point to a probability distribution function which
+ *     takes a float and returns a float, for the 0-bit probabilities.
+ *
+ * pdf_fcn_1_bit: point to a probability distribution function which
+ *     takes a float and returns a float, for the 1-bit probabilities.
+ *
+ * n_samples: the number of samples between min_sample and max_sample
+ *     to store in the lookup table.  Must be at least 2, but
+ *     otherwise is limited only by the amount of available memory;
+ *     generally, 65536 (1 << 16) is plenty of samples.
+ *
+ * min_sample: the minimum value below which any incoming value is
+ *     "rounded" up.
+ *
+ * max_sample: the maximum value above which any incoming value is
+ *     "rounded" down.
+ *
+ * sample_precision: the precision with which to sample the returned
+ *     value of the PDF function.
+ *  +  Cannot be < 0 or > 32.
+ *  +  "soft float" == 0
+ *  + otherwise, convert to an integer of the given value
+ *
+ * in "work", finds the (linearly) closest sample value for the given
+ *     input and outputs the metric for a 0-bit input on the first
+ *     stream and a 1-bit input on the second stream.
+ *
+ */
+
+  ecc_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                      gr_feval_ff* pdf_fcn_1_bit,
+                      int n_samples,
+                      float min_sample,
+                      float max_sample,
+                      int sample_precision);
+
+  size_t d_out_item_size_bytes;
+  code_metrics<float>* d_code_metrics;
+
+public:
+  inline ~ecc_syms_to_metrics() {
+    delete d_code_metrics;
+  };
+
+  bool check_topology (int ninputs, int noutputs);
+
+  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_SYMS_TO_METRICS_H */

Index: ecc_syms_to_metrics.i
===================================================================
RCS file: ecc_syms_to_metrics.i
diff -N ecc_syms_to_metrics.i
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ecc_syms_to_metrics.i       1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(ecc,syms_to_metrics);
+
+ecc_syms_to_metrics_sptr ecc_make_syms_to_metrics
+(gr_feval_ff* pdf_fcn_0_bit,
+ gr_feval_ff* pdf_fcn_1_bit,
+ int n_samples,
+ float min_sample, 
+ float max_sample,
+ int sample_precision);
+
+class ecc_syms_to_metrics : public gr_block
+{
+  ecc_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                      gr_feval_ff* pdf_fcn_1_bit,
+                      int n_samples,
+                      float min_sample, 
+                      float max_sample,
+                      int sample_precision);
+};

Index: libecc/code_io.cc
===================================================================
RCS file: libecc/code_io.cc
diff -N libecc/code_io.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libecc/code_io.cc   1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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 <code_io.h>
+
+#define DO_PRINT_DEBUG 0
+
+static const int g_num_bits_per_byte = 8;
+
+// nothing yet ... it's all in the header file for now.

Index: libecc/code_io.h
===================================================================
RCS file: libecc/code_io.h
diff -N libecc/code_io.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libecc/code_io.h    1 Aug 2006 19:02:35 -0000       1.1
@@ -0,0 +1,556 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio 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.
+ * 
+ * GNU Radio 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 GNU Radio; 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_CODE_IO_H
+#define INCLUDED_CODE_IO_H
+
+#include "code_types.h"
+#include <vector>
+#include <assert.h>
+#include <iostream>
+
+/*
+ * code_io provides classes which do the input and output for these
+ * codes.  One can add another class with its specific needs primarily
+ * by changing the way that the provided data is manipulated to read
+ * or write data items.
+ */
+
+/*
+ * combined io classes
+ */
+
+class code_io
+{
+public:
+  inline code_io (size_t n_streams) {
+    if (n_streams < 1) {
+      std::cerr << "code_io::code_io: Error:" <<
+       "Provided # of streams (" << n_streams <<
+       ") must be at least 1.\n";
+      assert (0);
+    }
+    d_n_streams = n_streams;
+    d_buf_ptrs.resize (d_n_streams);
+  };
+
+  virtual ~code_io () {};
+
+  inline void set_buffer (void** buffer, size_t n_items) {
+    if (buffer == 0) {
+      std::cerr << "code_io::set_buffer: Error:" <<
+       "Provided buffer is NULL.\n";
+      assert (0);
+    }
+    if (n_items == 0) {
+      std::cerr << "code_io::set_buffer: Warning:" <<
+       "Provided # of items is 0!\n";
+    }
+    d_buf = buffer;
+    d_n_items = d_n_items_left = n_items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      d_buf_ptrs[m] = d_buf[m];
+    }
+  };
+
+  inline void set_buffer (std::vector<void*>* buffer, size_t n_items) {
+    set_buffer (&((*buffer)[0]), n_items);};
+
+  inline void set_buffer (std::vector<void*>& buffer, size_t n_items) {
+    set_buffer (&(buffer[0]), n_items);};
+
+  inline virtual void increment_indices () {
+    if (d_n_items_left == 0) {
+      std::cerr << "code_io::increment_indices: Warning: "
+       "No items left!\n";
+    } else
+      d_n_items_left--;
+  };
+
+  // methods for getting info on class internals
+
+  const size_t& n_items_left () {return (d_n_items_left);};
+  const size_t n_items_used () {return (d_n_items - d_n_items_left);};
+  const size_t n_streams () {return (d_n_streams);};
+
+protected:
+  void** d_buf;
+  std::vector<void*> d_buf_ptrs;
+  size_t d_n_streams, d_n_items, d_n_items_left;
+};
+
+/*
+ * input classes
+ */
+
+class code_input : public code_io
+{
+public:
+  inline code_input (size_t n_streams) : code_io (n_streams) {};
+  virtual ~code_input () {};
+  virtual void read_item (void* item, size_t stream_n) = 0;
+  virtual void read_items (void* items) = 0;
+  inline virtual void increment_indices () {code_io::increment_indices ();};
+};
+
+typedef code_input* code_input_ptr;
+
+class code_input_id : public code_input
+{
+private:
+  typedef double input_t;
+
+public:
+/*!
+ * class code_input_id : public code_input
+ *
+ * "id":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'f': streams of double;
+ */
+  inline code_input_id (size_t n_streams) : code_input (n_streams) {};
+  virtual ~code_input_id () {};
+
+  inline virtual void read_item (void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    input_t* t_item = (input_t*) item;
+    (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
+  };
+  inline virtual void read_items (void* items) {
+    /* no error checking for better speed! */
+    input_t* t_items = (input_t*) items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
+    }
+  };
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      input_t* t_buf = (input_t*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+};
+
+class code_input_if : public code_input
+{
+private:
+  typedef float input_t;
+
+public:
+/*!
+ * class code_input_if : public code_input
+ *
+ * "if":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'f': streams of float;
+ */
+  inline code_input_if (size_t n_streams) : code_input (n_streams) {};
+  virtual ~code_input_if () {};
+
+  inline virtual void read_item (void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    input_t* t_item = (input_t*) item;
+    (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
+  };
+  inline virtual void read_items (void* items) {
+    /* no error checking for better speed! */
+    input_t* t_items = (input_t*) items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
+    }
+  };
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      input_t* t_buf = (input_t*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+};
+
+class code_input_ic : public code_input
+{
+private:
+  typedef char input_t;
+
+public:
+/*!
+ * class code_input_is : public code_input
+ *
+ * "ic":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'c': streams of char;
+ */
+  inline code_input_ic (size_t n_streams) : code_input (n_streams) {};
+  virtual ~code_input_ic () {};
+
+  inline virtual void read_item (void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    input_t* t_item = (input_t*) item;
+    (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
+  };
+  inline virtual void read_items (void* items) {
+    /* no error checking for better speed! */
+    input_t* t_items = (input_t*) items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
+    }
+  };
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      input_t* t_buf = (input_t*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+};
+
+class code_input_is : public code_input
+{
+private:
+  typedef short input_t;
+
+public:
+/*!
+ * class code_input_is : public code_input
+ *
+ * "is":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   's': streams of short;
+ */
+  inline code_input_is (size_t n_streams) : code_input (n_streams) {};
+  virtual ~code_input_is () {};
+
+  inline virtual void read_item (void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    input_t* t_item = (input_t*) item;
+    (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
+  };
+  inline virtual void read_items (void* items) {
+    /* no error checking for better speed! */
+    input_t* t_items = (input_t*) items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
+    }
+  };
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      input_t* t_buf = (input_t*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+};
+
+class code_input_il : public code_input
+{
+private:
+  typedef long input_t;
+
+public:
+/*!
+ * class code_input_il : public code_input
+ *
+ * "il":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'l': streams of long;
+ */
+  inline code_input_il (size_t n_streams) : code_input (n_streams) {};
+  virtual ~code_input_il () {};
+
+  inline virtual void read_item (void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    input_t* t_item = (input_t*) item;
+    (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
+  };
+  inline virtual void read_items (void* items) {
+    /* no error checking for better speed! */
+    input_t* t_items = (input_t*) items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
+    }
+  };
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      input_t* t_buf = (input_t*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+};
+
+class code_input_ill : public code_input
+{
+private:
+  typedef long long input_t;
+
+public:
+/*!
+ * class code_input_ill : public code_input
+ *
+ * "ill":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'll': streams of long long;
+ */
+  inline code_input_ill (size_t n_streams) : code_input (n_streams) {};
+  virtual ~code_input_ill () {};
+
+  inline virtual void read_item (void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    input_t* t_item = (input_t*) item;
+    (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
+  };
+  inline virtual void read_items (void* items) {
+    /* no error checking for better speed! */
+    input_t* t_items = (input_t*) items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
+    }
+  };
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      input_t* t_buf = (input_t*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+};
+
+class code_input_ic1 : public code_input
+{
+public:
+/*!
+ * class code_input_ic1 : public code_input
+ *
+ * "ic":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'c': streams of char;
+ *   '1': single bit per char;
+ * --> which bit to choose left to an inheriting class
+ */
+
+  inline code_input_ic1 (size_t n_streams) : code_input (n_streams) {};
+  virtual ~code_input_ic1 () {};
+
+  inline virtual void read_item (void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    char* t_item = (char*) item;
+    (*t_item) = (*((char*)(d_buf_ptrs[stream_n]))) & d_which_bit;
+  };
+  inline virtual void read_items (void* items) {
+    /* no error checking for better speed! */
+    char* t_items = (char*) items;
+    for (size_t m = 0; m < d_n_streams; m++) {
+      t_items[m] = (*((char*)(d_buf_ptrs[m]))) & d_which_bit;
+    }
+  };
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      char* t_buf = (char*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+
+protected:
+  char d_which_bit;
+};
+
+class code_input_ic1l : public code_input_ic1
+{
+public:
+/*!
+ * class code_input_ic1l : public code_input_ic1
+ *
+ * "ic1l":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'c': streams of char;
+ *   '1': single bit per char;
+ *   'l': using only the LSB of the char. 
+ */
+
+  inline code_input_ic1l (size_t n_streams) :
+    code_input_ic1 (n_streams) {d_which_bit = 1;};
+  virtual ~code_input_ic1l () {};
+};
+
+class code_input_ic1h : public code_input_ic1
+{
+public:
+/*!
+ * class code_input_ic1h : public code_input_ic1
+ *
+ * "ic1h":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'c': streams of char;
+ *   '1': single bit per char;
+ *   'h': using only the MSB of the char.
+ */
+
+  inline code_input_ic1h (size_t n_streams)
+    : code_input_ic1 (n_streams) {d_which_bit = 128;};
+  virtual ~code_input_ic1h () {};
+};
+
+class code_input_ic8l : public code_input_ic1l
+{
+protected:
+  size_t d_bit_shift;
+  const static size_t g_num_bits_per_byte = 8;
+
+public:
+/*!
+ * class code_input_ic8l : public code_input_ic1l
+ *
+ * "ic8l":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'c': streams of char;
+ *   '8': using all 8 bits per char;
+ *   'l': starting with the LSB and working up
+ */
+
+  inline code_input_ic8l (size_t n_streams) :
+    code_input_ic1l (n_streams) {d_bit_shift = 0;};
+
+  virtual ~code_input_ic8l () {};
+
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    if (++d_bit_shift % g_num_bits_per_byte == 0) {
+      d_bit_shift = 0;
+      for (size_t m = 0; m < d_n_streams; m++) {
+       char* t_buf = (char*) d_buf_ptrs[m];
+       d_buf_ptrs[m] = (void*)(++t_buf);
+      }
+    } else {
+      for (size_t m = 0; m < d_n_streams; m++) {
+       char* t_buf = (char*) d_buf_ptrs[m];
+       (*t_buf) >>= 1;
+      }
+    }
+  };
+};
+
+class code_input_ic8h : public code_input_ic1h
+{
+protected:
+  size_t d_bit_shift;
+  const static size_t g_num_bits_per_byte = 8;
+
+public:
+/*!
+ * class code_input_ic8h : public code_input_ic1h
+ *
+ * "ic8h":
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'c': streams of char;
+ *   '8': using all 8 bits per char;
+ *   'h': starting with the MSB and working down
+ */
+
+  inline code_input_ic8h (size_t n_streams) :
+    code_input_ic1h (n_streams) {d_bit_shift = 0;};
+
+  virtual ~code_input_ic8h () {};
+
+  inline virtual void increment_indices () {
+    code_input::increment_indices ();
+    if (++d_bit_shift % g_num_bits_per_byte == 0) {
+      d_bit_shift = 0;
+      for (size_t m = 0; m < d_n_streams; m++) {
+       char* t_buf = (char*) d_buf_ptrs[m];
+       d_buf_ptrs[m] = (void*)(++t_buf);
+      }
+    } else {
+      for (size_t m = 0; m < d_n_streams; m++) {
+       char* t_buf = (char*) d_buf_ptrs[m];
+       (*t_buf) <<= 1;
+      }
+    }
+  };
+};
+
+/*
+ * output classes
+ */
+
+class code_output : public code_io
+{
+public:
+  code_output (size_t n_streams) : code_io (n_streams) {};
+  virtual ~code_output () {};
+  virtual void write_item (const void* item, size_t stream_n) = 0;
+  virtual void write_items (const void* items) = 0;
+  virtual inline void increment_indices () {code_io::increment_indices ();};
+};
+
+typedef code_output* code_output_ptr;
+
+class code_output_ic1l : public code_output
+{
+public:
+/*!
+ * class code_output_ic1l : public code_output
+ *
+ *   'i': one stream per code input as defined by the instantiated
+ *        code ("individual", not mux'ed);
+ *   'c': streams of char;
+ *   '1': single bit per char;
+ *   'l': using only the right-most justified (LSB).
+ */
+
+  inline code_output_ic1l (size_t n_streams) : code_output (n_streams) {};
+  virtual ~code_output_ic1l () {};
+
+  inline virtual void write_item (const void* item, size_t stream_n) {
+    /* no error checking for better speed! */
+    const char* t_item = (char*) item;
+    (*((char*)(d_buf_ptrs[stream_n]))) = (*t_item) & 1;
+  };
+  inline virtual void write_items (const void* items) {
+    /* no error checking for better speed! */
+    const char* t_items = (char*) items;
+    for (size_t m = 0; m < d_n_streams; m++)
+      (*((char*)(d_buf_ptrs[m]))) = (t_items[m]) & 1;
+  };
+  inline virtual void increment_indices () {
+    code_output::increment_indices ();
+    for (size_t m = 0; m < d_n_streams; m++) {
+      char* t_buf = (char*) d_buf_ptrs[m];
+      d_buf_ptrs[m] = (void*)(++t_buf);
+    }
+  };
+};
+
+#endif /* INCLUDED_CODE_IO_H */

Index: gr_metrics_decode_viterbi_full_block.cc
===================================================================
RCS file: gr_metrics_decode_viterbi_full_block.cc
diff -N gr_metrics_decode_viterbi_full_block.cc
--- gr_metrics_decode_viterbi_full_block.cc     9 Jul 2006 16:15:17 -0000       
1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,228 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- *
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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 <gr_metrics_decode_viterbi_full_block.h>
-#include <gr_io_signature.h>
-#include <assert.h>
-#include <iostream>
-
-gr_metrics_decode_viterbi_full_block_sptr
-gr_make_metrics_decode_viterbi_full_block
-(int sample_precision,
- int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-{
-  return gr_metrics_decode_viterbi_full_block_sptr
-    (new gr_metrics_decode_viterbi_full_block
-     (sample_precision,
-      frame_size_bits,
-      n_code_inputs,
-      n_code_outputs,
-      code_generator,
-      do_termination,
-      start_memory_state,
-      end_memory_state));
-}
-
-gr_metrics_decode_viterbi_full_block_feedback_sptr
-gr_make_metrics_decode_viterbi_full_block_feedback
-(int sample_precision,
- int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- const std::vector<int> &code_feedback,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-{
-  return gr_metrics_decode_viterbi_full_block_feedback_sptr
-    (new gr_metrics_decode_viterbi_full_block
-     (sample_precision,
-      frame_size_bits,
-      n_code_inputs,
-      n_code_outputs,
-      code_generator,
-      code_feedback,
-      do_termination,
-      start_memory_state,
-      end_memory_state));
-}
-
-gr_metrics_decode_viterbi_full_block::gr_metrics_decode_viterbi_full_block
-(int sample_precision,
- int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-  : gr_block ("metrics_decode_viterbi_full_block",
-             gr_make_io_signature (0, 0, 0),
-             gr_make_io_signature (0, 0, 0))
-{
-  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
-                                                n_code_inputs,
-                                                n_code_outputs,
-                                                code_generator,
-                                                do_termination,
-                                                start_memory_state,
-                                                end_memory_state);
-
-  setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
-}
-
-gr_metrics_decode_viterbi_full_block::gr_metrics_decode_viterbi_full_block
-(int sample_precision,
- int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- const std::vector<int> &code_feedback,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-  : gr_block ("metrics_decode_viterbi_full_block_feedback",
-             gr_make_io_signature (0, 0, 0),
-             gr_make_io_signature (0, 0, 0))
-{
-  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
-                                                n_code_inputs,
-                                                n_code_outputs,
-                                                code_generator,
-                                                code_feedback,
-                                                do_termination,
-                                                start_memory_state,
-                                                end_memory_state);
-
-  setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
-}
-
-gr_metrics_decode_viterbi_full_block::~gr_metrics_decode_viterbi_full_block
-()
-{
-  delete d_decoder;
-  delete d_encoder;
-}
-
-void
-gr_metrics_decode_viterbi_full_block::setup_io_signatures
-(int sample_precision,
- int n_code_inputs,
- int n_code_outputs)
-{
-  // create the decoder using:
-  //
-  // the "i1" input model: individual input streams; two per metric
-  // type (0-bit, 1-bit), single metric per input item (char, short, long)
-  //
-  // the "ic1" output model:
-  // individual output streams per decoded code input stream;
-  // each item is a 'char' type with 1 bit aligned on the LSB.
-
-  d_decoder = new decoder_viterbi_full_block_i1_ic1 (sample_precision,
-                                                    d_encoder);
-
-  // error checking is done in the encoder and decoder classes
-  // so just use the parameters as given; will be correct!
-
-  d_n_code_inputs = n_code_inputs;
-  d_n_code_outputs = n_code_outputs;
-
-  // output signature is always the same:
-  // sizeof (char) with 1 bit per char as the LSB
-
-  set_output_signature (gr_make_io_signature (d_n_code_inputs,
-                                             d_n_code_inputs,
-                                             sizeof (char)));
-
-  // determine the input signature element size
-  size_t l_input_item_size_bytes;
-
-  if (sample_precision == 0) {
-    // float
-    l_input_item_size_bytes = sizeof (float);
-  } else if (sample_precision <= 8) {
-    // use char
-    l_input_item_size_bytes = sizeof (char);
-  } else if (sample_precision <= 16) {
-    // use short
-    l_input_item_size_bytes = sizeof (short);
-  } else {
-    // use long
-    l_input_item_size_bytes = sizeof (long);
-  }
-
-  set_input_signature (gr_make_io_signature (2*d_n_code_outputs,
-                                            2*d_n_code_outputs,
-                                            l_input_item_size_bytes));
-}
-
-void gr_metrics_decode_viterbi_full_block::forecast
-(int noutput_items,
- gr_vector_int &ninput_items_required)
-{
-  int ninput_items = d_decoder->compute_n_input_metrics (noutput_items);
-  size_t ninputs = ninput_items_required.size();
-  for (size_t n = 0; n < ninputs; n++)
-    ninput_items_required[n] = ninput_items;
-}
-
-int
-gr_metrics_decode_viterbi_full_block::general_work
-(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
-  // FIXME: compute the actual number of output items (1 bit char's) created.
-
-  size_t t_n_input_items = d_decoder->compute_n_input_metrics (noutput_items);
-  size_t t_n_output_items = d_decoder->compute_n_output_bits (t_n_input_items);
-
-  assert (t_n_output_items == ((size_t)noutput_items));
-
-  // "work" is handled by the decoder; which returns the actual number
-  // of input items (metrics) used.
-
-  t_n_input_items = d_decoder->decode ((const char**)(&input_items[0]),
-                                      (char**)(&output_items[0]),
-                                      noutput_items);
-
-  // consume the number of used input items on all input streams
-
-  consume_each (t_n_input_items);
-
-  // returns number of items written to each output stream
-
-  return (noutput_items);
-}

Index: gr_metrics_decode_viterbi_full_block.h
===================================================================
RCS file: gr_metrics_decode_viterbi_full_block.h
diff -N gr_metrics_decode_viterbi_full_block.h
--- gr_metrics_decode_viterbi_full_block.h      9 Jul 2006 16:15:17 -0000       
1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,163 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- *
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_GR_METRICS_DECODE_VITERBI_FULL_BLOCK_H
-#define INCLUDED_GR_METRICS_DECODE_VITERBI_FULL_BLOCK_H
-
-#include <gr_block.h>
-#include <libecc/decoder_viterbi_full_block_i1_ic1.h>
-#include <libecc/encoder_convolutional_ic1_ic1.h>
-
-class gr_metrics_decode_viterbi_full_block;
-
-typedef boost::shared_ptr<gr_metrics_decode_viterbi_full_block>
-gr_metrics_decode_viterbi_full_block_sptr,
-gr_metrics_decode_viterbi_full_block_feedback_sptr;
-
-gr_metrics_decode_viterbi_full_block_sptr
-gr_make_metrics_decode_viterbi_full_block
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- std::vector<int> code_generator,
- bool do_termination = true,
- int start_memory_state = 0,
- int end_memory_state = 0);
-
-gr_metrics_decode_viterbi_full_block_feedback_sptr
-gr_make_metrics_decode_viterbi_full_block_feedback
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- std::vector<int> code_generator,
- std::vector<int> code_feedback,
- bool do_termination = true,
- int start_memory_state = 0,
- int end_memory_state = 0);
-
-/*!
- * \brief Decode the incoming streams using a Viterbi-style decoder,
- *     full trellis block decoding.
- *
- * input: symbol metrics data.
- *
- * output: stream(s) of char, single bit stored in the LSB.
- */
-
-class gr_metrics_decode_viterbi_full_block : public gr_block
-{
-  friend gr_metrics_decode_viterbi_full_block_sptr
-  gr_make_metrics_decode_viterbi_full_block
-  (int sample_precision,
-   int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-
-  friend gr_metrics_decode_viterbi_full_block_feedback_sptr
-  gr_make_metrics_decode_viterbi_full_block_feedback
-  (int sample_precision,
-   int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   const std::vector<int> &code_feedback,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-/*
- * frame_size_bits: if == 0, then do streaming decoding (infinite
- *     trellis); otherwise this is the block size to decode before
- *     terminating the trellis.
- *
- * 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 is valid only if frame_size_bits != 0, and defines
- *     whether or not to to trellis termination.
- *
- * do_mux_input: is true, then the one input stream will be
- *     interpreted as the multiplexing all of the input bits.  For
- *     example for a 3 input decoder, the input stream would be
- *     [I1[k], I2[k], I3[k], I1[k+1], I2[k+1], ...], where "k" is the
- *     input sample time, and "I1" through "I3" are the 3 input
- *     streams.
- *
- * n_code_inputs: the number of decoder-input (encoder-output)
- *     streams, no matter if separate or mux'ed
- *
- * n_code_outputs: the number of decoder-output (encoder-input) streams
- */
-
-  gr_metrics_decode_viterbi_full_block
-  (int sample_precision,
-   int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-
-  gr_metrics_decode_viterbi_full_block
-  (int sample_precision,
-   int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   const std::vector<int> &code_feedback,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-
-public:
-  ~gr_metrics_decode_viterbi_full_block ();
-
-  virtual void forecast (int noutput_items,
-                        gr_vector_int &ninput_items_required);
-
-  virtual int general_work (int noutput_items,
-                           gr_vector_int &ninput_items,
-                           gr_vector_const_void_star &input_items,
-                           gr_vector_void_star &output_items);
-
-protected:
-  void setup_io_signatures (int sample_precision,
-                           int n_code_inputs,
-                           int n_code_outputs);
-
-  int d_n_code_inputs, d_n_code_outputs;
-  decoder_viterbi_full_block_i1_ic1* d_decoder;
-  encoder_convolutional_ic1_ic1* d_encoder;
-};
-
-#endif /* INCLUDED_GR_METRICS_DECODE_VITERBI_FULL_BLOCK_H */

Index: gr_metrics_decode_viterbi_full_block.i
===================================================================
RCS file: gr_metrics_decode_viterbi_full_block.i
diff -N gr_metrics_decode_viterbi_full_block.i
--- gr_metrics_decode_viterbi_full_block.i      9 Jul 2006 16:15:17 -0000       
1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,77 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,metrics_decode_viterbi_full_block);
-
-// corrected "class NAME" statement, which uses slightly different NAMEs
-
-typedef boost::shared_ptr<gr_metrics_decode_viterbi_full_block>
-gr_metrics_decode_viterbi_full_block_feedback_sptr;
-
-LOCAL_GR_SWIG_BLOCK_MAGIC(gr,metrics_decode_viterbi_full_block_feedback);
-
-gr_metrics_decode_viterbi_full_block_sptr
-gr_make_metrics_decode_viterbi_full_block
-(int sample_precision,
- int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- bool do_termination,
- int start_memory_state,
- int end_memory_state);
-
-gr_metrics_decode_viterbi_full_block_feedback_sptr
-gr_make_metrics_decode_viterbi_full_block_feedback
-(int sample_precision,
- int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- const std::vector<int> &code_feedback,
- bool do_termination,
- int start_memory_state,
- int end_memory_state);
-
-class gr_metrics_decode_viterbi_full_block : public gr_block
-{
-  gr_metrics_decode_viterbi_full_block
-  (int sample_precision,
-   int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-
-  gr_metrics_decode_viterbi_full_block
-  (int sample_precision,
-   int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   const std::vector<int> &code_feedback,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-};

Index: gr_streams_encode_convolutional.cc
===================================================================
RCS file: gr_streams_encode_convolutional.cc
diff -N gr_streams_encode_convolutional.cc
--- gr_streams_encode_convolutional.cc  14 Jul 2006 15:49:54 -0000      1.4
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,220 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- *
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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 <gr_streams_encode_convolutional.h>
-#include <gr_io_signature.h>
-#include <assert.h>
-#include <iostream>
-
-gr_streams_encode_convolutional_sptr 
-gr_make_streams_encode_convolutional
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-{
-  return gr_streams_encode_convolutional_sptr
-    (new gr_streams_encode_convolutional (frame_size_bits,
-                                         n_code_inputs,
-                                         n_code_outputs,
-                                         code_generator,
-                                         do_termination,
-                                         start_memory_state,
-                                         end_memory_state));
-}
-
-gr_streams_encode_convolutional_sptr 
-gr_make_streams_encode_convolutional_feedback
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- const std::vector<int> &code_feedback,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-{
-  return gr_streams_encode_convolutional_sptr
-    (new gr_streams_encode_convolutional (frame_size_bits,
-                                         n_code_inputs,
-                                         n_code_outputs,
-                                         code_generator,
-                                         code_feedback,
-                                         do_termination,
-                                         start_memory_state,
-                                         end_memory_state));
-}
-
-gr_streams_encode_convolutional::gr_streams_encode_convolutional
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generators,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-  : gr_block ("streams_encode_convolutional",
-             gr_make_io_signature (0, 0, 0),
-             gr_make_io_signature (0, 0, 0))
-{
-  // error checking is done by the encoder class itself;
-  // just pass items on here.
-
-  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
-                                                n_code_inputs,
-                                                n_code_outputs,
-                                                code_generators,
-                                                do_termination,
-                                                start_memory_state,
-                                                end_memory_state);
-
-  setup_io_signatures (n_code_inputs, n_code_outputs);
-}
-
-gr_streams_encode_convolutional::gr_streams_encode_convolutional
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generators,
- const std::vector<int> &code_feedback,
- bool do_termination,
- int start_memory_state,
- int end_memory_state)
-  : gr_block ("streams_encode_convolutional_feedback",
-             gr_make_io_signature (0, 0, 0),
-             gr_make_io_signature (0, 0, 0))
-{
-  // error checking is done by the encoder class itself;
-  // just pass items on here.
-
-  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
-                                                n_code_inputs,
-                                                n_code_outputs,
-                                                code_generators,
-                                                code_feedback,
-                                                do_termination,
-                                                start_memory_state,
-                                                end_memory_state);
-
-  setup_io_signatures (n_code_inputs, n_code_outputs);
-}
-
-void
-gr_streams_encode_convolutional::setup_io_signatures
-(int n_code_inputs,
- int n_code_outputs)
-{
-  fprintf (stderr, "gr_s_e_c: d_encoder == %X\n", (unsigned int)d_encoder);
-
-  // create the correct input signature; 1 bit per input char
-
-  set_input_signature (gr_make_io_signature (n_code_inputs,
-                                            n_code_inputs,
-                                            sizeof (char)));
-
-  // create the correct output signature; 1 bit per output char
-
-  set_output_signature (gr_make_io_signature (n_code_outputs,
-                                             n_code_outputs,
-                                             sizeof (char)));
-
-  // no need to set the output multiple (to 1 item), since 1 is the
-  // default, and the encoder class handles the rest internally
-
-  // no need to set the relative rate (# out / # in) because for each
-  // input bit per input stream there is 1 output bit per output
-  // stream ... with a little added for termination, but ignore those.
-}
-
-gr_streams_encode_convolutional::~gr_streams_encode_convolutional
-()
-{
-  delete d_encoder;
-  d_encoder = 0;
-}
-
-/*
- * Compute the number of input items needed to produce 'n_output'
- * bits.  Handled internally by the encoder.
- */
-
-void gr_streams_encode_convolutional::forecast
-(int noutput_items,
- gr_vector_int &ninput_items_required)
-{
-  fprintf (stderr, "gr_s_e_c::forecast: #out = %d\n",
-         noutput_items);
-
-  int ninput_items = d_encoder->compute_n_input_bits (noutput_items);
-
-  fprintf (stderr, "s_e_c::forecast: #out = %d, #in = %d\n",
-         noutput_items, ninput_items);
-
-  size_t ninputs = ninput_items_required.size();
-  for (size_t n = 0; n < ninputs; n++)
-    ninput_items_required[n] = ninput_items;
-}
-
-int
-gr_streams_encode_convolutional::general_work
-(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
-  fprintf (stderr, "gr_s_e_c::general_work: Starting #out = %d\n",
-          noutput_items);
-
-  // FIXME: compute the actual number of output items (1 bit char's) created.
-
-  size_t t_n_input_items = d_encoder->compute_n_input_bits (noutput_items);
-
-#if 0
-  size_t t_n_output_items = d_encoder->compute_n_output_bits (t_n_input_items);
-
-  assert (t_n_output_items == ((size_t)noutput_items));
-#endif
-
-  // "work" is handled by the encoder; which returns the actual number
-  // of input items (1-bit char's) used.
-
-  t_n_input_items = d_encoder->encode ((const char **)(&input_items[0]), 
-                                      (char **)(&output_items[0]),
-                                      (size_t) noutput_items);
-
-  assert (0);
-
-  // consume the number of used input items on all input streams
-
-  consume_each (t_n_input_items);
-
-  // returns number of items written to each output stream
-
-  return (noutput_items);
-}

Index: gr_streams_encode_convolutional.h
===================================================================
RCS file: gr_streams_encode_convolutional.h
diff -N gr_streams_encode_convolutional.h
--- gr_streams_encode_convolutional.h   9 Jul 2006 21:02:44 -0000       1.3
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,155 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- *
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_GR_STREAMS_ENCODE_CONVOLUTIONAL_H
-#define INCLUDED_GR_STREAMS_ENCODE_CONVOLUTIONAL_H
-
-#include <gr_block.h>
-#include <libecc/encoder_convolutional_ic1_ic1.h>
-
-/*!
- * \brief Encode the incoming streams using a convolutional encoder
- *
- * input: 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: 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.
- *
- * 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.  E.g. "4" in binary is "100", which would be
- *     "D^2" for code generation.  "6" == 110b == "D^2 + D"
- *  ==> The vector is listed in order for each output 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, I2->O1, I1->O2, I2->O2]
- *     with each element being an integer 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.
- */
-
-class gr_streams_encode_convolutional;
-typedef boost::shared_ptr<gr_streams_encode_convolutional>
-  gr_streams_encode_convolutional_sptr;
-
-gr_streams_encode_convolutional_sptr
-gr_make_streams_encode_convolutional
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- bool do_termination = true,
- int start_memory_state = 0,
- int end_memory_state = 0);
-
-gr_streams_encode_convolutional_sptr
-gr_make_streams_encode_convolutional_feedback
-(int frame_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- const std::vector<int> &code_feedback,
- bool do_termination = true,
- int start_memory_state = 0,
- int end_memory_state = 0);
-
-class gr_streams_encode_convolutional : public gr_block
-{
-  friend gr_streams_encode_convolutional_sptr
-  gr_make_streams_encode_convolutional
-  (int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-
-  friend gr_streams_encode_convolutional_sptr
-  gr_make_streams_encode_convolutional_feedback
-  (int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   const std::vector<int> &code_feedback,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-
-  gr_streams_encode_convolutional (int frame_size_bits,
-                                  int n_code_inputs,
-                                  int n_code_outputs,
-                                  const std::vector<int> &code_generator,
-                                  bool do_termination,
-                                  int start_memory_state,
-                                  int end_memory_state);
-
-  gr_streams_encode_convolutional (int frame_size_bits,
-                                  int n_code_inputs,
-                                  int n_code_outputs,
-                                  const std::vector<int> &code_generator,
-                                  const std::vector<int> &code_feedback,
-                                  bool do_termination,
-                                  int start_memory_state,
-                                  int end_memory_state);
-
-  void setup_io_signatures (int n_code_inputs, int n_code_outputs);
-
-  encoder_convolutional_ic1_ic1* d_encoder;
-
-public:
-  ~gr_streams_encode_convolutional ();
-
-  inline encoder_convolutional_ic1_ic1* encoder () {return (d_encoder);};
-
-  virtual void forecast (int noutput_items,
-                        gr_vector_int &ninput_items_required);
-
-  virtual int general_work (int noutput_items,
-                           gr_vector_int &ninput_items,
-                           gr_vector_const_void_star &input_items,
-                           gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_STREAMS_ENCODE_CONVOLUTIONAL_H */

Index: gr_streams_encode_convolutional.i
===================================================================
RCS file: gr_streams_encode_convolutional.i
diff -N gr_streams_encode_convolutional.i
--- gr_streams_encode_convolutional.i   9 Jul 2006 21:02:44 -0000       1.3
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,77 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,streams_encode_convolutional);
-
-// Rename second constructor
-%rename(streams_encode_convolutional_feedback) 
gr_make_streams_encode_convolutional_feedback;
-
-// support vectors of these ... for use in the convolutional decoder
-// as well as Turbo Codes (both encoder and decoder).
-
-namespace std {
-  %template(x_vector_gr_streams_encode_convolutional_sptr) 
vector<gr_streams_encode_convolutional_sptr>;
-};
-
-gr_streams_encode_convolutional_sptr
-gr_make_streams_encode_convolutional
-(int block_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- bool do_termination = true,
- int start_memory_state = 0,
- int end_memory_state = 0);
-
-gr_streams_encode_convolutional_sptr
-gr_make_streams_encode_convolutional_feedback
-(int block_size_bits,
- int n_code_inputs,
- int n_code_outputs,
- const std::vector<int> &code_generator,
- const std::vector<int> &code_feedback,
- bool do_termination = true,
- int start_memory_state = 0,
- int end_memory_state = 0);
-
-class gr_streams_encode_convolutional : public gr_block
-{
-private:
-  gr_streams_encode_convolutional
-  (int block_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-
-  gr_streams_encode_convolutional
-  (int block_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generator,
-   const std::vector<int> &code_feedback,
-   bool do_termination,
-   int start_memory_state,
-   int end_memory_state);
-};

Index: gr_streams_encode_turbo.cc
===================================================================
RCS file: gr_streams_encode_turbo.cc
diff -N gr_streams_encode_turbo.cc
--- gr_streams_encode_turbo.cc  9 Jul 2006 16:15:17 -0000       1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,209 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- *
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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 <gr_streams_encode_turbo.h>
-#include <gr_io_signature.h>
-#include <assert.h>
-#include <iostream>
-
-gr_streams_encode_turbo_sptr 
-gr_make_streams_encode_turbo
-(int n_code_inputs,
- int n_code_outputs,
- const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
- const std::vector<size_t> &interleavers)
-{
-  return gr_streams_encode_turbo_sptr
-    (new gr_streams_encode_turbo (n_code_inputs,
-                                 n_code_outputs,
-                                 encoders,
-                                 interleavers));
-}
-
-gr_streams_encode_turbo::gr_streams_encode_turbo
-(int n_code_inputs,
- int n_code_outputs,
- const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
- const std::vector<size_t> &interleavers)
-  : gr_block ("streams_encode_turbo",
-             gr_make_io_signature (0, 0, 0),
-             gr_make_io_signature (0, 0, 0))
-{
-  // error checking is done by the encoder class itself;
-  // just pass items on here.
-
-  // check out individual encoders, to make sure the total input /
-  // output matches those specified by the user.
-
-  d_n_encoders = encoders.size ();
-
-  if (d_n_encoders < 2) {
-    std::cerr << "gr_streams_encode_turbo: Error: "
-      "too few (" << d_n_encoders << ") encoders specified; a Turbo "
-      "code requires at least 2 constituent encoders.\n";
-    assert (0);
-  }
-
-  // make sure that the block size and termination are consistent for
-  // all encoders; warn the user if not, since it doesn't really
-  // matter to the encoder (but it might to the decoder; remains to be
-  // seen).
-
-  encoder_convolutional_ic1_ic1* t_ec = encoders[0]->encoder ();
-  d_block_size_bits = t_ec->block_size_bits ();
-  d_do_termination = t_ec->do_termination ();
-  bool t_diff_block_size, t_diff_termination;
-  t_diff_block_size = t_diff_termination = false;
-
-  for (size_t m = 1; m < d_n_encoders; m++) {
-    t_ec = encoders[0]->encoder ();
-    size_t t_block_size_bits = t_ec->block_size_bits ();
-    if (t_block_size_bits != d_block_size_bits)
-      t_diff_block_size = true;
-    bool t_do_termination = t_ec->do_termination ();
-    if (t_do_termination != d_do_termination)
-      t_do_termination = true;
-  }
-
-  if (t_diff_block_size == true) {
-    std::cout << "gr_streams_encode_turbo: Warning: "
-      "Some constituent encoders have different block size (bits).\n";
-  }
-  if (t_diff_termination == true) {
-    std::cout << "gr_streams_encode_turbo: Warning: "
-      "Some constituent encoders are differently terminationed.\n";
-  }
-
-  std::cout << "gr_streams_encode_turbo: setup:\n"
-    "d_n_encoders = " << d_n_encoders << "\n"
-    "n_code_inputs = " << n_code_inputs << "\n"
-    "n_code_outputs = " << n_code_outputs << "\n\n"
-    "Individual Encoders:\n";
-
-  for (size_t m = 0; m < d_n_encoders; m++) {
-    t_ec = encoders[m]->encoder ();
-    std::cout << "  [" << (m+1) << "]:\n"
-      "n_code_inputs = " << (t_ec->n_code_inputs()) << "\n"
-      "n_code_outputs = " << (t_ec->n_code_outputs()) << "\n"
-      "block_size_bits = " << (t_ec->block_size_bits()) << "\n"
-      "do_termination = " <<
-      ((t_ec->do_termination()==true)?"true":"false") << "\n";
-  }
-
-#if 1
-  assert (0);
-#else
-  if (d_n_encoders != (interleavers.size())) {}
-
-  d_encoder = new encoder_turbo_ic1_ic1 (n_code_inputs,
-                                        n_code_outputs,
-                                        code_generators,
-                                        do_termination,
-                                        start_memory_state,
-                                        end_memory_state);
-#endif
-
-  // create the correct input signature; 1 bit per input char
-
-  set_input_signature (gr_make_io_signature (n_code_inputs,
-                                            n_code_inputs,
-                                            sizeof (char)));
-
-  // create the correct output signature; 1 bit per output char
-
-  set_output_signature (gr_make_io_signature (n_code_outputs,
-                                             n_code_outputs,
-                                             sizeof (char)));
-
-// set the output multiple to 1 item, then let the encoder class
-// handle the rest internally
-
-  set_output_multiple (1);
-}
-
-gr_streams_encode_turbo::~gr_streams_encode_turbo
-()
-{
-  if (d_encoder)
-    delete d_encoder;
-}
-
-/*
- * Compute the number of input bits (items in this case, since each
- * item has 1 bit in it) needed to produce 'n_output' bits (items in
- * this case, since each item has 1 bit in it).
- *
- * For turbo 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.
- */
-
-void gr_streams_encode_turbo::forecast
-(int noutput_items,
- gr_vector_int &ninput_items_required)
-{
-  int ninput_items = d_encoder->compute_n_input_bits (noutput_items);
-  size_t ninputs = ninput_items_required.size();
-  for (size_t n = 0; n < ninputs; n++)
-    ninput_items_required[n] = ninput_items;
-}
-
-int
-gr_streams_encode_turbo::general_work
-(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
-  // FIXME: compute the actual number of output items (1 bit char's) created.
-
-  size_t t_n_input_items = d_encoder->compute_n_input_bits (noutput_items);
-  size_t t_n_output_items = d_encoder->compute_n_output_bits (t_n_input_items);
-
-  assert (t_n_output_items == ((size_t)noutput_items));
-
-  // "work" is handled by the encoder; which returns the actual number
-  // of input items (1-bit char's) used.
-
-  t_n_input_items = d_encoder->encode ((const char **)(&input_items[0]), 
-                                      (char **)(&output_items[0]),
-                                      (size_t) noutput_items);
-
-  // consume the number of used input items on all input streams
-
-  consume_each (t_n_input_items);
-
-  // returns number of items written to each output stream
-
-  return (noutput_items);
-}

Index: gr_streams_encode_turbo.h
===================================================================
RCS file: gr_streams_encode_turbo.h
diff -N gr_streams_encode_turbo.h
--- gr_streams_encode_turbo.h   9 Jul 2006 16:15:17 -0000       1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,104 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- *
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_GR_STREAMS_ENCODE_TURBO_H
-#define INCLUDED_GR_STREAMS_ENCODE_TURBO_H
-
-#include <gr_block.h>
-#include <gr_streams_encode_convolutional.h>
-
-#if 0
-#include <libecc/encoder_turbo_ic1_ic1.h>
-#else
-#include <libecc/encoder_turbo.h>
-#endif
-
-/*!
- * \brief Encode the incoming stream(s) using a turbo encoder
- *
- * input: 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: 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.
- *
- * n_code_inputs:
- * n_code_outputs: the total number of code inputs and outputs for the
- *     overall turbo encoder (not just the constituent codes).
- *
- * encoders: the constituent encoders to be used; all -should- be
- *     configured with the same "block_size" and "termination", though
- *     from this encoder's perspective it doesn't really matter.
- *
- * interleavers: the interleavers to use before each encoder,
- *     respectively, except the first encoder which will not use an
- *     interleaver.
- */
-
-class gr_streams_encode_turbo;
-
-typedef boost::shared_ptr<gr_streams_encode_turbo>
-gr_streams_encode_turbo_sptr;
-
-gr_streams_encode_turbo_sptr
-gr_make_streams_encode_turbo
-(int n_code_inputs,
- int n_code_outputs,
- const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
- const std::vector<size_t> &interleavers);
-
-class gr_streams_encode_turbo : public gr_block
-{
-  friend gr_streams_encode_turbo_sptr
-  gr_make_streams_encode_turbo
-    (int n_code_inputs,
-     int n_code_outputs,
-     const std::vector<gr_streams_encode_convolutional_sptr> &d_encoders,
-     const std::vector<size_t> &d_interleavers);
-
-  gr_streams_encode_turbo
-    (int n_code_inputs,
-     int n_code_outputs,
-     const std::vector<gr_streams_encode_convolutional_sptr> &d_encoders,
-     const std::vector<size_t> &d_interleavers);
-
-  std::vector<gr_streams_encode_turbo_sptr> d_encoders;
-  std::vector<size_t> d_interleavers;
-  size_t d_n_encoders, d_block_size_bits;
-  bool d_do_termination;
-  encoder_turbo* d_encoder;
-
-public:
-  ~gr_streams_encode_turbo ();
-
-  virtual void forecast (int noutput_items,
-                        gr_vector_int &ninput_items_required);
-
-  virtual int general_work (int noutput_items,
-                           gr_vector_int &ninput_items,
-                           gr_vector_const_void_star &input_items,
-                           gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_GR_STREAMS_ENCODE_TURBO_H */

Index: gr_streams_encode_turbo.i
===================================================================
RCS file: gr_streams_encode_turbo.i
diff -N gr_streams_encode_turbo.i
--- gr_streams_encode_turbo.i   9 Jul 2006 16:15:17 -0000       1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,41 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,streams_encode_turbo);
-
-#include <gr_streams_encode_convolutional.h>
-
-gr_streams_encode_turbo_sptr
-gr_make_streams_encode_turbo
-(int n_code_inputs,
- int n_code_outputs,
- const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
- const std::vector<size_t> &interleavers);
-
-class gr_streams_encode_turbo : public gr_block
-{
-  gr_streams_encode_turbo
-  (int frame_size_bits,
-   int n_code_inputs,
-   const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
-   const std::vector<size_t> &interleavers);
-};

Index: gr_syms_to_metrics.cc
===================================================================
RCS file: gr_syms_to_metrics.cc
diff -N gr_syms_to_metrics.cc
--- gr_syms_to_metrics.cc       5 Jul 2006 17:49:58 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,167 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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 <gr_syms_to_metrics.h>
-#include <gr_io_signature.h>
-#include <assert.h>
-
-gr_syms_to_metrics_sptr 
-gr_make_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
-                        gr_feval_ff* pdf_fcn_1_bit,
-                        int n_samples,
-                        float min_sample,
-                        float max_sample,
-                        int sample_precision)
-{
-  return gr_syms_to_metrics_sptr
-    (new gr_syms_to_metrics (pdf_fcn_0_bit,
-                            pdf_fcn_1_bit,
-                            n_samples,
-                            min_sample,
-                            max_sample,
-                            sample_precision));
-}
-
-/*
- * dummy functions and variables to get the float(*)(float) function
- * to work properly with the gr_feval_XX stuff.
- */
-
-static gr_feval_ff* l_pdf_fcn_0_bit;
-static gr_feval_ff* l_pdf_fcn_1_bit;
-
-static float pdf_fcn_0 (float x)
-{
-  return (l_pdf_fcn_0_bit->eval (x));
-}
-
-static float pdf_fcn_1 (float x)
-{
-  return (l_pdf_fcn_1_bit->eval (x));
-}
-
-gr_syms_to_metrics::gr_syms_to_metrics
-(gr_feval_ff* pdf_fcn_0_bit,
- gr_feval_ff* pdf_fcn_1_bit,
- int n_samples,
- float min_sample,
- float max_sample,
- int sample_precision)
-  : gr_block ("syms_to_metrics",
-             gr_make_io_signature (1, -1, sizeof (float)),
-             gr_make_io_signature (0, 0, 0))
-{
-  if ((sample_precision < 0) | (sample_precision > 32)) {
-    fprintf (stderr, "gr_syms_to_metrics: sample_precision must be "
-            " between 0 and 32.\n");
-    assert (0);
-  }
-
-  l_pdf_fcn_0_bit = pdf_fcn_0_bit;
-  l_pdf_fcn_1_bit = pdf_fcn_1_bit;
-
-  if (sample_precision == 0) {
-    // float
-    d_out_item_size_bytes = sizeof (float);
-    d_code_metrics = new code_metric_ff (&pdf_fcn_0,
-                                        &pdf_fcn_1,
-                                        n_samples,
-                                        min_sample,
-                                        max_sample);
-  } else if (sample_precision <= 8) {
-    // use char
-    d_out_item_size_bytes = sizeof (char);
-    d_code_metrics = new code_metric_fb (&pdf_fcn_0,
-                                        &pdf_fcn_1,
-                                        n_samples,
-                                        min_sample,
-                                        max_sample,
-                                        sample_precision);
-  } else if (sample_precision <= 16) {
-    // use short
-    d_out_item_size_bytes = sizeof (short);
-    d_code_metrics = new code_metric_fs (&pdf_fcn_0,
-                                        &pdf_fcn_1,
-                                        n_samples,
-                                        min_sample,
-                                        max_sample,
-                                        sample_precision);
-  } else {
-    // use long
-    d_out_item_size_bytes = sizeof (long);
-    d_code_metrics = new code_metric_fl (&pdf_fcn_0,
-                                        &pdf_fcn_1,
-                                        n_samples,
-                                        min_sample,
-                                        max_sample,
-                                        sample_precision);
-  }
-
-  set_output_signature (gr_make_io_signature (1, -1, d_out_item_size_bytes));
-}
-
-bool gr_syms_to_metrics::check_topology (int ninputs, int noutputs)
-{
-  return ((noutputs == (2*ninputs)) ? true : false);
-}
-
-void
-gr_syms_to_metrics::forecast
-(int noutput_items,
- gr_vector_int &ninput_items_required)
-{
-  // always 1:1, for all streams
-  for (size_t n = 0; n < ninput_items_required.size(); n++) {
-    ninput_items_required[n] = noutput_items;
-  }
-}
-
-int
-gr_syms_to_metrics::general_work
-(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
-  size_t l_n_output_items = noutput_items;
-
-  for (size_t n = 0; n < input_items.size(); n++) {
-    float* t_in_buf = (float*)(&input_items[n]);
-    void* t_out_buf_0_bit = (void*)(&(output_items[2*n]));
-    void* t_out_buf_1_bit = (void*)(&(output_items[(2*n)+1]));
-
-    d_code_metrics->convert (l_n_output_items, t_in_buf,
-                            t_out_buf_0_bit, t_out_buf_1_bit);
-  }
-
-  // consume the number of used input items on all input streams
-
-  consume_each (noutput_items);
-
-  // returns number of items written to each output stream
-
-  return (noutput_items);
-}

Index: gr_syms_to_metrics.h
===================================================================
RCS file: gr_syms_to_metrics.h
diff -N gr_syms_to_metrics.h
--- gr_syms_to_metrics.h        3 Jul 2006 02:12:53 -0000       1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,121 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_SYMS_TO_METRICS_H
-#define INCLUDED_SYMS_TO_METRICS_H
-
-#include <gr_block.h>
-#include <gr_feval.h>
-#include <vector>
-#include <libecc/code_metrics.h>
-
-class gr_syms_to_metrics;
-typedef boost::shared_ptr<gr_syms_to_metrics> gr_syms_to_metrics_sptr;
-
-gr_syms_to_metrics_sptr gr_make_syms_to_metrics
-(gr_feval_ff* pdf_fcn_0_bit,
- gr_feval_ff* pdf_fcn_1_bit,
- int n_samples,
- float min_sample,
- float max_sample,
- int sample_precision);
-
-/*!
- * \brief Convert the input stream(s) of soft (float) symbols to
- * log-probability metrics of user-specified precision; output is 2
- * streams per input stream, each stream consisting of the metric for
- * receiving a 0-bit and 1-bit, respectively, with the lower-numbered
- * stream being the 0-bit.
- *
- * input: stream(s) of float; output: stream(s) of metrics
- */
-
-class gr_syms_to_metrics : public gr_block
-{
-  friend gr_syms_to_metrics_sptr
-  gr_make_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
-                          gr_feval_ff* pdf_fcn_1_bit,
-                          int n_samples,
-                          float min_sample,
-                          float max_sample,
-                          int sample_precision);
-
-/*
- * gr_syms_to_metrics: Convert the input soft (float) symbols into
- *     log-probabilities (metrics) for use in the convolutional
- *     decoder.  Samples the provided PDF function in 'n_samples'
- *     places from 'min_sample' to 'max_sample', takes the log of that
- *     value, then converts the result into a given precision and
- *     stores all results in a "handy dandy" lookup table for much
- *     faster processing.
- *
- * pdf_fcn_0_bit: point to a probability distribution function which
- *     takes a float and returns a float, for the 0-bit probabilities.
- *
- * pdf_fcn_1_bit: point to a probability distribution function which
- *     takes a float and returns a float, for the 1-bit probabilities.
- *
- * n_samples: the number of samples between min_sample and max_sample
- *     to store in the lookup table.  Must be at least 2, but
- *     otherwise is limited only by the amount of available memory;
- *     generally, 65536 (1 << 16) is plenty of samples.
- *
- * min_sample: the minimum value below which any incoming value is
- *     "rounded" up.
- *
- * max_sample: the maximum value above which any incoming value is
- *     "rounded" down.
- *
- * sample_precision: the precision with which to sample the returned
- *     value of the PDF function.
- *  +  Cannot be < 0 or > 32.
- *  +  "soft float" == 0
- *  + otherwise, convert to an integer of the given value
- *
- * in "work", finds the (linearly) closest sample value for the given
- *     input and outputs the metric for a 0-bit input on the first
- *     stream and a 1-bit input on the second stream.
- *
- */
-
-  gr_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
-                     gr_feval_ff* pdf_fcn_1_bit,
-                     int n_samples,
-                     float min_sample,
-                     float max_sample,
-                     int sample_precision);
-
-  size_t d_out_item_size_bytes;
-  code_metrics* d_code_metrics;
-
-public:
-  bool check_topology (int ninputs, int noutputs);
-
-  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
-
-  int general_work (int noutput_items,
-                   gr_vector_int &ninput_items,
-                   gr_vector_const_void_star &input_items,
-                   gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_SYMS_TO_METRICS_H */

Index: gr_syms_to_metrics.i
===================================================================
RCS file: gr_syms_to_metrics.i
diff -N gr_syms_to_metrics.i
--- gr_syms_to_metrics.i        3 Jul 2006 02:12:53 -0000       1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,41 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-GR_SWIG_BLOCK_MAGIC(gr,syms_to_metrics);
-
-gr_syms_to_metrics_sptr gr_make_syms_to_metrics
-(gr_feval_ff* pdf_fcn_0_bit,
- gr_feval_ff* pdf_fcn_1_bit,
- int n_samples,
- float min_sample, 
- float max_sample,
- int sample_precision);
-
-class gr_syms_to_metrics : public gr_block
-{
-  gr_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
-                     gr_feval_ff* pdf_fcn_1_bit,
-                     int n_samples,
-                     float min_sample, 
-                     float max_sample,
-                     int sample_precision);
-};

Index: libecc/decoder_viterbi_full_block_i1_ic1.cc
===================================================================
RCS file: libecc/decoder_viterbi_full_block_i1_ic1.cc
diff -N libecc/decoder_viterbi_full_block_i1_ic1.cc
--- libecc/decoder_viterbi_full_block_i1_ic1.cc 9 Jul 2006 16:15:17 -0000       
1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,162 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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 "decoder_viterbi_full_block_i1_ic1.h"
-#include <assert.h>
-#include <iostream>
-#include <math.h>
-
-const int g_max_block_size_bits = 10000000;
-const int g_max_num_streams = 10;
-const int g_num_bits_per_byte = 8;
-
-#define DO_TIME_THOUGHPUT 0
-
-#define DO_PRINT_DEBUG_INST 0
-#define DO_PRINT_DEBUG_FSM 0
-#define DO_PRINT_DEBUG_INIT 0
-#define DO_PRINT_DEBUG_UP 0
-#define DO_PRINT_DEBUG_UP_0 0
-#define DO_PRINT_DEBUG_UP_1 0
-#define DO_PRINT_DEBUG_MIDDLE 0
-#define DO_PRINT_DEBUG_MIDDLE_0 0
-#define DO_PRINT_DEBUG_MIDDLE_1 0
-#define DO_PRINT_DEBUG_TERM 0
-#define DO_PRINT_DEBUG_TERM_1 0
-#define DO_PRINT_DEBUG_OUTPUT 0
-#define DO_PRINT_DEBUG_OUTPUT_0 0
-#define DO_PRINT_DEBUG_EXIT 0
-#define DO_PRINT_DEBUG 1
-
-#if DO_TIME_THOUGHPUT
-#include <mld/mld_timer.h>
-#endif
-#if DO_PRINT_DEBUG
-#include <mld/n2bs.h>
-#endif
-
-// FIXME
-
-size_t
-decoder_viterbi_full_block_i1_ic1::compute_n_output_bits
-(size_t n_input_items)
-{
-  assert (0);
-  return (0);
-}
-
-/*
- * Compute the number of input items (metrics) needed to produce
- * 'noutput' bits.  For convolutional decoders, there is 1
- * bit output per metric input per stream, with the addition of a some
- * metrics for trellis termination if selected.  Without termination,
- * there is exactly 1:1 input to output (1 metric in to 1 bit out),
- * no matter the encoding type.
- *
- * if (not terminating), then get the number of output bits.
- *
- * otherwise, find the number of blocks (not necessarily an integer),
- * and then compute the number of input metrics (including termination)
- * required to produce those blocks.  Subtract the number of bits
- * leftover from the previous computation, then find the number of input
- * metrics, ceil'd to make sure there are enough.
- */
-
-size_t
-decoder_viterbi_full_block_i1_ic1::compute_n_input_metrics
-(size_t n_output_bits)
-{
-  int t_ninput_items = 0;
-  int t_noutput_bits = ((int) n_output_bits) - ((int) d_n_saved_bits);
-
-  // if there are enough saved bits, just use those, no inputs required
-
-  if (t_noutput_bits <= 0)
-    return (0);
-
-  // remove any bits already in the decoding trellis
-
-  if (d_time_count != 0) {
-    int t_time_bits = ((d_time_count > d_block_size_bits) ? 0 :
-                      d_block_size_bits - d_time_count);
-    t_noutput_bits -= t_time_bits;
-    t_ninput_items += t_time_bits;
-  }
-  // if completing this trellis doesn't create enough outputs ...
-
-  if (t_noutput_bits > 0) {
-
-    // there is a 1:1 ratio between input symbols and output bits (per
-    // stream), except for termination bits which are already taken
-    // into account in the total # of input bits per stream class
-    // variable; need to round the # output bits to the
-
-    // find the number of blocks, ceil'd to the next higher integer
-
-    int t_nblocks = (int) ceilf (((float) t_noutput_bits) /
-                                ((float) d_block_size_bits));
-
-    // find the number of required input bits
-
-    t_ninput_items += t_nblocks * d_n_total_inputs_per_stream;
-  }
-
-  return (t_ninput_items);
-}
-
-// FIXME, from here down dummies to get correct compiling; for testing
-// purposes only.
-
-void
-decoder_viterbi_full_block_i1_ic1::increment_input_indices
-(bool while_decoding)
-{
-  if (while_decoding)
-    std::cout << "foo!";
-
-#if 0
-// increment the in_buf index, depending on mux'ing or not
-  t_in_buf_ndx += (d_do_mux_inputs == false) ? 1 : d_n_code_outputs;
-#endif
-}
-
-void
-decoder_viterbi_full_block_i1_ic1::increment_output_indices
-(bool while_decoding)
-{
-  if (while_decoding)
-    std::cout << "bar!";
-}
-
-void
-decoder_viterbi_full_block_i1_ic1::output_bit
-(char t_out_bit,
- char** out_buf,
- size_t t_output_stream)
-{
-  if (t_out_bit)
-    std::cout << "mop!";
-}

Index: libecc/decoder_viterbi_full_block_i1_ic1.h
===================================================================
RCS file: libecc/decoder_viterbi_full_block_i1_ic1.h
diff -N libecc/decoder_viterbi_full_block_i1_ic1.h
--- libecc/decoder_viterbi_full_block_i1_ic1.h  9 Jul 2006 16:15:17 -0000       
1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,66 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_DECODER_VITERBI_FULL_BLOCK_IC1_H
-#define INCLUDED_DECODER_VITERBI_FULL_BLOCK_IC1_H
-
-#include "decoder_viterbi_full_block.h"
-
-class decoder_viterbi_full_block_i1_ic1 : public decoder_viterbi_full_block
-{
-/*!
- * class decoder_viterbi_full_block_i1_ic1 :
- *     public decoder_viterbi_full_block
- *
- * Decode the incoming metrics using a Viterbi-style decoder, doing
- *     full trellis block decoding before putting out any bits
- *
- * input is "i1": one stream per input (as defined by the
- *     code-output), with one metric per input item.
- *
- * output is "ic1": streams of char, one stream per output (as defined
- *     by the code-input), using only the right-most justified (LSB?)
- *     bit as the single output bit per output item.
- *
- * The rest of the options are outlined in the inherited classes'
- *     header files.
- */
-
-public:
-  inline decoder_viterbi_full_block_i1_ic1
-  (int sample_precision,
-   encoder_convolutional* l_encoder)
-    : decoder_viterbi_full_block (sample_precision, l_encoder) {};
-
-  virtual ~decoder_viterbi_full_block_i1_ic1 () {};
-
-  virtual size_t compute_n_input_metrics (size_t n_output_bits);
-  virtual size_t compute_n_output_bits (size_t n_input_metrics);
-
-protected:
-  virtual void increment_input_indices (bool while_decoding);
-  virtual void output_bit (char t_out_bit, char** out_buf,
-                          size_t t_output_stream);
-  virtual void increment_output_indices (bool while_decoding);
-};
-
-#endif /* INCLUDED_DECODER_VITERBI_FULL_BLOCK_I1_IC1_H */

Index: libecc/encoder_convolutional_ic1_ic1.cc
===================================================================
RCS file: libecc/encoder_convolutional_ic1_ic1.cc
diff -N libecc/encoder_convolutional_ic1_ic1.cc
--- libecc/encoder_convolutional_ic1_ic1.cc     20 Jul 2006 17:42:54 -0000      
1.7
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,188 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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.h>
-#include <assert.h>
-#include <iostream>
-#include <mld/n2bs.h>
-
-#define DO_PRINT_DEBUG 0
-
-static const int g_num_bits_per_byte = 8;
-
-// FIXME
-size_t
-encoder_convolutional_ic1_ic1::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::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_total_n_delays - 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 blocks of data which could be processed
-
-    size_t t_n_output_bits_per_block = d_block_size_bits + d_total_n_delays;
-
-    // get the base number of input items required for the given
-    // number of blocks to be generated
-
-    size_t t_n_blocks = t_n_output_bits / t_n_output_bits_per_block;
-    t_n_input_bits = t_n_blocks * d_block_size_bits;
-
-    // add to that the number of leftover inputs needed to generate
-    // the remainder of the outputs within the remaining block, up to
-    // the given block size (since anything beyond that within this
-    // block requires no inputs)
-
-    size_t t_leftover_bits = t_n_output_bits % t_n_output_bits_per_block;
-    t_n_input_bits += ((t_leftover_bits > d_block_size_bits) ?
-                      d_block_size_bits : t_leftover_bits);
-  }
-
-  return (t_n_input_bits);
-}
-
-void
-encoder_convolutional_ic1_ic1::write_output_bits
-(char** out_buf)
-{
-  // write all the outputs bits in d_current_outputs LSB (&1) to the
-  // given output buffer.
-
-  // 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[" << 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], 1) << ", ";
-    }
-
-    out_buf[n][d_out_buf_ndx] = d_current_outputs[n];
-
-    if (DO_PRINT_DEBUG) {
-      std::cout << "O_o[][] = " <<
-       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++;
-}
-
-void
-encoder_convolutional_ic1_ic1::get_next_inputs__input
-(const char** in_buf)
-{
-  // 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[" << m << "][" << d_in_buf_ndx << "] = " <<
-       n2bs (d_current_inputs[m], 1) << "\n";
-    }
-  }
-
-  // decrement the number of bits left on all streams
-
-  if (DO_PRINT_DEBUG) {
-    std::cout << "# in bits left: " << d_n_input_bits_left <<
-      " -> " << (d_n_input_bits_left-1) << "\n";
-  }
-
-  d_n_input_bits_left--;
-
-  // increment the input index (not the bit shift index) for the next
-  // read
-
-  if (DO_PRINT_DEBUG) {
-    std::cout << "# in buf ndx: " << d_in_buf_ndx <<
-      " -> " << (d_in_buf_ndx+1) << "\n";
-  }
-
-  d_in_buf_ndx++;
-}

Index: libecc/encoder_convolutional_ic1_ic1.h
===================================================================
RCS file: libecc/encoder_convolutional_ic1_ic1.h
diff -N libecc/encoder_convolutional_ic1_ic1.h
--- libecc/encoder_convolutional_ic1_ic1.h      15 Jul 2006 23:48:15 -0000      
1.6
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,91 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_H
-#define INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_H
-
-#include "encoder_convolutional.h"
-
-class encoder_convolutional_ic1_ic1 : public encoder_convolutional
-{
-public:
-/*!
- * class encoder_convolutional_ic1_ic1 : public encoder_convolutional
- *
- * Encode the incoming streams using a convolutional encoder,
- *     "feedforward" or feedback.  Optional termination, data
- *     streaming, and starting and ending memory states.
- *
- * 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.
- */
-
-  encoder_convolutional_ic1_ic1
-  (int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generators,
-   bool do_termination = true,
-   int start_memory_state = 0,
-   int end_memory_state = 0)
-    : encoder_convolutional (frame_size_bits,
-                            n_code_inputs,
-                            n_code_outputs,
-                            code_generators,
-                            do_termination,
-                            start_memory_state,
-                            end_memory_state) {};
-
-  encoder_convolutional_ic1_ic1
-  (int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generators,
-   const std::vector<int> &code_feedback,
-   bool do_termination = true,
-   int start_memory_state = 0,
-   int end_memory_state = 0)
-    : encoder_convolutional (frame_size_bits,
-                            n_code_inputs,
-                            n_code_outputs,
-                            code_generators,
-                            code_feedback,
-                            do_termination,
-                            start_memory_state,
-                            end_memory_state) {};
-
-  virtual ~encoder_convolutional_ic1_ic1 () {};
-
-  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 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: libecc/encoder_convolutional_ic8_ic8.cc
===================================================================
RCS file: libecc/encoder_convolutional_ic8_ic8.cc
diff -N libecc/encoder_convolutional_ic8_ic8.cc
--- libecc/encoder_convolutional_ic8_ic8.cc     5 Jul 2006 20:57:44 -0000       
1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,224 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_ic8_ic8.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
-
-// FIXME: when 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
-
-// FIXME
-size_t
-encoder_convolutional_ic8_ic8::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_ic8_ic8::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_ic8_ic8::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++;
-    d_in_buf_ndx++;
-  }
-
-  // nothing to do while encoding, so no else
-
-#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_ic8_ic8::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 "ic8" type output
-
-  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);
-  }
-
-  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';
-  }
-
-#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_ic8_ic8::get_next_bit__input
-(const char** in_buf,
- size_t code_input_n)
-{
-  // get a bit from this particular input stream
-  // one bit per output item for "ic8" type input
-
-  if (DO_PRINT_DEBUG) {
-    std::cout << "I[" << p << "][" << d_in_buf_ndx << "] = ";
-    cout_binary (t_next_bit, g_num_bits_per_byte);
-    std::cout << ", st_i[" << p << "] = ";
-    cout_binary ((*t_states_ptr), d_max_memory+2);
-    std::cout << ", I[" << p << "][" << d_in_buf_ndx << "][" <<
-      d_in_bit_shift << "] = " << t_next_bit <<
-      ", st_o[" << p << "] = ";
-    cout_binary (t_state, d_max_memory+2);
-    std::cout << '\n';
-  }
-
-   return ((in_buf[code_input_n][d_in_buf_ndx] >> d_in_bit_shift) & 1);
-}
-
-char
-encoder_convolutional_ic8_ic8::get_next_bit__term
-(size_t code_input_n)
-{
-  return ((d_term_states[code_input_n] >> d_in_bit_shift) & 1);
-}

Index: libecc/encoder_convolutional_ic8_ic8.h
===================================================================
RCS file: libecc/encoder_convolutional_ic8_ic8.h
diff -N libecc/encoder_convolutional_ic8_ic8.h
--- libecc/encoder_convolutional_ic8_ic8.h      15 Jul 2006 23:48:15 -0000      
1.3
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,96 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio 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.
- * 
- * GNU Radio 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 GNU Radio; 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_IC8_IC8_H
-#define INCLUDED_ENCODER_CONVOLUTIONAL_IC8_IC8_H
-
-#include "encoder_convolutional.h"
-
-/*!
- * class encoder_convolutional_ic8_ic8 : public encoder_convolutional
- *
- * Encode the incoming streams using a convolutional encoder,
- *     "feedforward" or feedback.  Optional termination, data
- *     streaming, and starting and ending memory states.
- *
- * input is "ic8": streams of char, one stream per input as defined by the
- *     instantiated code, using all 8 bits in the char.
- *
- * FIXME: need to have inputs for MSB or LSB first input and output.
- *
- * output is "ic8": streams of char, one stream per output as defined by the
- *     instantiated code, using all 8 bits in the char.
- */
-
-class encoder_convolutional_ic8_ic8 : public encoder_convolutional
-{
-public:
-  encoder_convolutional_ic8_ic8
-  (int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generators,
-   bool do_termination = true,
-   int start_memory_state = 0,
-   int end_memory_state = 0)
-    : encoder_convolutional (frame_size_bits,
-                            n_code_inputs,
-                            n_code_outputs,
-                            code_generators,
-                            do_termination,
-                            start_memory_state,
-                            end_memory_state) {};
-
-  encoder_convolutional_ic8_ic8
-  (int frame_size_bits,
-   int n_code_inputs,
-   int n_code_outputs,
-   const std::vector<int> &code_generators,
-   const std::vector<int> &code_feedback,
-   bool do_termination = true,
-   int start_memory_state = 0,
-   int end_memory_state = 0)
-    : encoder_convolutional (frame_size_bits,
-                            n_code_inputs,
-                            n_code_outputs,
-                            code_generators,
-                            code_feedback,
-                            do_termination,
-                            start_memory_state,
-                            end_memory_state) {};
-
-  virtual ~encoder_convolutional_ic8_ic8 () {};
-
-  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_IC8_IC8_H */




reply via email to

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