From a663f5b481679d8a352c668825cee92f548f3fcc Mon Sep 17 00:00:00 2001
From: trondeau <trondeau@221aa14e-8319-0410-a670-987f0aec2ac5>
Date: Sun, 10 Jun 2007 18:16:11 +0000
Subject: Merging OFDM features branch r5661:5759 into trunk. OFDM works over
 the air with BPSK and QPSK modulations on subcarriers. Passes make distcheck.

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5761 221aa14e-8319-0410-a670-987f0aec2ac5
---
 gnuradio-core/src/lib/general/Makefile.am          |  12 +
 gnuradio-core/src/lib/general/general.i            |   8 +
 gnuradio-core/src/lib/general/gr_delay.cc          |   2 +-
 .../src/lib/general/gr_ofdm_bpsk_mapper.cc         |  73 ++----
 .../src/lib/general/gr_ofdm_bpsk_mapper.h          |  31 +--
 .../src/lib/general/gr_ofdm_bpsk_mapper.i          |  13 +-
 .../src/lib/general/gr_ofdm_correlator.cc          |  38 +++-
 gnuradio-core/src/lib/general/gr_ofdm_correlator.h |  12 +-
 gnuradio-core/src/lib/general/gr_ofdm_correlator.i |   6 +-
 .../src/lib/general/gr_ofdm_frame_sink.cc          |  80 +++++--
 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h |  40 ++--
 gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i |   8 +-
 .../src/lib/general/gr_ofdm_insert_preamble.cc     | 186 +++++++++++++++
 .../src/lib/general/gr_ofdm_insert_preamble.h      | 102 +++++++++
 .../src/lib/general/gr_ofdm_insert_preamble.i      |  35 +++
 .../src/lib/general/gr_ofdm_qam_mapper.cc          | 249 +++++++++++++++++++++
 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h |  84 +++++++
 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i |  46 ++++
 .../src/lib/general/gr_ofdm_qpsk_mapper.cc         | 141 ++++++++++++
 .../src/lib/general/gr_ofdm_qpsk_mapper.h          |  76 +++++++
 .../src/lib/general/gr_ofdm_qpsk_mapper.i          |  44 ++++
 gnuradio-core/src/lib/general/gr_ofdm_sampler.cc   |   4 +-
 gnuradio-core/src/lib/general/gr_regenerate_bb.cc  |  74 ++++++
 gnuradio-core/src/lib/general/gr_regenerate_bb.h   |  59 +++++
 gnuradio-core/src/lib/general/gr_regenerate_bb.i   |  31 +++
 25 files changed, 1314 insertions(+), 140 deletions(-)
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h
 create mode 100644 gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i
 create mode 100644 gnuradio-core/src/lib/general/gr_regenerate_bb.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_regenerate_bb.h
 create mode 100644 gnuradio-core/src/lib/general/gr_regenerate_bb.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 d774baa1c5..35aac0a22f 100644
--- a/gnuradio-core/src/lib/general/Makefile.am
+++ b/gnuradio-core/src/lib/general/Makefile.am
@@ -102,7 +102,10 @@ libgeneral_la_SOURCES = 		\
         gr_ofdm_mapper_bcv.cc           \
         gr_ofdm_bpsk_demapper.cc        \
         gr_ofdm_bpsk_mapper.cc          \
+        gr_ofdm_qpsk_mapper.cc          \
+        gr_ofdm_qam_mapper.cc	        \
 	gr_ofdm_frame_sink.cc		\
+	gr_ofdm_insert_preamble.cc	\
         gr_ofdm_sampler.cc              \
 	gr_pa_2x2_phase_combiner.cc	\
 	gr_packet_sink.cc		\
@@ -121,6 +124,7 @@ libgeneral_la_SOURCES = 		\
 	gr_pwr_squelch_ff.cc		\
 	gr_quadrature_demod_cf.cc	\
 	gr_random.cc			\
+	gr_regenerate_bb.cc		\
 	gr_remez.cc			\
 	gr_reverse.cc			\
 	gr_rms_cf.cc			\
@@ -240,8 +244,11 @@ grinclude_HEADERS = 			\
         gr_ofdm_demapper_vcb.h          \
         gr_ofdm_mapper_bcv.h            \
         gr_ofdm_bpsk_mapper.h           \
+        gr_ofdm_qpsk_mapper.h		\
+        gr_ofdm_qam_mapper.h		\
         gr_ofdm_bpsk_demapper.h         \
         gr_ofdm_frame_sink.h		\
+	gr_ofdm_insert_preamble.h	\
 	gr_ofdm_sampler.h               \
 	gr_pa_2x2_phase_combiner.h	\
 	gr_packet_sink.h		\
@@ -260,6 +267,7 @@ grinclude_HEADERS = 			\
 	gr_pwr_squelch_ff.h		\
 	gr_quadrature_demod_cf.h	\
 	gr_random.h			\
+	gr_regenerate_bb.h		\
 	gr_remez.h			\
 	gr_reverse.h			\
 	gr_rms_cf.h			\
@@ -381,7 +389,10 @@ swiginclude_HEADERS =			\
         gr_ofdm_mapper_bcv.i            \
         gr_ofdm_bpsk_demapper.i         \
         gr_ofdm_bpsk_mapper.i           \
+        gr_ofdm_qpsk_mapper.i	        \
+        gr_ofdm_qam_mapper.i	        \
         gr_ofdm_frame_sink.i		\
+	gr_ofdm_insert_preamble.i	\
 	gr_ofdm_sampler.i               \
 	gr_pa_2x2_phase_combiner.i	\
 	gr_packet_sink.i		\
@@ -399,6 +410,7 @@ swiginclude_HEADERS =			\
 	gr_pwr_squelch_cc.i		\
 	gr_pwr_squelch_ff.i		\
 	gr_quadrature_demod_cf.i	\
+	gr_regenerate_bb.i		\
 	gr_remez.i			\
 	gr_rms_cf.i			\
 	gr_rms_ff.i			\
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index 1fdb4239a6..b362d24d05 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -97,8 +97,12 @@
 #include <gr_ofdm_cyclic_prefixer.h>
 #include <gr_ofdm_bpsk_demapper.h>
 #include <gr_ofdm_bpsk_mapper.h>
+#include <gr_ofdm_qpsk_mapper.h>
+#include <gr_ofdm_qam_mapper.h>
 #include <gr_ofdm_frame_sink.h>
+#include <gr_ofdm_insert_preamble.h>
 #include <gr_ofdm_sampler.h>
+#include <gr_regenerate_bb.h>
 #include <gr_costas_loop_cc.h>
 #include <gr_pa_2x2_phase_combiner.h>
 #include <gr_kludge_copy.h>
@@ -200,8 +204,12 @@
 %include "gr_ofdm_cyclic_prefixer.i"
 %include "gr_ofdm_bpsk_demapper.i"
 %include "gr_ofdm_bpsk_mapper.i"
+%include "gr_ofdm_qpsk_mapper.i"
+%include "gr_ofdm_qam_mapper.i"
 %include "gr_ofdm_frame_sink.i"
+%include "gr_ofdm_insert_preamble.i"
 %include "gr_ofdm_sampler.i"
+%include "gr_regenerate_bb.i"
 %include "gr_costas_loop_cc.i"
 %include "gr_pa_2x2_phase_combiner.i"
 %include "gr_kludge_copy.i"
diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc
index 89ab3ce0e0..73b61a9a0c 100644
--- a/gnuradio-core/src/lib/general/gr_delay.cc
+++ b/gnuradio-core/src/lib/general/gr_delay.cc
@@ -52,7 +52,7 @@ gr_delay::work (int noutput_items,
   const char *iptr;
   char *optr;
 
-  for(int i = 0; i < input_items.size(); i++) {
+  for(size_t i = 0; i < input_items.size(); i++) {
     iptr = (const char *) input_items[i];
     optr = (char *) output_items[i];
 
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 f0b52c3255..5b4631227c 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
@@ -26,23 +26,18 @@
 
 #include <gr_ofdm_bpsk_mapper.h>
 #include <gr_io_signature.h>
-#include <vector>
+#include <stdexcept>
 
 gr_ofdm_bpsk_mapper_sptr
 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)
+			  unsigned int occupied_carriers, unsigned int fft_length)
 {
-  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length, 
-							    known_symbol1, known_symbol2));
+  return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length));
 }
 
 // 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)
+					  unsigned int occupied_carriers, unsigned int fft_length)
   : 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))),
@@ -50,20 +45,18 @@ gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit,
     d_occupied_carriers(occupied_carriers),
     d_fft_length(fft_length),
     d_bit_offset(0),
-    d_header_sent(0),
-    d_known_symbol1(known_symbol1),
-    d_known_symbol2(known_symbol2)
+    d_pending_flag(0)
 {
-  assert(d_occupied_carriers <= d_fft_length);
-  assert(d_occupied_carriers == d_known_symbol1.size());
-  assert(d_occupied_carriers == d_known_symbol2.size());
+  if (!(d_occupied_carriers <= d_fft_length))
+    throw std::invalid_argument("gr_ofdm_bpsk_mapper: occupied carriers must be <= fft_length");
 }
 
 gr_ofdm_bpsk_mapper::~gr_ofdm_bpsk_mapper(void)
 {
 }
 
-float randombit()
+static float
+randombit()
 {
   int r = rand()&1;
   return (float)(-1 + 2*r);
@@ -90,47 +83,25 @@ gr_ofdm_bpsk_mapper::work(int noutput_items,
     d_msg = d_msgq->delete_head();	   // block, waiting for a message
     d_msg_offset = 0;
     d_bit_offset = 0;
-    d_header_sent = 0;
+    d_pending_flag = 1;			   // new packet, write start of packet flag
     
     if((d_msg->length() == 0) && (d_msg->type() == 1)) {
       d_msg.reset();
-      return -1;
+      return -1;		// We're done; no more messages coming.
     }
   }
 
-  if(output_items.size() == 2) {
-    char *sig = (char *)output_items[1];
-    if(d_header_sent == 1) {
-      sig[0] = 1;
-    }
-    else {
-      sig[0] = 0;
-    }
-  }
+  char *out_flag = 0;
+  if(output_items.size() == 2)
+    out_flag = (char *) output_items[1];
   
+
   // Build a single symbol:
+  
 
   // 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++;
-
-    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++;
-
-    return 1;
-  }
-
   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;
@@ -150,14 +121,16 @@ gr_ofdm_bpsk_mapper::work(int noutput_items,
       i++;
     }
 
-    if (d_msg->type() == 1)	           // type == 1 sets EOF
+    if (d_msg->type() == 1)	        // type == 1 sets EOF
       d_eof = true;
-    d_msg.reset();   // finished packet, free message
- 
+    d_msg.reset();   			// finished packet, free message
     assert(d_bit_offset == 0);
-    return 1;          // produced one symbol
   }
-  
+
+  if (out_flag)
+    out_flag[0] = d_pending_flag;
+  d_pending_flag = 0;
+
   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 41b2f5bede..da78ca4753 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.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
  * 
@@ -27,19 +27,16 @@
 #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 msgq_limit, 
-			  unsigned occupied_carriers, unsigned int fft_length,
-			  const std::vector<gr_complex> &known_symbol1, 
-			  const std::vector<gr_complex> &known_symbol2);
+			  unsigned occupied_carriers, unsigned int fft_length);
 
 /*!
- * \brief take a stream of bytes in and map to a vector of complex
+ * \brief take a message in and map to a vector of complex
  * constellation points suitable for IFFT input to be used in an ofdm
  * modulator.  Simple BPSK version.
  */
@@ -47,28 +44,22 @@ gr_make_ofdm_bpsk_mapper (unsigned msgq_limit,
 class gr_ofdm_bpsk_mapper : public gr_sync_block
 {
   friend gr_ofdm_bpsk_mapper_sptr
-    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);
-  
+  gr_make_ofdm_bpsk_mapper (unsigned msgq_limit, 
+			    unsigned occupied_carriers, unsigned int fft_length);
  protected:
   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);
-  
+		       unsigned occupied_carriers, unsigned int fft_length);
+
  private:
   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_fft_length;
-  unsigned int d_bit_offset;
-  unsigned int d_header_sent;
-  std::vector<gr_complex> d_known_symbol1, d_known_symbol2;
+  unsigned int 		d_occupied_carriers;
+  unsigned int 		d_fft_length;
+  unsigned int 		d_bit_offset;
+  int			d_pending_flag;
 
  public:
   ~gr_ofdm_bpsk_mapper(void);
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 d0094062a6..2af37d641e 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.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
  * 
@@ -20,25 +20,20 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#include <vector>
-
 GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper);
 
 gr_ofdm_bpsk_mapper_sptr 
 gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit,
 			  unsigned int bits_per_symbol, 
-			  unsigned int fft_length,
-			  const std::vector<gr_complex> &known_symbol1, 
-			  const std::vector<gr_complex> &known_symbol2);
+			  unsigned int fft_length);
+
 
 class gr_ofdm_bpsk_mapper : public gr_sync_block
 {
  protected:
   gr_ofdm_bpsk_mapper (unsigned int msgq_limit,
 		       unsigned int bits_per_symbol,
-		       unsigned int fft_length,
-		       const std::vector<gr_complex> &known_symbol1, 
-		       const std::vector<gr_complex> &known_symbol2);
+		       unsigned int fft_length);
 
  public:
   gr_msg_queue_sptr msgq();
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
index 3973b83749..4eb6626a17 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
@@ -30,28 +30,32 @@
 
 #define VERBOSE 0
 #define M_TWOPI (2*M_PI)
+#define MAX_NUM_SYMBOLS 1000
 
 gr_ofdm_correlator_sptr
 gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length, 
 			 unsigned int cplen,
 			 const std::vector<gr_complex> &known_symbol1, 
-			 const std::vector<gr_complex> &known_symbol2)
+			 const std::vector<gr_complex> &known_symbol2,
+			 unsigned int max_fft_shift_len)
 {
   return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, fft_length, cplen,
-							  known_symbol1, known_symbol2));
+							  known_symbol1, known_symbol2,
+							  max_fft_shift_len));
 }
 
 gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int fft_length, 
 					unsigned int cplen,
 					const std::vector<gr_complex> &known_symbol1, 
-					const std::vector<gr_complex> &known_symbol2)
+					const std::vector<gr_complex> &known_symbol2,
+					unsigned int max_fft_shift_len)
   : gr_block ("ofdm_correlator",
 	      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_fft_length(fft_length),
     d_cplen(cplen),
-    d_freq_shift_len(5),
+    d_freq_shift_len(max_fft_shift_len),
     d_known_symbol1(known_symbol1),
     d_known_symbol2(known_symbol2),
     d_coarse_freq(0),
@@ -62,16 +66,24 @@ gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int
 
   std::vector<gr_complex>::iterator i1, i2;
 
-  int i = 0;
+  unsigned int i = 0, j = 0;
   gr_complex one(1.0, 0.0);
   for(i1 = d_known_symbol1.begin(), i2 = d_known_symbol2.begin(); i1 != d_known_symbol1.end(); i1++, i2++) {
     d_diff_corr_factor[i] = one / ((*i1) * conj(*i2));
     i++;
   }
+  
+  d_phase_lut = new gr_complex[(2*d_freq_shift_len+1) * MAX_NUM_SYMBOLS];
+  for(i = 0; i <= 2*d_freq_shift_len; i++) {
+    for(j = 0; j < MAX_NUM_SYMBOLS; j++) {
+      d_phase_lut[j + i*MAX_NUM_SYMBOLS] =  gr_expj(-M_TWOPI*d_cplen/d_fft_length*(i-d_freq_shift_len)*j);
+    }
+  }
 }
 
 gr_ofdm_correlator::~gr_ofdm_correlator(void)
 {
+  delete [] d_phase_lut;
 }
 
 void
@@ -87,7 +99,12 @@ gr_ofdm_correlator::coarse_freq_comp(int freq_delta, int 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);
+  //return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
+
+  assert(d_freq_shift_len + freq_delta >= 0);
+  assert(symbol_count <= MAX_NUM_SYMBOLS);
+
+  return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count];
 }
 
 bool
@@ -132,14 +149,17 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
 	d_snr_est = 10*log10(fabs(h_sqrd.real()/h_sqrd.imag()));
       }
 
+#if VERBOSE
       printf("CORR: Found, bin %d\tSNR Est %f dB\tcorr power fraction %f\n", 
              search_delta, d_snr_est, h_sqrd.real()/power);
+#endif
+
       // search_delta,10*log10(h_sqrd.real()/fabs(h_sqrd.imag())),h_sqrd.real()/power);
       break;
     }
     else {
       if(search_delta <= 0)
-	search_delta = (-search_delta) + 1;
+	search_delta = (-search_delta) + 2;
       else
 	search_delta = -search_delta;
     }
@@ -161,10 +181,6 @@ gr_ofdm_correlator::calculate_equalizer(const gr_complex *previous, const gr_com
     d_hestimate[i] = 0.5F * (d_known_symbol1[i] / previous[i+zeros_on_left+d_coarse_freq] +
 			     d_known_symbol2[i] / (coarse_freq_comp(d_coarse_freq,1)*
 						   current[i+zeros_on_left+d_coarse_freq]));
-    
-#if VERBOSE
-    fprintf(stderr, "%f %f ", d_hestimate[i].real(), d_hestimate[i].imag());
-#endif
   }
 #if VERBOSE
   fprintf(stderr, "\n");
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
index 44a6847af3..36aa1f0b69 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
@@ -34,7 +34,8 @@ gr_ofdm_correlator_sptr
 gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 			 unsigned int cplen,
 			 const std::vector<gr_complex> &known_symbol1, 
-			 const std::vector<gr_complex> &known_symbol2);
+			 const std::vector<gr_complex> &known_symbol2,
+			 unsigned int max_fft_shift_len=4);
 
 /*!
  * \brief take a vector of complex constellation points in from an FFT
@@ -65,18 +66,21 @@ class gr_ofdm_correlator : public gr_block
    *                            start of a frame after known_symbol1 (usually a BPSK PN sequence). 
    *                            Both of these start symbols are differentially correlated to compensate
    *                            for phase changes between symbols. 
+   * \param max_fft_shift_len   Set's the maximum distance you can look between bins for correlation
    */
   friend gr_ofdm_correlator_sptr
   gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 			   unsigned int cplen,
 			   const std::vector<gr_complex> &known_symbol1, 
-			   const std::vector<gr_complex> &known_symbol2);
+			   const std::vector<gr_complex> &known_symbol2,
+			   unsigned int max_fft_shift_len);
   
  protected:
   gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
 		      unsigned int cplen,
 		      const std::vector<gr_complex> &known_symbol1, 
-		      const std::vector<gr_complex> &known_symbol2);
+		      const std::vector<gr_complex> &known_symbol2,
+		      unsigned int max_fft_shift_len);
   
  private:
   unsigned char slicer(gr_complex x);
@@ -96,6 +100,8 @@ class gr_ofdm_correlator : public gr_block
   unsigned int d_phase_count;           // !< \brief accumulator for coarse freq correction
   float d_snr_est;                      // !< an estimation of the signal to noise ratio
 
+  gr_complex *d_phase_lut;  // !< look-up table for coarse frequency compensation
+
   void forecast(int noutput_items, gr_vector_int &ninput_items_required);
 
  public:
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
index 40f9f83ff8..700faaa097 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
@@ -29,7 +29,8 @@ gr_make_ofdm_correlator (unsigned int occupied_carriers,
 			 unsigned int fft_length,
 			 unsigned int cplen,
 			 const std::vector<gr_complex> &known_symbol1, 
-			 const std::vector<gr_complex> &known_symbol2);
+			 const std::vector<gr_complex> &known_symbol2,
+			 unsigned int max_fft_shift_len=4);
 
 class gr_ofdm_correlator : public gr_sync_decimator
 {
@@ -38,7 +39,8 @@ class gr_ofdm_correlator : public gr_sync_decimator
 		      unsigned int fft_length,
 		      unsigned int cplen,
 		      const std::vector<gr_complex> &known_symbol1, 
-		      const std::vector<gr_complex> &known_symbol2);
+		      const std::vector<gr_complex> &known_symbol2,
+		      unsigned int max_fft_shift_len);
 
  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
index acaf1258bd..c04aca3d7a 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
@@ -79,6 +79,14 @@ unsigned char gr_ofdm_frame_sink::bpsk_slicer(gr_complex x)
   return (unsigned char)(x.real() > 0 ? 1 : 0);
 }
 
+unsigned char gr_ofdm_frame_sink::qpsk_slicer(gr_complex x)
+{
+  unsigned char i = (x.real() > 0 ? 1 : 0);
+  unsigned char q = (x.imag() > 0 ? 1 : 0);
+
+  return (q << 1) | i;
+}
+
 unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
 					       unsigned char *out)
 {
@@ -101,23 +109,56 @@ unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
   return bytes_produced;
 }
 
+unsigned int gr_ofdm_frame_sink::qpsk_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 |= qpsk_slicer(in[i++]) << (d_byte_offset);
+      d_byte_offset += 2;
+    }
+
+    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)
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
+			const std::string &mod)
 {
-  return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers));
+  return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers, mod));
 }
 
 
-gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
+gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
+				       const std::string &mod)
   : 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)];
+  d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/4.0)];
+
+  if(mod == "qpsk") {
+    d_demapper = &gr_ofdm_frame_sink::qpsk_demapper;
+  }
+  else if(mod == "bpsk") {
+    d_demapper = &gr_ofdm_frame_sink::bpsk_demapper;
+  }
+  else {
+    throw std::invalid_argument("Modulation type must be BPSK or QPSK.");  
+  }
 
   enter_search();
 }
@@ -134,15 +175,15 @@ gr_ofdm_frame_sink::work (int noutput_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);
-  
+  //bytes = bpsk_demapper(&in[0], d_bytes_out);
+  bytes = (this->*d_demapper)(&in[0], d_bytes_out);  
+
   switch(d_state) {
       
   case STATE_SYNC_SEARCH:    // Look for flag indicating beginning of pkt
@@ -155,12 +196,13 @@ gr_ofdm_frame_sink::work (int noutput_items,
     break;
 
   case STATE_HAVE_SYNC:
-    if(sig[0])
-      printf("ERROR -- Found SYNC in HAVE_SYNC\n");
-    if (VERBOSE)
+    if (VERBOSE) {
+      if(sig[0])
+	printf("ERROR -- Found SYNC in HAVE_SYNC\n");
       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);
@@ -174,10 +216,9 @@ gr_ofdm_frame_sink::work (int noutput_items,
 	// 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");
+	  
+	  if (VERBOSE)
+	    printf("\nPacket Length: %d\n", d_packetlen);
 	  
 	  while((j < bytes) && (d_packetlen_cnt < d_packetlen)) {
 	    d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
@@ -201,10 +242,11 @@ gr_ofdm_frame_sink::work (int noutput_items,
     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");
+    if (VERBOSE) {
+      if(sig[0])
+	printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen);
+      fprintf(stderr,"Packet Build\n");
+    }
     
     j = 0;
     while(j < bytes) {
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
index d77c76741e..8f38abb04b 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2005,2006 Free Software Foundation, Inc.
+ * Copyright 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -30,30 +30,22 @@ 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);
+gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+			 const std::string &mod);
 
 /*!
- * \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.
+ * \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs
+ * them into packets, and sends to to a message queue sink.
+
+ * NOTE: The mod input parameter simply chooses a pre-defined demapper/slicer. Eventually,
+ * we want to be able to pass in a reference to an object to do the demapping and slicing
+ * for a given modulation type.
  */
 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);
+  gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+			   const std::string &mod);
 
  private:
   enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
@@ -78,7 +70,8 @@ class gr_ofdm_frame_sink : public gr_sync_block
   int		     d_packetlen_cnt;		// how many so far
 
  protected:
-  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+		     const std::string &mod);
 
   void enter_search();
   void enter_have_sync();
@@ -94,6 +87,13 @@ class gr_ofdm_frame_sink : public gr_sync_block
   unsigned int bpsk_demapper(const gr_complex *in,
 			     unsigned char *out);  
 
+  unsigned char qpsk_slicer(gr_complex x);
+  unsigned int qpsk_demapper(const gr_complex *in,
+			     unsigned char *out);
+
+  // pointer to mod-specific demapper
+  unsigned int (gr_ofdm_frame_sink::*d_demapper)(const gr_complex *in, unsigned char *out);
+
  public:
   ~gr_ofdm_frame_sink();
 
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
index b05c8b795c..32a0ec9fdf 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -23,12 +23,14 @@
 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);
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+			const std::string &mod);
 
 class gr_ofdm_frame_sink : public gr_sync_block
 {
  protected:
-  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+  gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+		     const std::string &mod);
 
  public:
   ~gr_ofdm_frame_sink();
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc
new file mode 100644
index 0000000000..41b23fcd55
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc
@@ -0,0 +1,186 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_ofdm_insert_preamble.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_ofdm_insert_preamble_sptr
+gr_make_ofdm_insert_preamble(int fft_length,
+			     const std::vector<std::vector<gr_complex> > &preamble)
+{
+  return gr_ofdm_insert_preamble_sptr(new gr_ofdm_insert_preamble(fft_length,
+								  preamble));
+}
+
+gr_ofdm_insert_preamble::gr_ofdm_insert_preamble
+       (int fft_length,
+	const std::vector<std::vector<gr_complex> > &preamble)
+  : gr_block("ofdm_insert_preamble",
+	     gr_make_io_signature2(2, 2,
+				   sizeof(gr_complex)*fft_length,
+				   sizeof(char)),
+	     gr_make_io_signature2(1, 2,
+				   sizeof(gr_complex)*fft_length,
+				   sizeof(char))),
+    d_fft_length(fft_length),
+    d_preamble(preamble),
+    d_state(ST_IDLE),
+    d_nsymbols_output(0),
+    d_pending_flag(0)
+{
+  // sanity check preamble symbols
+  for (size_t i = 0; i < d_preamble.size(); i++){
+    if (d_preamble[i].size() != (size_t) d_fft_length)
+      throw std::invalid_argument("gr_ofdm_insert_preamble: invalid length for preamble symbol");
+  }
+
+  enter_idle();
+}
+
+
+gr_ofdm_insert_preamble::~gr_ofdm_insert_preamble()
+{
+}
+
+int
+gr_ofdm_insert_preamble::general_work (int noutput_items,
+				       gr_vector_int &ninput_items_v,
+				       gr_vector_const_void_star &input_items,
+				       gr_vector_void_star &output_items)
+{
+  int ninput_items = std::min(ninput_items_v[0], ninput_items_v[1]);
+  const gr_complex *in_sym = (const gr_complex *) input_items[0];
+  const unsigned char *in_flag = (const unsigned char *) input_items[1];
+
+  gr_complex *out_sym = (gr_complex *) output_items[0];
+  unsigned char *out_flag = 0;
+  if (output_items.size() == 2)
+    out_flag = (unsigned char *) output_items[1];
+
+
+  int no = 0;	// number items output
+  int ni = 0;	// number items read from input
+
+
+#define write_out_flag() 			\
+  do { if (out_flag) 				\
+          out_flag[no] = d_pending_flag; 	\
+       d_pending_flag = 0; 			\
+  } while(0)
+
+
+  while (no < noutput_items && ni < ninput_items){
+    switch(d_state){
+    case ST_IDLE:
+      if (in_flag[ni] & 0x1)	// this is first symbol of new payload
+	enter_preamble();
+      else
+	ni++;			// eat one input symbol
+      break;
+      
+    case ST_PREAMBLE:
+      assert(in_flag[ni] & 0x1);
+      if (d_nsymbols_output >= (int) d_preamble.size()){
+	// we've output all the preamble
+	enter_first_payload();
+      }
+      else {
+	memcpy(&out_sym[no * d_fft_length],
+	       &d_preamble[d_nsymbols_output][0],
+	       d_fft_length*sizeof(gr_complex));
+
+	write_out_flag();
+	no++;
+	d_nsymbols_output++;
+      }
+      break;
+      
+    case ST_FIRST_PAYLOAD:
+      // copy first payload symbol from input to output
+      memcpy(&out_sym[no * d_fft_length],
+	     &in_sym[ni * d_fft_length],
+	     d_fft_length * sizeof(gr_complex));
+
+      write_out_flag();
+      no++;
+      ni++;
+      enter_payload();
+      break;
+      
+    case ST_PAYLOAD:
+      if (in_flag[ni] & 0x1){	// this is first symbol of a new payload
+	enter_preamble();
+	break;
+      }
+
+      // copy a symbol from input to output
+      memcpy(&out_sym[no * d_fft_length],
+	     &in_sym[ni * d_fft_length],
+	     d_fft_length * sizeof(gr_complex));
+
+      write_out_flag();
+      no++;
+      ni++;
+      break;
+
+    default:
+      std::cerr << "gr_ofdm_insert_preamble: (can't happen) invalid state, resetting\n";
+      enter_idle();
+    }
+  }
+
+  consume_each(ni);
+  return no;
+}
+
+void
+gr_ofdm_insert_preamble::enter_idle()
+{
+  d_state = ST_IDLE;
+  d_nsymbols_output = 0;
+  d_pending_flag = 0;
+}
+
+void
+gr_ofdm_insert_preamble::enter_preamble()
+{
+  d_state = ST_PREAMBLE;
+  d_nsymbols_output = 0;
+  d_pending_flag = 1;
+}
+
+void
+gr_ofdm_insert_preamble::enter_first_payload()
+{
+  d_state = ST_FIRST_PAYLOAD;
+}
+
+void
+gr_ofdm_insert_preamble::enter_payload()
+{
+  d_state = ST_PAYLOAD;
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h
new file mode 100644
index 0000000000..48622b06d9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h
@@ -0,0 +1,102 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_INSERT_PREAMBLE_H
+#define INCLUDED_GR_OFDM_INSERT_PREAMBLE_H
+
+#include <gr_block.h>
+#include <vector>
+
+class gr_ofdm_insert_preamble;
+typedef boost::shared_ptr<gr_ofdm_insert_preamble> gr_ofdm_insert_preamble_sptr;
+
+gr_ofdm_insert_preamble_sptr
+gr_make_ofdm_insert_preamble(int fft_length,
+			     const std::vector<std::vector<gr_complex> > &preamble);
+
+/*!
+ * \brief insert "pre-modulated" preamble symbols before each payload.
+ *
+ * <pre>
+ * input 1: stream of vectors of gr_complex [fft_length]
+ *          These are the modulated symbols of the payload.
+ *
+ * input 2: stream of char.  The LSB indicates whether the corresponding
+ *          symbol on input 1 is the first symbol of the payload or not.
+ *          It's a 1 if the corresponding symbol is the first symbol,
+ *          otherwise 0.
+ *
+ * N.B., this implies that there must be at least 1 symbol in the payload.
+ *
+ *
+ * output 1: stream of vectors of gr_complex [fft_length]
+ *           These include the preamble symbols and the payload symbols.
+ *
+ * output 2: stream of char.  The LSB indicates whether the corresponding
+ *           symbol on input 1 is the first symbol of a packet (i.e., the
+ *           first symbol of the preamble.)   It's a 1 if the corresponding
+ *           symbol is the first symbol, otherwise 0.
+ * </pre>
+ *
+ * \param fft_length length of each symbol in samples.
+ * \param preamble   vector of symbols that represent the pre-modulated preamble.
+ */
+
+class gr_ofdm_insert_preamble : public gr_block
+{
+  friend gr_ofdm_insert_preamble_sptr
+  gr_make_ofdm_insert_preamble(int fft_length,
+			       const std::vector<std::vector<gr_complex> > &preamble);
+
+protected:
+  gr_ofdm_insert_preamble(int fft_length,
+			  const std::vector<std::vector<gr_complex> > &preamble);
+
+private:
+  enum state_t {
+    ST_IDLE,
+    ST_PREAMBLE,
+    ST_FIRST_PAYLOAD,
+    ST_PAYLOAD
+  };
+
+  int						d_fft_length;
+  const std::vector<std::vector<gr_complex> > 	d_preamble;
+  state_t					d_state;
+  int						d_nsymbols_output;
+  int						d_pending_flag;
+
+  void enter_idle();
+  void enter_preamble();
+  void enter_first_payload();
+  void enter_payload();
+  
+
+public:
+  ~gr_ofdm_insert_preamble();
+
+  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_OFDM_INSERT_PREAMBLE_H */
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i
new file mode 100644
index 0000000000..183e91b0e3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i
@@ -0,0 +1,35 @@
+/* -*- 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,ofdm_insert_preamble);
+
+gr_ofdm_insert_preamble_sptr
+gr_make_ofdm_insert_preamble(int fft_length,
+			     const std::vector<std::vector<gr_complex> > &preamble);
+
+
+class gr_ofdm_insert_preamble : public gr_block
+{
+ protected:
+  gr_ofdm_insert_preamble(int fft_length,
+			  const std::vector<std::vector<gr_complex> > &preamble);
+};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc
new file mode 100644
index 0000000000..8e774fe766
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc
@@ -0,0 +1,249 @@
+/* -*- 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_qam_mapper.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_ofdm_qam_mapper_sptr
+gr_make_ofdm_qam_mapper (unsigned int msgq_limit, 
+			 unsigned int occupied_carriers, unsigned int fft_length,
+			 int m)
+{
+  return gr_ofdm_qam_mapper_sptr (new gr_ofdm_qam_mapper (msgq_limit, occupied_carriers, fft_length, m));
+}
+
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
+gr_ofdm_qam_mapper::gr_ofdm_qam_mapper (unsigned int msgq_limit, 
+					unsigned int occupied_carriers, unsigned int fft_length,
+					int m)
+  : gr_sync_block ("ofdm_qam_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_fft_length(fft_length),
+    d_bit_offset(0),
+    d_pending_flag(0),
+    d_mod_order(m)
+{
+  if (!(d_occupied_carriers <= d_fft_length))
+    throw std::invalid_argument("gr_ofdm_qam_mapper: occupied carriers must be <= fft_length");
+
+  bool ok = false;
+  if(m == 2) {
+    ok = true;
+  }
+  if(m == 4) {
+    ok = true;
+  }
+  if(m == 16) {
+    ok = true;
+  }
+  if(m == 64) {
+    ok = true;
+  }
+  if(m == 256) {
+    ok = true;
+  }
+  
+  if(!ok)
+    throw std::invalid_argument("Order M must be [2, 4, 16, 64, 256]");  
+
+  make_constellation();
+}
+
+gr_ofdm_qam_mapper::~gr_ofdm_qam_mapper(void)
+{
+}
+
+void gr_ofdm_qam_mapper::make_constellation()
+{
+  int i = 0, j = 0, ii = 0, jj = 0;
+  // number of bits/symbol (log2(M))
+  int k = (int)(log10(d_mod_order) / log10(2.0));
+
+  int a, b;
+  float re, im;
+  float coeff = 1;
+  std::vector<int> bits_i, bits_q;
+
+  int rr = 0;
+  int ss = 0;
+  int ll = bits_i.size();
+
+  for(i=0; i < d_mod_order; i++) {
+    a = (i & (0x01 << (k-1))) >> (k-1);
+    b = (i & (0x01 << (k-2))) >> (k-2);
+    for(j=2; j < k; j+=2) {
+      bits_i.push_back( (i & (0x01 << (k-j-1))) >> (k-j-1));
+      bits_q.push_back( (i & (0x01 << (k-(j+1)-1))) >> (k-(j+1)-1));
+    }
+    
+    ss = 0;
+    ll = bits_i.size();
+    for(ii = 0; ii < ll; ii++) {
+      rr = 0;
+      for(jj = 0; jj < (ll-ii); jj++) {
+	rr = abs(bits_i[jj] - rr);
+      }
+      ss += rr * pow(2.0, ii+1.0);
+    }
+    re = (2.0*a-1.0)*(ss+1.0);
+    
+    ss = 0;
+    ll = bits_q.size();
+    for(ii = 0; ii < ll; ii++) {
+      rr = 0;
+      for(jj = 0; jj < (ll-ii); jj++) {
+	rr = abs(bits_q[jj] - rr);
+      }
+      ss += rr*pow(2.0, ii+1.0);
+    }
+    im = (2.0*b-1.0)*(ss+1.0);
+      
+    a = std::max(re, im);
+    if(a > coeff) {
+      coeff = a;
+    }
+    d_constellation_map.push_back(gr_complex(re, im));
+  }
+  
+  d_constellation_map[0] = gr_complex(-3, -3);
+  d_constellation_map[1] = gr_complex(-3, -1);
+  d_constellation_map[2] = gr_complex(-3, 1);
+  d_constellation_map[3] = gr_complex(-3, 3);
+  d_constellation_map[4] = gr_complex(-1, -3);
+  d_constellation_map[5] = gr_complex(-1, -1);
+  d_constellation_map[6] = gr_complex(-1, 1);
+  d_constellation_map[7] = gr_complex(-1, 3);
+  d_constellation_map[8] = gr_complex(1, -3);
+  d_constellation_map[9] = gr_complex(1, -1);
+  d_constellation_map[10] = gr_complex(1, 1);
+  d_constellation_map[11] = gr_complex(1, 3);
+  d_constellation_map[12] = gr_complex(3, -3);
+  d_constellation_map[13] = gr_complex(3, -1);
+  d_constellation_map[14] = gr_complex(3, 1);
+  d_constellation_map[15] = gr_complex(3, 3);
+
+  coeff = sqrt(31.0)/2.0;
+  for(i = 0; i < d_constellation_map.size(); i++) {
+    d_constellation_map[i] /= coeff;
+    printf("const[%d]: %f + j%f\n", i, d_constellation_map[i].real(), d_constellation_map[i].imag());
+  }
+}
+
+static float
+randombit()
+{
+  int r = rand()&1;
+  return (float)(-1 + 2*r);
+}
+
+int
+gr_ofdm_qam_mapper::work(int noutput_items,
+			  gr_vector_const_void_star &input_items,
+			  gr_vector_void_star &output_items)
+{
+  gr_complex *out = (gr_complex *)output_items[0];
+  
+  unsigned int i=0;
+  unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
+
+  //printf("OFDM QAM Mapper:  ninput_items: %d   noutput_items: %d\n", ninput_items[0], noutput_items);
+
+  if(d_eof) {
+    return -1;
+  }
+  
+  if(!d_msg) {
+    d_msg = d_msgq->delete_head();	   // block, waiting for a message
+    d_msg_offset = 0;
+    d_bit_offset = 0;
+    d_pending_flag = 1;			   // new packet, write start of packet flag
+    
+    if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+      d_msg.reset();
+      return -1;		// We're done; no more messages coming.
+    }
+  }
+
+  char *out_flag = 0;
+  if(output_items.size() == 2)
+    out_flag = (char *) output_items[1];
+  
+
+  // Build a single symbol:
+  
+
+  // Initialize all bins to 0 to set unused carriers
+  memset(out, 0, d_fft_length*sizeof(gr_complex));
+  
+  i = 0;
+  while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+    unsigned char bit0 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit1 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit2 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit3 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+
+    unsigned char bit = (bit0 << 3) | (bit1 << 2) | (bit2 << 1) | (bit3 << 0);
+    
+    out[i + zeros_on_left] = d_constellation_map[bit];
+    i++;
+    if(d_bit_offset == 8) {
+      d_bit_offset = 0;
+      d_msg_offset++;
+    }
+  }
+
+  // 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] = d_constellation_map[rand() & 0x0F];
+      i++;
+    }
+
+    if (d_msg->type() == 1)	        // type == 1 sets EOF
+      d_eof = true;
+    d_msg.reset();   			// finished packet, free message
+    assert(d_bit_offset == 0);
+  }
+
+  if (out_flag)
+    out_flag[0] = d_pending_flag;
+  d_pending_flag = 0;
+
+  return 1;  // produced symbol
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h
new file mode 100644
index 0000000000..2b2a8e39f4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h
@@ -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.
+ */
+
+#ifndef INCLUDED_GR_OFDM_QAM_MAPPER_H
+#define INCLUDED_GR_OFDM_QAM_MAPPER_H
+
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_ofdm_qam_mapper;
+typedef boost::shared_ptr<gr_ofdm_qam_mapper> gr_ofdm_qam_mapper_sptr;
+
+gr_ofdm_qam_mapper_sptr 
+gr_make_ofdm_qam_mapper (unsigned msgq_limit, 
+			 unsigned occupied_carriers, unsigned int fft_length,
+			 int m=4);
+
+/*!
+ * \brief take a message in and map to a vector of complex
+ * constellation points suitable for IFFT input to be used in an ofdm
+ * modulator.  Simple QAM version.
+ */
+
+class gr_ofdm_qam_mapper : public gr_sync_block
+{
+  friend gr_ofdm_qam_mapper_sptr
+  gr_make_ofdm_qam_mapper (unsigned msgq_limit, 
+			   unsigned occupied_carriers, unsigned int fft_length,
+			   int m);
+ protected:
+  gr_ofdm_qam_mapper (unsigned msgq_limit, 
+		      unsigned occupied_carriers, unsigned int fft_length,
+		      int m);
+
+ private:
+  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_fft_length;
+  unsigned int 		d_bit_offset;
+  int			d_pending_flag;
+
+  int                     d_mod_order;
+  std::vector<gr_complex> d_constellation_map;
+
+  void make_constellation();
+
+ public:
+  ~gr_ofdm_qam_mapper(void);
+
+  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);
+
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i
new file mode 100644
index 0000000000..84fd0851c4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i
@@ -0,0 +1,46 @@
+/* -*- 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,ofdm_qam_mapper);
+
+gr_ofdm_qam_mapper_sptr 
+gr_make_ofdm_qam_mapper (unsigned int msgq_limit,
+			 unsigned int bits_per_symbol, 
+			 unsigned int fft_length,
+			 int m=16);
+
+
+class gr_ofdm_qam_mapper : public gr_sync_block
+{
+ protected:
+  gr_ofdm_qam_mapper (unsigned int msgq_limit,
+		      unsigned int bits_per_symbol,
+		      unsigned int fft_length,
+		      int m);
+  
+ public:
+  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_qpsk_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
new file mode 100644
index 0000000000..cad14c706a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
@@ -0,0 +1,141 @@
+/* -*- 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_qpsk_mapper.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_ofdm_qpsk_mapper_sptr
+gr_make_ofdm_qpsk_mapper (unsigned int msgq_limit, 
+			  unsigned int occupied_carriers, unsigned int fft_length)
+{
+  return gr_ofdm_qpsk_mapper_sptr (new gr_ofdm_qpsk_mapper (msgq_limit, occupied_carriers, fft_length));
+}
+
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
+gr_ofdm_qpsk_mapper::gr_ofdm_qpsk_mapper (unsigned int msgq_limit, 
+					  unsigned int occupied_carriers, unsigned int fft_length)
+  : gr_sync_block ("ofdm_qpsk_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_fft_length(fft_length),
+    d_bit_offset(0),
+    d_pending_flag(0)
+{
+  if (!(d_occupied_carriers <= d_fft_length))
+    throw std::invalid_argument("gr_ofdm_qpsk_mapper: occupied carriers must be <= fft_length");
+}
+
+gr_ofdm_qpsk_mapper::~gr_ofdm_qpsk_mapper(void)
+{
+}
+
+static gr_complex
+randombit()
+{
+  int r1 = rand()&1;
+  int r2 = rand()&1;
+  return gr_complex((0.707)*(-1 + 2*r1),(0.707)*(-1 + 2*r2));
+}
+
+int
+gr_ofdm_qpsk_mapper::work(int noutput_items,
+			  gr_vector_const_void_star &input_items,
+			  gr_vector_void_star &output_items)
+{
+  gr_complex *out = (gr_complex *)output_items[0];
+  
+  unsigned int i=0;
+  unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+  unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
+
+  //printf("OFDM QPSK Mapper:  ninput_items: %d   noutput_items: %d\n", ninput_items[0], noutput_items);
+
+  if(d_eof) {
+    return -1;
+  }
+  
+  if(!d_msg) {
+    d_msg = d_msgq->delete_head();	   // block, waiting for a message
+    d_msg_offset = 0;
+    d_bit_offset = 0;
+    d_pending_flag = 1;			   // new packet, write start of packet flag
+    
+    if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+      d_msg.reset();
+      return -1;		// We're done; no more messages coming.
+    }
+  }
+
+  char *out_flag = 0;
+  if(output_items.size() == 2)
+    out_flag = (char *) output_items[1];
+  
+
+  // Build a single symbol:
+  
+
+  // Initialize all bins to 0 to set unused carriers
+  memset(out, 0, d_fft_length*sizeof(gr_complex));
+  
+  i = 0;
+  while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+    unsigned char bit0 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    unsigned char bit1 = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+    d_bit_offset++;
+    
+    out[i + zeros_on_left] = gr_complex((0.707)*(-1+2*(bit0)), (0.707)*(-1+2*(bit1)) );
+    i++;
+    if(d_bit_offset == 8) {
+      d_bit_offset = 0;
+      d_msg_offset++;
+    }
+  }
+
+  // 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] = randombit();
+      i++;
+    }
+
+    if (d_msg->type() == 1)	        // type == 1 sets EOF
+      d_eof = true;
+    d_msg.reset();   			// finished packet, free message
+    assert(d_bit_offset == 0);
+  }
+
+  if (out_flag)
+    out_flag[0] = d_pending_flag;
+  d_pending_flag = 0;
+
+  return 1;  // produced symbol
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h
new file mode 100644
index 0000000000..93bd8f9878
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h
@@ -0,0 +1,76 @@
+/* -*- 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_OFDM_QPSK_MAPPER_H
+#define INCLUDED_GR_OFDM_QPSK_MAPPER_H
+
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_ofdm_qpsk_mapper;
+typedef boost::shared_ptr<gr_ofdm_qpsk_mapper> gr_ofdm_qpsk_mapper_sptr;
+
+gr_ofdm_qpsk_mapper_sptr 
+gr_make_ofdm_qpsk_mapper (unsigned msgq_limit, 
+			  unsigned occupied_carriers, unsigned int fft_length);
+
+/*!
+ * \brief take a message in and map to a vector of complex
+ * constellation points suitable for IFFT input to be used in an ofdm
+ * modulator.  Simple QPSK version.
+ */
+
+class gr_ofdm_qpsk_mapper : public gr_sync_block
+{
+  friend gr_ofdm_qpsk_mapper_sptr
+  gr_make_ofdm_qpsk_mapper (unsigned msgq_limit, 
+			    unsigned occupied_carriers, unsigned int fft_length);
+ protected:
+  gr_ofdm_qpsk_mapper (unsigned msgq_limit, 
+		       unsigned occupied_carriers, unsigned int fft_length);
+
+ private:
+  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_fft_length;
+  unsigned int 		d_bit_offset;
+  int			d_pending_flag;
+
+ public:
+  ~gr_ofdm_qpsk_mapper(void);
+
+  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);
+
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i
new file mode 100644
index 0000000000..5f19f08f3a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i
@@ -0,0 +1,44 @@
+/* -*- 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,ofdm_qpsk_mapper);
+
+gr_ofdm_qpsk_mapper_sptr 
+gr_make_ofdm_qpsk_mapper (unsigned int msgq_limit,
+			  unsigned int bits_per_symbol, 
+			  unsigned int fft_length);
+
+
+class gr_ofdm_qpsk_mapper : public gr_sync_block
+{
+ protected:
+  gr_ofdm_qpsk_mapper (unsigned int msgq_limit,
+		       unsigned int bits_per_symbol,
+		       unsigned int fft_length);
+
+ public:
+  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_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
index 5f5a91fd23..1ca738a291 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
@@ -67,7 +67,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
 
   int found=0;
 
-  unsigned int i=d_fft_length-1;
+  int i=d_fft_length-1;
 
   while(!found && i<std::min(ninput_items[0],ninput_items[1]) )
     if(trigger[i])
@@ -77,7 +77,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
 
   if(found) {
     assert(i-d_fft_length+1 >= 0);
-    for(unsigned int j=i-d_fft_length+1;j<=i;j++)
+    for(int j=i-d_fft_length+1;j<=i;j++)
       *optr++ = iptr[j];
     consume_each(i-d_fft_length+2);
     //printf("OFDM Sampler found:  ninput_items: %d/%d   noutput_items: %d  consumed: %d   found: %d\n", 
diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.cc b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc
new file mode 100644
index 0000000000..6b0535e189
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc
@@ -0,0 +1,74 @@
+/* -*- 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_regenerate_bb.h>
+#include <gr_io_signature.h>
+
+gr_regenerate_bb_sptr
+gr_make_regenerate_bb (int period, unsigned int max_regen)
+{
+  return gr_regenerate_bb_sptr (new gr_regenerate_bb (period, max_regen));
+}
+
+gr_regenerate_bb::gr_regenerate_bb (int period, unsigned int max_regen)
+  : gr_sync_block ("regenerate_bb",
+		   gr_make_io_signature (1, 1, sizeof (char)),
+		   gr_make_io_signature (1, 1, sizeof (char))),
+    d_period(period),
+    d_max_regen(max_regen),
+    d_regen_count(0)
+{
+}
+
+int
+gr_regenerate_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) {
+      d_countdown = d_period;
+      optr[i] = 1;
+      d_regen_count = 0;
+    }
+
+    if(d_regen_count <= d_max_regen) {
+      d_countdown--;
+      
+      if(d_countdown == 0) {
+	optr[i] = 1;
+	d_countdown = d_period;
+	d_regen_count++;
+      }
+    }
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.h b/gnuradio-core/src/lib/general/gr_regenerate_bb.h
new file mode 100644
index 0000000000..446e658ae4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.h
@@ -0,0 +1,59 @@
+/* -*- 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_REGENERATE_BB_H
+#define INCLUDED_GR_REGENERATE_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_regenerate_bb;
+typedef boost::shared_ptr<gr_regenerate_bb> gr_regenerate_bb_sptr;
+
+gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500);
+
+/*!
+ * \brief Detect the peak of a signal
+ * \ingroup block
+ *
+ * If a peak is detected, this block outputs a 1 repeated every period samples 
+ * until reset by detection of another 1 on the input
+ */
+class gr_regenerate_bb : public gr_sync_block
+{
+  friend gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen);
+
+  gr_regenerate_bb (int period, unsigned int max_regen);
+
+ private:
+  int d_period;
+  int d_countdown;
+  unsigned int d_max_regen;
+  unsigned int d_regen_count;
+
+ 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_regenerate_bb.i b/gnuradio-core/src/lib/general/gr_regenerate_bb.i
new file mode 100644
index 0000000000..6afd84d8de
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_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,regenerate_bb)
+
+gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500);
+
+class gr_regenerate_bb : public gr_sync_block
+{
+ private:
+  gr_regenerate_bb (int period, unsigned int max_regen);
+};
-- 
cgit v1.2.3