[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [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,
trondeau <=