From c7dbfcc7d78275f76d8c2a8ef21e3100721874be Mon Sep 17 00:00:00 2001
From: trondeau <trondeau@221aa14e-8319-0410-a670-987f0aec2ac5>
Date: Mon, 4 Jun 2007 16:08:44 +0000
Subject: merge ordm/receiver branch -r5574:5659. Reworks OFDM receiver with
 refactored OFDM blocks. A few bug fixes for other blocks have also been
 slipped in.

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5661 221aa14e-8319-0410-a670-987f0aec2ac5
---
 gnuradio-core/src/lib/general/Makefile.am          |  13 +-
 gnuradio-core/src/lib/general/general.i            |   6 +-
 gnuradio-core/src/lib/general/gr_conjugate_cc.cc   |  27 ++-
 gnuradio-core/src/lib/general/gr_delay.cc          |   2 +-
 gnuradio-core/src/lib/general/gr_dpll_bb.cc        |  84 ++++++++
 gnuradio-core/src/lib/general/gr_dpll_bb.h         |  57 +++++
 gnuradio-core/src/lib/general/gr_dpll_bb.i         |  31 +++
 gnuradio-core/src/lib/general/gr_dpll_ff.cc        |  86 --------
 gnuradio-core/src/lib/general/gr_dpll_ff.h         |  59 ------
 gnuradio-core/src/lib/general/gr_dpll_ff.i         |  33 ---
 .../src/lib/general/gr_ofdm_bpsk_mapper.cc         | 168 ++++++++-------
 .../src/lib/general/gr_ofdm_bpsk_mapper.h          |  49 +++--
 .../src/lib/general/gr_ofdm_bpsk_mapper.i          |  29 +--
 .../src/lib/general/gr_ofdm_correlator.cc          |  54 +++--
 gnuradio-core/src/lib/general/gr_ofdm_correlator.h |  34 +--
 gnuradio-core/src/lib/general/gr_ofdm_correlator.i |  16 +-
 .../src/lib/general/gr_ofdm_frame_sink.cc          | 235 +++++++++++++++++++++
 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h | 105 +++++++++
 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i |  35 +++
 gnuradio-core/src/lib/general/gr_ofdm_sampler.cc   |   6 +-
 gnuradio-core/src/lib/general/gr_skiphead.cc       |  76 ++++---
 gnuradio-core/src/lib/general/gr_skiphead.h        |  26 ++-
 gnuradio-core/src/lib/general/gr_skiphead.i        |  14 +-
 gnuradio-core/src/lib/general/gr_stream_mux.cc     | 158 ++++----------
 gnuradio-core/src/lib/general/gr_stream_mux.h      |  16 +-
 25 files changed, 888 insertions(+), 531 deletions(-)
 create mode 100644 gnuradio-core/src/lib/general/gr_dpll_bb.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_dpll_bb.h
 create mode 100644 gnuradio-core/src/lib/general/gr_dpll_bb.i
 delete mode 100644 gnuradio-core/src/lib/general/gr_dpll_ff.cc
 delete mode 100644 gnuradio-core/src/lib/general/gr_dpll_ff.h
 delete mode 100644 gnuradio-core/src/lib/general/gr_dpll_ff.i
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i

(limited to 'gnuradio-core/src/lib/general')

diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am
index c76130039b..d774baa1c5 100644
--- a/gnuradio-core/src/lib/general/Makefile.am
+++ b/gnuradio-core/src/lib/general/Makefile.am
@@ -63,7 +63,7 @@ libgeneral_la_SOURCES = 		\
 	gr_diff_decoder_bb.cc		\
 	gr_diff_encoder_bb.cc		\
 	gr_diff_phasor_cc.cc		\
-	gr_dpll_ff.cc			\
+	gr_dpll_bb.cc			\
 	gr_fake_channel_coder_pp.cc	\
 	gr_fast_atan2f.cc		\
 	gr_feedforward_agc_cc.cc	\
@@ -102,6 +102,7 @@ libgeneral_la_SOURCES = 		\
         gr_ofdm_mapper_bcv.cc           \
         gr_ofdm_bpsk_demapper.cc        \
         gr_ofdm_bpsk_mapper.cc          \
+	gr_ofdm_frame_sink.cc		\
         gr_ofdm_sampler.cc              \
 	gr_pa_2x2_phase_combiner.cc	\
 	gr_packet_sink.cc		\
@@ -197,7 +198,7 @@ grinclude_HEADERS = 			\
 	gr_deinterleave.h		\
 	gr_delay.h			\
 	gr_diff_phasor_cc.h		\
-	gr_dpll_ff.h			\
+	gr_dpll_bb.h			\
 	gr_expj.h			\
 	gr_fake_channel_coder_pp.h	\
 	gr_feedforward_agc_cc.h		\
@@ -240,7 +241,8 @@ grinclude_HEADERS = 			\
         gr_ofdm_mapper_bcv.h            \
         gr_ofdm_bpsk_mapper.h           \
         gr_ofdm_bpsk_demapper.h         \
-        gr_ofdm_sampler.h               \
+        gr_ofdm_frame_sink.h		\
+	gr_ofdm_sampler.h               \
 	gr_pa_2x2_phase_combiner.h	\
 	gr_packet_sink.h		\
 	gr_phase_modulator_fc.h		\
@@ -342,7 +344,7 @@ swiginclude_HEADERS =			\
 	gr_diff_decoder_bb.i		\
 	gr_diff_encoder_bb.i		\
 	gr_diff_phasor_cc.i		\
-	gr_dpll_ff.i			\
+	gr_dpll_bb.i			\
 	gr_deinterleave.i		\
 	gr_delay.i			\
 	gr_fake_channel_coder_pp.i	\
@@ -379,7 +381,8 @@ swiginclude_HEADERS =			\
         gr_ofdm_mapper_bcv.i            \
         gr_ofdm_bpsk_demapper.i         \
         gr_ofdm_bpsk_mapper.i           \
-        gr_ofdm_sampler.i               \
+        gr_ofdm_frame_sink.i		\
+	gr_ofdm_sampler.i               \
 	gr_pa_2x2_phase_combiner.i	\
 	gr_packet_sink.i		\
 	gr_phase_modulator_fc.i		\
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index 64144a05af..1fdb4239a6 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -84,7 +84,7 @@
 #include <gr_packet_sink.h>
 #include <gr_lms_dfe_cc.h>
 #include <gr_lms_dfe_ff.h>
-#include <gr_dpll_ff.h>
+#include <gr_dpll_bb.h>
 #include <gr_pll_freqdet_cf.h>
 #include <gr_pll_refout_cc.h>
 #include <gr_pll_carriertracking_cc.h>
@@ -97,6 +97,7 @@
 #include <gr_ofdm_cyclic_prefixer.h>
 #include <gr_ofdm_bpsk_demapper.h>
 #include <gr_ofdm_bpsk_mapper.h>
+#include <gr_ofdm_frame_sink.h>
 #include <gr_ofdm_sampler.h>
 #include <gr_costas_loop_cc.h>
 #include <gr_pa_2x2_phase_combiner.h>
@@ -186,7 +187,7 @@
 %include "gr_packet_sink.i"
 %include "gr_lms_dfe_cc.i"
 %include "gr_lms_dfe_ff.i"
-%include "gr_dpll_ff.i"
+%include "gr_dpll_bb.i"
 %include "gr_pll_freqdet_cf.i"
 %include "gr_pll_refout_cc.i"
 %include "gr_pll_carriertracking_cc.i"
@@ -199,6 +200,7 @@
 %include "gr_ofdm_cyclic_prefixer.i"
 %include "gr_ofdm_bpsk_demapper.i"
 %include "gr_ofdm_bpsk_mapper.i"
+%include "gr_ofdm_frame_sink.i"
 %include "gr_ofdm_sampler.i"
 %include "gr_costas_loop_cc.i"
 %include "gr_pa_2x2_phase_combiner.i"
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
index 0a5b3790ee..453c6d338a 100644
--- a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
@@ -53,19 +53,24 @@ gr_conjugate_cc::work (int noutput_items,
   int	size = noutput_items;
 
   while (size >= 8){
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    optr[0] = conj(iptr[0]);
+    optr[1] = conj(iptr[1]);
+    optr[2] = conj(iptr[2]);
+    optr[3] = conj(iptr[3]);
+    optr[4] = conj(iptr[4]);
+    optr[5] = conj(iptr[5]);
+    optr[6] = conj(iptr[6]);
+    optr[7] = conj(iptr[7]);
     size -= 8;
+    optr += 8;
+    iptr += 8;
+  }
+
+  while (size-- > 0) {
+    *optr = conj(*iptr);
+    iptr++;
+    optr++;
   }
 
-  while (size-- > 0)
-    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-  
   return noutput_items;
 }
diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc
index 12c50e4b6c..89ab3ce0e0 100644
--- a/gnuradio-core/src/lib/general/gr_delay.cc
+++ b/gnuradio-core/src/lib/general/gr_delay.cc
@@ -56,7 +56,7 @@ gr_delay::work (int noutput_items,
     iptr = (const char *) input_items[i];
     optr = (char *) output_items[i];
 
-    memcpy(optr, iptr + delay()*d_itemsize, noutput_items*d_itemsize);
+    memcpy(optr, iptr, noutput_items*d_itemsize);
   }
   
   return noutput_items;
diff --git a/gnuradio-core/src/lib/general/gr_dpll_bb.cc b/gnuradio-core/src/lib/general/gr_dpll_bb.cc
new file mode 100644
index 0000000000..d5b7265281
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dpll_bb.h>
+#include <gr_io_signature.h>
+
+gr_dpll_bb_sptr
+gr_make_dpll_bb (float period, float gain)
+{
+  return gr_dpll_bb_sptr (new gr_dpll_bb (period, gain));
+}
+
+gr_dpll_bb::gr_dpll_bb (float period, float gain)
+  : gr_sync_block ("dpll_bb",
+		   gr_make_io_signature (1, 1, sizeof (char)),
+		   gr_make_io_signature (1, 1, sizeof (char))),
+    d_restart(0),d_pulse_phase(0)
+{
+  d_pulse_frequency = 1.0/period;
+  d_gain = gain;
+  d_decision_threshold = 1.0 - 0.5*d_pulse_frequency;
+#if 1
+  fprintf(stderr,"frequency = %f period = %f gain = %f threshold = %f\n",
+	  d_pulse_frequency,
+	  period,
+	  d_gain,
+	  d_decision_threshold);
+#endif
+  set_history(1); // so we can look behind us
+}
+
+int
+gr_dpll_bb::work (int noutput_items,
+	      gr_vector_const_void_star &input_items,
+	      gr_vector_void_star &output_items)
+{
+  const char *iptr = (const char *) input_items[0];
+  char *optr = (char *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    optr[i]= 0;
+    if(iptr[i] == 1) {
+      if (d_restart == 0) {
+	d_pulse_phase = 1;
+      } else {
+	if (d_pulse_phase > 0.5) d_pulse_phase += d_gain*(1.0-d_pulse_phase);
+	else d_pulse_phase -= d_gain*d_pulse_phase;
+      }
+      d_restart = 3;
+    }
+    if (d_pulse_phase > d_decision_threshold) {
+      d_pulse_phase -= 1.0;
+      if (d_restart > 0) {
+	d_restart -= 1;
+	optr[i] = 1;
+      }
+    }
+    d_pulse_phase += d_pulse_frequency;
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_dpll_bb.h b/gnuradio-core/src/lib/general/gr_dpll_bb.h
new file mode 100644
index 0000000000..c80612bc5e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DPLL_BB_H
+#define INCLUDED_GR_DPLL_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_dpll_bb;
+typedef boost::shared_ptr<gr_dpll_bb> gr_dpll_bb_sptr;
+
+gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
+
+/*!
+ * \brief Detect the peak of a signal
+ * \ingroup block
+ *
+ * If a peak is detected, this block outputs a 1, 
+ * or it outputs 0's.
+ */
+class gr_dpll_bb : public gr_sync_block
+{
+  friend gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
+
+  gr_dpll_bb (float period, float gain);
+
+ private:
+  unsigned char d_restart;
+  float d_pulse_phase, d_pulse_frequency,d_gain,d_decision_threshold;
+
+ public:
+
+  int work (int noutput_items,
+	    gr_vector_const_void_star &input_items,
+	    gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_dpll_bb.i b/gnuradio-core/src/lib/general/gr_dpll_bb.i
new file mode 100644
index 0000000000..ae95e2dfbb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dpll_bb)
+
+  gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
+
+class gr_dpll_bb : public gr_sync_block
+{
+ private:
+  gr_dpll_bb (float period, float gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.cc b/gnuradio-core/src/lib/general/gr_dpll_ff.cc
deleted file mode 100644
index ae868fce5d..0000000000
--- a/gnuradio-core/src/lib/general/gr_dpll_ff.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// WARNING: this file is machine generated.  Edits will be over written
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_dpll_ff.h>
-#include <gr_io_signature.h>
-
-gr_dpll_ff_sptr
-gr_make_dpll_ff (float period, float gain)
-{
-  return gr_dpll_ff_sptr (new gr_dpll_ff (period, gain));
-}
-
-gr_dpll_ff::gr_dpll_ff (float period, float gain)
-  : gr_sync_block ("dpll_ff",
-		   gr_make_io_signature (1, 1, sizeof (float)),
-		   gr_make_io_signature (1, 1, sizeof (float))),
-    d_restart(0),d_pulse_phase(0)
-{
-  d_pulse_frequency = 1.0/period;
-  d_gain = gain;
-  d_decision_threshold = 1.0 - 0.5*d_pulse_frequency;
-#if 1
-  fprintf(stderr,"frequency = %f period = %f gain = %f threshold = %f\n",
-	  d_pulse_frequency,
-	  period,
-	  d_gain,
-	  d_decision_threshold);
-#endif
-  set_history(1); // so we can look behind us
-}
-
-int
-gr_dpll_ff::work (int noutput_items,
-	      gr_vector_const_void_star &input_items,
-	      gr_vector_void_star &output_items)
-{
-  float *iptr = (float *) input_items[0];
-  float *optr = (float *) output_items[0];
-
-  for (int i = 0; i < noutput_items; i++){
-    optr[i]= (float)0;
-    if(iptr[i] ==(float)1) {
-      if (d_restart == 0) {
-	d_pulse_phase = 1;
-      } else {
-	if (d_pulse_phase > 0.5) d_pulse_phase += d_gain*(1.0-d_pulse_phase);
-	else d_pulse_phase -= d_gain*d_pulse_phase;
-      }
-      d_restart = 3;
-    }
-    if (d_pulse_phase > d_decision_threshold) {
-      d_pulse_phase -= 1.0;
-      if (d_restart > 0) {
-	d_restart -= 1;
-	optr[i] = (float)1;
-      }
-    }
-    d_pulse_phase += d_pulse_frequency;
-  }
-  return noutput_items;
-}
diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.h b/gnuradio-core/src/lib/general/gr_dpll_ff.h
deleted file mode 100644
index 1de1efa855..0000000000
--- a/gnuradio-core/src/lib/general/gr_dpll_ff.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// WARNING: this file is machine generated.  Edits will be over written
-
-#ifndef INCLUDED_GR_DPLL_FF_H
-#define INCLUDED_GR_DPLL_FF_H
-
-#include <gr_sync_block.h>
-
-class gr_dpll_ff;
-typedef boost::shared_ptr<gr_dpll_ff> gr_dpll_ff_sptr;
-
-gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain);
-
-/*!
- * \brief Detect the peak of a signal
- * \ingroup block
- *
- * If a peak is detected, this block outputs a 1, 
- * or it outputs 0's.
- */
-class gr_dpll_ff : public gr_sync_block
-{
-  friend gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain);
-
-  gr_dpll_ff (float period, float gain);
-
- private:
-  unsigned char d_restart;
-  float d_pulse_phase, d_pulse_frequency,d_gain,d_decision_threshold;
-
- public:
-
-  int work (int noutput_items,
-	    gr_vector_const_void_star &input_items,
-	    gr_vector_void_star &output_items);
-};
-
-#endif
diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.i b/gnuradio-core/src/lib/general/gr_dpll_ff.i
deleted file mode 100644
index 9606fba521..0000000000
--- a/gnuradio-core/src/lib/general/gr_dpll_ff.i
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// WARNING: this file is machine generated.  Edits will be over written
-
-GR_SWIG_BLOCK_MAGIC(gr,dpll_ff)
-
-  gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain);
-
-class gr_dpll_ff : public gr_sync_block
-{
- private:
-  gr_dpll_ff (float period, float gain);
-};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
index df4632398d..f0b52c3255 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -29,30 +29,32 @@
 #include <vector>
 
 gr_ofdm_bpsk_mapper_sptr
-gr_make_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen,
-			  std::vector<gr_complex> known_symbol1, std::vector<gr_complex> known_symbol2)
+gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit, 
+			  unsigned int occupied_carriers, unsigned int fft_length,
+			  const std::vector<gr_complex> &known_symbol1, 
+			  const std::vector<gr_complex> &known_symbol2)
 {
-  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (mtu, occupied_carriers, vlen, 
+  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length, 
 							    known_symbol1, known_symbol2));
 }
 
-gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen,
-					  std::vector<gr_complex> known_symbol1, 
-					  std::vector<gr_complex> known_symbol2)
-  : gr_block ("ofdm_bpsk_mapper",
-	      gr_make_io_signature (1, 1, 2*sizeof(int) + sizeof(unsigned char)*mtu),
-	      gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen)),
-    d_mtu(mtu),
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
+gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit, 
+					  unsigned int occupied_carriers, unsigned int fft_length,
+					  const std::vector<gr_complex> &known_symbol1, 
+					  const std::vector<gr_complex> &known_symbol2)
+  : gr_sync_block ("ofdm_bpsk_mapper",
+		   gr_make_io_signature (0, 0, 0),
+		   gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
+    d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
     d_occupied_carriers(occupied_carriers),
-    d_vlen(vlen),
-    d_packet_offset(0),
+    d_fft_length(fft_length),
     d_bit_offset(0),
     d_header_sent(0),
     d_known_symbol1(known_symbol1),
     d_known_symbol2(known_symbol2)
-
 {
-  assert(d_occupied_carriers < d_vlen);
+  assert(d_occupied_carriers <= d_fft_length);
   assert(d_occupied_carriers == d_known_symbol1.size());
   assert(d_occupied_carriers == d_known_symbol2.size());
 }
@@ -61,99 +63,101 @@ gr_ofdm_bpsk_mapper::~gr_ofdm_bpsk_mapper(void)
 {
 }
 
-void
-gr_ofdm_bpsk_mapper::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+float randombit()
 {
-  unsigned ninputs = ninput_items_required.size ();
-  for (unsigned i = 0; i < ninputs; i++)
-    ninput_items_required[i] = 1;
+  int r = rand()&1;
+  return (float)(-1 + 2*r);
 }
 
 int
-gr_ofdm_bpsk_mapper::general_work(int noutput_items,
-				  gr_vector_int &ninput_items,
-				  gr_vector_const_void_star &input_items,
-				  gr_vector_void_star &output_items)
+gr_ofdm_bpsk_mapper::work(int noutput_items,
+			  gr_vector_const_void_star &input_items,
+			  gr_vector_void_star &output_items)
 {
-  const gr_frame *in = (const gr_frame *) input_items[0];
   gr_complex *out = (gr_complex *)output_items[0];
   
   unsigned int i=0;
-  unsigned int num_symbols = 0, pkt_length;
+  unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
 
   //printf("OFDM BPSK Mapper:  ninput_items: %d   noutput_items: %d\n", ninput_items[0], noutput_items);
 
-  pkt_length = in[0].length;
-
-  std::vector<gr_complex>::iterator ks_itr;
-  if(d_header_sent == 0) {
-     ks_itr = d_known_symbol1.begin();
-  }
-  else if(d_header_sent == 1) {
-    ks_itr = d_known_symbol2.begin();
+  if(d_eof) {
+    return -1;
   }
   
-  if(d_header_sent < 2) {
-    //  Add training symbols here
-    for(i=0; i < (ceil((d_vlen - d_occupied_carriers)/2.0)); i++) {
-      out[i] = gr_complex(0,0);
+  if(!d_msg) {
+    d_msg = d_msgq->delete_head();	   // block, waiting for a message
+    d_msg_offset = 0;
+    d_bit_offset = 0;
+    d_header_sent = 0;
+    
+    if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+      d_msg.reset();
+      return -1;
     }
-    for(;i<d_vlen - ceil((d_vlen-d_occupied_carriers)/2.0);i++) {
-      //out[i] = gr_complex(1,0);
-      out[i] = *(ks_itr++);
+  }
+
+  if(output_items.size() == 2) {
+    char *sig = (char *)output_items[1];
+    if(d_header_sent == 1) {
+      sig[0] = 1;
     }
-    for(; i < d_vlen; i++) {
-      out[i] = gr_complex(0,0);
+    else {
+      sig[0] = 0;
     }
-
-    num_symbols = 1;
-    out += d_vlen;
-    d_header_sent++;
   }
   
-  unsigned int unoccupied_carriers = d_vlen - d_occupied_carriers;
-  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
-  unsigned int zeros_on_right = unoccupied_carriers - zeros_on_left;
+  // Build a single symbol:
 
-  while(num_symbols < (unsigned)noutput_items) {
+  // Initialize all bins to 0 to set unused carriers
+  memset(out, 0, d_fft_length*sizeof(gr_complex));
+  
+  if(d_header_sent == 0) {
+     for(i=0; i < d_occupied_carriers; i++) {
+       out[i+zeros_on_left] = d_known_symbol1[i];
+     }
+    d_header_sent++;
 
-    // stick in unused carriers
-    for(i = d_vlen-zeros_on_right; i < d_vlen; i++) {
-      out[i] = gr_complex(0,0);
+    return 1;
+  }
+  
+  if(d_header_sent == 1) {
+    for(i=0; i < d_occupied_carriers; i++) {
+      out[i+zeros_on_left] = d_known_symbol2[i];
     }
+    d_header_sent++;
 
-    for(i=0; i < zeros_on_left; i++) {
-      out[i] = gr_complex(0,0);
-    }
+    return 1;
+  }
 
-    while((d_packet_offset < pkt_length) && (i < d_vlen-zeros_on_right)) {
-      unsigned char bit = (in[0].data[d_packet_offset] >> (d_bit_offset++)) & 0x01;
-      out[i++] = gr_complex(-1+2*(bit));
-      if(d_bit_offset == 8) {
-	d_bit_offset = 0;
-	d_packet_offset++;
-      }
+  i = 0;
+  while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+    unsigned char bit = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    out[i + zeros_on_left] = gr_complex(-1+2*(bit));
+    i++;
+    d_bit_offset++;
+    if(d_bit_offset == 8) {
+      d_bit_offset = 0;
+      d_msg_offset++;
     }
+  }
 
-    // Ran out of data to put in symbols
-    if(d_packet_offset == pkt_length) {
-      while(i < d_vlen-zeros_on_right) {
-	out[i++] = gr_complex(0,0);
-      }
-
-      d_packet_offset = 0;
-      assert(d_bit_offset == 0);
-      num_symbols++;
-      d_header_sent = 0;
-      consume_each(1);
-      return num_symbols;
+  // Ran out of data to put in symbol
+  if (d_msg_offset == d_msg->length()) {
+    while(i < d_occupied_carriers) {   // finish filling out the symbol
+      out[i + zeros_on_left] = gr_complex(randombit(),0);
+      i++;
     }
-    
-    // Ran out of space in symbol
-    out += d_vlen;
-    num_symbols++;
+
+    if (d_msg->type() == 1)	           // type == 1 sets EOF
+      d_eof = true;
+    d_msg.reset();   // finished packet, free message
+ 
+    assert(d_bit_offset == 0);
+    return 1;          // produced one symbol
   }
-  consume_each(0);
-  return num_symbols;
+  
+  return 1;  // produced symbol
 }
 
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
index 1ae6c75d82..41b2f5bede 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
@@ -24,17 +24,19 @@
 #define INCLUDED_GR_OFDM_BPSK_MAPPER_H
 
 
-#include <gr_block.h>
-#include <gr_frame.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
 #include <vector>
 
 class gr_ofdm_bpsk_mapper;
 typedef boost::shared_ptr<gr_ofdm_bpsk_mapper> gr_ofdm_bpsk_mapper_sptr;
 
 gr_ofdm_bpsk_mapper_sptr 
-gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen,
-			  std::vector<gr_complex> known_symbol1, 
-			  std::vector<gr_complex> known_symbol2);
+gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, 
+			  unsigned occupied_carriers, unsigned int fft_length,
+			  const std::vector<gr_complex> &known_symbol1, 
+			  const std::vector<gr_complex> &known_symbol2);
 
 /*!
  * \brief take a stream of bytes in and map to a vector of complex
@@ -42,35 +44,40 @@ gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int
  * modulator.  Simple BPSK version.
  */
 
-class gr_ofdm_bpsk_mapper : public gr_block
+class gr_ofdm_bpsk_mapper : public gr_sync_block
 {
   friend gr_ofdm_bpsk_mapper_sptr
-    gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen,
-			      std::vector<gr_complex> known_symbol1, 
-			      std::vector<gr_complex> known_symbol2);
+    gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, 
+			      unsigned occupied_carriers, unsigned int fft_length,
+			      const std::vector<gr_complex> &known_symbol1, 
+			      const std::vector<gr_complex> &known_symbol2);
   
  protected:
-  gr_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen,
-		       std::vector<gr_complex> known_symbol1, 
-		       std::vector<gr_complex> known_symbol2);
+  gr_ofdm_bpsk_mapper (unsigned msgq_limit, 
+		       unsigned occupied_carriers, unsigned int fft_length,
+		       const std::vector<gr_complex> &known_symbol1, 
+		       const std::vector<gr_complex> &known_symbol2);
   
  private:
-  unsigned int d_mtu;
+  gr_msg_queue_sptr	d_msgq;
+  gr_message_sptr	d_msg;
+  unsigned		d_msg_offset;
+  bool			d_eof;
+  
   unsigned int d_occupied_carriers;
-  unsigned int d_vlen;
-  unsigned int d_packet_offset;
+  unsigned int d_fft_length;
   unsigned int d_bit_offset;
   unsigned int d_header_sent;
   std::vector<gr_complex> d_known_symbol1, d_known_symbol2;
 
-  void forecast (int noutput_items, gr_vector_int &ninput_items_required);
-
  public:
   ~gr_ofdm_bpsk_mapper(void);
-  int general_work(int noutput_items,
-		   gr_vector_int &ninput_items,
-		   gr_vector_const_void_star &input_items,
-		   gr_vector_void_star &output_items);
+
+  gr_msg_queue_sptr	msgq() const { return d_msgq; }
+
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
 
 };
 
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
index 12b86dc33d..d0094062a6 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
@@ -22,27 +22,28 @@
 
 #include <vector>
 
-GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper)
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper);
 
 gr_ofdm_bpsk_mapper_sptr 
-gr_make_ofdm_bpsk_mapper (unsigned int mtu,
+gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit,
 			  unsigned int bits_per_symbol, 
-			  unsigned int vlen,
-			  std::vector<gr_complex> known_symbol1, 
-			  std::vector<gr_complex> known_symbol2);
+			  unsigned int fft_length,
+			  const std::vector<gr_complex> &known_symbol1, 
+			  const std::vector<gr_complex> &known_symbol2);
 
-class gr_ofdm_bpsk_mapper : public gr_block
+class gr_ofdm_bpsk_mapper : public gr_sync_block
 {
  protected:
-  gr_ofdm_bpsk_mapper (unsigned int mtu,
+  gr_ofdm_bpsk_mapper (unsigned int msgq_limit,
 		       unsigned int bits_per_symbol,
-		       unsigned int vlen,
-		       std::vector<gr_complex> known_symbol1,
-		       std::vector<gr_complex> known_symbol2);
+		       unsigned int fft_length,
+		       const std::vector<gr_complex> &known_symbol1, 
+		       const std::vector<gr_complex> &known_symbol2);
 
  public:
-  int general_work(int noutput_items,
-		   gr_vector_int &ninput_items,
-		   gr_vector_const_void_star &input_items,
-		   gr_vector_void_star &output_items);
+  gr_msg_queue_sptr msgq();
+
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
 };
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
index 21fbc6b3ec..3973b83749 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006, 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,29 +26,30 @@
 
 #include <gr_ofdm_correlator.h>
 #include <gr_io_signature.h>
+#include <gr_expj.h>
 
 #define VERBOSE 0
 #define M_TWOPI (2*M_PI)
 
 gr_ofdm_correlator_sptr
-gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen, 
+gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length, 
 			 unsigned int cplen,
-			 std::vector<gr_complex> known_symbol1, 
-			 std::vector<gr_complex> known_symbol2)
+			 const std::vector<gr_complex> &known_symbol1, 
+			 const std::vector<gr_complex> &known_symbol2)
 {
-  return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, vlen, cplen,
+  return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, fft_length, cplen,
 							  known_symbol1, known_symbol2));
 }
 
-gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int vlen, 
+gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int fft_length, 
 					unsigned int cplen,
-					std::vector<gr_complex> known_symbol1, 
-					std::vector<gr_complex> known_symbol2)
+					const std::vector<gr_complex> &known_symbol1, 
+					const std::vector<gr_complex> &known_symbol2)
   : gr_block ("ofdm_correlator",
-	      gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen),
-	      gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers)),
+	      gr_make_io_signature (1, 1, sizeof(gr_complex)*fft_length),
+	      gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char))),
     d_occupied_carriers(occupied_carriers),
-    d_vlen(vlen),
+    d_fft_length(fft_length),
     d_cplen(cplen),
     d_freq_shift_len(5),
     d_known_symbol1(known_symbol1),
@@ -84,8 +85,9 @@ gr_ofdm_correlator::forecast (int noutput_items, gr_vector_int &ninput_items_req
 gr_complex
 gr_ofdm_correlator::coarse_freq_comp(int freq_delta, int symbol_count)
 {
-  return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count),
-		    sin(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count));
+  //  return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count),
+  //	    sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count));
+  return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
 }
 
 bool
@@ -99,7 +101,7 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
   gr_complex h_sqrd = gr_complex(0.0,0.0);
   float power = 0.0F;
 
-  while(!found && (abs(search_delta) < d_freq_shift_len)) {
+  while(!found && ((unsigned)abs(search_delta) < d_freq_shift_len)) {
     h_sqrd = gr_complex(0.0,0.0);
     power = 0.0F;
 
@@ -115,11 +117,20 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
 	     search_delta, h_sqrd.real(), h_sqrd.imag(), power, h_sqrd.real()/power, arg(h_sqrd)); 
 #endif
 
-    if(h_sqrd.real() > 0.75*power) {
+      // FIXME: Look at h_sqrd.read() > power
+    if((h_sqrd.real() > 0.82*power)  && (h_sqrd.real() < 1.1 * power)) {
       found = true;
       d_coarse_freq = search_delta;
       d_phase_count = 1;
-      d_snr_est = 10*log10(power/(power-h_sqrd.real()));
+      //d_snr_est = 10*log10(power/(power-h_sqrd.real()));
+
+      // check for low noise power; sets maximum SNR at 100 dB
+      if(fabs(h_sqrd.imag()) <= 1e-12) {
+	d_snr_est = 100.0;
+      }
+      else {
+	d_snr_est = 10*log10(fabs(h_sqrd.real()/h_sqrd.imag()));
+      }
 
       printf("CORR: Found, bin %d\tSNR Est %f dB\tcorr power fraction %f\n", 
              search_delta, d_snr_est, h_sqrd.real()/power);
@@ -168,23 +179,30 @@ gr_ofdm_correlator::general_work(int noutput_items,
 {
   const gr_complex *in = (const gr_complex *)input_items[0];
   const gr_complex *previous = &in[0];
-  const gr_complex *current = &in[d_vlen];
+  const gr_complex *current = &in[d_fft_length];
 
   gr_complex *out = (gr_complex *) output_items[0];
+  char *sig = (char *) output_items[1];
   
   unsigned int i=0;
 
-  int unoccupied_carriers = d_vlen - d_occupied_carriers;
+  int unoccupied_carriers = d_fft_length - d_occupied_carriers;
   int zeros_on_left = (int)ceil(unoccupied_carriers/2.0);
 
   bool corr = correlate(previous, current, zeros_on_left);
   if(corr) {
     calculate_equalizer(previous, current, zeros_on_left);
+    sig[0] = 1;
+  }
+  else {
+    sig[0] = 0;
   }
 
   for(i = 0; i < d_occupied_carriers; i++) {
     out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)*current[i+zeros_on_left+d_coarse_freq];
   }
+  
+
   d_phase_count++;
   consume_each(1);
   return 1;
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
index 4c44cca329..44a6847af3 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006, 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -31,10 +31,10 @@ class gr_ofdm_correlator;
 typedef boost::shared_ptr<gr_ofdm_correlator> gr_ofdm_correlator_sptr;
 
 gr_ofdm_correlator_sptr 
-gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 			 unsigned int cplen,
-			 std::vector<gr_complex> known_symbol1, 
-			 std::vector<gr_complex> known_symbol2);
+			 const std::vector<gr_complex> &known_symbol1, 
+			 const std::vector<gr_complex> &known_symbol2);
 
 /*!
  * \brief take a vector of complex constellation points in from an FFT
@@ -48,7 +48,7 @@ gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
  * been corrected and that the samples fall in the middle of one FFT bin.
  *
  * It then uses one of those known
- * symbosl to estimate the channel response overa all subcarriers and does a simple 
+ * symbols to estimate the channel response over all subcarriers and does a simple 
  * 1-tap equalization on all subcarriers. This corrects for the phase and amplitude
  * distortion caused by the channel.
  */
@@ -58,7 +58,7 @@ class gr_ofdm_correlator : public gr_block
   /*! 
    * \brief Build an OFDM correlator and equalizer.
    * \param occupied_carriers   The number of subcarriers with data in the received symbol
-   * \param vlen                The size of the FFT vector (occupied_carriers + unused carriers)
+   * \param fft_length          The size of the FFT vector (occupied_carriers + unused carriers)
    * \param known_symbol1       A vector of complex numbers representing a known symbol at the
    *                            start of a frame (usually a BPSK PN sequence)
    * \param known_symbol2       A vector of complex numbers representing a known symbol at the
@@ -67,16 +67,16 @@ class gr_ofdm_correlator : public gr_block
    *                            for phase changes between symbols. 
    */
   friend gr_ofdm_correlator_sptr
-  gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+  gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 			   unsigned int cplen,
-			   std::vector<gr_complex> known_symbol1, 
-			   std::vector<gr_complex> known_symbol2);
+			   const std::vector<gr_complex> &known_symbol1, 
+			   const std::vector<gr_complex> &known_symbol2);
   
  protected:
-  gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+  gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 		      unsigned int cplen,
-		      std::vector<gr_complex> known_symbol1, 
-		      std::vector<gr_complex> known_symbol2);
+		      const std::vector<gr_complex> &known_symbol1, 
+		      const std::vector<gr_complex> &known_symbol2);
   
  private:
   unsigned char slicer(gr_complex x);
@@ -86,15 +86,15 @@ class gr_ofdm_correlator : public gr_block
   gr_complex coarse_freq_comp(int freq_delta, int count);
   
   unsigned int d_occupied_carriers;  // !< \brief number of subcarriers with data
-  unsigned int d_vlen;               // !< \brief length of FFT vector
+  unsigned int d_fft_length;         // !< \brief length of FFT vector
   unsigned int d_cplen;              // !< \brief length of cyclic prefix in samples
   unsigned int d_freq_shift_len;     // !< \brief number of surrounding bins to look at for correlation
   std::vector<gr_complex> d_known_symbol1, d_known_symbol2; // !< \brief known symbols at start of frame
   std::vector<gr_complex> d_diff_corr_factor; // !< \brief factor used in correlation
-  std::vector<gr_complex> d_hestimate; // !< channel estimate
-  signed int d_coarse_freq; // !< \brief search distance in number of bins
-  unsigned int d_phase_count;        // !< \brief accumulator for coarse freq correction
-  float d_snr_est;  // !< an estimation of the signal to noise ratio
+  std::vector<gr_complex> d_hestimate;  // !< channel estimate
+  signed int d_coarse_freq;             // !< \brief search distance in number of bins
+  unsigned int d_phase_count;           // !< \brief accumulator for coarse freq correction
+  float d_snr_est;                      // !< an estimation of the signal to noise ratio
 
   void forecast(int noutput_items, gr_vector_int &ninput_items_required);
 
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
index fbbf6a8afd..40f9f83ff8 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2006, 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -22,23 +22,23 @@
 
 #include <vector>
 
-GR_SWIG_BLOCK_MAGIC(gr,ofdm_correlator)
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_correlator);
 
 gr_ofdm_correlator_sptr 
 gr_make_ofdm_correlator (unsigned int occupied_carriers, 
-			 unsigned int vlen,
+			 unsigned int fft_length,
 			 unsigned int cplen,
-			 std::vector<gr_complex> known_symbol1, 
-			 std::vector<gr_complex> known_symbol2);
+			 const std::vector<gr_complex> &known_symbol1, 
+			 const std::vector<gr_complex> &known_symbol2);
 
 class gr_ofdm_correlator : public gr_sync_decimator
 {
  protected:
   gr_ofdm_correlator (unsigned int occupied_carriers,
-		      unsigned int vlen,
+		      unsigned int fft_length,
 		      unsigned int cplen,
-		      std::vector<gr_complex> known_symbol1, 
-		      std::vector<gr_complex> known_symbol2);
+		      const std::vector<gr_complex> &known_symbol1, 
+		      const std::vector<gr_complex> &known_symbol2);
 
  public:
   float snr() { return d_snr_est; }
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
new file mode 100644
index 0000000000..acaf1258bd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
@@ -0,0 +1,235 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ofdm_frame_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <stdexcept>
+
+#define VERBOSE 0
+
+inline void
+gr_ofdm_frame_sink::enter_search()
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_search\n");
+
+  d_state = STATE_SYNC_SEARCH;
+
+}
+    
+inline void
+gr_ofdm_frame_sink::enter_have_sync()
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_have_sync\n");
+
+  d_state = STATE_HAVE_SYNC;
+
+  // clear state of demapper
+  d_byte_offset = 0;
+  d_partial_byte = 0;
+
+  d_header = 0;
+  d_headerbytelen_cnt = 0;
+}
+
+inline void
+gr_ofdm_frame_sink::enter_have_header()
+{
+  d_state = STATE_HAVE_HEADER;
+
+  // header consists of two 16-bit shorts in network byte order
+  // payload length is lower 12 bits
+  // whitener offset is upper 4 bits
+  d_packetlen = (d_header >> 16) & 0x0fff;
+  d_packet_whitener_offset = (d_header >> 28) & 0x000f;
+  d_packetlen_cnt = 0;
+
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", 
+	    d_packetlen, d_packet_whitener_offset);
+}
+
+unsigned char gr_ofdm_frame_sink::bpsk_slicer(gr_complex x)
+{
+  return (unsigned char)(x.real() > 0 ? 1 : 0);
+}
+
+unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
+					       unsigned char *out)
+{
+  unsigned int i=0, bytes_produced=0;
+
+  while(i < d_occupied_carriers) {
+
+    while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
+      //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag()); 
+      d_partial_byte |= bpsk_slicer(in[i++]) << (d_byte_offset++);
+    }
+
+    if(d_byte_offset == 8) {
+      out[bytes_produced++] = d_partial_byte;
+      d_byte_offset = 0;
+      d_partial_byte = 0;
+    }
+  }
+
+  return bytes_produced;
+}
+
+
+
+gr_ofdm_frame_sink_sptr
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
+{
+  return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers));
+}
+
+
+gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
+  : gr_sync_block ("ofdm_frame_sink",
+		   gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)),
+		   gr_make_io_signature (0, 0, 0)),
+    d_target_queue(target_queue), d_occupied_carriers(occupied_carriers), 
+    d_byte_offset(0), d_partial_byte(0)
+{
+  d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/8.0)];
+
+  enter_search();
+}
+
+gr_ofdm_frame_sink::~gr_ofdm_frame_sink ()
+{
+  delete [] d_bytes_out;
+}
+
+int
+gr_ofdm_frame_sink::work (int noutput_items,
+			  gr_vector_const_void_star &input_items,
+			  gr_vector_void_star &output_items)
+{
+  const gr_complex *in = (const gr_complex *) input_items[0];
+  const char *sig = (const char *) input_items[1];
+  int count_tones=0, count_items=0;
+  unsigned int j = 0;
+  unsigned int bytes=0;
+  
+  if (VERBOSE)
+    fprintf(stderr,">>> Entering state machine\n");
+  
+  bytes = bpsk_demapper(&in[0], d_bytes_out);
+  
+  switch(d_state) {
+      
+  case STATE_SYNC_SEARCH:    // Look for flag indicating beginning of pkt
+    if (VERBOSE)
+      fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
+    
+    if (sig[0]) {  // Found it, set up for header decode
+      enter_have_sync();
+    }
+    break;
+
+  case STATE_HAVE_SYNC:
+    if(sig[0])
+      printf("ERROR -- Found SYNC in HAVE_SYNC\n");
+    if (VERBOSE)
+      fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
+	      d_headerbytelen_cnt, d_header);
+    
+    j = 0;
+    while(j < bytes) {
+      d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF);
+      j++;
+      
+      if (++d_headerbytelen_cnt == HEADERBYTELEN) {
+	
+	if (VERBOSE)
+	  fprintf(stderr, "got header: 0x%08x\n", d_header);
+	
+	// we have a full header, check to see if it has been received properly
+	if (header_ok()){
+	  enter_have_header();
+	  printf("\nPacket Length: %d\n", d_packetlen);
+	  //for(int k=0; k < d_packetlen; k++)
+	  //  printf("%02x", d_packet[k]);
+	  //printf("\n");
+	  
+	  while((j < bytes) && (d_packetlen_cnt < d_packetlen)) {
+	    d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
+	  }
+	  
+	  if(d_packetlen_cnt == d_packetlen) {
+	    gr_message_sptr msg =
+	      gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen);
+	    memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+	    d_target_queue->insert_tail(msg);		// send it
+	    msg.reset();  				// free it up
+	    
+	    enter_search();				
+	  }
+	}
+	else {
+	  enter_search();				// bad header
+	}
+      }
+    }
+    break;
+      
+  case STATE_HAVE_HEADER:
+    if(sig[0])
+      printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen);
+    if (VERBOSE)
+	fprintf(stderr,"Packet Build\n");
+    
+    j = 0;
+    while(j < bytes) {
+      d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
+      
+      if (d_packetlen_cnt == d_packetlen){		// packet is filled
+	// build a message
+	// NOTE: passing header field as arg1 is not scalable
+	gr_message_sptr msg =
+	  gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt);
+	memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+	
+	d_target_queue->insert_tail(msg);		// send it
+	msg.reset();  				// free it up
+	
+	enter_search();
+	break;
+      }
+    }
+    break;
+    
+  default:
+    assert(0);
+    
+  } // switch
+  
+  return 1;
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
new file mode 100644
index 0000000000..d77c76741e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_FRAME_SINK_H
+#define INCLUDED_GR_OFDM_FRAME_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class gr_ofdm_frame_sink;
+typedef boost::shared_ptr<gr_ofdm_frame_sink> gr_ofdm_frame_sink_sptr;
+
+gr_ofdm_frame_sink_sptr 
+gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+/*!
+ * \brief Given a stream of bits and access_code flags, assemble packets.
+ * \ingroup sink
+ *
+ * input: stream of bytes from gr_correlate_access_code_bb
+ * output: none.  Pushes assembled packet into target queue
+ *
+ * The framer expects a fixed length header of 2 16-bit shorts
+ * containing the payload length, followed by the payload.  If the 
+ * 2 16-bit shorts are not identical, this packet is ignored.  Better
+ * algs are welcome.
+ *
+ * The input data consists of bytes that have two bits used.
+ * Bit 0, the LSB, contains the data bit.
+ * Bit 1 if set, indicates that the corresponding bit is the
+ * the first bit of the packet.  That is, this bit is the first
+ * one after the access code.
+ */
+class gr_ofdm_frame_sink : public gr_sync_block
+{
+  friend gr_ofdm_frame_sink_sptr 
+  gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+ private:
+  enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+  static const int MAX_PKT_LEN    = 4096;
+  static const int HEADERBYTELEN   = 4;
+
+  gr_msg_queue_sptr  d_target_queue;		// where to send the packet when received
+  state_t            d_state;
+  unsigned int       d_header;			// header bits
+  int		     d_headerbytelen_cnt;	// how many so far
+
+  unsigned char      *d_bytes_out;              // hold the current bytes produced by the demapper    
+
+  unsigned int       d_occupied_carriers;
+  unsigned int       d_byte_offset;
+  unsigned int       d_partial_byte;
+
+  unsigned char      d_packet[MAX_PKT_LEN];	// assembled payload
+  int 		     d_packetlen;		// length of packet
+  int                d_packet_whitener_offset;  // offset into whitener string to use
+  int		     d_packetlen_cnt;		// how many so far
+
+ protected:
+  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+  void enter_search();
+  void enter_have_sync();
+  void enter_have_header();
+  
+  bool header_ok()
+  {
+    // confirm that two copies of header info are identical
+    return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+  }
+
+  unsigned char bpsk_slicer(gr_complex x);
+  unsigned int bpsk_demapper(const gr_complex *in,
+			     unsigned char *out);  
+
+ public:
+  ~gr_ofdm_frame_sink();
+
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_OFDM_FRAME_SINK_H */
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
new file mode 100644
index 0000000000..b05c8b795c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink);
+
+gr_ofdm_frame_sink_sptr 
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+class gr_ofdm_frame_sink : public gr_sync_block
+{
+ protected:
+  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+ public:
+  ~gr_ofdm_frame_sink();
+};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
index 9ac5abdcd8..5f5a91fd23 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
@@ -38,7 +38,7 @@ gr_make_ofdm_sampler (unsigned int fft_length,
 gr_ofdm_sampler::gr_ofdm_sampler (unsigned int fft_length, 
 				  unsigned int symbol_length)
   : gr_block ("ofdm_sampler",
-	      gr_make_io_signature (2, 2, sizeof (gr_complex)),
+	      gr_make_io_signature2 (2, 2, sizeof (gr_complex), sizeof(char)),
 	      gr_make_io_signature (1, 1, sizeof (gr_complex)*fft_length)),
     d_fft_length(fft_length), d_symbol_length(symbol_length)
 {
@@ -61,7 +61,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
 			       gr_vector_void_star &output_items)
 {
   gr_complex *iptr = (gr_complex *) input_items[0];
-  gr_complex *trigger = (gr_complex *) input_items[1];
+  char *trigger = (char *) input_items[1];
 
   gr_complex *optr = (gr_complex *) output_items[0];
 
@@ -70,7 +70,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
   unsigned int i=d_fft_length-1;
 
   while(!found && i<std::min(ninput_items[0],ninput_items[1]) )
-    if(trigger[i].real() > 0.5)
+    if(trigger[i])
       found = 1;
     else
       i++;
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.cc b/gnuradio-core/src/lib/general/gr_skiphead.cc
index 4a1f875117..e395cbf663 100644
--- a/gnuradio-core/src/lib/general/gr_skiphead.cc
+++ b/gnuradio-core/src/lib/general/gr_skiphead.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -26,45 +26,57 @@
 #include <gr_skiphead.h>
 #include <gr_io_signature.h>
 
-gr_skiphead::gr_skiphead (size_t sizeof_stream_item, int nitems)
-  : gr_sync_block ("skiphead",
-       gr_make_io_signature (1, 1, sizeof_stream_item),
-       gr_make_io_signature (1, 1, sizeof_stream_item)),
-    d_nitems (nitems), d_nskipped_items (0)
+gr_skiphead::gr_skiphead (size_t itemsize, size_t nitems_to_skip)
+  : gr_block ("skiphead",
+	      gr_make_io_signature(1, 1, itemsize),
+	      gr_make_io_signature(1, 1, itemsize)),
+    d_nitems_to_skip(nitems_to_skip), d_nitems(0)
 {
 }
 
-gr_block_sptr
-gr_make_skiphead (size_t sizeof_stream_item, int nitems)
+gr_skiphead_sptr
+gr_make_skiphead (size_t itemsize, size_t nitems_to_skip)
 {
-  return gr_block_sptr (new gr_skiphead (sizeof_stream_item, nitems));
+  return gr_skiphead_sptr (new gr_skiphead (itemsize, nitems_to_skip));
 }
 
 int
-gr_skiphead::work (int noutput_items,
-        gr_vector_const_void_star &input_items,
-        gr_vector_void_star &output_items)
+gr_skiphead::general_work(int noutput_items,
+			  gr_vector_int &ninput_items_ignored,
+			  gr_vector_const_void_star &input_items,
+			  gr_vector_void_star &output_items)
 {
-  int items_to_skip = d_nitems - d_nskipped_items;
-  if (items_to_skip <=0)
-  {
-     //Done with skipping, copy all input to the output;
-     memcpy (output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item (0));
-     return noutput_items;
-  } else if (items_to_skip < noutput_items)
-  {
-     memcpy (output_items[0], &(((char *)input_items[0])[items_to_skip*input_signature()->sizeof_stream_item (0)]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
-    //memcpy (output_items[0], &((input_items[0])[items_to_skip]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
-     //memcpy (output_items[0], input_items[0]+items_to_skip*input_signature()->sizeof_stream_item (0), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
-     d_nskipped_items += items_to_skip;
-     consume_each (items_to_skip);
-     return (noutput_items -items_to_skip);
-  } else
-  {
-     d_nskipped_items += noutput_items;
-     consume_each (items_to_skip);
-     return 0;
+  const char *in = (const char *) input_items[0];
+  char *out = (char *) output_items[0];
+
+  int ninput_items = noutput_items;	// we've got at least this many input items
+  int ii = 0;				// input index
+
+  while (ii < ninput_items){
+
+    long long ni_total = ii + d_nitems;  	// total items processed so far
+    if (ni_total < d_nitems_to_skip){		// need to skip some more
+
+      int n_to_skip = (int) std::min(d_nitems_to_skip - ni_total,
+				     (long long)(ninput_items - ii));
+      ii += n_to_skip;
+    }
+
+    else {		// nothing left to skip.  copy away
+
+      int n_to_copy = ninput_items - ii;
+      if (n_to_copy > 0){
+	size_t itemsize = output_signature()->sizeof_stream_item(0);
+	memcpy(out, in + (ii*itemsize), n_to_copy*itemsize);
+      }
+
+      d_nitems += ninput_items;
+      consume_each(ninput_items);
+      return n_to_copy;
+    }
   }
 
-  return -1;//Should never get here
+  d_nitems += ninput_items;
+  consume_each(ninput_items);
+  return 0;
 }
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.h b/gnuradio-core/src/lib/general/gr_skiphead.h
index 81898ef404..6e2c782722 100644
--- a/gnuradio-core/src/lib/general/gr_skiphead.h
+++ b/gnuradio-core/src/lib/general/gr_skiphead.h
@@ -26,6 +26,10 @@
 #include <gr_sync_block.h>
 #include <stddef.h>      // size_t
 
+class gr_skiphead;
+typedef boost::shared_ptr<gr_skiphead> gr_skiphead_sptr;
+
+
 /*!
  * \brief skips the first N items, from then on copies items to the output
  * \ingroup block
@@ -33,22 +37,24 @@
  * Useful for building test cases and sources which have metadata or junk at the start
  */
 
-class gr_skiphead : public gr_sync_block
+class gr_skiphead : public gr_block
 {
-  friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
-  gr_skiphead (size_t sizeof_stream_item, int nitems);
+  friend gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
+  gr_skiphead (size_t itemsize, size_t nitems_to_skip);
 
-  int  d_nitems;
-  int  d_nskipped_items;
+  long long  		d_nitems_to_skip;
+  long long		d_nitems;		// total items seen
 
  public:
-  int work (int noutput_items,
-     gr_vector_const_void_star &input_items,
-     gr_vector_void_star &output_items);
+
+  int general_work(int noutput_items,
+		   gr_vector_int &ninput_items,
+		   gr_vector_const_void_star &input_items,
+		   gr_vector_void_star &output_items);
 };
 
-gr_block_sptr
-gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+gr_skiphead_sptr
+gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
 
 
 #endif /* INCLUDED_GR_SKIPHEAD_H */
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.i b/gnuradio-core/src/lib/general/gr_skiphead.i
index 8942f184e8..c725e26bb5 100644
--- a/gnuradio-core/src/lib/general/gr_skiphead.i
+++ b/gnuradio-core/src/lib/general/gr_skiphead.i
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -20,11 +20,11 @@
  * Boston, MA 02110-1301, USA.
  */
 
-%ignore gr_skiphead;
+GR_SWIG_BLOCK_MAGIC(gr,skiphead);
+
+gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
+
 class gr_skiphead : public gr_block {
-  friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
-  gr_skiphead (size_t sizeof_stream_item, int nitems);
+  friend gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
+  gr_skiphead (size_t itemsize, size_t nitems_to_skip);
 };
-
-%rename(skiphead) gr_make_skiphead;
-gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
diff --git a/gnuradio-core/src/lib/general/gr_stream_mux.cc b/gnuradio-core/src/lib/general/gr_stream_mux.cc
index 1eaad29a2b..e7e45de74c 100644
--- a/gnuradio-core/src/lib/general/gr_stream_mux.cc
+++ b/gnuradio-core/src/lib/general/gr_stream_mux.cc
@@ -44,6 +44,10 @@ gr_stream_mux::gr_stream_mux (size_t itemsize, const std::vector<int> &lengths)
     d_residual(0),
     d_lengths(lengths)
 {
+  if(d_lengths[d_stream] == 0) {
+    increment_stream();
+  }
+  d_residual = d_lengths[d_stream];
 }    
 
 gr_stream_mux::~gr_stream_mux(void)
@@ -55,9 +59,17 @@ gr_stream_mux::forecast (int noutput_items, gr_vector_int &ninput_items_required
 {
   unsigned ninputs = ninput_items_required.size ();
   for (unsigned i = 0; i < ninputs; i++)
-    ninput_items_required[i] = 0;
+    ninput_items_required[i] = (d_lengths[i] == 0 ? 0 : 1);
 }
 
+void gr_stream_mux::increment_stream()
+{
+  do {
+    d_stream = (d_stream+1) % d_lengths.size();
+  } while(d_lengths[d_stream] == 0);
+  
+  d_residual = d_lengths[d_stream];
+}
 
 int
 gr_stream_mux::general_work(int noutput_items,
@@ -65,128 +77,46 @@ gr_stream_mux::general_work(int noutput_items,
 			    gr_vector_const_void_star &input_items,
 			    gr_vector_void_star &output_items)
 {
-    
     char *out = (char *) output_items[0];
     const char *in;
+    int out_index = 0;
+    std::vector<int> input_index(d_lengths.size(), 0);
 
-    int acc = 0;
-    int N=0;
-    int M=0;
-    std::vector<int> consume_vector(d_lengths.size(), 0);
+    if(VERBOSE) {
+      printf("mux: nouput_items: %d   d_stream: %d\n", noutput_items, d_stream);
+      for(size_t i = 0; i < d_lengths.size(); i++)
+	printf("\tninput_items[%d]: %d\n", i, ninput_items[i]);
+    }
 
-    #if VERBOSE
-    printf("mux: nouput_items: %d   d_stream: %d\n", noutput_items, d_stream);
-    for(int i = 0; i < d_lengths.size(); i++)
-      printf("\tninput_items[%d]: %d\n", i, ninput_items[i]);
-    #endif
+    while (1) {
+      int r = std::min(noutput_items - out_index,
+		       std::min(d_residual,
+				ninput_items[d_stream] - input_index[d_stream]));
+      if(VERBOSE) {
+	printf("mux: r=%d\n", r);
+	printf("\tnoutput_items - out_index: %d\n", 
+	       noutput_items - out_index);
+	printf("\td_residual: %d\n", 
+	       d_residual);
+	printf("\tninput_items[d_stream] - input_index[d_stream]: %d\n", 
+	       ninput_items[d_stream] - input_index[d_stream]);
+      }
 
-    in = (const char *) input_items[d_stream];
+      if(r <= 0) {
+	return out_index;
+      }
 
-    if(d_residual) {
-      #if VERBOSE
-      printf("Cleaning up residual bytes (%d) from stream %d\n", d_residual, d_stream);
-      #endif
+      in = (const char *) input_items[d_stream] + input_index[d_stream]*d_itemsize;
       
-      // get the number of items available in input stream up to the
-      // num items required
-      N=std::min(d_residual, ninput_items[d_stream]);
-      
-      // get the number of items we can put into the output buffer
-      M=std::min(N, noutput_items);
-
-      // copy the items to the output buff
-      memcpy(out, in, M*d_itemsize);
+      memcpy(&out[out_index*d_itemsize], in, r*d_itemsize);
+      out_index += r;
+      input_index[d_stream] += r;
+      d_residual -= r;
 
-      // increment the output accumulator
-      acc += M;
-
-      // keep track of items consumed
-      consume_vector[d_stream]=M;
+      consume(d_stream, r);
       
-      // keep track if there are residual items left from the input stream
-      d_residual -= M;
-
-      #if VERBOSE
-      printf("Stream: %d (%x)  Wrote: %d bytes  Output has: %d bytes  residual: %d bytes\n", 
-	     d_stream, in, M, acc, d_residual);
-      #endif
-
-      // if no residual items, we're done with this input stream for
-      // this round
-      if (!d_residual) {
-	if(d_stream == d_lengths.size() - 1) {
-	  d_stream=0;  // wrap stream pointer
-	}
-	else {
-	  d_stream++;  // or increment the stream pointer
-	}
-        #if VERBOSE
-	printf("Going to next stream: %d\n", d_stream);
-	#endif
-	in = ((const char *) (input_items[d_stream])) + d_itemsize*consume_vector[d_stream];
-      }
-    }
-
-    if(!d_residual) {
-      while (acc<noutput_items){
-	// get the number of items available in input stream up to the
-	// num items required
-	N=std::min(d_lengths[d_stream], ninput_items[d_stream]);
-	
-	// get the number of items we can put into the output buffer
-	M=std::min(N, noutput_items-acc);
-	
-	// copy the items to the output buff
-	memcpy(out+acc*d_itemsize,in,M*d_itemsize);
-	
-	// increment the output accumulator
-	acc += M;
-	
-	// keep track of items consumed
-	consume_vector[d_stream]+=M;
-	
-	// keep track if there are residual items left from the input stream
-	d_residual=d_lengths[d_stream] - M;
-	
-        #if VERBOSE
-	printf("Stream: %d (%x)  Wrote: %d bytes  Output has: %d bytes  residual: %d bytes\n", 
-	       d_stream, in, M, acc, d_residual);
-        #endif
-
-	// if no residual items, we're done with this input stream for
-	// this round
-	if (!d_residual) {
-	  if(d_stream == d_lengths.size() - 1) {
-	    d_stream=0;  // wrap stream pointer
-	  }
-	  else {
-	    d_stream++;  // or increment the stream pointer
-	  }
-          #if VERBOSE
-	  printf("Going to next stream: %d\n", d_stream);
-          #endif
-	  
-	  // get next stream pointer
-	  in = ((const char *) (input_items[d_stream])) + d_itemsize*consume_vector[d_stream];
-	}
-	else{ 
-	  break;
-	}   
+      if(d_residual == 0) {
+	increment_stream();
       }
     }
-    
-    for (unsigned int j=0;j<d_lengths.size();j++){
-      consume(j,consume_vector[j]);
-
-      #if VERBOSE
-      printf("consuming: %d on stream: %d\n", consume_vector[j], j);
-      #endif
-    }
-
-    #if VERBOSE
-    printf("mux: returning: %d\n\n", acc);
-    #endif
-
-    return acc;
-                
 }
diff --git a/gnuradio-core/src/lib/general/gr_stream_mux.h b/gnuradio-core/src/lib/general/gr_stream_mux.h
index 4929400017..5ea783cb6c 100644
--- a/gnuradio-core/src/lib/general/gr_stream_mux.h
+++ b/gnuradio-core/src/lib/general/gr_stream_mux.h
@@ -25,7 +25,6 @@
 
 
 #include <gr_block.h>
-#include <gr_frame.h>
 #include <vector>
 
 class gr_stream_mux;
@@ -66,14 +65,15 @@ class gr_stream_mux : public gr_block
   
  protected:
    gr_stream_mux (size_t itemsize, const std::vector<int> &lengths);
+
  private:
-   size_t d_itemsize;
-   unsigned int d_stream;
-   int d_residual;
-   int d_times;
-   int d_unconsume;
-   //gr_vector_int d_unconsume;            
-   gr_vector_int d_lengths;
+  size_t d_itemsize;
+  unsigned int d_stream;    // index of currently selected stream
+  int d_residual;           // number if items left to put into current stream
+  gr_vector_int d_lengths;  // number if items to pack per stream
+ 
+  void increment_stream();
+
  public:
   ~gr_stream_mux(void);
 
-- 
cgit v1.2.3