commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r5761 - in gnuradio/trunk: gnuradio-core/src/lib/gener


From: trondeau
Subject: [Commit-gnuradio] r5761 - in gnuradio/trunk: gnuradio-core/src/lib/general gnuradio-core/src/lib/swig gnuradio-core/src/python/gnuradio gnuradio-core/src/python/gnuradio/blksimpl gnuradio-core/src/python/gnuradio/gr gnuradio-examples/python/ofdm
Date: Sun, 10 Jun 2007 12:16:11 -0600 (MDT)

Author: trondeau
Date: 2007-06-10 12:16:11 -0600 (Sun, 10 Jun 2007)
New Revision: 5761

Added:
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.h
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.i
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py
   
gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py
   gnuradio/trunk/gnuradio-examples/python/ofdm/ofdm_sync_pn.m
   gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m
Removed:
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py
Modified:
   gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am
   gnuradio/trunk/gnuradio-core/src/lib/general/general.i
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_delay.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
   gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
   gnuradio/trunk/gnuradio-core/src/lib/swig/gnuradio.i
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/packet_utils.py
   gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
   gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
   gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
   gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
   gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
Log:
Merging OFDM features branch r5661:5759 into trunk. OFDM works over the air 
with BPSK and QPSK modulations on subcarriers. Passes make distcheck.

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am    2007-06-10 
18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am    2007-06-10 
18:16:11 UTC (rev 5761)
@@ -102,7 +102,10 @@
         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 @@
        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 @@
         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 @@
        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 @@
         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 @@
        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                     \

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/general.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/general.i      2007-06-10 
18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/general.i      2007-06-10 
18:16:11 UTC (rev 5761)
@@ -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"

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_delay.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_delay.cc    2007-06-10 
18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_delay.cc    2007-06-10 
18:16:11 UTC (rev 5761)
@@ -52,7 +52,7 @@
   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];
 

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc 
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc 
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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 @@
     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 @@
     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 @@
       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
 }
 

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h  
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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 @@
 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);

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i  
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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();

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc  
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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 @@
 
   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 @@
 {
   //  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 @@
        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 @@
     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");

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h   
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -34,7 +34,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);
 
 /*!
  * \brief take a vector of complex constellation points in from an FFT
@@ -65,18 +66,21 @@
    *                            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 @@
   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:

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.i   
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.i   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -29,7 +29,8 @@
                         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 @@
                      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; }

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc  
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -79,6 +79,14 @@
   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,24 +109,57 @@
   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 @@
 {
   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 @@
     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,11 +216,10 @@
        // 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 @@
     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) {

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h   
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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 @@
 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 @@
   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 @@
   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();
 

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i   
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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();

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc     
                        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.cc     
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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;
+}

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h      
                        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.h      
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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 */

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i      
                        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_insert_preamble.i      
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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);
+};

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc          
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.cc  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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
+}
+

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h           
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.h   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i           
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qam_mapper.i   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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);
+};

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc         
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.cc 
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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
+}
+

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h          
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.h  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i          
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_qpsk_mapper.i  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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);
+};

Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc     
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc     
2007-06-10 18:16:11 UTC (rev 5761)
@@ -67,7 +67,7 @@
 
   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 @@
 
   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", 

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.cc (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_regenerate_bb.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.cc            
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.cc    
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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;
+}

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.h (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_regenerate_bb.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.h             
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.h     
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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

Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.i (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/lib/general/gr_regenerate_bb.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.i             
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_regenerate_bb.i     
2007-06-10 18:16:11 UTC (rev 5761)
@@ -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);
+};

Modified: gnuradio/trunk/gnuradio-core/src/lib/swig/gnuradio.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/swig/gnuradio.i        2007-06-10 
18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/lib/swig/gnuradio.i        2007-06-10 
18:16:11 UTC (rev 5761)
@@ -59,7 +59,15 @@
   %template()    vector<int>;
   %template()    vector<float>;
   %template()    vector<double>;
-  %template()    vector<std::complex<float> >;
+
+  %template()    vector< std::complex<float> >;
+  %template()     vector< std::vector< unsigned char > >;
+  %template()     vector< std::vector< char > >;
+  %template()     vector< std::vector< short > >;
+  %template()     vector< std::vector< int > >;
+  %template()     vector< std::vector< float > >;
+  %template()     vector< std::vector< double > >;
+  %template()     vector< std::vector< std::complex<float> > >;
 };
 
 ////////////////////////////////////////////////////////////////////////

Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am       
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am       
2007-06-10 18:16:11 UTC (rev 5761)
@@ -40,9 +40,12 @@
        cpm.py                  \
        nbfm_rx.py              \
        nbfm_tx.py              \
-       ofdm_pkt.py             \
+       ofdm.py                 \
        ofdm_receiver.py        \
-       ofdm_sync.py            \
+       ofdm_sync_fixed.py      \
+       ofdm_sync_ml.py         \
+       ofdm_sync_pnac.py       \
+       ofdm_sync_pn.py         \
        pkt.py                  \
        psk.py                  \
        qam.py                  \

Copied: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py           
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -0,0 +1,284 @@
+
+#
+# Copyright 2006,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.
+# 
+
+import math
+from numpy import fft
+from gnuradio import gr, ofdm_packet_utils
+import gnuradio.gr.gr_threading as _threading
+
+from gnuradio.blksimpl.ofdm_receiver import ofdm_receiver
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                   mod/demod with packets as i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+class ofdm_mod(gr.hier_block):
+    """
+    Modulates an OFDM stream. Based on the options fft_length, occupied_tones, 
and
+    cp_length, this block creates OFDM symbols using a specified modulation 
option.
+    
+    Send packets by calling send_pkt
+    """
+    def __init__(self, fg, options, msgq_limit=2, pad_for_usrp=True):
+        """
+       Hierarchical block for sending packets
+
+        Packets to be sent are enqueued by calling send_pkt.
+        The output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+        @param options: pass modulation options from higher layers (fft 
length, occupied tones, etc.)
+        @param msgq_limit: maximum number of messages in message queue
+        @type msgq_limit: int
+        @param pad_for_usrp: If true, packets are padded such that they end up 
a multiple of 128 samples
+        """
+
+        self._pad_for_usrp = pad_for_usrp
+        self._modulation = options.modulation
+        self._fft_length = options.fft_length
+        self._occupied_tones = options.occupied_tones
+        self._cp_length = options.cp_length
+
+        win = [] #[1 for i in range(self._fft_length)]
+
+        # Use freq domain to get doubled-up known symbol for correlation in 
time domain
+        zeros_on_left = int(math.ceil((self._fft_length - 
self._occupied_tones)/2.0))
+        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
+        for i in range(len(ksfreq)):
+            if((zeros_on_left + i) & 1):
+                ksfreq[i] = 0
+
+        # hard-coded known symbols
+        preambles = (ksfreq,
+                     known_symbols_4512_1[0:self._occupied_tones],
+                     known_symbols_4512_2[0:self._occupied_tones])
+        
+        padded_preambles = list()
+        for pre in preambles:
+            padded = self._fft_length*[0,]
+            padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre
+            padded_preambles.append(padded)
+            
+        symbol_length = options.fft_length + options.cp_length
+
+        # The next step will all us to pass a constellation into a generic 
mapper function instead
+        # of using these hard-coded versions
+        if self._modulation == "bpsk":
+            self._pkt_input = gr.ofdm_bpsk_mapper(msgq_limit, 
options.occupied_tones, options.fft_length)
+        elif self._modulation == "qpsk":
+            self._pkt_input = gr.ofdm_qpsk_mapper(msgq_limit, 
options.occupied_tones, options.fft_length)
+        else:
+            print "Modulation type not supported (must be \"bpsk\" or \"qpsk\""
+        
+        self.preambles = gr.ofdm_insert_preamble(self._fft_length, 
padded_preambles)
+        self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
+        self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length, 
symbol_length)
+        self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length))
+        
+        fg.connect((self._pkt_input, 0), (self.preambles, 0))
+        fg.connect((self._pkt_input, 1), (self.preambles, 1))
+        fg.connect(self.preambles, self.ifft, self.cp_adder, self.scale)
+        
+        if options.verbose:
+            self._print_verbage()
+
+        if options.log:
+            fg.connect(self._pkt_input, 
gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat"))
+
+        gr.hier_block.__init__(self, fg, None, self.scale)
+
+    def send_pkt(self, payload='', eof=False):
+        """
+        Send the payload.
+
+        @param payload: data to send
+        @type payload: string
+        """
+        if eof:
+            msg = gr.message(1) # tell self._pkt_input we're not sending any 
more packets
+        else:
+            # print "original_payload =", string_to_hex_list(payload)
+            pkt = ofdm_packet_utils.make_packet(payload, 1, 1, 
self._pad_for_usrp)
+
+            #print "pkt =", string_to_hex_list(pkt)
+            msg = gr.message_from_string(pkt)
+        self._pkt_input.msgq().insert_tail(msg)
+
+    def add_options(normal, expert):
+        """
+        Adds OFDM-specific options to the Options Parser
+        """
+        normal.add_option("-m", "--modulation", type="string", default="bpsk",
+                          help="set modulation type (bpsk or qpsk) 
[default=%default]")
+        expert.add_option("", "--fft-length", type="intx", default=512,
+                          help="set the number of FFT bins [default=%default]")
+        expert.add_option("", "--occupied-tones", type="intx", default=200,
+                          help="set the number of occupied FFT bins 
[default=%default]")
+        expert.add_option("", "--cp-length", type="intx", default=128,
+                          help="set the number of bits in the cyclic prefix 
[default=%default]")
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+    def _print_verbage(self):
+        """
+        Prints information about the OFDM modulator
+        """
+        print "\nOFDM Modulator:"
+        print "Modulation Type: %s"    % (self._modulation)
+        print "FFT length:      %3d"   % (self._fft_length)
+        print "Occupied Tones:  %3d"   % (self._occupied_tones)
+        print "CP length:       %3d"   % (self._cp_length)
+
+
+class ofdm_demod(gr.hier_block):
+    """
+    Demodulates a received OFDM stream. Based on the options fft_length, 
occupied_tones, and
+    cp_length, this block performs synchronization, FFT, and demodulation of 
incoming OFDM
+    symbols and passes packets up the a higher layer.
+
+    The input is complex baseband.  When packets are demodulated, they are 
passed to the
+    app via the callback.
+    """
+
+    def __init__(self, fg, options, callback=None):
+        """
+       Hierarchical block for demodulating and deframing packets.
+
+       The input is the complex modulated signal at baseband.
+        Demodulated packets are sent to the handler.
+
+       @param fg: flow graph
+       @type fg: flow graph
+        @param options: pass modulation options from higher layers (fft 
length, occupied tones, etc.)
+        @param callback:  function of two args: ok, payload
+        @type callback: ok: bool; payload: string
+       """
+        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY
+
+        self._modulation = options.modulation
+        self._fft_length = options.fft_length
+        self._occupied_tones = options.occupied_tones
+        self._cp_length = options.cp_length
+        self._snr = options.snr
+
+
+        # Use freq domain to get doubled-up known symbol for correlation in 
time domain
+        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
+        for i in range(len(ksfreq)):
+            if(i&1):
+                ksfreq[i] = 0        
+
+        zeros_on_left = int(math.ceil((self._fft_length - 
self._occupied_tones)/2.0))
+        zeros_on_right = self._fft_length - self._occupied_tones - 
zeros_on_left
+        ks0 = zeros_on_left*[0.0,]
+        ks0.extend(ksfreq)
+        ks0.extend(zeros_on_right*[0.0,])
+        
+        ks0time = fft.ifft(ks0)
+        # ADD SCALING FACTOR
+        ks0time = ks0time.tolist()
+
+        # hard-coded known symbols
+        preambles = (ks0time,
+                     known_symbols_4512_1[0:self._occupied_tones],
+                     known_symbols_4512_2[0:self._occupied_tones])
+        
+        symbol_length = self._fft_length + self._cp_length
+        self.ofdm_recv = ofdm_receiver(fg, self._fft_length, self._cp_length,
+                                       self._occupied_tones, self._snr, 
preambles,
+                                       options.log)
+        self.ofdm_demod = gr.ofdm_frame_sink(self._rcvd_pktq,
+                                             self._occupied_tones,
+                                             self._modulation)
+        
+        fg.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
+        fg.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
+
+        if options.verbose:
+            self._print_verbage()
+            
+        gr.hier_block.__init__(self, fg, self.ofdm_recv, None)
+        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
+
+
+    def add_options(normal, expert):
+        """
+        Adds OFDM-specific options to the Options Parser
+        """
+        normal.add_option("-m", "--modulation", type="string", default="bpsk",
+                          help="set modulation type (bpsk or qpsk) 
[default=%default]")
+        expert.add_option("", "--fft-length", type="intx", default=512,
+                          help="set the number of FFT bins [default=%default]")
+        expert.add_option("", "--occupied-tones", type="intx", default=200,
+                          help="set the number of occupied FFT bins 
[default=%default]")
+        expert.add_option("", "--cp-length", type="intx", default=128,
+                          help="set the number of bits in the cyclic prefix 
[default=%default]")
+    # Make a static method to call before instantiation
+    add_options = staticmethod(add_options)
+
+    def _print_verbage(self):
+        """
+        Prints information about the OFDM demodulator
+        """
+        print "\nOFDM Demodulator:"
+        print "Modulation Type: %s"    % (self._modulation)
+        print "FFT length:      %3d"   % (self._fft_length)
+        print "Occupied Tones:  %3d"   % (self._occupied_tones)
+        print "CP length:       %3d"   % (self._cp_length)
+
+
+
+class _queue_watcher_thread(_threading.Thread):
+    def __init__(self, rcvd_pktq, callback):
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self.rcvd_pktq = rcvd_pktq
+        self.callback = callback
+        self.keep_running = True
+        self.start()
+
+
+    def run(self):
+        while self.keep_running:
+            msg = self.rcvd_pktq.delete_head()
+            ok, payload = ofdm_packet_utils.unmake_packet(msg.to_string())
+            if self.callback:
+                self.callback(ok, payload)
+
+# Generating known symbols with:
+# i = [2*random.randint(0,1)-1 for i in range(4512)]
+
+known_symbols_200_1 = [1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 
-1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 
-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 
1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 
1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 
-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 
-1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 
-1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 
1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 
-1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 
-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 
-1.0, 1.0, 1.0, -1.0]
+        
+known_symbols_200_2 = [-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 
1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 
1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 
-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
-1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 
-1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 
-1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 
1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 
-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 
1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 
1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 
1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 
1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 
1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]
+
+
+known_symbols_4512_1 = [-1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 
-1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 
1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 
1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 
1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 
-1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 
-1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 
-1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 
-1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 
-1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 
-1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 
1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 
-1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 
-1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 
-1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 
1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 
1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 
1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 
1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 
1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 
-1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 
1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 
-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 
1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 
-1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 
1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 
-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 
1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 
1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 
1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 
1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 
-1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 
1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 
-1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 
-1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 
1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 
1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 
-1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 
-1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 
-1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 
-1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 
-1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 
1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 
-1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 
1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 
1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 
1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 
-1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 
1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 
1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 
-1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 
1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 
-1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 
-1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 
1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 
1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 
-1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 
-1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 
1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 
-1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 
1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 
-1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 
1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 
-1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 
1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 
-1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 
1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 
1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 
-1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 
-1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 
1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 
-1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 
-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 
1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 
-1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 
-1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 
1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 
-1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 
1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 
1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 
1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 
-1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 
-1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 
1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 
-1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 
-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 
-1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 
-1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 
1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 
-1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 
1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 
-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 
-1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 
-1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 
1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 
1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 
-1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 
-1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 
-1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 
-1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 
-1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 
-1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 
1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 
-1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 
-1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 
-1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 
1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 
-1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 
-1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 
-1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 
-1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 
1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 
-1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 
-1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 
1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 
-1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 
1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 
-1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 
-1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 
1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 
-1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 
-1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 
-1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 
1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 
-1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 
-1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 
1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 
-1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 
-1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 
-1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 
1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 
1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 
-1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 
-1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 
1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 
-1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 
-1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 
-1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 
1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 
1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 
-1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 
-1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 
1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 
-1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 
-1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 
-1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 
-1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 
-1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 
1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 
-1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 
1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 
-1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 
-1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 
1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 
1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 
-1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 
-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 
1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 
1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 
-1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 
1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 
-1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 
1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 
-1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 
1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 
1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 
-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 
1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 
1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 
1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 
-1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 
-1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 
1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 
-1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 
1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 
-1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 
-1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 
-1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 
-1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 
-1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 
-1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 
-1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 
-1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 
-1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 
-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 
-1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 
-1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 
-1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 
1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 
-1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 
1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 
1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 
1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1]
+
+known_symbols_4512_2 = [1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 
-1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 
1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 
-1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 
-1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 
1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 
-1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 
-1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 
-1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 
-1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 
1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 
-1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 
1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 
-1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 
-1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 
-1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 
1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 
-1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 
1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 
-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 
-1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 
-1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 
-1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 
-1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 
1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 
1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 
-1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 
-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 
-1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 
-1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 
-1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 
1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 
1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 
1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 
1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 
1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 
-1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 
1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 
-1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 
1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 
-1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 
-1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 
-1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 
-1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 
-1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 
1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 
1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 
1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 
-1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 
-1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 
-1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 
-1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 
1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 
-1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 
1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 
-1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 
-1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 
-1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 
1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 
1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 
-1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 
1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 
-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 
1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 
-1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 
-1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 
1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 
1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 
-1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 
-1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 
1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 
-1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 
1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 
1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 
-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 
-1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 
1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 
1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 
-1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 
-1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 
-1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 
-1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 
1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 
1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 
1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 
-1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 
1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 
-1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 
1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 
1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 
-1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 
1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 
1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 
1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 
-1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 
-1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 
-1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 
-1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 
1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 
-1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 
-1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 
-1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 
1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 
-1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 
-1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 
-1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 
1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 
1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 
-1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 
-1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 
1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 
-1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 
-1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 
1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 
1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 
-1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 
1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 
1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 
-1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 
-1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 
1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 
1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 
1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 
1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 
1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 
1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 
-1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 
-1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 
1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 
1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 
1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 
-1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 
1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 
-1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 
-1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 
-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 
1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 
-1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 
1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 
-1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 
1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 
-1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 
1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 
1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 
-1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 
-1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 
1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 
-1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 
-1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 
1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 
1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 
1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 
-1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 
-1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 
1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 
-1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 
1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 
1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 
1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 
-1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 
-1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 
-1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 
-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 
-1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 
-1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 
-1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 
-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 
1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 
1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 
-1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 
-1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 
1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 
1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 
-1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 
-1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 
-1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 
1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 
-1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 
1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 
-1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 
-1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 
1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 
1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 
-1, -1, 1, 1, 1, 1, -1, -1]
+
+
+known_symbols_4512_impulse = 4512*[1,]
+
+known_symbols_4512_3 = [-1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 
-1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 
-1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 
-1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 
-1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 
-1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 
1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 
-1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 
1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 
1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 
1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 
-1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 
1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 
1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 
-1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 
-1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 
-1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 
-1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 
1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 
1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 
-1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 
-1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 
1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 
1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 
1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 
1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 
1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 
1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 
-1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 
-1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 
-1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 
-1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 
-1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 
-1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 
1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 
1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 
1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 
1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 
-1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 
1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 
-1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 
-1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 
-1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 
1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 
-1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 
1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 
1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 
1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 
1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 
1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 
-1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 
1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 
-1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 
-1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 
1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 
-1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 
1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 
1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 
-1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 
1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 
-1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 
1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 
-1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 
1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 
-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 
1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 
1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 
-1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 
-1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 
-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 
1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 
1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 
-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 
-1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 
1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 
-1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 
1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 
1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 
1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 
-1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 
1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 
-1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 
1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 
1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 
-1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 
1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 
1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 
-1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 
-1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 
-1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 
1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 
-1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 
-1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 
-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 
1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 
-1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 
1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 
-1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 
1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 
-1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 
1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 
1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 
1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 
-1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 
1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 
1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 
-1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 
-1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 
1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 
1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 
-1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 
-1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 
-1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 
-1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 
1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 
-1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 
1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 
-1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 
-1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 
1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 
-1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 
1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 
1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 
-1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 
1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 
-1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 
1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 
-1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 
-1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 
-1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 
-1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 
-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 
-1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 
1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 
1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 
1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 
1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 
1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 
-1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 
-1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 
1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 
-1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 
1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 
1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 
-1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 
1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 
1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 
-1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 
-1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 
-1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 
1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 
1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 
1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 
-1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 
-1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 
1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 
-1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 
1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 
-1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 
-1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 
-1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 
-1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 
-1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 
1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 
-1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 
1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 
-1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 
1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 
1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 
1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 
-1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 
1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 
-1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 
-1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 
1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 
-1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 
1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 
-1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 
-1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 
1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 
-1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 
-1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 
-1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 
1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 
-1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 
-1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 
1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 
1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 
1, -1, 1, -1]

Deleted: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py

Modified: 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py  
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py  
2007-06-10 18:16:11 UTC (rev 5761)
@@ -22,10 +22,12 @@
 
 import math
 from gnuradio import gr
-from gnuradio.blksimpl.ofdm_sync import ofdm_sync
+from gnuradio.blksimpl.ofdm_sync_ml import ofdm_sync_ml
+from gnuradio.blksimpl.ofdm_sync_pn import ofdm_sync_pn
+from gnuradio.blksimpl.ofdm_sync_pnac import ofdm_sync_pnac
 
 class ofdm_receiver(gr.hier_block):
-    def __init__(self, fg, fft_length, cp_length, occupied_tones, snr, ks1, 
ks2):
+    def __init__(self, fg, fft_length, cp_length, occupied_tones, snr, ks, 
logging=False):
         self.fg = fg
 
         bw = (float(occupied_tones) / float(fft_length)) / 2.0
@@ -39,14 +41,21 @@
         
         win = [1 for i in range(fft_length)]
 
-        self.ofdm_sync = ofdm_sync(fg, fft_length, cp_length, snr)
+        SYNC = "pn"
+        if SYNC == "ml":
+            self.ofdm_sync = ofdm_sync_ml(fg, fft_length, cp_length, snr, 
logging)
+        elif SYNC == "pn":
+            self.ofdm_sync = ofdm_sync_pn(fg, fft_length, cp_length, logging)
+        elif SYNC == "pnac":
+            self.ofdm_sync = ofdm_sync_pnac(fg, fft_length, cp_length, ks[0])
+
         self.fft_demod = gr.fft_vcc(fft_length, True, win, True)
         self.ofdm_corr  = gr.ofdm_correlator(occupied_tones, fft_length,
-                                             cp_length, ks1, ks2)
+                                             cp_length, ks[1], ks[2])
 
         self.fg.connect(self.chan_filt, self.ofdm_sync, self.fft_demod, 
self.ofdm_corr)
         
-        if 1:
+        if logging:
             self.fg.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex, 
"chan_filt_c.dat"))
             self.fg.connect(self.fft_demod, 
gr.file_sink(gr.sizeof_gr_complex*fft_length, "fft_out_c.dat"))
             self.fg.connect(self.ofdm_corr, 
gr.file_sink(gr.sizeof_gr_complex*occupied_tones, "ofdm_corr_out_c.dat"))

Deleted: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py

Copied: 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py)
===================================================================
--- 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py    
                            (rev 0)
+++ 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py    
    2007-06-10 18:16:11 UTC (rev 5761)
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+#
+# 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.
+# 
+
+import math
+from gnuradio import gr
+
+class ofdm_sync_fixed(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, snr):
+        self.fg = fg
+
+        # Use a fixed trigger point instead of sync block
+        data = (fft_length+cp_len)*[0,]
+        data[(fft_length+cp_len)-1] = 1
+        peak_trigger = gr.vector_source_b(data, True)
+        
+        self.fg.connect(peak_trigger, (self.sampler,1))
+
+        if 1:
+            self.fg.connect(self.sampler, 
gr.file_sink(gr.sizeof_gr_complex*fft_length,
+                                                       
"ofdm_sync_fixed-sampler_c.dat"))
+        
+        gr.hier_block.__init__(self, fg, (self.sampler,0), self.sampler)

Copied: 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py   
                        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# 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.
+# 
+
+import math
+from gnuradio import gr
+
+class ofdm_sync_ml(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, snr, logging):
+        ''' Maximum Likelihood OFDM synchronizer:
+        J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation
+        of Time and Frequency Offset in OFDM Systems," IEEE Trans.
+        Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997.
+        '''
+
+        self.fg = fg
+
+        # FIXME: when converting to hier_block2's, the output signature
+        # should be the output of the divider (the normalized peaks) and
+        # the angle value out of the sample and hold block
+
+        self.input = gr.add_const_cc(0)
+
+        SNR = 10.0**(snr/10.0)
+        rho = SNR / (SNR + 1.0)
+        symbol_length = fft_length + cp_length
+
+        # ML Sync
+
+        # Energy Detection from ML Sync
+
+        # Create a delay line
+        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length)
+        self.fg.connect(self.input, self.delay)
+
+        # magnitude squared blocks
+        self.magsqrd1 = gr.complex_to_mag_squared()
+        self.magsqrd2 = gr.complex_to_mag_squared()
+        self.adder = gr.add_ff()
+
+        moving_sum_taps = [rho/2 for i in range(cp_length)]
+        self.moving_sum_filter = gr.fir_filter_fff(1,moving_sum_taps)
+        
+        self.fg.connect(self.input,self.magsqrd1)
+        self.fg.connect(self.delay,self.magsqrd2)
+        self.fg.connect(self.magsqrd1,(self.adder,0))
+        self.fg.connect(self.magsqrd2,(self.adder,1))
+        self.fg.connect(self.adder,self.moving_sum_filter)
+        
+
+        # Correlation from ML Sync
+        self.conjg = gr.conjugate_cc();
+        self.mixer = gr.multiply_cc();
+
+        movingsum2_taps = [1.0 for i in range(cp_length)]
+        self.movingsum2 = gr.fir_filter_ccf(1,movingsum2_taps)
+        
+        # Correlator data handler
+        self.c2mag = gr.complex_to_mag()
+        self.angle = gr.complex_to_arg()
+        self.fg.connect(self.input,(self.mixer,1))
+        self.fg.connect(self.delay,self.conjg,(self.mixer,0))
+        self.fg.connect(self.mixer,self.movingsum2,self.c2mag)
+        self.fg.connect(self.movingsum2,self.angle)
+
+        # ML Sync output arg, need to find maximum point of this
+        self.diff = gr.sub_ff()
+        self.fg.connect(self.c2mag,(self.diff,0))
+        self.fg.connect(self.moving_sum_filter,(self.diff,1))
+
+        #ML measurements input to sampler block and detect
+        nco_sensitivity = -1.0/fft_length
+        self.f2c = gr.float_to_complex()
+        self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
+        self.sample_and_hold = gr.sample_and_hold_ff()
+        self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+        self.sigmix = gr.multiply_cc()
+
+        # Mix the signal with an NCO controlled by the sync loop
+        self.fg.connect(self.input, (self.sigmix,0))
+        self.fg.connect(self.nco, (self.sigmix,1))
+        self.fg.connect(self.sigmix, (self.sampler,0))
+
+        # use the sync loop values to set the sampler and the NCO
+        #     self.diff = theta
+        #     self.angle = epsilon
+                          
+        self.fg.connect(self.diff, self.pk_detect)
+
+        use_dpll = 1
+        if use_dpll:
+            self.dpll = gr.dpll_bb(float(symbol_length),0.01)
+            self.fg.connect(self.pk_detect, self.dpll)
+            self.fg.connect(self.dpll, (self.sampler,1))
+            self.fg.connect(self.dpll, (self.sample_and_hold,1))
+        else:
+            self.fg.connect(self.pk_detect, (self.sampler,1))
+            self.fg.connect(self.pk_detect, (self.sample_and_hold,1))
+            
+        self.fg.connect(self.angle, (self.sample_and_hold,0))
+        self.fg.connect(self.sample_and_hold, self.nco)
+
+        if logging:
+            self.fg.connect(self.diff, gr.file_sink(gr.sizeof_float, 
"ofdm_sync_ml-theta_f.dat"))
+            self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, 
"ofdm_sync_ml-epsilon_f.dat"))
+            self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, 
"ofdm_sync_ml-peaks_b.dat"))
+            if use_dpll:
+                self.fg.connect(self.dpll, gr.file_sink(gr.sizeof_char, 
"ofdm_sync_ml-dpll_b.dat"))
+
+            self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, 
"ofdm_sync_ml-sigmix_c.dat"))
+            self.fg.connect(self.sampler, 
gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_ml-sampler_c.dat"))
+            self.fg.connect(self.sample_and_hold, 
gr.file_sink(gr.sizeof_float, "ofdm_sync_ml-sample_and_hold_f.dat"))
+            self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, 
"ofdm_sync_ml-nco_c.dat"))
+            self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, 
"ofdm_sync_ml-input_c.dat"))
+
+        gr.hier_block.__init__(self, fg, self.input, self.sampler)

Copied: 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py (from 
rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py   
                        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# 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.
+# 
+
+import math
+from numpy import fft
+from gnuradio import gr
+
+class ofdm_sync_pn(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, logging=False):
+        ''' OFDM synchronization using PN Correlation:
+        T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing
+        Synchonization for OFDM," IEEE Trans. Communications, vol. 45,
+        no. 12, 1997.
+        '''
+        
+        self.fg = fg
+
+        # FIXME: when converting to hier_block2's, the output signature
+        # should be the output of the divider (the normalized peaks) and
+        # the angle value out of the sample and hold block
+            
+        self.input = gr.add_const_cc(0)
+
+        symbol_length = fft_length + cp_length
+
+        # PN Sync
+
+        # Create a delay line
+        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)
+
+        # Correlation from ML Sync
+        self.conjg = gr.conjugate_cc();
+        self.corr = gr.multiply_cc();
+
+        # Create a moving sum filter for the corr output
+        if 1:
+            moving_sum_taps = [1.0 for i in range(fft_length//2)]
+            self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
+        else:
+            moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)]
+            self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps)
+
+        # Create a moving sum filter for the input
+        self.inputmag2 = gr.complex_to_mag_squared()
+        movingsum2_taps = [1.0 for i in range(fft_length//2)]
+
+        if 1:
+            self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
+        else:
+            self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps)
+
+        self.square = gr.multiply_ff()
+        self.normalize = gr.divide_ff()
+     
+        # Get magnitude (peaks) and angle (phase/freq error)
+        self.c2mag = gr.complex_to_mag_squared()
+        self.angle = gr.complex_to_arg()
+
+        self.sample_and_hold = gr.sample_and_hold_ff()
+
+        # Mix the signal with an NCO controlled by the sync loop
+        nco_sensitivity = -2.0/fft_length
+        self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+        self.sigmix = gr.multiply_cc()
+
+        #ML measurements input to sampler block and detect
+        self.sub1 = gr.add_const_ff(-1)
+        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
+        self.regen = gr.regenerate_bb(symbol_length)
+
+        self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+        
+        self.fg.connect(self.input, self.delay)
+        self.fg.connect(self.input, (self.corr,0))
+        self.fg.connect(self.delay, self.conjg)
+        self.fg.connect(self.conjg, (self.corr,1))
+        self.fg.connect(self.corr, self.moving_sum_filter)
+        self.fg.connect(self.moving_sum_filter, self.c2mag)
+        self.fg.connect(self.moving_sum_filter, self.angle)
+        self.fg.connect(self.angle, (self.sample_and_hold,0))
+        self.fg.connect(self.sample_and_hold, self.nco)
+
+        self.fg.connect(self.input, (self.sigmix,0))
+        self.fg.connect(self.nco, (self.sigmix,1))
+        self.fg.connect(self.sigmix, (self.sampler,0))
+
+        self.fg.connect(self.input, self.inputmag2, self.inputmovingsum)
+        self.fg.connect(self.inputmovingsum, (self.square,0))
+        self.fg.connect(self.inputmovingsum, (self.square,1))
+        self.fg.connect(self.square, (self.normalize,1))
+        self.fg.connect(self.c2mag, (self.normalize,0))
+
+        # Create a moving sum filter for the corr output
+        matched_filter_taps = [1.0/cp_length for i in range(cp_length)]
+        self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps)
+        self.fg.connect(self.normalize, self.matched_filter)
+        
+        self.fg.connect(self.matched_filter, self.sub1, self.pk_detect)
+        self.fg.connect(self.pk_detect, self.regen)
+        self.fg.connect(self.regen, (self.sampler,1))
+        self.fg.connect(self.pk_detect, (self.sample_and_hold,1))
+
+
+        if logging:
+            self.fg.connect(self.matched_filter, gr.file_sink(gr.sizeof_float, 
"ofdm_sync_pn-mf_f.dat"))
+            self.fg.connect(self.normalize, gr.file_sink(gr.sizeof_float, 
"ofdm_sync_pn-theta_f.dat"))
+            self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, 
"ofdm_sync_pn-epsilon_f.dat"))
+            self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, 
"ofdm_sync_pn-peaks_b.dat"))
+            self.fg.connect(self.regen, gr.file_sink(gr.sizeof_char, 
"ofdm_sync_pn-regen_b.dat"))
+            self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, 
"ofdm_sync_pn-sigmix_c.dat"))
+            self.fg.connect(self.sampler, 
gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_pn-sampler_c.dat"))
+            self.fg.connect(self.sample_and_hold, 
gr.file_sink(gr.sizeof_float, "ofdm_sync_pn-sample_and_hold_f.dat"))
+            self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, 
"ofdm_sync_pn-nco_c.dat"))
+            self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, 
"ofdm_sync_pn-input_c.dat"))
+
+        gr.hier_block.__init__(self, fg, self.input, self.sampler)

Copied: 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py 
                        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py 
2007-06-10 18:16:11 UTC (rev 5761)
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+#
+# 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.
+# 
+
+import math
+from numpy import fft
+from gnuradio import gr
+
+class ofdm_sync_pnac(gr.hier_block):
+    def __init__(self, fg, fft_length, cp_length, ks):
+        self.fg = fg
+
+        # FIXME: when converting to hier_block2's, the output signature
+        # should be the output of the divider (the normalized peaks) and
+        # the angle value out of the sample and hold block
+            
+        self.input = gr.add_const_cc(0)
+
+        symbol_length = fft_length + cp_length
+
+        # PN Sync
+
+        # autocorrelate with the known symbol
+        ks = ks[0:fft_length//2]
+        ks.reverse()
+        self.crosscorr_filter = gr.fir_filter_ccc(1, ks)
+        self.fg.connect(self.crosscorr_filter, 
gr.file_sink(gr.sizeof_gr_complex, "crosscorr.dat"))
+        
+        # Create a delay line
+        self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)
+
+        # Correlation from ML Sync
+        self.conjg = gr.conjugate_cc();
+        self.corr = gr.multiply_cc();
+
+        # Create a moving sum filter for the corr output
+        moving_sum_taps = [1.0 for i in range(fft_length//2)]
+        self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
+
+        # Create a moving sum filter for the input
+        self.inputmag2 = gr.complex_to_mag_squared()
+        movingsum2_taps = [1.0 for i in range(fft_length/2)]
+        self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
+        self.square = gr.multiply_ff()
+        self.normalize = gr.divide_ff()
+     
+        # Get magnitude (peaks) and angle (phase/freq error)
+        self.c2mag = gr.complex_to_mag_squared()
+        self.angle = gr.complex_to_arg()
+
+        self.sample_and_hold = gr.sample_and_hold_ff()
+
+        # Mix the signal with an NCO controlled by the sync loop
+        nco_sensitivity = -1.0/fft_length
+        self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+        self.sigmix = gr.multiply_cc()
+
+        #ML measurements input to sampler block and detect
+        self.sub1 = gr.add_const_ff(-1)
+        self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
+
+        self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+        
+        self.fg.connect(self.input, self.crosscorr_filter)
+        self.fg.connect(self.crosscorr_filter, self.delay)
+        self.fg.connect(self.crosscorr_filter, (self.corr,0))
+        self.fg.connect(self.delay, self.conjg)
+        self.fg.connect(self.conjg, (self.corr,1))
+        self.fg.connect(self.corr, self.moving_sum_filter)
+        self.fg.connect(self.moving_sum_filter, self.c2mag)
+        self.fg.connect(self.moving_sum_filter, self.angle)
+        self.fg.connect(self.angle, (self.sample_and_hold,0))
+        self.fg.connect(self.sample_and_hold, self.nco)
+
+        self.fg.connect(self.input, (self.sigmix,0))
+        self.fg.connect(self.nco, (self.sigmix,1))
+        self.fg.connect(self.sigmix, (self.sampler,0))
+
+        self.fg.connect(self.input, self.inputmag2, self.inputmovingsum)
+        self.fg.connect(self.inputmovingsum, (self.square,0))
+        self.fg.connect(self.inputmovingsum, (self.square,1))
+        self.fg.connect(self.square, (self.normalize,1))
+        self.fg.connect(self.c2mag, (self.normalize,0))
+        self.fg.connect(self.normalize, self.sub1, self.pk_detect)
+
+        self.fg.connect(self.pk_detect, (self.sampler,1))
+        self.fg.connect(self.pk_detect, (self.sample_and_hold,1))
+            
+
+        if 1:
+            self.fg.connect(self.normalize, gr.file_sink(gr.sizeof_float,
+                                                         
"ofdm_sync_pnac-theta_f.dat"))
+            self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float,
+                                                     
"ofdm_sync_pnac-epsilon_f.dat"))
+            self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char,
+                                                         
"ofdm_sync_pnac-peaks_b.dat"))
+            self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex,
+                                                      
"ofdm_sync_pnac-sigmix_c.dat"))
+            self.fg.connect(self.sampler, 
gr.file_sink(gr.sizeof_gr_complex*fft_length,
+                                                       
"ofdm_sync_pnac-sampler_c.dat"))
+            self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float,
+                                                               
"ofdm_sync_pnac-sample_and_hold_f.dat"))
+            self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex,
+                                                   "ofdm_sync_pnac-nco_c.dat"))
+            self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex,
+                                                     
"ofdm_sync_pnac-input_c.dat"))
+
+        gr.hier_block.__init__(self, fg, self.input, self.sampler)

Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am     
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am     
2007-06-10 18:16:11 UTC (rev 5761)
@@ -80,6 +80,7 @@
        qa_mute.py                      \
        qa_nlog10.py                    \
        qa_noise.py                     \
+       qa_ofdm_insert_preamble.py      \
        qa_packed_to_unpacked.py        \
        qa_pipe_fittings.py             \
        qa_pll_carriertracking.py       \

Copied: 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py 
(from rev 5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py)
===================================================================
--- 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py  
                            (rev 0)
+++ 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_ofdm_insert_preamble.py  
    2007-06-10 18:16:11 UTC (rev 5761)
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+#
+# 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.
+# 
+
+from gnuradio import gr, gr_unittest
+from pprint import pprint
+
+class testing (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def helper(self, v0, v1, fft_length, preamble):
+        fg = self.fg
+        src0 = gr.vector_source_c(v0)
+        src1 = gr.vector_source_b(v1)
+        
+        s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_length)
+
+        # print "len(v) = %d" % (len(v))
+
+        op = gr.ofdm_insert_preamble(fft_length, preamble)
+
+        v2s = gr.vector_to_stream(gr.sizeof_gr_complex, fft_length)
+        dst0 = gr.vector_sink_c()
+        dst1 = gr.vector_sink_b()
+
+        fg.connect(src0, s2v, (op, 0))
+        fg.connect(src1, (op, 1))
+        fg.connect((op, 0), v2s, dst0)
+        fg.connect((op, 1), dst1)
+
+        fg.run()
+        r0 = dst0.data()
+        r0v = []
+        for i in range(len(r0)//fft_length):
+            r0v.append(r0[i*fft_length:(i+1)*fft_length])
+            
+        r1 = dst1.data()
+        self.assertEqual(len(r0v), len(r1))
+        return (r1, r0v)
+        
+    def check_match(self, actual, expected_list):
+        lst = []
+        map(lambda x: lst.append(x), expected_list)
+        self.assertEqual(actual, lst)
+
+
+    # ----------------------------------------------------------------
+
+    def test_000(self):
+        # no preamble, 1 symbol payloads
+
+        preamble = ()
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+
+        p = tuple(p)
+            
+        r = self.helper(v, npayloads*[1], fft_length, preamble)
+        # pprint(r)
+
+        self.assertEqual(r[0], tuple(npayloads*[1]))
+        self.check_match(r[1], (p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]))
+            
+
+    def test_001(self):
+        # 1 symbol preamble, 1 symbol payloads
+        preamble = ((100, 101, 102, 103, 104, 105, 106, 107),)
+        p0 = preamble[0]
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+
+        
+        r = self.helper(v, npayloads*[1], fft_length, preamble)
+
+        self.assertEqual(r[0], tuple(npayloads*[1, 0]))
+        self.check_match(r[1], (p0, p[0],
+                                p0, p[1],
+                                p0, p[2],
+                                p0, p[3],
+                                p0, p[4],
+                                p0, p[5],
+                                p0, p[6],
+                                p0, p[7]))
+
+    def test_002(self):
+        # 2 symbol preamble, 1 symbol payloads
+        preamble = ((100, 101, 102, 103, 104, 105, 106, 107),
+                    (200, 201, 202, 203, 204, 205, 206, 207))
+        p0 = preamble[0]
+        p1 = preamble[1]
+
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+        
+        r = self.helper(v, npayloads*[1], fft_length, preamble)
+
+        self.assertEqual(r[0], tuple(npayloads*[1, 0, 0]))
+        self.check_match(r[1], (p0, p1, p[0],
+                                p0, p1, p[1],
+                                p0, p1, p[2],
+                                p0, p1, p[3],
+                                p0, p1, p[4],
+                                p0, p1, p[5],
+                                p0, p1, p[6],
+                                p0, p1, p[7]))
+
+
+    def xtest_003_preamble(self):
+        # 2 symbol preamble, 2 symbol payloads
+        preamble = ((100, 101, 102, 103, 104, 105, 106, 107),
+                    (200, 201, 202, 203, 204, 205, 206, 207))
+        p0 = preamble[0]
+        p1 = preamble[1]
+
+        fft_length = 8
+        npayloads = 8
+        v = []
+        p = []
+        for i in range(npayloads * 2):
+            t = fft_length*[(i + i*1j)]
+            p.append(tuple(t))
+            v += t
+        
+        r = self.helper(v, npayloads*[1, 0], fft_length, preamble)
+
+        self.assertEqual(r[0], tuple(npayloads*[1, 0, 0, 0]))
+        self.check_match(r[1], (p0, p1, p[0],  p[1],
+                                p0, p1, p[2],  p[3],
+                                p0, p1, p[4],  p[5],
+                                p0, p1, p[6],  p[7],
+                                p0, p1, p[8],  p[9],
+                                p0, p1, p[10], p[11],
+                                p0, p1, p[12], p[13],
+                                p0, p1, p[14], p[15]))
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()

Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py       
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py       
2007-06-10 18:16:11 UTC (rev 5761)
@@ -96,7 +96,7 @@
     return struct.pack('!HH', val, val)
 
 def make_packet(payload, samples_per_symbol, bits_per_symbol,
-                pad_for_usrp=True, whitener_offset=0, dowhiten=1):
+                pad_for_usrp=True, whitener_offset=0, whitening=True):
     """
     Build a packet, given access code, payload, and whitener offset
 
@@ -106,10 +106,13 @@
     @param bits_per_symbol:       (needed for padding calculation)
     @type bits_per_symbol:        int
     @param whitener_offset        offset into whitener string to use [0-16)
+    @param whitening:             Turn whitener on or off
+    @type whitening:              bool
     
     Packet will have access code at the beginning, followed by length, payload
     and finally CRC-32.
     """
+
     if not whitener_offset >=0 and whitener_offset < 16:
         raise ValueError, "whitener_offset must be between 0 and 15, inclusive 
(%i)" % (whitener_offset,)
 
@@ -129,7 +132,7 @@
         usrp_packing = _npadding_bytes(packet_length, samples_per_symbol, 
bits_per_symbol) * '\x55'
         pkt_dt = pkt_dt + usrp_packing
 
-    if(dowhiten):
+    if(whitening):
         pkt = pkt_hd + whiten(pkt_dt, whitener_offset)
     else:
         pkt = pkt_hd + pkt_dt
@@ -147,8 +150,10 @@
     is a multiple of 128 samples.
 
     @param ptk_byte_len: len in bytes of packet, not including padding.
-    @param samples_per_symbol: samples per bit (1 bit / symbolwith GMSK)
+    @param samples_per_symbol: samples per bit (1 bit / symbolwidth GMSK)
     @type samples_per_symbol: int
+    @param bits_per_symbol: bits per symbol (log2(modulation order))
+    @type bits_per_symbol: int
 
     @returns number of bytes of padding to append.
     """
@@ -160,13 +165,17 @@
     return byte_modulus - r
     
 
-def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dodewhiten=1):
+def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dewhitening=1):
     """
     Return (ok, payload)
 
     @param whitened_payload_with_crc: string
+    @param whitener_offset        offset into whitener string to use [0-16)
+    @param dewhitening:           Turn whitener on or off
+    @type  dewhitening:           bool
     """
-    if dodewhiten:
+
+    if dewhitening:
         payload_with_crc = dewhiten(whitened_payload_with_crc, whitener_offset)
     else:
         payload_with_crc = whitened_payload_with_crc

Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/packet_utils.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/packet_utils.py    
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/packet_utils.py    
2007-06-10 18:16:11 UTC (rev 5761)
@@ -157,8 +157,10 @@
     is a multiple of 128 samples.
 
     @param ptk_byte_len: len in bytes of packet, not including padding.
-    @param samples_per_symbol: samples per bit (1 bit / symbolwith GMSK)
+    @param samples_per_symbol: samples per bit (1 bit / symbolwidth GMSK)
     @type samples_per_symbol: int
+    @param bits_per_symbol: bits per symbol (log2(modulation order))
+    @type bits_per_symbol: int
 
     @returns number of bytes of padding to append.
     """

Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py      
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py      
2007-06-10 18:16:11 UTC (rev 5761)
@@ -24,7 +24,6 @@
 from gnuradio import eng_notation
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
-from gnuradio.blksimpl import ofdm_pkt
 
 import random, time, struct, sys, math, os
 
@@ -77,10 +76,11 @@
         self.connect(self.zeros, (self.mux,0))
         self.connect(self.txpath, (self.mux,1))
         self.connect(self.mux, self.throttle, self.channel, self.rxpath)
-        
-        self.connect(self.txpath, gr.file_sink(gr.sizeof_gr_complex, 
"txpath.dat"))
-        self.connect(self.mux, gr.file_sink(gr.sizeof_gr_complex, "mux.dat"))
-        self.connect(self.channel, gr.file_sink(gr.sizeof_gr_complex, 
"channel.dat"))
+
+        if options.log:
+            self.connect(self.txpath, gr.file_sink(gr.sizeof_gr_complex, 
"txpath.dat"))
+            self.connect(self.mux, gr.file_sink(gr.sizeof_gr_complex, 
"mux.dat"))
+            self.connect(self.channel, gr.file_sink(gr.sizeof_gr_complex, 
"channel.dat"))
             
 # /////////////////////////////////////////////////////////////////////////////
 #                                   main
@@ -121,7 +121,7 @@
     parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
                       help="set megabytes to transmit [default=%default]")
     parser.add_option("-r", "--sample-rate", type="eng_float", default=1e5,
-                      help="set sample rate to RATE (%default)") 
+                      help="limit sample rate to RATE in throttle (%default)") 
     parser.add_option("", "--snr", type="eng_float", default=30,
                       help="set the SNR of the channel in dB 
[default=%default]")
     parser.add_option("", "--frequency-offset", type="eng_float", default=0,
@@ -137,8 +137,8 @@
 
     transmit_path.add_options(parser, expert_grp)
     receive_path.add_options(parser, expert_grp)
-    ofdm_pkt.mod_ofdm_pkts.add_options(parser, expert_grp)
-    ofdm_pkt.demod_ofdm_pkts.add_options(parser, expert_grp)
+    blks.ofdm_mod.add_options(parser, expert_grp)
+    blks.ofdm_demod.add_options(parser, expert_grp)
     
     (options, args) = parser.parse_args ()
        

Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py   
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2005, 2006 Free Software Foundation, Inc.
+# Copyright 2006, 2007 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -20,17 +20,17 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-from gnuradio import gr, gru, modulation_utils
+from gnuradio import gr, blks
 from gnuradio import usrp
 from gnuradio import eng_notation
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
-import random, time, struct, sys, math
+import random, time, struct, sys
 
 # from current dir
 from receive_path import receive_path
-import ofdm, fusb_options
+import fusb_options
 
 class usrp_graph(gr.flow_graph):
     def __init__(self, callback, options):
@@ -118,9 +118,6 @@
         Adds usrp-specific options to the Options Parser
         """
         add_freq_option(normal)
-        if not normal.has_option("--bitrate"):
-            normal.add_option("-r", "--bitrate", type="eng_float", 
default=None,
-                              help="specify bitrate.  samples-per-symbol and 
interp/decim will be derived.")
         normal.add_option("-R", "--rx-subdev-spec", type="subdev", 
default=None,
                           help="select USRP Rx side A or B")
         normal.add_option("", "--rx-gain", type="eng_float", default=None, 
metavar="GAIN",
@@ -129,8 +126,6 @@
                           help="print min and max Rx gain available on 
selected daughterboard")
         normal.add_option("-v", "--verbose", action="store_true", 
default=False)
 
-        expert.add_option("-S", "--samples-per-symbol", type="int", 
default=None,
-                          help="set samples/symbol [default=%default]")
         expert.add_option("", "--rx-freq", type="eng_float", default=None,
                           help="set Rx frequency to FREQ [default=%default]", 
metavar="FREQ")
         expert.add_option("-d", "--decim", type="intx", default=32,
@@ -175,14 +170,27 @@
             n_right += 1
         print "ok: %r \t pktno: %d \t n_rcvd: %d \t n_right: %d" % (ok, pktno, 
n_rcvd, n_right)
 
+        if 0:
+            printlst = list()
+            for x in payload[2:]:
+                t = hex(ord(x)).replace('0x', '')
+                if(len(t) == 1):
+                    t = '0' + t
+                printlst.append(t)
+            printable = ''.join(printlst)
+
+            print printable
+            print "\n"
+
     parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
     expert_grp = parser.add_option_group("Expert")
-    parser.add_option("-r", "--sample-rate", type="eng_float", default=1e5,
-                      help="set sample rate to RATE (%default)") 
+    parser.add_option("","--discontinuous", action="store_true", default=False,
+                      help="enable discontinuous")
 
     usrp_graph.add_options(parser, expert_grp)
     receive_path.add_options(parser, expert_grp)
-    ofdm.ofdm_mod.add_options(parser, expert_grp)
+    blks.ofdm_mod.add_options(parser, expert_grp)
+    blks.ofdm_demod.add_options(parser, expert_grp)
     fusb_options.add_options(expert_grp)
 
     (options, args) = parser.parse_args ()

Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py   
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py   
2007-06-10 18:16:11 UTC (rev 5761)
@@ -20,18 +20,18 @@
 # Boston, MA 02110-1301, USA.
 # 
 
-from gnuradio import gr, gru, modulation_utils
+from gnuradio import gr, blks
 from gnuradio import usrp
 from gnuradio import eng_notation
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
 
-import random, time, struct, sys, math
+import time, struct, sys
 
 # from current dir
 from transmit_path import transmit_path
 from pick_bitrate import pick_tx_bitrate
-import ofdm, fusb_options
+import fusb_options
 
 class usrp_graph(gr.flow_graph):
     def __init__(self, options):
@@ -39,7 +39,6 @@
 
         self._tx_freq            = options.tx_freq         # tranmitter's 
center frequency
         self._tx_subdev_spec     = options.tx_subdev_spec  # daughterboard to 
use
-        self._bitrate            = options.bitrate         # desired bit rate
         self._interp             = options.interp          # interpolating 
rate for the USRP (prelim)
         self._fusb_block_size    = options.fusb_block_size # usb info for USRP
         self._fusb_nblocks       = options.fusb_nblocks    # usb info for USRP
@@ -82,7 +81,7 @@
 
         # Set the USRP for maximum transmit gain
         # (Note that on the RFX cards this is a nop.)
-        self.set_gain(self.subdev.gain_range()[0])
+        self.set_gain(self.subdev.gain_range()[1])
 
         # enable Auto Transmit/Receive switching
         self.set_auto_tr(True)
@@ -126,15 +125,10 @@
         Adds usrp-specific options to the Options Parser
         """
         add_freq_option(normal)
-        if not normal.has_option('--bitrate'):
-            normal.add_option("-r", "--bitrate", type="eng_float", 
default=None,
-                              help="specify bitrate.  samples-per-symbol and 
interp/decim will be derived.")
         normal.add_option("-T", "--tx-subdev-spec", type="subdev", 
default=None,
                           help="select USRP Tx side A or B")
         normal.add_option("-v", "--verbose", action="store_true", 
default=False)
 
-        expert.add_option("-S", "--samples-per-symbol", type="int", 
default=None,
-                          help="set samples/symbol [default=%default]")
         expert.add_option("", "--tx-freq", type="eng_float", default=None,
                           help="set transmit frequency to FREQ 
[default=%default]", metavar="FREQ")
         expert.add_option("-i", "--interp", type="intx", default=64,
@@ -181,21 +175,17 @@
                       help="set packet size [default=%default]")
     parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
                       help="set megabytes to transmit [default=%default]")
-    parser.add_option("-r", "--sample-rate", type="eng_float", default=1e5,
-                      help="set sample rate to RATE (%default)") 
+    parser.add_option("","--discontinuous", action="store_true", default=False,
+                      help="enable discontinuous mode")
 
     usrp_graph.add_options(parser, expert_grp)
     transmit_path.add_options(parser, expert_grp)
-    ofdm.ofdm_mod.add_options(parser, expert_grp)
+    blks.ofdm_mod.add_options(parser, expert_grp)
+    blks.ofdm_demod.add_options(parser, expert_grp)
     fusb_options.add_options(expert_grp)
 
     (options, args) = parser.parse_args ()
 
-    if(options.mtu < options.size):
-        sys.stderr.write("MTU (%.0f) must be larger than the packet size 
(%.0f)\n"
-                         % (options.mtu, options.size))
-        sys.exit(1)
-
     # build the graph
     fg = usrp_graph(options)
 
@@ -215,8 +205,8 @@
         send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff))
         n += pkt_size
         sys.stderr.write('.')
-        #if options.discontinuous and pktno % 5 == 4:
-        #    time.sleep(1)
+        if options.discontinuous and pktno % 5 == 1:
+            time.sleep(1)
         pktno += 1
         
     send_pkt(eof=True)

Copied: gnuradio/trunk/gnuradio-examples/python/ofdm/ofdm_sync_pn.m (from rev 
5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-examples/python/ofdm/ofdm_sync_pn.m)
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/ofdm_sync_pn.m                 
        (rev 0)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/ofdm_sync_pn.m 2007-06-10 
18:16:11 UTC (rev 5761)
@@ -0,0 +1,21 @@
+mf = read_float_binary('ofdm_sync_pn-mf_f.dat');
+theta_pn = read_float_binary('ofdm_sync_pn-theta_f.dat');
+peaks_pn = read_char_binary('ofdm_sync_pn-peaks_b.dat');
+regen_pn = read_char_binary('ofdm_sync_pn-regen_b.dat');
+angle_pn = read_float_binary('ofdm_sync_pn-epsilon_f.dat');
+
+plot(mf, 'k')
+hold
+plot(theta_pn, 'g');
+plot(peaks_pn, 'r');
+plot(regen_pn, 'b');
+xlim([100, 50000]);
+ylim([0, 1])
+i = find(peaks_pn);
+i(100:200)
+hold off
+
+ipeaks = find(peaks_pn);
+dpeaks = diff(ipeaks);
+hist(dpeaks, 30)
+set(gca, 'FontSize', 30, 'FontWeight', 'Bold');

Copied: gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m (from rev 
5759, 
gnuradio/branches/features/ofdm/sync/gnuradio-examples/python/ofdm/plot_ofdm.m)
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m                    
        (rev 0)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m    2007-06-10 
18:16:11 UTC (rev 5761)
@@ -0,0 +1,65 @@
+function plot_ofdm(fft_size, occ_tones)
+
+ofdm = read_complex_binary('ofdm_corr_out_c.dat');
+ofdm_split = split_vect(ofdm, occ_tones);
+
+fftc = read_complex_binary('fft_out_c.dat');
+fftc_split = split_vect(fftc, fft_size);
+
+figure(1)
+set(gcf, 'Position', [50 50 1000 600]);
+
+a = size(ofdm_split);
+if nargin == 3
+    maxcount = count;
+    if maxcount > a(1)
+        error('plot_ofdm:tolong', 'Requested count size exceeds size of 
vectors');
+    end
+else
+    maxcount = a(1);
+end
+
+for i = 1:20000
+    x = ofdm_split(i,:);
+    y = fftc_split(i+1,:);
+    
+    subplot(2,2,1)
+    plot(real(x), imag(x), 'bo')
+    set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+    axis([-1.5, 1.5, -1.5, 1.5])
+    title('I&Q Constellation', 'FontSize', 36);
+    xlabel('Inphase', 'FontSize', 32);
+    ylabel('Quadrature', 'FontSize', 32);
+    
+    subplot(2,2,3)
+    plot(angle(x*j), 'bo')
+    set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+    axis([0, occ_tones, -3.5, 3.5])
+    title('Equalized Symbol Angle', 'FontSize', 36);
+    xlabel('Bin Number (Occ. Tones)', 'FontSize', 32);
+    ylabel('Symbol Angle', 'FontSize', 32);
+    
+    subplot(2,2,2)
+    plot(angle(y*j), 'bo')
+    set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+    axis([0, fft_size, -3.5, 3.5]) 
+    title('Unequalized Symbol Angle', 'FontSize', 36);
+    xlabel('Bin Number (FFT Size)', 'FontSize', 32);
+    ylabel('Symbol Angle', 'FontSize', 32);
+    
+    Y = 20*log10(abs(y) ./ max(abs(y)));
+    subplot(2,2,4)
+    plot(Y, 'b-')
+    set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+    axis([0, fft_size, -50, 1]);
+    title('Frequency Domain of Unequalized Rx', 'FontSize', 36);
+    xlabel('Bin Number (FFT Size)', 'FontSize', 32);
+    ylabel('Power (dB)', 'FontSize', 32);
+    
+    %     N = 20*log10(var(abs(x)-1))
+    
+    disp(sprintf('Symbol Number: %d\n', i))
+%     disp(sprintf('\tFreq Error: %f\n', anglesh_pn(1+(i-1)*fft_size)))
+    pause
+
+end

Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py        
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py        
2007-06-10 18:16:11 UTC (rev 5761)
@@ -43,9 +43,8 @@
         self._rx_callback = rx_callback      # this callback is fired when 
there's a packet available
 
         # receiver
-        self.ofdm_receiver = \
-            blks.demod_ofdm_pkts(fg, options,
-                                 callback=self._rx_callback)
+        self.ofdm_rx = \
+                     blks.ofdm_demod(fg, options, callback=self._rx_callback)
 
         # Carrier Sensing Blocks
         #alpha = 0.001
@@ -57,7 +56,7 @@
         if self._verbose:
             self._print_verbage()
         
-        gr.hier_block.__init__(self, fg, self.ofdm_receiver, None)
+        gr.hier_block.__init__(self, fg, self.ofdm_rx, None)
 
     def carrier_sensed(self):
         """
@@ -98,9 +97,4 @@
         """
         Prints information about the receive path
         """
-        print "Using RX d'board %s"    % (self.subdev.side_and_name(),)
-        print "Rx gain:         %g"    % (self.gain,)
-        print "modulation:      %s"    % (self._demod_class.__name__)
-        print "bitrate:         %sb/s" % 
(eng_notation.num_to_str(self._bitrate))
-        print "samples/symbol:  %3d"   % (self._samples_per_symbol)
-        print "decim:           %3d"   % (self._decim)
+        pass

Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py       
2007-06-10 18:10:02 UTC (rev 5760)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py       
2007-06-10 18:16:11 UTC (rev 5761)
@@ -41,11 +41,8 @@
         self._verbose      = options.verbose
         self._tx_amplitude = options.tx_amplitude    # digital amplitude sent 
to USRP
 
-        self.ofdm_transmitter = \
-            blks.mod_ofdm_pkts(fg,
-                               options,
-                               msgq_limit=4,
-                               pad_for_usrp=False)
+        self.ofdm_tx = \
+                     blks.ofdm_mod(fg, options, msgq_limit=4, 
pad_for_usrp=False)
 
         self.amp = gr.multiply_const_cc(1)
         self.set_tx_amplitude(self._tx_amplitude)
@@ -55,7 +52,7 @@
             self._print_verbage()
 
         # Create and setup transmit path flow graph
-        fg.connect(self.ofdm_transmitter, self.amp)
+        fg.connect(self.ofdm_tx, self.amp)
         gr.hier_block.__init__(self, fg, None, self.amp)
 
     def set_tx_amplitude(self, ampl):
@@ -70,14 +67,8 @@
         """
         Calls the transmitter method to send a packet
         """
-        return self.ofdm_transmitter.send_pkt(payload, eof)
+        return self.ofdm_tx.send_pkt(payload, eof)
         
-    def bitrate(self):
-        return self._bitrate
-
-    def samples_per_symbol(self):
-        return self._samples_per_symbol
-
     def add_options(normal, expert):
         """
         Adds transmitter-specific options to the Options Parser





reply via email to

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