summaryrefslogtreecommitdiff
path: root/gnuradio-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src')
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc4
-rw-r--r--gnuradio-core/src/lib/general/Makefile.am13
-rw-r--r--gnuradio-core/src/lib/general/general.i6
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.cc27
-rw-r--r--gnuradio-core/src/lib/general/gr_delay.cc2
-rw-r--r--gnuradio-core/src/lib/general/gr_dpll_bb.cc (renamed from gnuradio-core/src/lib/general/gr_dpll_ff.cc)30
-rw-r--r--gnuradio-core/src/lib/general/gr_dpll_bb.h (renamed from gnuradio-core/src/lib/general/gr_dpll_ff.h)18
-rw-r--r--gnuradio-core/src/lib/general/gr_dpll_bb.i (renamed from gnuradio-core/src/lib/io/gr_frame.h)20
-rw-r--r--gnuradio-core/src/lib/general/gr_dpll_ff.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc168
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h49
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i29
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_correlator.cc54
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_correlator.h34
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_correlator.i16
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc235
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h105
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i (renamed from gnuradio-core/src/lib/io/gr_message_vector_source.i)15
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_sampler.cc6
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.cc76
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.h26
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.i14
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_mux.cc158
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_mux.h16
-rw-r--r--gnuradio-core/src/lib/gengen/Makefile.gen18
-rwxr-xr-xgnuradio-core/src/lib/gengen/generate_common.py2
-rw-r--r--gnuradio-core/src/lib/gengen/gengen_generated.i12
-rw-r--r--gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t8
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t6
-rw-r--r--gnuradio-core/src/lib/io/Makefile.am7
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.cc90
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.h24
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.i2
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.cc118
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.h67
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.i46
-rw-r--r--gnuradio-core/src/lib/io/gr_message_vector_source.cc97
-rw-r--r--gnuradio-core/src/lib/io/gr_message_vector_source.h63
-rw-r--r--gnuradio-core/src/lib/io/io.i3
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am3
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py50
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py151
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py55
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py141
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/Makefile.am2
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_delay.py65
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_skiphead.py102
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py170
-rw-r--r--gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py32
49 files changed, 1702 insertions, 786 deletions
diff --git a/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc
index 312626a1d..ac3ae46e0 100644
--- a/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc
@@ -37,8 +37,8 @@ gr_fractional_interpolator_cc_sptr gr_make_fractional_interpolator_cc(float phas
gr_fractional_interpolator_cc::gr_fractional_interpolator_cc(float phase_shift, float interp_ratio)
: gr_block ("fractional_interpolator_cc",
- gr_make_io_signature (1, 1, sizeof (float)),
- gr_make_io_signature (1, 1, sizeof (float))),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
d_mu (phase_shift), d_mu_inc (interp_ratio), d_interp(new gri_mmse_fir_interpolator_cc())
{
if (interp_ratio <= 0)
diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am
index c76130039..d774baa1c 100644
--- a/gnuradio-core/src/lib/general/Makefile.am
+++ b/gnuradio-core/src/lib/general/Makefile.am
@@ -63,7 +63,7 @@ libgeneral_la_SOURCES = \
gr_diff_decoder_bb.cc \
gr_diff_encoder_bb.cc \
gr_diff_phasor_cc.cc \
- gr_dpll_ff.cc \
+ gr_dpll_bb.cc \
gr_fake_channel_coder_pp.cc \
gr_fast_atan2f.cc \
gr_feedforward_agc_cc.cc \
@@ -102,6 +102,7 @@ libgeneral_la_SOURCES = \
gr_ofdm_mapper_bcv.cc \
gr_ofdm_bpsk_demapper.cc \
gr_ofdm_bpsk_mapper.cc \
+ gr_ofdm_frame_sink.cc \
gr_ofdm_sampler.cc \
gr_pa_2x2_phase_combiner.cc \
gr_packet_sink.cc \
@@ -197,7 +198,7 @@ grinclude_HEADERS = \
gr_deinterleave.h \
gr_delay.h \
gr_diff_phasor_cc.h \
- gr_dpll_ff.h \
+ gr_dpll_bb.h \
gr_expj.h \
gr_fake_channel_coder_pp.h \
gr_feedforward_agc_cc.h \
@@ -240,7 +241,8 @@ grinclude_HEADERS = \
gr_ofdm_mapper_bcv.h \
gr_ofdm_bpsk_mapper.h \
gr_ofdm_bpsk_demapper.h \
- gr_ofdm_sampler.h \
+ gr_ofdm_frame_sink.h \
+ gr_ofdm_sampler.h \
gr_pa_2x2_phase_combiner.h \
gr_packet_sink.h \
gr_phase_modulator_fc.h \
@@ -342,7 +344,7 @@ swiginclude_HEADERS = \
gr_diff_decoder_bb.i \
gr_diff_encoder_bb.i \
gr_diff_phasor_cc.i \
- gr_dpll_ff.i \
+ gr_dpll_bb.i \
gr_deinterleave.i \
gr_delay.i \
gr_fake_channel_coder_pp.i \
@@ -379,7 +381,8 @@ swiginclude_HEADERS = \
gr_ofdm_mapper_bcv.i \
gr_ofdm_bpsk_demapper.i \
gr_ofdm_bpsk_mapper.i \
- gr_ofdm_sampler.i \
+ gr_ofdm_frame_sink.i \
+ gr_ofdm_sampler.i \
gr_pa_2x2_phase_combiner.i \
gr_packet_sink.i \
gr_phase_modulator_fc.i \
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index 64144a05a..1fdb4239a 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -84,7 +84,7 @@
#include <gr_packet_sink.h>
#include <gr_lms_dfe_cc.h>
#include <gr_lms_dfe_ff.h>
-#include <gr_dpll_ff.h>
+#include <gr_dpll_bb.h>
#include <gr_pll_freqdet_cf.h>
#include <gr_pll_refout_cc.h>
#include <gr_pll_carriertracking_cc.h>
@@ -97,6 +97,7 @@
#include <gr_ofdm_cyclic_prefixer.h>
#include <gr_ofdm_bpsk_demapper.h>
#include <gr_ofdm_bpsk_mapper.h>
+#include <gr_ofdm_frame_sink.h>
#include <gr_ofdm_sampler.h>
#include <gr_costas_loop_cc.h>
#include <gr_pa_2x2_phase_combiner.h>
@@ -186,7 +187,7 @@
%include "gr_packet_sink.i"
%include "gr_lms_dfe_cc.i"
%include "gr_lms_dfe_ff.i"
-%include "gr_dpll_ff.i"
+%include "gr_dpll_bb.i"
%include "gr_pll_freqdet_cf.i"
%include "gr_pll_refout_cc.i"
%include "gr_pll_carriertracking_cc.i"
@@ -199,6 +200,7 @@
%include "gr_ofdm_cyclic_prefixer.i"
%include "gr_ofdm_bpsk_demapper.i"
%include "gr_ofdm_bpsk_mapper.i"
+%include "gr_ofdm_frame_sink.i"
%include "gr_ofdm_sampler.i"
%include "gr_costas_loop_cc.i"
%include "gr_pa_2x2_phase_combiner.i"
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
index 0a5b3790e..453c6d338 100644
--- a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
@@ -53,19 +53,24 @@ gr_conjugate_cc::work (int noutput_items,
int size = noutput_items;
while (size >= 8){
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+ optr[0] = conj(iptr[0]);
+ optr[1] = conj(iptr[1]);
+ optr[2] = conj(iptr[2]);
+ optr[3] = conj(iptr[3]);
+ optr[4] = conj(iptr[4]);
+ optr[5] = conj(iptr[5]);
+ optr[6] = conj(iptr[6]);
+ optr[7] = conj(iptr[7]);
size -= 8;
+ optr += 8;
+ iptr += 8;
+ }
+
+ while (size-- > 0) {
+ *optr = conj(*iptr);
+ iptr++;
+ optr++;
}
- while (size-- > 0)
- *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
-
return noutput_items;
}
diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc
index 12c50e4b6..89ab3ce0e 100644
--- a/gnuradio-core/src/lib/general/gr_delay.cc
+++ b/gnuradio-core/src/lib/general/gr_delay.cc
@@ -56,7 +56,7 @@ gr_delay::work (int noutput_items,
iptr = (const char *) input_items[i];
optr = (char *) output_items[i];
- memcpy(optr, iptr + delay()*d_itemsize, noutput_items*d_itemsize);
+ memcpy(optr, iptr, noutput_items*d_itemsize);
}
return noutput_items;
diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.cc b/gnuradio-core/src/lib/general/gr_dpll_bb.cc
index ae868fce5..d5b726528 100644
--- a/gnuradio-core/src/lib/general/gr_dpll_ff.cc
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.cc
@@ -20,25 +20,23 @@
* Boston, MA 02110-1301, USA.
*/
-// WARNING: this file is machine generated. Edits will be over written
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <gr_dpll_ff.h>
+#include <gr_dpll_bb.h>
#include <gr_io_signature.h>
-gr_dpll_ff_sptr
-gr_make_dpll_ff (float period, float gain)
+gr_dpll_bb_sptr
+gr_make_dpll_bb (float period, float gain)
{
- return gr_dpll_ff_sptr (new gr_dpll_ff (period, gain));
+ return gr_dpll_bb_sptr (new gr_dpll_bb (period, gain));
}
-gr_dpll_ff::gr_dpll_ff (float period, float gain)
- : gr_sync_block ("dpll_ff",
- gr_make_io_signature (1, 1, sizeof (float)),
- gr_make_io_signature (1, 1, sizeof (float))),
+gr_dpll_bb::gr_dpll_bb (float period, float gain)
+ : gr_sync_block ("dpll_bb",
+ gr_make_io_signature (1, 1, sizeof (char)),
+ gr_make_io_signature (1, 1, sizeof (char))),
d_restart(0),d_pulse_phase(0)
{
d_pulse_frequency = 1.0/period;
@@ -55,16 +53,16 @@ gr_dpll_ff::gr_dpll_ff (float period, float gain)
}
int
-gr_dpll_ff::work (int noutput_items,
+gr_dpll_bb::work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
- float *iptr = (float *) input_items[0];
- float *optr = (float *) output_items[0];
+ const char *iptr = (const char *) input_items[0];
+ char *optr = (char *) output_items[0];
for (int i = 0; i < noutput_items; i++){
- optr[i]= (float)0;
- if(iptr[i] ==(float)1) {
+ optr[i]= 0;
+ if(iptr[i] == 1) {
if (d_restart == 0) {
d_pulse_phase = 1;
} else {
@@ -77,7 +75,7 @@ gr_dpll_ff::work (int noutput_items,
d_pulse_phase -= 1.0;
if (d_restart > 0) {
d_restart -= 1;
- optr[i] = (float)1;
+ optr[i] = 1;
}
}
d_pulse_phase += d_pulse_frequency;
diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.h b/gnuradio-core/src/lib/general/gr_dpll_bb.h
index 1de1efa85..c80612bc5 100644
--- a/gnuradio-core/src/lib/general/gr_dpll_ff.h
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.h
@@ -20,17 +20,15 @@
* Boston, MA 02110-1301, USA.
*/
-// WARNING: this file is machine generated. Edits will be over written
-
-#ifndef INCLUDED_GR_DPLL_FF_H
-#define INCLUDED_GR_DPLL_FF_H
+#ifndef INCLUDED_GR_DPLL_BB_H
+#define INCLUDED_GR_DPLL_BB_H
#include <gr_sync_block.h>
-class gr_dpll_ff;
-typedef boost::shared_ptr<gr_dpll_ff> gr_dpll_ff_sptr;
+class gr_dpll_bb;
+typedef boost::shared_ptr<gr_dpll_bb> gr_dpll_bb_sptr;
-gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain);
+gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
/*!
* \brief Detect the peak of a signal
@@ -39,11 +37,11 @@ gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain);
* If a peak is detected, this block outputs a 1,
* or it outputs 0's.
*/
-class gr_dpll_ff : public gr_sync_block
+class gr_dpll_bb : public gr_sync_block
{
- friend gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain);
+ friend gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
- gr_dpll_ff (float period, float gain);
+ gr_dpll_bb (float period, float gain);
private:
unsigned char d_restart;
diff --git a/gnuradio-core/src/lib/io/gr_frame.h b/gnuradio-core/src/lib/general/gr_dpll_bb.i
index 07317e9df..ae95e2dfb 100644
--- a/gnuradio-core/src/lib/io/gr_frame.h
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.i
@@ -20,22 +20,12 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_GR_FRAME_H
-#define INCLUDED_GR_FRAME_H
+GR_SWIG_BLOCK_MAGIC(gr,dpll_bb)
-#include <vector>
+ gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
-class gr_frame
+class gr_dpll_bb : public gr_sync_block
{
- public:
- gr_frame(unsigned int mtu)
- : mtu(mtu), length(0)
- { }
-
- unsigned int mtu;
- unsigned int length;
- unsigned char data[];
+ private:
+ gr_dpll_bb (float period, float gain);
};
-
-#endif
-
diff --git a/gnuradio-core/src/lib/general/gr_dpll_ff.i b/gnuradio-core/src/lib/general/gr_dpll_ff.i
deleted file mode 100644
index 9606fba52..000000000
--- a/gnuradio-core/src/lib/general/gr_dpll_ff.i
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-// WARNING: this file is machine generated. Edits will be over written
-
-GR_SWIG_BLOCK_MAGIC(gr,dpll_ff)
-
- gr_dpll_ff_sptr gr_make_dpll_ff (float period, float gain);
-
-class gr_dpll_ff : public gr_sync_block
-{
- private:
- gr_dpll_ff (float period, float gain);
-};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
index df4632398..f0b52c325 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -29,30 +29,32 @@
#include <vector>
gr_ofdm_bpsk_mapper_sptr
-gr_make_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen,
- std::vector<gr_complex> known_symbol1, std::vector<gr_complex> known_symbol2)
+gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit,
+ unsigned int occupied_carriers, unsigned int fft_length,
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2)
{
- return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (mtu, occupied_carriers, vlen,
+ return gr_ofdm_bpsk_mapper_sptr (new gr_ofdm_bpsk_mapper (msgq_limit, occupied_carriers, fft_length,
known_symbol1, known_symbol2));
}
-gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int mtu, unsigned int occupied_carriers, unsigned int vlen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2)
- : gr_block ("ofdm_bpsk_mapper",
- gr_make_io_signature (1, 1, 2*sizeof(int) + sizeof(unsigned char)*mtu),
- gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen)),
- d_mtu(mtu),
+// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet
+gr_ofdm_bpsk_mapper::gr_ofdm_bpsk_mapper (unsigned int msgq_limit,
+ unsigned int occupied_carriers, unsigned int fft_length,
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2)
+ : gr_sync_block ("ofdm_bpsk_mapper",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))),
+ d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false),
d_occupied_carriers(occupied_carriers),
- d_vlen(vlen),
- d_packet_offset(0),
+ d_fft_length(fft_length),
d_bit_offset(0),
d_header_sent(0),
d_known_symbol1(known_symbol1),
d_known_symbol2(known_symbol2)
-
{
- assert(d_occupied_carriers < d_vlen);
+ assert(d_occupied_carriers <= d_fft_length);
assert(d_occupied_carriers == d_known_symbol1.size());
assert(d_occupied_carriers == d_known_symbol2.size());
}
@@ -61,99 +63,101 @@ gr_ofdm_bpsk_mapper::~gr_ofdm_bpsk_mapper(void)
{
}
-void
-gr_ofdm_bpsk_mapper::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+float randombit()
{
- unsigned ninputs = ninput_items_required.size ();
- for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = 1;
+ int r = rand()&1;
+ return (float)(-1 + 2*r);
}
int
-gr_ofdm_bpsk_mapper::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
+gr_ofdm_bpsk_mapper::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
{
- const gr_frame *in = (const gr_frame *) input_items[0];
gr_complex *out = (gr_complex *)output_items[0];
unsigned int i=0;
- unsigned int num_symbols = 0, pkt_length;
+ unsigned int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+ unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
//printf("OFDM BPSK Mapper: ninput_items: %d noutput_items: %d\n", ninput_items[0], noutput_items);
- pkt_length = in[0].length;
-
- std::vector<gr_complex>::iterator ks_itr;
- if(d_header_sent == 0) {
- ks_itr = d_known_symbol1.begin();
- }
- else if(d_header_sent == 1) {
- ks_itr = d_known_symbol2.begin();
+ if(d_eof) {
+ return -1;
}
- if(d_header_sent < 2) {
- // Add training symbols here
- for(i=0; i < (ceil((d_vlen - d_occupied_carriers)/2.0)); i++) {
- out[i] = gr_complex(0,0);
+ if(!d_msg) {
+ d_msg = d_msgq->delete_head(); // block, waiting for a message
+ d_msg_offset = 0;
+ d_bit_offset = 0;
+ d_header_sent = 0;
+
+ if((d_msg->length() == 0) && (d_msg->type() == 1)) {
+ d_msg.reset();
+ return -1;
}
- for(;i<d_vlen - ceil((d_vlen-d_occupied_carriers)/2.0);i++) {
- //out[i] = gr_complex(1,0);
- out[i] = *(ks_itr++);
+ }
+
+ if(output_items.size() == 2) {
+ char *sig = (char *)output_items[1];
+ if(d_header_sent == 1) {
+ sig[0] = 1;
}
- for(; i < d_vlen; i++) {
- out[i] = gr_complex(0,0);
+ else {
+ sig[0] = 0;
}
-
- num_symbols = 1;
- out += d_vlen;
- d_header_sent++;
}
- unsigned int unoccupied_carriers = d_vlen - d_occupied_carriers;
- unsigned int zeros_on_left = (unsigned)ceil(unoccupied_carriers/2.0);
- unsigned int zeros_on_right = unoccupied_carriers - zeros_on_left;
+ // Build a single symbol:
- while(num_symbols < (unsigned)noutput_items) {
+ // Initialize all bins to 0 to set unused carriers
+ memset(out, 0, d_fft_length*sizeof(gr_complex));
+
+ if(d_header_sent == 0) {
+ for(i=0; i < d_occupied_carriers; i++) {
+ out[i+zeros_on_left] = d_known_symbol1[i];
+ }
+ d_header_sent++;
- // stick in unused carriers
- for(i = d_vlen-zeros_on_right; i < d_vlen; i++) {
- out[i] = gr_complex(0,0);
+ return 1;
+ }
+
+ if(d_header_sent == 1) {
+ for(i=0; i < d_occupied_carriers; i++) {
+ out[i+zeros_on_left] = d_known_symbol2[i];
}
+ d_header_sent++;
- for(i=0; i < zeros_on_left; i++) {
- out[i] = gr_complex(0,0);
- }
+ return 1;
+ }
- while((d_packet_offset < pkt_length) && (i < d_vlen-zeros_on_right)) {
- unsigned char bit = (in[0].data[d_packet_offset] >> (d_bit_offset++)) & 0x01;
- out[i++] = gr_complex(-1+2*(bit));
- if(d_bit_offset == 8) {
- d_bit_offset = 0;
- d_packet_offset++;
- }
+ i = 0;
+ while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) {
+ unsigned char bit = (d_msg->msg()[d_msg_offset] >> (d_bit_offset)) & 0x01;
+ out[i + zeros_on_left] = gr_complex(-1+2*(bit));
+ i++;
+ d_bit_offset++;
+ if(d_bit_offset == 8) {
+ d_bit_offset = 0;
+ d_msg_offset++;
}
+ }
- // Ran out of data to put in symbols
- if(d_packet_offset == pkt_length) {
- while(i < d_vlen-zeros_on_right) {
- out[i++] = gr_complex(0,0);
- }
-
- d_packet_offset = 0;
- assert(d_bit_offset == 0);
- num_symbols++;
- d_header_sent = 0;
- consume_each(1);
- return num_symbols;
+ // Ran out of data to put in symbol
+ if (d_msg_offset == d_msg->length()) {
+ while(i < d_occupied_carriers) { // finish filling out the symbol
+ out[i + zeros_on_left] = gr_complex(randombit(),0);
+ i++;
}
-
- // Ran out of space in symbol
- out += d_vlen;
- num_symbols++;
+
+ if (d_msg->type() == 1) // type == 1 sets EOF
+ d_eof = true;
+ d_msg.reset(); // finished packet, free message
+
+ assert(d_bit_offset == 0);
+ return 1; // produced one symbol
}
- consume_each(0);
- return num_symbols;
+
+ return 1; // produced symbol
}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
index 1ae6c75d8..41b2f5bed 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.h
@@ -24,17 +24,19 @@
#define INCLUDED_GR_OFDM_BPSK_MAPPER_H
-#include <gr_block.h>
-#include <gr_frame.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
#include <vector>
class gr_ofdm_bpsk_mapper;
typedef boost::shared_ptr<gr_ofdm_bpsk_mapper> gr_ofdm_bpsk_mapper_sptr;
gr_ofdm_bpsk_mapper_sptr
-gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+gr_make_ofdm_bpsk_mapper (unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length,
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
/*!
* \brief take a stream of bytes in and map to a vector of complex
@@ -42,35 +44,40 @@ gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int
* modulator. Simple BPSK version.
*/
-class gr_ofdm_bpsk_mapper : public gr_block
+class gr_ofdm_bpsk_mapper : public gr_sync_block
{
friend gr_ofdm_bpsk_mapper_sptr
- gr_make_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ gr_make_ofdm_bpsk_mapper (unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length,
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
protected:
- gr_ofdm_bpsk_mapper (unsigned mtu, unsigned occupied_carriers, unsigned int vlen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ gr_ofdm_bpsk_mapper (unsigned msgq_limit,
+ unsigned occupied_carriers, unsigned int fft_length,
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
private:
- unsigned int d_mtu;
+ gr_msg_queue_sptr d_msgq;
+ gr_message_sptr d_msg;
+ unsigned d_msg_offset;
+ bool d_eof;
+
unsigned int d_occupied_carriers;
- unsigned int d_vlen;
- unsigned int d_packet_offset;
+ unsigned int d_fft_length;
unsigned int d_bit_offset;
unsigned int d_header_sent;
std::vector<gr_complex> d_known_symbol1, d_known_symbol2;
- void forecast (int noutput_items, gr_vector_int &ninput_items_required);
-
public:
~gr_ofdm_bpsk_mapper(void);
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
+
+ gr_msg_queue_sptr msgq() const { return d_msgq; }
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
index 12b86dc33..d0094062a 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_mapper.i
@@ -22,27 +22,28 @@
#include <vector>
-GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper)
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_mapper);
gr_ofdm_bpsk_mapper_sptr
-gr_make_ofdm_bpsk_mapper (unsigned int mtu,
+gr_make_ofdm_bpsk_mapper (unsigned int msgq_limit,
unsigned int bits_per_symbol,
- unsigned int vlen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ unsigned int fft_length,
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
-class gr_ofdm_bpsk_mapper : public gr_block
+class gr_ofdm_bpsk_mapper : public gr_sync_block
{
protected:
- gr_ofdm_bpsk_mapper (unsigned int mtu,
+ gr_ofdm_bpsk_mapper (unsigned int msgq_limit,
unsigned int bits_per_symbol,
- unsigned int vlen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ unsigned int fft_length,
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
public:
- int general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
+ gr_msg_queue_sptr msgq();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
index 21fbc6b3e..3973b8374 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006, 2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -26,29 +26,30 @@
#include <gr_ofdm_correlator.h>
#include <gr_io_signature.h>
+#include <gr_expj.h>
#define VERBOSE 0
#define M_TWOPI (2*M_PI)
gr_ofdm_correlator_sptr
-gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
unsigned int cplen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2)
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2)
{
- return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, vlen, cplen,
+ return gr_ofdm_correlator_sptr (new gr_ofdm_correlator (occupied_carriers, fft_length, cplen,
known_symbol1, known_symbol2));
}
-gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int vlen,
+gr_ofdm_correlator::gr_ofdm_correlator (unsigned occupied_carriers, unsigned int fft_length,
unsigned int cplen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2)
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2)
: gr_block ("ofdm_correlator",
- gr_make_io_signature (1, 1, sizeof(gr_complex)*vlen),
- gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)*fft_length),
+ gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char))),
d_occupied_carriers(occupied_carriers),
- d_vlen(vlen),
+ d_fft_length(fft_length),
d_cplen(cplen),
d_freq_shift_len(5),
d_known_symbol1(known_symbol1),
@@ -84,8 +85,9 @@ gr_ofdm_correlator::forecast (int noutput_items, gr_vector_int &ninput_items_req
gr_complex
gr_ofdm_correlator::coarse_freq_comp(int freq_delta, int symbol_count)
{
- return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count),
- sin(-M_TWOPI*freq_delta*d_cplen/d_vlen*symbol_count));
+ // return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count),
+ // sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count));
+ return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
}
bool
@@ -99,7 +101,7 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
gr_complex h_sqrd = gr_complex(0.0,0.0);
float power = 0.0F;
- while(!found && (abs(search_delta) < d_freq_shift_len)) {
+ while(!found && ((unsigned)abs(search_delta) < d_freq_shift_len)) {
h_sqrd = gr_complex(0.0,0.0);
power = 0.0F;
@@ -115,11 +117,20 @@ gr_ofdm_correlator::correlate(const gr_complex *previous, const gr_complex *curr
search_delta, h_sqrd.real(), h_sqrd.imag(), power, h_sqrd.real()/power, arg(h_sqrd));
#endif
- if(h_sqrd.real() > 0.75*power) {
+ // FIXME: Look at h_sqrd.read() > power
+ if((h_sqrd.real() > 0.82*power) && (h_sqrd.real() < 1.1 * power)) {
found = true;
d_coarse_freq = search_delta;
d_phase_count = 1;
- d_snr_est = 10*log10(power/(power-h_sqrd.real()));
+ //d_snr_est = 10*log10(power/(power-h_sqrd.real()));
+
+ // check for low noise power; sets maximum SNR at 100 dB
+ if(fabs(h_sqrd.imag()) <= 1e-12) {
+ d_snr_est = 100.0;
+ }
+ else {
+ d_snr_est = 10*log10(fabs(h_sqrd.real()/h_sqrd.imag()));
+ }
printf("CORR: Found, bin %d\tSNR Est %f dB\tcorr power fraction %f\n",
search_delta, d_snr_est, h_sqrd.real()/power);
@@ -168,23 +179,30 @@ gr_ofdm_correlator::general_work(int noutput_items,
{
const gr_complex *in = (const gr_complex *)input_items[0];
const gr_complex *previous = &in[0];
- const gr_complex *current = &in[d_vlen];
+ const gr_complex *current = &in[d_fft_length];
gr_complex *out = (gr_complex *) output_items[0];
+ char *sig = (char *) output_items[1];
unsigned int i=0;
- int unoccupied_carriers = d_vlen - d_occupied_carriers;
+ int unoccupied_carriers = d_fft_length - d_occupied_carriers;
int zeros_on_left = (int)ceil(unoccupied_carriers/2.0);
bool corr = correlate(previous, current, zeros_on_left);
if(corr) {
calculate_equalizer(previous, current, zeros_on_left);
+ sig[0] = 1;
+ }
+ else {
+ sig[0] = 0;
}
for(i = 0; i < d_occupied_carriers; i++) {
out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)*current[i+zeros_on_left+d_coarse_freq];
}
+
+
d_phase_count++;
consume_each(1);
return 1;
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
index 4c44cca32..44a6847af 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006, 2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -31,10 +31,10 @@ class gr_ofdm_correlator;
typedef boost::shared_ptr<gr_ofdm_correlator> gr_ofdm_correlator_sptr;
gr_ofdm_correlator_sptr
-gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
unsigned int cplen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
/*!
* \brief take a vector of complex constellation points in from an FFT
@@ -48,7 +48,7 @@ gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
* been corrected and that the samples fall in the middle of one FFT bin.
*
* It then uses one of those known
- * symbosl to estimate the channel response overa all subcarriers and does a simple
+ * symbols to estimate the channel response over all subcarriers and does a simple
* 1-tap equalization on all subcarriers. This corrects for the phase and amplitude
* distortion caused by the channel.
*/
@@ -58,7 +58,7 @@ class gr_ofdm_correlator : public gr_block
/*!
* \brief Build an OFDM correlator and equalizer.
* \param occupied_carriers The number of subcarriers with data in the received symbol
- * \param vlen The size of the FFT vector (occupied_carriers + unused carriers)
+ * \param fft_length The size of the FFT vector (occupied_carriers + unused carriers)
* \param known_symbol1 A vector of complex numbers representing a known symbol at the
* start of a frame (usually a BPSK PN sequence)
* \param known_symbol2 A vector of complex numbers representing a known symbol at the
@@ -67,16 +67,16 @@ class gr_ofdm_correlator : public gr_block
* for phase changes between symbols.
*/
friend gr_ofdm_correlator_sptr
- gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+ gr_make_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
unsigned int cplen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
protected:
- gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int vlen,
+ gr_ofdm_correlator (unsigned int occupied_carriers, unsigned int fft_length,
unsigned int cplen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
private:
unsigned char slicer(gr_complex x);
@@ -86,15 +86,15 @@ class gr_ofdm_correlator : public gr_block
gr_complex coarse_freq_comp(int freq_delta, int count);
unsigned int d_occupied_carriers; // !< \brief number of subcarriers with data
- unsigned int d_vlen; // !< \brief length of FFT vector
+ unsigned int d_fft_length; // !< \brief length of FFT vector
unsigned int d_cplen; // !< \brief length of cyclic prefix in samples
unsigned int d_freq_shift_len; // !< \brief number of surrounding bins to look at for correlation
std::vector<gr_complex> d_known_symbol1, d_known_symbol2; // !< \brief known symbols at start of frame
std::vector<gr_complex> d_diff_corr_factor; // !< \brief factor used in correlation
- std::vector<gr_complex> d_hestimate; // !< channel estimate
- signed int d_coarse_freq; // !< \brief search distance in number of bins
- unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction
- float d_snr_est; // !< an estimation of the signal to noise ratio
+ std::vector<gr_complex> d_hestimate; // !< channel estimate
+ signed int d_coarse_freq; // !< \brief search distance in number of bins
+ unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction
+ float d_snr_est; // !< an estimation of the signal to noise ratio
void forecast(int noutput_items, gr_vector_int &ninput_items_required);
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
index fbbf6a8af..40f9f83ff 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2006, 2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -22,23 +22,23 @@
#include <vector>
-GR_SWIG_BLOCK_MAGIC(gr,ofdm_correlator)
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_correlator);
gr_ofdm_correlator_sptr
gr_make_ofdm_correlator (unsigned int occupied_carriers,
- unsigned int vlen,
+ unsigned int fft_length,
unsigned int cplen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
class gr_ofdm_correlator : public gr_sync_decimator
{
protected:
gr_ofdm_correlator (unsigned int occupied_carriers,
- unsigned int vlen,
+ unsigned int fft_length,
unsigned int cplen,
- std::vector<gr_complex> known_symbol1,
- std::vector<gr_complex> known_symbol2);
+ const std::vector<gr_complex> &known_symbol1,
+ const std::vector<gr_complex> &known_symbol2);
public:
float snr() { return d_snr_est; }
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
new file mode 100644
index 000000000..acaf1258b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
@@ -0,0 +1,235 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ofdm_frame_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <stdexcept>
+
+#define VERBOSE 0
+
+inline void
+gr_ofdm_frame_sink::enter_search()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_search\n");
+
+ d_state = STATE_SYNC_SEARCH;
+
+}
+
+inline void
+gr_ofdm_frame_sink::enter_have_sync()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_sync\n");
+
+ d_state = STATE_HAVE_SYNC;
+
+ // clear state of demapper
+ d_byte_offset = 0;
+ d_partial_byte = 0;
+
+ d_header = 0;
+ d_headerbytelen_cnt = 0;
+}
+
+inline void
+gr_ofdm_frame_sink::enter_have_header()
+{
+ d_state = STATE_HAVE_HEADER;
+
+ // header consists of two 16-bit shorts in network byte order
+ // payload length is lower 12 bits
+ // whitener offset is upper 4 bits
+ d_packetlen = (d_header >> 16) & 0x0fff;
+ d_packet_whitener_offset = (d_header >> 28) & 0x000f;
+ d_packetlen_cnt = 0;
+
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n",
+ d_packetlen, d_packet_whitener_offset);
+}
+
+unsigned char gr_ofdm_frame_sink::bpsk_slicer(gr_complex x)
+{
+ return (unsigned char)(x.real() > 0 ? 1 : 0);
+}
+
+unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
+ unsigned char *out)
+{
+ unsigned int i=0, bytes_produced=0;
+
+ while(i < d_occupied_carriers) {
+
+ while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
+ //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag());
+ d_partial_byte |= bpsk_slicer(in[i++]) << (d_byte_offset++);
+ }
+
+ if(d_byte_offset == 8) {
+ out[bytes_produced++] = d_partial_byte;
+ d_byte_offset = 0;
+ d_partial_byte = 0;
+ }
+ }
+
+ return bytes_produced;
+}
+
+
+
+gr_ofdm_frame_sink_sptr
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
+{
+ return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers));
+}
+
+
+gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
+ : gr_sync_block ("ofdm_frame_sink",
+ gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)),
+ gr_make_io_signature (0, 0, 0)),
+ d_target_queue(target_queue), d_occupied_carriers(occupied_carriers),
+ d_byte_offset(0), d_partial_byte(0)
+{
+ d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/8.0)];
+
+ enter_search();
+}
+
+gr_ofdm_frame_sink::~gr_ofdm_frame_sink ()
+{
+ delete [] d_bytes_out;
+}
+
+int
+gr_ofdm_frame_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ const char *sig = (const char *) input_items[1];
+ int count_tones=0, count_items=0;
+ unsigned int j = 0;
+ unsigned int bytes=0;
+
+ if (VERBOSE)
+ fprintf(stderr,">>> Entering state machine\n");
+
+ bytes = bpsk_demapper(&in[0], d_bytes_out);
+
+ switch(d_state) {
+
+ case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
+ if (VERBOSE)
+ fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
+
+ if (sig[0]) { // Found it, set up for header decode
+ enter_have_sync();
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ if(sig[0])
+ printf("ERROR -- Found SYNC in HAVE_SYNC\n");
+ if (VERBOSE)
+ fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
+ d_headerbytelen_cnt, d_header);
+
+ j = 0;
+ while(j < bytes) {
+ d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF);
+ j++;
+
+ if (++d_headerbytelen_cnt == HEADERBYTELEN) {
+
+ if (VERBOSE)
+ fprintf(stderr, "got header: 0x%08x\n", d_header);
+
+ // we have a full header, check to see if it has been received properly
+ if (header_ok()){
+ enter_have_header();
+ printf("\nPacket Length: %d\n", d_packetlen);
+ //for(int k=0; k < d_packetlen; k++)
+ // printf("%02x", d_packet[k]);
+ //printf("\n");
+
+ while((j < bytes) && (d_packetlen_cnt < d_packetlen)) {
+ d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
+ }
+
+ if(d_packetlen_cnt == d_packetlen) {
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen);
+ memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ }
+ }
+ else {
+ enter_search(); // bad header
+ }
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ if(sig[0])
+ printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen);
+ if (VERBOSE)
+ fprintf(stderr,"Packet Build\n");
+
+ j = 0;
+ while(j < bytes) {
+ d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
+
+ if (d_packetlen_cnt == d_packetlen){ // packet is filled
+ // build a message
+ // NOTE: passing header field as arg1 is not scalable
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt);
+ memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ break;
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+
+ } // switch
+
+ return 1;
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
new file mode 100644
index 000000000..d77c76741
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_FRAME_SINK_H
+#define INCLUDED_GR_OFDM_FRAME_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class gr_ofdm_frame_sink;
+typedef boost::shared_ptr<gr_ofdm_frame_sink> gr_ofdm_frame_sink_sptr;
+
+gr_ofdm_frame_sink_sptr
+gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+/*!
+ * \brief Given a stream of bits and access_code flags, assemble packets.
+ * \ingroup sink
+ *
+ * input: stream of bytes from gr_correlate_access_code_bb
+ * output: none. Pushes assembled packet into target queue
+ *
+ * The framer expects a fixed length header of 2 16-bit shorts
+ * containing the payload length, followed by the payload. If the
+ * 2 16-bit shorts are not identical, this packet is ignored. Better
+ * algs are welcome.
+ *
+ * The input data consists of bytes that have two bits used.
+ * Bit 0, the LSB, contains the data bit.
+ * Bit 1 if set, indicates that the corresponding bit is the
+ * the first bit of the packet. That is, this bit is the first
+ * one after the access code.
+ */
+class gr_ofdm_frame_sink : public gr_sync_block
+{
+ friend gr_ofdm_frame_sink_sptr
+ gr_make_ofdm_frame_sink (gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+ private:
+ enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+ static const int MAX_PKT_LEN = 4096;
+ static const int HEADERBYTELEN = 4;
+
+ gr_msg_queue_sptr d_target_queue; // where to send the packet when received
+ state_t d_state;
+ unsigned int d_header; // header bits
+ int d_headerbytelen_cnt; // how many so far
+
+ unsigned char *d_bytes_out; // hold the current bytes produced by the demapper
+
+ unsigned int d_occupied_carriers;
+ unsigned int d_byte_offset;
+ unsigned int d_partial_byte;
+
+ unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
+ int d_packetlen; // length of packet
+ int d_packet_whitener_offset; // offset into whitener string to use
+ int d_packetlen_cnt; // how many so far
+
+ protected:
+ gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
+
+ void enter_search();
+ void enter_have_sync();
+ void enter_have_header();
+
+ bool header_ok()
+ {
+ // confirm that two copies of header info are identical
+ return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+ }
+
+ unsigned char bpsk_slicer(gr_complex x);
+ unsigned int bpsk_demapper(const gr_complex *in,
+ unsigned char *out);
+
+ public:
+ ~gr_ofdm_frame_sink();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_OFDM_FRAME_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_vector_source.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
index ff8bd5de5..b05c8b795 100644
--- a/gnuradio-core/src/lib/io/gr_message_vector_source.i
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2004,2006 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,17 +20,16 @@
* Boston, MA 02110-1301, USA.
*/
-GR_SWIG_BLOCK_MAGIC(gr,message_vector_source);
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink);
-gr_message_vector_source_sptr gr_make_message_vector_source (size_t max_msg_size, int msgq_limit=0);
+gr_ofdm_frame_sink_sptr
+gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
-class gr_message_vector_source : public gr_sync_block
+class gr_ofdm_frame_sink : public gr_sync_block
{
protected:
- gr_message_vector_source (size_t itemsize, int msgq_limit);
+ gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_tones);
public:
- ~gr_message_vector_source ();
-
- gr_msg_queue_sptr msgq() const;
+ ~gr_ofdm_frame_sink();
};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
index 9ac5abdcd..5f5a91fd2 100644
--- a/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
+++ b/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
@@ -38,7 +38,7 @@ gr_make_ofdm_sampler (unsigned int fft_length,
gr_ofdm_sampler::gr_ofdm_sampler (unsigned int fft_length,
unsigned int symbol_length)
: gr_block ("ofdm_sampler",
- gr_make_io_signature (2, 2, sizeof (gr_complex)),
+ gr_make_io_signature2 (2, 2, sizeof (gr_complex), sizeof(char)),
gr_make_io_signature (1, 1, sizeof (gr_complex)*fft_length)),
d_fft_length(fft_length), d_symbol_length(symbol_length)
{
@@ -61,7 +61,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
gr_vector_void_star &output_items)
{
gr_complex *iptr = (gr_complex *) input_items[0];
- gr_complex *trigger = (gr_complex *) input_items[1];
+ char *trigger = (char *) input_items[1];
gr_complex *optr = (gr_complex *) output_items[0];
@@ -70,7 +70,7 @@ gr_ofdm_sampler::general_work (int noutput_items,
unsigned int i=d_fft_length-1;
while(!found && i<std::min(ninput_items[0],ninput_items[1]) )
- if(trigger[i].real() > 0.5)
+ if(trigger[i])
found = 1;
else
i++;
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.cc b/gnuradio-core/src/lib/general/gr_skiphead.cc
index 4a1f87511..e395cbf66 100644
--- a/gnuradio-core/src/lib/general/gr_skiphead.cc
+++ b/gnuradio-core/src/lib/general/gr_skiphead.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -26,45 +26,57 @@
#include <gr_skiphead.h>
#include <gr_io_signature.h>
-gr_skiphead::gr_skiphead (size_t sizeof_stream_item, int nitems)
- : gr_sync_block ("skiphead",
- gr_make_io_signature (1, 1, sizeof_stream_item),
- gr_make_io_signature (1, 1, sizeof_stream_item)),
- d_nitems (nitems), d_nskipped_items (0)
+gr_skiphead::gr_skiphead (size_t itemsize, size_t nitems_to_skip)
+ : gr_block ("skiphead",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_nitems_to_skip(nitems_to_skip), d_nitems(0)
{
}
-gr_block_sptr
-gr_make_skiphead (size_t sizeof_stream_item, int nitems)
+gr_skiphead_sptr
+gr_make_skiphead (size_t itemsize, size_t nitems_to_skip)
{
- return gr_block_sptr (new gr_skiphead (sizeof_stream_item, nitems));
+ return gr_skiphead_sptr (new gr_skiphead (itemsize, nitems_to_skip));
}
int
-gr_skiphead::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
+gr_skiphead::general_work(int noutput_items,
+ gr_vector_int &ninput_items_ignored,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
{
- int items_to_skip = d_nitems - d_nskipped_items;
- if (items_to_skip <=0)
- {
- //Done with skipping, copy all input to the output;
- memcpy (output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item (0));
- return noutput_items;
- } else if (items_to_skip < noutput_items)
- {
- memcpy (output_items[0], &(((char *)input_items[0])[items_to_skip*input_signature()->sizeof_stream_item (0)]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
- //memcpy (output_items[0], &((input_items[0])[items_to_skip]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
- //memcpy (output_items[0], input_items[0]+items_to_skip*input_signature()->sizeof_stream_item (0), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
- d_nskipped_items += items_to_skip;
- consume_each (items_to_skip);
- return (noutput_items -items_to_skip);
- } else
- {
- d_nskipped_items += noutput_items;
- consume_each (items_to_skip);
- return 0;
+ const char *in = (const char *) input_items[0];
+ char *out = (char *) output_items[0];
+
+ int ninput_items = noutput_items; // we've got at least this many input items
+ int ii = 0; // input index
+
+ while (ii < ninput_items){
+
+ long long ni_total = ii + d_nitems; // total items processed so far
+ if (ni_total < d_nitems_to_skip){ // need to skip some more
+
+ int n_to_skip = (int) std::min(d_nitems_to_skip - ni_total,
+ (long long)(ninput_items - ii));
+ ii += n_to_skip;
+ }
+
+ else { // nothing left to skip. copy away
+
+ int n_to_copy = ninput_items - ii;
+ if (n_to_copy > 0){
+ size_t itemsize = output_signature()->sizeof_stream_item(0);
+ memcpy(out, in + (ii*itemsize), n_to_copy*itemsize);
+ }
+
+ d_nitems += ninput_items;
+ consume_each(ninput_items);
+ return n_to_copy;
+ }
}
- return -1;//Should never get here
+ d_nitems += ninput_items;
+ consume_each(ninput_items);
+ return 0;
}
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.h b/gnuradio-core/src/lib/general/gr_skiphead.h
index 81898ef40..6e2c78272 100644
--- a/gnuradio-core/src/lib/general/gr_skiphead.h
+++ b/gnuradio-core/src/lib/general/gr_skiphead.h
@@ -26,6 +26,10 @@
#include <gr_sync_block.h>
#include <stddef.h> // size_t
+class gr_skiphead;
+typedef boost::shared_ptr<gr_skiphead> gr_skiphead_sptr;
+
+
/*!
* \brief skips the first N items, from then on copies items to the output
* \ingroup block
@@ -33,22 +37,24 @@
* Useful for building test cases and sources which have metadata or junk at the start
*/
-class gr_skiphead : public gr_sync_block
+class gr_skiphead : public gr_block
{
- friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
- gr_skiphead (size_t sizeof_stream_item, int nitems);
+ friend gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
+ gr_skiphead (size_t itemsize, size_t nitems_to_skip);
- int d_nitems;
- int d_nskipped_items;
+ long long d_nitems_to_skip;
+ long long d_nitems; // total items seen
public:
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
};
-gr_block_sptr
-gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+gr_skiphead_sptr
+gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
#endif /* INCLUDED_GR_SKIPHEAD_H */
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.i b/gnuradio-core/src/lib/general/gr_skiphead.i
index 8942f184e..c725e26bb 100644
--- a/gnuradio-core/src/lib/general/gr_skiphead.i
+++ b/gnuradio-core/src/lib/general/gr_skiphead.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,11 +20,11 @@
* Boston, MA 02110-1301, USA.
*/
-%ignore gr_skiphead;
+GR_SWIG_BLOCK_MAGIC(gr,skiphead);
+
+gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
+
class gr_skiphead : public gr_block {
- friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
- gr_skiphead (size_t sizeof_stream_item, int nitems);
+ friend gr_skiphead_sptr gr_make_skiphead (size_t itemsize, size_t nitems_to_skip);
+ gr_skiphead (size_t itemsize, size_t nitems_to_skip);
};
-
-%rename(skiphead) gr_make_skiphead;
-gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
diff --git a/gnuradio-core/src/lib/general/gr_stream_mux.cc b/gnuradio-core/src/lib/general/gr_stream_mux.cc
index 1eaad29a2..e7e45de74 100644
--- a/gnuradio-core/src/lib/general/gr_stream_mux.cc
+++ b/gnuradio-core/src/lib/general/gr_stream_mux.cc
@@ -44,6 +44,10 @@ gr_stream_mux::gr_stream_mux (size_t itemsize, const std::vector<int> &lengths)
d_residual(0),
d_lengths(lengths)
{
+ if(d_lengths[d_stream] == 0) {
+ increment_stream();
+ }
+ d_residual = d_lengths[d_stream];
}
gr_stream_mux::~gr_stream_mux(void)
@@ -55,9 +59,17 @@ gr_stream_mux::forecast (int noutput_items, gr_vector_int &ninput_items_required
{
unsigned ninputs = ninput_items_required.size ();
for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = 0;
+ ninput_items_required[i] = (d_lengths[i] == 0 ? 0 : 1);
}
+void gr_stream_mux::increment_stream()
+{
+ do {
+ d_stream = (d_stream+1) % d_lengths.size();
+ } while(d_lengths[d_stream] == 0);
+
+ d_residual = d_lengths[d_stream];
+}
int
gr_stream_mux::general_work(int noutput_items,
@@ -65,128 +77,46 @@ gr_stream_mux::general_work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
-
char *out = (char *) output_items[0];
const char *in;
+ int out_index = 0;
+ std::vector<int> input_index(d_lengths.size(), 0);
- int acc = 0;
- int N=0;
- int M=0;
- std::vector<int> consume_vector(d_lengths.size(), 0);
+ if(VERBOSE) {
+ printf("mux: nouput_items: %d d_stream: %d\n", noutput_items, d_stream);
+ for(size_t i = 0; i < d_lengths.size(); i++)
+ printf("\tninput_items[%d]: %d\n", i, ninput_items[i]);
+ }
- #if VERBOSE
- printf("mux: nouput_items: %d d_stream: %d\n", noutput_items, d_stream);
- for(int i = 0; i < d_lengths.size(); i++)
- printf("\tninput_items[%d]: %d\n", i, ninput_items[i]);
- #endif
+ while (1) {
+ int r = std::min(noutput_items - out_index,
+ std::min(d_residual,
+ ninput_items[d_stream] - input_index[d_stream]));
+ if(VERBOSE) {
+ printf("mux: r=%d\n", r);
+ printf("\tnoutput_items - out_index: %d\n",
+ noutput_items - out_index);
+ printf("\td_residual: %d\n",
+ d_residual);
+ printf("\tninput_items[d_stream] - input_index[d_stream]: %d\n",
+ ninput_items[d_stream] - input_index[d_stream]);
+ }
- in = (const char *) input_items[d_stream];
+ if(r <= 0) {
+ return out_index;
+ }
- if(d_residual) {
- #if VERBOSE
- printf("Cleaning up residual bytes (%d) from stream %d\n", d_residual, d_stream);
- #endif
+ in = (const char *) input_items[d_stream] + input_index[d_stream]*d_itemsize;
- // get the number of items available in input stream up to the
- // num items required
- N=std::min(d_residual, ninput_items[d_stream]);
-
- // get the number of items we can put into the output buffer
- M=std::min(N, noutput_items);
-
- // copy the items to the output buff
- memcpy(out, in, M*d_itemsize);
+ memcpy(&out[out_index*d_itemsize], in, r*d_itemsize);
+ out_index += r;
+ input_index[d_stream] += r;
+ d_residual -= r;
- // increment the output accumulator
- acc += M;
-
- // keep track of items consumed
- consume_vector[d_stream]=M;
+ consume(d_stream, r);
- // keep track if there are residual items left from the input stream
- d_residual -= M;
-
- #if VERBOSE
- printf("Stream: %d (%x) Wrote: %d bytes Output has: %d bytes residual: %d bytes\n",
- d_stream, in, M, acc, d_residual);
- #endif
-
- // if no residual items, we're done with this input stream for
- // this round
- if (!d_residual) {
- if(d_stream == d_lengths.size() - 1) {
- d_stream=0; // wrap stream pointer
- }
- else {
- d_stream++; // or increment the stream pointer
- }
- #if VERBOSE
- printf("Going to next stream: %d\n", d_stream);
- #endif
- in = ((const char *) (input_items[d_stream])) + d_itemsize*consume_vector[d_stream];
- }
- }
-
- if(!d_residual) {
- while (acc<noutput_items){
- // get the number of items available in input stream up to the
- // num items required
- N=std::min(d_lengths[d_stream], ninput_items[d_stream]);
-
- // get the number of items we can put into the output buffer
- M=std::min(N, noutput_items-acc);
-
- // copy the items to the output buff
- memcpy(out+acc*d_itemsize,in,M*d_itemsize);
-
- // increment the output accumulator
- acc += M;
-
- // keep track of items consumed
- consume_vector[d_stream]+=M;
-
- // keep track if there are residual items left from the input stream
- d_residual=d_lengths[d_stream] - M;
-
- #if VERBOSE
- printf("Stream: %d (%x) Wrote: %d bytes Output has: %d bytes residual: %d bytes\n",
- d_stream, in, M, acc, d_residual);
- #endif
-
- // if no residual items, we're done with this input stream for
- // this round
- if (!d_residual) {
- if(d_stream == d_lengths.size() - 1) {
- d_stream=0; // wrap stream pointer
- }
- else {
- d_stream++; // or increment the stream pointer
- }
- #if VERBOSE
- printf("Going to next stream: %d\n", d_stream);
- #endif
-
- // get next stream pointer
- in = ((const char *) (input_items[d_stream])) + d_itemsize*consume_vector[d_stream];
- }
- else{
- break;
- }
+ if(d_residual == 0) {
+ increment_stream();
}
}
-
- for (unsigned int j=0;j<d_lengths.size();j++){
- consume(j,consume_vector[j]);
-
- #if VERBOSE
- printf("consuming: %d on stream: %d\n", consume_vector[j], j);
- #endif
- }
-
- #if VERBOSE
- printf("mux: returning: %d\n\n", acc);
- #endif
-
- return acc;
-
}
diff --git a/gnuradio-core/src/lib/general/gr_stream_mux.h b/gnuradio-core/src/lib/general/gr_stream_mux.h
index 492940001..5ea783cb6 100644
--- a/gnuradio-core/src/lib/general/gr_stream_mux.h
+++ b/gnuradio-core/src/lib/general/gr_stream_mux.h
@@ -25,7 +25,6 @@
#include <gr_block.h>
-#include <gr_frame.h>
#include <vector>
class gr_stream_mux;
@@ -66,14 +65,15 @@ class gr_stream_mux : public gr_block
protected:
gr_stream_mux (size_t itemsize, const std::vector<int> &lengths);
+
private:
- size_t d_itemsize;
- unsigned int d_stream;
- int d_residual;
- int d_times;
- int d_unconsume;
- //gr_vector_int d_unconsume;
- gr_vector_int d_lengths;
+ size_t d_itemsize;
+ unsigned int d_stream; // index of currently selected stream
+ int d_residual; // number if items left to put into current stream
+ gr_vector_int d_lengths; // number if items to pack per stream
+
+ void increment_stream();
+
public:
~gr_stream_mux(void);
diff --git a/gnuradio-core/src/lib/gengen/Makefile.gen b/gnuradio-core/src/lib/gengen/Makefile.gen
index ceb8692b4..238622bdd 100644
--- a/gnuradio-core/src/lib/gengen/Makefile.gen
+++ b/gnuradio-core/src/lib/gengen/Makefile.gen
@@ -62,9 +62,9 @@ GENERATED_H = \
gr_packed_to_unpacked_bb.h \
gr_packed_to_unpacked_ii.h \
gr_packed_to_unpacked_ss.h \
- gr_peak_detector_ff.h \
- gr_peak_detector_ii.h \
- gr_peak_detector_ss.h \
+ gr_peak_detector_fb.h \
+ gr_peak_detector_ib.h \
+ gr_peak_detector_sb.h \
gr_sample_and_hold_bb.h \
gr_sample_and_hold_ff.h \
gr_sample_and_hold_ii.h \
@@ -152,9 +152,9 @@ GENERATED_I = \
gr_packed_to_unpacked_bb.i \
gr_packed_to_unpacked_ii.i \
gr_packed_to_unpacked_ss.i \
- gr_peak_detector_ff.i \
- gr_peak_detector_ii.i \
- gr_peak_detector_ss.i \
+ gr_peak_detector_fb.i \
+ gr_peak_detector_ib.i \
+ gr_peak_detector_sb.i \
gr_sample_and_hold_bb.i \
gr_sample_and_hold_ff.i \
gr_sample_and_hold_ii.i \
@@ -242,9 +242,9 @@ GENERATED_CC = \
gr_packed_to_unpacked_bb.cc \
gr_packed_to_unpacked_ii.cc \
gr_packed_to_unpacked_ss.cc \
- gr_peak_detector_ff.cc \
- gr_peak_detector_ii.cc \
- gr_peak_detector_ss.cc \
+ gr_peak_detector_fb.cc \
+ gr_peak_detector_ib.cc \
+ gr_peak_detector_sb.cc \
gr_sample_and_hold_bb.cc \
gr_sample_and_hold_ff.cc \
gr_sample_and_hold_ii.cc \
diff --git a/gnuradio-core/src/lib/gengen/generate_common.py b/gnuradio-core/src/lib/gengen/generate_common.py
index aaf15f04a..c049438a2 100755
--- a/gnuradio-core/src/lib/gengen/generate_common.py
+++ b/gnuradio-core/src/lib/gengen/generate_common.py
@@ -59,9 +59,9 @@ others = (
('gr_unpacked_to_packed_XX', ('bb','ss','ii')),
('gr_packed_to_unpacked_XX', ('bb','ss','ii')),
('gr_sample_and_hold_XX', ('bb','ss','ii','ff')),
- ('gr_peak_detector_XX', ('ff','ii','ss')),
('gr_argmax_XX', ('fs','is','ss')),
('gr_max_XX', ('ff','ii','ss')),
+ ('gr_peak_detector_XX', ('fb','ib','sb'))
)
diff --git a/gnuradio-core/src/lib/gengen/gengen_generated.i b/gnuradio-core/src/lib/gengen/gengen_generated.i
index bab1f03e6..26dd3f41a 100644
--- a/gnuradio-core/src/lib/gengen/gengen_generated.i
+++ b/gnuradio-core/src/lib/gengen/gengen_generated.i
@@ -62,9 +62,9 @@
#include <gr_packed_to_unpacked_bb.h>
#include <gr_packed_to_unpacked_ii.h>
#include <gr_packed_to_unpacked_ss.h>
-#include <gr_peak_detector_ff.h>
-#include <gr_peak_detector_ii.h>
-#include <gr_peak_detector_ss.h>
+#include <gr_peak_detector_fb.h>
+#include <gr_peak_detector_ib.h>
+#include <gr_peak_detector_sb.h>
#include <gr_sample_and_hold_bb.h>
#include <gr_sample_and_hold_ff.h>
#include <gr_sample_and_hold_ii.h>
@@ -152,9 +152,9 @@
%include <gr_packed_to_unpacked_bb.i>
%include <gr_packed_to_unpacked_ii.i>
%include <gr_packed_to_unpacked_ss.i>
-%include <gr_peak_detector_ff.i>
-%include <gr_peak_detector_ii.i>
-%include <gr_peak_detector_ss.i>
+%include <gr_peak_detector_fb.i>
+%include <gr_peak_detector_ib.i>
+%include <gr_peak_detector_sb.i>
%include <gr_sample_and_hold_bb.i>
%include <gr_sample_and_hold_ff.i>
%include <gr_sample_and_hold_ii.i>
diff --git a/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
index 812ec9fd2..19a5b98aa 100644
--- a/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
+++ b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
@@ -44,7 +44,7 @@ gr_make_@BASE_NAME@ (float threshold_factor_rise,
int look_ahead, float alpha)
: gr_sync_block ("@BASE_NAME@",
gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
- gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ gr_make_io_signature (1, 1, sizeof (char))),
d_threshold_factor_rise(threshold_factor_rise),
d_threshold_factor_fall(threshold_factor_fall),
d_look_ahead(look_ahead), d_avg_alpha(alpha), d_avg(0), d_found(0)
@@ -57,9 +57,9 @@ int
gr_vector_void_star &output_items)
{
@I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
- @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+ char *optr = (char *) output_items[0];
- memset(optr, 0, noutput_items*sizeof(@O_TYPE@));
+ memset(optr, 0, noutput_items*sizeof(char));
@I_TYPE@ peak_val = -(@I_TYPE@)INFINITY;
int peak_ind = 0;
@@ -90,7 +90,7 @@ int
i++;
}
else {
- optr[peak_ind] = (@O_TYPE@)1;
+ optr[peak_ind] = 1;
state = 0;
peak_val = -(@I_TYPE@)INFINITY;
//printf("Leaving State 1: Peak: %f Peak Ind: %d i: %d noutput_items: %d\n",
diff --git a/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t
index 3b9715575..3f2c5f6f1 100644
--- a/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t
+++ b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t
@@ -37,7 +37,7 @@ gr_make_@BASE_NAME@ ()
@NAME@::@NAME@ ()
: gr_sync_block ("@BASE_NAME@",
- gr_make_io_signature (2, 2, sizeof (@I_TYPE@)),
+ gr_make_io_signature2 (2, 2, sizeof (@I_TYPE@), sizeof(char)),
gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
d_data(0)
{
@@ -49,11 +49,11 @@ int
gr_vector_void_star &output_items)
{
@I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
- @I_TYPE@ *ctrl = (@I_TYPE@ *) input_items[1];
+ const char *ctrl = (const char *) input_items[1];
@O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
for (int i = 0; i < noutput_items; i++){
- if(ctrl[i] > 0.5) {
+ if(ctrl[i]) {
d_data = iptr[i];
}
optr[i] = d_data;
diff --git a/gnuradio-core/src/lib/io/Makefile.am b/gnuradio-core/src/lib/io/Makefile.am
index 049e6984a..4835c68c2 100644
--- a/gnuradio-core/src/lib/io/Makefile.am
+++ b/gnuradio-core/src/lib/io/Makefile.am
@@ -29,12 +29,12 @@ noinst_LTLIBRARIES = libio.la
libio_la_SOURCES = \
gr_file_sink.cc \
+ gr_file_sink_base.cc \
gr_file_source.cc \
gr_file_descriptor_sink.cc \
gr_file_descriptor_source.cc \
gr_message_sink.cc \
gr_message_source.cc \
- gr_message_vector_source.cc \
gr_oscope_guts.cc \
gr_oscope_sink_f.cc \
gr_oscope_sink_x.cc \
@@ -57,13 +57,12 @@ libio_la_SOURCES = \
grinclude_HEADERS = \
gr_file_sink.h \
+ gr_file_sink_base.h \
gr_file_source.h \
gr_file_descriptor_sink.h \
gr_file_descriptor_source.h \
- gr_frame.h \
gr_message_sink.h \
gr_message_source.h \
- gr_message_vector_source.h \
gr_oscope_guts.h \
gr_oscope_sink_f.h \
gr_oscope_sink_x.h \
@@ -90,12 +89,12 @@ grinclude_HEADERS = \
swiginclude_HEADERS = \
io.i \
gr_file_sink.i \
+ gr_file_sink_base.i \
gr_file_source.i \
gr_file_descriptor_sink.i \
gr_file_descriptor_source.i \
gr_message_sink.i \
gr_message_source.i \
- gr_message_vector_source.i \
gr_oscope_sink.i \
microtune_xxxx_eval_board.i \
microtune_4702_eval_board.i \
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.cc b/gnuradio-core/src/lib/io/gr_file_sink.cc
index b7cf6c24e..0994fd2ba 100644
--- a/gnuradio-core/src/lib/io/gr_file_sink.cc
+++ b/gnuradio-core/src/lib/io/gr_file_sink.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2006 Free Software Foundation, Inc.
+ * Copyright 2004,2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -26,91 +26,28 @@
#include <gr_file_sink.h>
#include <gr_io_signature.h>
-#include <cstdio>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <stdexcept>
-// win32 (mingw/msvc) specific
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#ifdef O_BINARY
-#define OUR_O_BINARY O_BINARY
-#else
-#define OUR_O_BINARY 0
-#endif
-// should be handled via configure
-#ifdef O_LARGEFILE
-#define OUR_O_LARGEFILE O_LARGEFILE
-#else
-#define OUR_O_LARGEFILE 0
-#endif
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename)
+{
+ return gr_file_sink_sptr (new gr_file_sink (itemsize, filename));
+}
gr_file_sink::gr_file_sink(size_t itemsize, const char *filename)
: gr_sync_block ("file_sink",
gr_make_io_signature(1, 1, itemsize),
gr_make_io_signature(0, 0, 0)),
- d_itemsize(itemsize), d_fp(0), d_new_fp(0), d_updated(false)
+ gr_file_sink_base(filename, true),
+ d_itemsize(itemsize)
{
if (!open(filename))
throw std::runtime_error ("can't open file");
}
-gr_file_sink_sptr
-gr_make_file_sink (size_t itemsize, const char *filename)
-{
- return gr_file_sink_sptr (new gr_file_sink (itemsize, filename));
-}
-
gr_file_sink::~gr_file_sink ()
{
- close();
- if (d_fp){
- fclose((FILE *) d_fp);
- d_fp = 0;
- }
-}
-
-bool
-gr_file_sink::open(const char *filename)
-{
- omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
-
- // we use the open system call to get access to the O_LARGEFILE flag.
- int fd;
- if ((fd = ::open (filename,
- O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY, 0664)) < 0){
- perror (filename);
- return false;
- }
-
- if (d_new_fp){ // if we've already got a new one open, close it
- fclose((FILE *) d_new_fp);
- d_new_fp = 0;
- }
-
- if ((d_new_fp = fdopen (fd, "wb")) == NULL){
- perror (filename);
- ::close(fd); // don't leak file descriptor if fdopen fails.
- }
-
- d_updated = true;
- return d_new_fp != 0;
-}
-
-void
-gr_file_sink::close()
-{
- omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
-
- if (d_new_fp){
- fclose((FILE *) d_new_fp);
- d_new_fp = 0;
- }
- d_updated = true;
}
int
@@ -121,20 +58,13 @@ gr_file_sink::work (int noutput_items,
char *inbuf = (char *) input_items[0];
int nwritten = 0;
- if (d_updated){
- omni_mutex_lock l(d_mutex); // hold mutex for duration of this block
- if (d_fp)
- fclose((FILE *)d_fp);
- d_fp = d_new_fp; // install new file pointer
- d_new_fp = 0;
- d_updated = false;
- }
+ do_update(); // update d_fp is reqd
if (!d_fp)
return noutput_items; // drop output on the floor
while (nwritten < noutput_items){
- int count = fwrite (inbuf, d_itemsize, noutput_items - nwritten, (FILE *) d_fp);
+ int count = fwrite (inbuf, d_itemsize, noutput_items - nwritten, d_fp);
if (count == 0) // FIXME add error handling
break;
nwritten += count;
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.h b/gnuradio-core/src/lib/io/gr_file_sink.h
index c289a150c..fd0cd6f62 100644
--- a/gnuradio-core/src/lib/io/gr_file_sink.h
+++ b/gnuradio-core/src/lib/io/gr_file_sink.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,7 +24,7 @@
#define INCLUDED_GR_FILE_SINK_H
#include <gr_sync_block.h>
-#include <omnithread.h>
+#include <gr_file_sink_base.h>
class gr_file_sink;
typedef boost::shared_ptr<gr_file_sink> gr_file_sink_sptr;
@@ -36,16 +36,12 @@ gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
* \ingroup sink
*/
-class gr_file_sink : public gr_sync_block
+class gr_file_sink : public gr_sync_block, public gr_file_sink_base
{
friend gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
private:
size_t d_itemsize;
- void *d_fp; // current FILE pointer
- void *d_new_fp; // new FILE pointer
- bool d_updated; // is there a new FILE pointer?
- omni_mutex d_mutex;
protected:
gr_file_sink(size_t itemsize, const char *filename);
@@ -53,23 +49,9 @@ class gr_file_sink : public gr_sync_block
public:
~gr_file_sink();
- /*!
- * \brief Open filename and begin output to it.
- */
- bool open(const char *filename);
-
- /*!
- * \brief Close current output file.
- *
- * Closes current output file and ignores any output until
- * open is called to connect to another file.
- */
- void close();
-
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
};
-
#endif /* INCLUDED_GR_FILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.i b/gnuradio-core/src/lib/io/gr_file_sink.i
index 80f869562..202ab9317 100644
--- a/gnuradio-core/src/lib/io/gr_file_sink.i
+++ b/gnuradio-core/src/lib/io/gr_file_sink.i
@@ -25,7 +25,7 @@ GR_SWIG_BLOCK_MAGIC(gr,file_sink)
gr_file_sink_sptr
gr_make_file_sink (size_t itemsize, const char *filename);
-class gr_file_sink : public gr_sync_block
+class gr_file_sink : public gr_sync_block, public gr_file_sink_base
{
protected:
gr_file_sink (size_t itemsize, const char *filename);
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.cc b/gnuradio-core/src/lib/io/gr_file_sink_base.cc
new file mode 100644
index 000000000..44d01ba8d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.cc
@@ -0,0 +1,118 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_sink_base.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+gr_file_sink_base::gr_file_sink_base(const char *filename, bool is_binary)
+ : d_fp(0), d_new_fp(0), d_updated(false), d_is_binary(is_binary)
+{
+ if (!open(filename))
+ throw std::runtime_error ("can't open file");
+}
+
+gr_file_sink_base::~gr_file_sink_base ()
+{
+ close();
+ if (d_fp){
+ fclose(d_fp);
+ d_fp = 0;
+ }
+}
+
+bool
+gr_file_sink_base::open(const char *filename)
+{
+ omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
+
+ // we use the open system call to get access to the O_LARGEFILE flag.
+ int fd;
+ if ((fd = ::open (filename,
+ O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY,
+ 0664)) < 0){
+ perror (filename);
+ return false;
+ }
+
+ if (d_new_fp){ // if we've already got a new one open, close it
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+
+ if ((d_new_fp = fdopen (fd, d_is_binary ? "wb" : "w")) == NULL){
+ perror (filename);
+ ::close(fd); // don't leak file descriptor if fdopen fails.
+ }
+
+ d_updated = true;
+ return d_new_fp != 0;
+}
+
+void
+gr_file_sink_base::close()
+{
+ omni_mutex_lock l(d_mutex); // hold mutex for duration of this function
+
+ if (d_new_fp){
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+ d_updated = true;
+}
+
+void
+gr_file_sink_base::do_update()
+{
+ if (d_updated){
+ omni_mutex_lock l(d_mutex); // hold mutex for duration of this block
+ if (d_fp)
+ fclose(d_fp);
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_updated = false;
+ }
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.h b/gnuradio-core/src/lib/io/gr_file_sink_base.h
new file mode 100644
index 000000000..98fc7b652
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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_FILE_SINK_BASE_H
+#define INCLUDED_GR_FILE_SINK_BASE_H
+
+#include <omnithread.h>
+#include <cstdio>
+
+/*!
+ * \brief Common base class for file sinks
+ */
+class gr_file_sink_base
+{
+ protected:
+ FILE *d_fp; // current FILE pointer
+ FILE *d_new_fp; // new FILE pointer
+ bool d_updated; // is there a new FILE pointer?
+ bool d_is_binary;
+ omni_mutex d_mutex;
+
+ protected:
+ gr_file_sink_base(const char *filename, bool is_binary);
+
+ public:
+ ~gr_file_sink_base();
+
+ /*!
+ * \brief Open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief Close current output file.
+ *
+ * Closes current output file and ignores any output until
+ * open is called to connect to another file.
+ */
+ void close();
+
+ /*!
+ * \brief if we've had an update, do it now.
+ */
+ void do_update();
+};
+
+
+#endif /* INCLUDED_GR_FILE_SINK_BASE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.i b/gnuradio-core/src/lib/io/gr_file_sink_base.i
new file mode 100644
index 000000000..b83f251e1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.i
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+class gr_file_sink_base
+{
+ protected:
+ gr_file_sink_base(const char *filename, bool is_binary);
+
+ public:
+ ~gr_file_sink_base();
+
+ /*!
+ * \brief Open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief Close current output file.
+ *
+ * Closes current output file and ignores any output until
+ * open is called to connect to another file.
+ */
+ void close();
+
+ /*!
+ * \brief if we've had an update, do it now.
+ */
+ void do_update();
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_vector_source.cc b/gnuradio-core/src/lib/io/gr_message_vector_source.cc
deleted file mode 100644
index 69e2bc8df..000000000
--- a/gnuradio-core/src/lib/io/gr_message_vector_source.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_message_vector_source.h>
-#include <gr_io_signature.h>
-#include <cstdio>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdexcept>
-
-
-// public constructor that returns a shared_ptr
-
-gr_message_vector_source_sptr
-gr_make_message_vector_source(size_t max_msg_size, int msgq_limit)
-{
- return gr_message_vector_source_sptr(new gr_message_vector_source(max_msg_size,msgq_limit));
-}
-
-gr_message_vector_source::gr_message_vector_source (size_t max_msg_size, int msgq_limit)
- : gr_sync_block("message_vector_source",
- gr_make_io_signature(0, 0, 0),
- gr_make_io_signature(1, 1, 2*sizeof(int) + max_msg_size * sizeof(char))), // Make room for length fields
- d_max_msg_size(max_msg_size), d_msgq(gr_make_msg_queue(msgq_limit)), d_eof(false)
-{
-}
-
-gr_message_vector_source::~gr_message_vector_source()
-{
-}
-
-int
-gr_message_vector_source::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- /*
- char *out = (char *) output_items[0];
-
- if (d_eof)
- return -1;
-
- gr_message_sptr msg = d_msgq->delete_head();
-
- if (msg->type() == 1) { // type == 1 sets EOF
- d_eof = true;
- }
-
- assert(msg->length() <= d_max_msg_size);
- memset((int*)out, msg->length(), 1);
- memcpy (&out[4], (msg->msg()), msg->length());
- */
-
- char *out = (char *) output_items[0];
- gr_frame *myframe = (gr_frame*)out;
-
- if (d_eof)
- return -1;
-
- gr_message_sptr msg = d_msgq->delete_head();
-
- if (msg->type() == 1) { // type == 1 sets EOF
- d_eof = true;
- }
-
- assert(msg->length() <= d_max_msg_size);
- myframe->length = msg->length();
- myframe->mtu = d_max_msg_size;
- memcpy (myframe->data, (msg->msg()), msg->length());
-
- return 1;
-}
diff --git a/gnuradio-core/src/lib/io/gr_message_vector_source.h b/gnuradio-core/src/lib/io/gr_message_vector_source.h
deleted file mode 100644
index 8b3465355..000000000
--- a/gnuradio-core/src/lib/io/gr_message_vector_source.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_MESSAGE_VECTOR_SOURCE_H
-#define INCLUDED_GR_MESSAGE_VECTOR_SOURCE_H
-
-#include <gr_sync_block.h>
-#include <gr_message.h>
-#include <gr_msg_queue.h>
-#include <gr_frame.h>
-
-class gr_message_vector_source;
-typedef boost::shared_ptr<gr_message_vector_source> gr_message_vector_source_sptr;
-
-gr_message_vector_source_sptr gr_make_message_vector_source (size_t max_msg_size, int msgq_limit=0);
-
-/*!
- * \brief Turn received messages into vectors
- * \ingroup source
- */
-class gr_message_vector_source : public gr_sync_block
-{
- private:
- size_t d_max_msg_size;
- gr_msg_queue_sptr d_msgq;
- bool d_eof;
-
- friend gr_message_vector_source_sptr
- gr_make_message_vector_source(size_t max_msg_size, int msgq_limit);
-
- protected:
- gr_message_vector_source (size_t max_msg_size, int msgq_limit);
-
- public:
- ~gr_message_vector_source ();
-
- 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 /* INCLUDED_GR_MESSAGE_VECTOR_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i
index 806e83e1f..c6344051e 100644
--- a/gnuradio-core/src/lib/io/io.i
+++ b/gnuradio-core/src/lib/io/io.i
@@ -34,12 +34,12 @@
#include <ppio.h>
#include <gr_message_source.h>
#include <gr_message_sink.h>
-#include <gr_message_vector_source.h>
#include <gr_udp_sink.h>
#include <gr_udp_source.h>
%}
+%include "gr_file_sink_base.i"
%include "gr_file_sink.i"
%include "gr_file_source.i"
%include "gr_file_descriptor_sink.i"
@@ -51,7 +51,6 @@
%include "gr_oscope_sink.i"
%include "ppio.i"
%include "gr_message_source.i"
-%include "gr_message_vector_source.i"
%include "gr_message_sink.i"
%include "gr_udp_sink.i"
%include "gr_udp_source.i"
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am b/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
index 381340c42..b8c800110 100644
--- a/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
@@ -29,6 +29,7 @@ grblkspythondir = $(grpythondir)/blksimpl
grblkspython_PYTHON = \
__init__.py \
am_demod.py \
+ channel_model.py \
dbpsk.py \
dqpsk.py \
d8psk.py \
@@ -40,6 +41,8 @@ grblkspython_PYTHON = \
nbfm_rx.py \
nbfm_tx.py \
ofdm_pkt.py \
+ ofdm_receiver.py \
+ ofdm_sync.py \
pkt.py \
psk.py \
qam.py \
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py b/gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py
new file mode 100644
index 000000000..c7b3f07b8
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py
@@ -0,0 +1,50 @@
+#!/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
+
+class channel_model(gr.hier_block):
+ def __init__(self, fg, noise_voltage=0.0, frequency_offset=0.0, epsilon=1.0, taps=[1.0,0.0]):
+ ''' Creates a channel model that includes:
+ - AWGN noise power in terms of noise voltage
+ - A frequency offest in the channel in ratio
+ - A timing offset ratio to model clock difference (epsilon)
+ - Multipath taps
+ '''
+
+ print epsilon
+ self.timing_offset = gr.fractional_interpolator_cc(0, epsilon)
+
+ self.multipath = gr.fir_filter_ccc(1, taps)
+
+ self.noise_adder = gr.add_cc()
+ self.noise = gr.noise_source_c(gr.GR_GAUSSIAN,noise_voltage)
+ self.freq_offset = gr.sig_source_c(1, gr.GR_SIN_WAVE, frequency_offset, 1.0, 0.0)
+ self.mixer_offset = gr.multiply_cc()
+
+ fg.connect(self.timing_offset, self.multipath)
+ fg.connect(self.multipath, (self.mixer_offset,0))
+ fg.connect(self.freq_offset,(self.mixer_offset,1))
+ fg.connect(self.mixer_offset, (self.noise_adder,1))
+ fg.connect(self.noise, (self.noise_adder,0))
+
+ gr.hier_block.__init__(self, fg, self.timing_offset, self.noise_adder)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py
index 355455da1..9a98b374b 100644
--- a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_pkt.py
@@ -1,3 +1,4 @@
+
#
# Copyright 2005,2006,2007 Free Software Foundation, Inc.
#
@@ -19,10 +20,13 @@
# Boston, MA 02110-1301, USA.
#
+import math
from math import pi
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
@@ -34,7 +38,7 @@ class mod_ofdm_pkts(gr.hier_block):
Send packets by calling send_pkt
"""
- def __init__(self, fg, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True):
+ def __init__(self, fg, options, msgq_limit=2, pad_for_usrp=True):
"""
Hierarchical block for sending packets
@@ -43,29 +47,38 @@ class mod_ofdm_pkts(gr.hier_block):
@param fg: flow graph
@type fg: flow graph
- @param modulator: instance of modulator class (gr_block or hier_block)
- @type modulator: complex baseband out
- @param access_code: AKA sync vector
- @type access_code: string of 1's and 0's between 1 and 64 long
@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
See modulators for remaining parameters
"""
- self._modulator = modulator
self._pad_for_usrp = pad_for_usrp
- if access_code is None:
- access_code = ofdm_packet_utils.default_access_code
- if not ofdm_packet_utils.is_1_0_string(access_code):
- raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
- self._access_code = access_code
+ win = [] #[1 for i in range(self._fft_length)]
+
+ # hard-coded known symbol
+ ks1 = known_symbols_4512_1[0:options.occupied_tones]
+ #ks1 = known_symbols_4512_impulse[0:options.occupied_tones]
+ ks2 = known_symbols_4512_2[0:options.occupied_tones]
+
+ symbol_length = options.fft_length + options.cp_length
# accepts messages from the outside world
- self._pkt_input = gr.message_vector_source(self._modulator.mtu(), msgq_limit)
- fg.connect(self._pkt_input, self._modulator)
- gr.hier_block.__init__(self, fg, None, self._modulator)
+ self._pkt_input = gr.ofdm_bpsk_mapper(msgq_limit, options.occupied_tones, options.fft_length, ks1, ks2)
+ self.ifft = gr.fft_vcc(options.fft_length, False, win, True)
+ self.cp_adder = gr.ofdm_cyclic_prefixer(options.fft_length, symbol_length)
+ self.scale = gr.multiply_const_cc(1.0 / math.sqrt(options.fft_length))
+
+ fg.connect(self._pkt_input, self.ifft, self.cp_adder, self.scale)
+
+ if options.verbose:
+ self._print_verbage()
+
+ if 1:
+ 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):
"""
@@ -79,14 +92,41 @@ class mod_ofdm_pkts(gr.hier_block):
else:
# print "original_payload =", string_to_hex_list(payload)
pkt = ofdm_packet_utils.make_packet(payload,
- self._modulator.samples_per_symbol(),
- self._modulator.bits_per_symbol(),
- self._access_code,
+ self.samples_per_symbol(),
+ self.bits_per_symbol(),
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 samples_per_symbol(self):
+ return 2
+
+ def bits_per_symbol(self=None): # staticmethod that's also callable on an instance
+ return 1
+ bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM
+
+ def add_options(normal, expert):
+ """
+ Adds OFDM-specific options to the Options Parser
+ """
+ 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 "FFT length: %3d" % (self._fft_length)
+ print "Occupied Tones: %3d" % (self._occupied_tones)
+ print "CP length: %3d" % (self._cp_length)
class demod_ofdm_pkts(gr.hier_block):
@@ -97,7 +137,7 @@ class demod_ofdm_pkts(gr.hier_block):
app via the callback.
"""
- def __init__(self, fg, demodulator, access_code=None, callback=None, threshold=-1):
+ def __init__(self, fg, options, callback=None):
"""
Hierarchical block for demodulating and deframing packets.
@@ -108,36 +148,54 @@ class demod_ofdm_pkts(gr.hier_block):
@type fg: flow graph
@param demodulator: instance of demodulator class (gr_block or hier_block)
@type demodulator: complex baseband in
- @param access_code: AKA sync vector
- @type access_code: string of 1's and 0's
@param callback: function of two args: ok, payload
@type callback: ok: bool; payload: string
- @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default)
- @type threshold: int
"""
+ self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY
- self._demodulator = demodulator
- if access_code is None:
- access_code = ofdm_packet_utils.default_access_code
- if not ofdm_packet_utils.is_1_0_string(access_code):
- raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
- self._access_code = access_code
+ ks1 = known_symbols_4512_1[0:options.occupied_tones]
+ #ks1 = known_symbols_4512_impulse[0:options.occupied_tones]
+ ks2 = known_symbols_4512_2[0:options.occupied_tones]
+
+ symbol_length = options.fft_length + options.cp_length
+ self.ofdm_recv = ofdm_receiver(fg, options.fft_length, options.cp_length,
+ options.occupied_tones, options.snr, ks1, ks2)
+ self.ofdm_demod = gr.ofdm_frame_sink(self._rcvd_pktq,
+ options.occupied_tones)
+
+ fg.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
+ fg.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
- if threshold == -1:
- threshold = 12 # FIXME raise exception
+ gr.hier_block.__init__(self, fg, self.ofdm_recv, None)
+ self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
- self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY
- self.bytes_to_bits = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST)
- self.correlator = gr.correlate_access_code_bb(access_code, threshold)
- self.framer_sink = gr.framer_sink_1(self._rcvd_pktq)
- fg.connect(self._demodulator, self.bytes_to_bits, self.correlator, self.framer_sink)
+ def bits_per_symbol(self=None): # staticmethod that's also callable on an instance
+ return 1
+ bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM
+
+ def add_options(normal, expert):
+ """
+ Adds OFDM-specific options to the Options Parser
+ """
+ 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 "FFT length: %3d" % (self._fft_length)
+ print "Occupied Tones: %3d" % (self._occupied_tones)
+ print "CP length: %3d" % (self._cp_length)
- if 0:
- fg.connect(self.bytes_to_bits, gr.file_sink(gr.sizeof_char, "received_bits.out"))
-
- gr.hier_block.__init__(self, fg, self._demodulator, None)
- self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
class _queue_watcher_thread(_threading.Thread):
@@ -156,3 +214,16 @@ class _queue_watcher_thread(_threading.Thread):
ok, payload = ofdm_packet_utils.unmake_packet(msg.to_string())
if self.callback:
self.callback(ok, payload)
+
+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,]
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
new file mode 100644
index 000000000..e2f593283
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# 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 gnuradio import gr
+from gnuradio.blksimpl.ofdm_sync import ofdm_sync
+
+class ofdm_receiver(gr.hier_block):
+ def __init__(self, fg, fft_length, cp_length, occupied_tones, snr, ks1, ks2):
+ self.fg = fg
+
+ bw = (float(occupied_tones) / float(fft_length)) / 2.0
+ tb = bw*0.08
+ chan_coeffs = gr.firdes.low_pass (1.0, # gain
+ 1.0, # sampling rate
+ bw+tb, # midpoint of trans. band
+ tb, # width of trans. band
+ gr.firdes.WIN_HAMMING) # filter type
+ self.chan_filt = gr.fft_filter_ccc(1, chan_coeffs)
+
+ win = [1 for i in range(fft_length)]
+
+ self.ofdm_sync = ofdm_sync(fg, fft_length, cp_length, snr)
+ 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)
+
+ self.fg.connect(self.chan_filt, self.ofdm_sync, self.fft_demod, self.ofdm_corr)
+
+ if 1:
+ 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"))
+ self.fg.connect((self.ofdm_corr,1), gr.file_sink(1, "found_corr_b.dat"))
+
+ gr.hier_block.__init__(self, fg, self.chan_filt, self.ofdm_corr)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py
new file mode 100644
index 000000000..271be93de
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync.py
@@ -0,0 +1,141 @@
+#!/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(gr.hier_block):
+ def __init__(self, fg, fft_length, cp_length, snr):
+ self.fg = fg
+
+ 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.inv = gr.multiply_const_ff(-1)
+ 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
+
+ fixed_timing = 0
+ if fixed_timing:
+ # Use a fixed trigger point instead of sync block
+ peak_null = gr.null_sink(gr.sizeof_char)
+ data = 640*[0,]
+ data[639] = 1
+ peak_trigger = gr.vector_source_b(data, True)
+
+ self.fg.connect(self.pk_detect, peak_null)
+ self.fg.connect(peak_trigger, (self.sampler,1))
+ self.fg.connect(peak_trigger, (self.sample_and_hold,1))
+ else:
+ self.dpll = gr.dpll_bb(float(symbol_length),0.01)
+ if use_dpll:
+ 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.inv, self.nco)
+
+ if 1:
+ self.fg.connect(self.diff, gr.file_sink(gr.sizeof_float, "theta_f.dat"))
+ self.fg.connect(self.angle, gr.file_sink(gr.sizeof_float, "epsilon_f.dat"))
+ if fixed_timing:
+ self.fg.connect(peak_trigger, gr.file_sink(gr.sizeof_char, "peaks_b.dat"))
+ else:
+ self.fg.connect(self.pk_detect, gr.file_sink(gr.sizeof_char, "peaks_b.dat"))
+ if use_dpll:
+ self.fg.connect(self.dpll, gr.file_sink(gr.sizeof_char, "dpll_b.dat"))
+
+ self.fg.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex, "sigmix_c.dat"))
+ self.fg.connect(self.sampler, gr.file_sink(gr.sizeof_gr_complex*fft_length, "sampler_c.dat"))
+ self.fg.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float, "sample_and_hold_f.dat"))
+ self.fg.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex, "nco_c.dat"))
+ self.fg.connect(self.input, gr.file_sink(gr.sizeof_gr_complex, "input_c.dat"))
+
+ gr.hier_block.__init__(self, fg, self.input, self.sampler)
diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
index 557bf13f9..dc0e4a8a3 100644
--- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
@@ -55,6 +55,7 @@ noinst_PYTHON = \
qa_complex_to_xxx.py \
qa_constellation_decoder_cb.py \
qa_correlate_access_code.py \
+ qa_delay.py \
qa_diff_encoder.py \
qa_diff_phasor_cc.py \
qa_feval.py \
@@ -89,6 +90,7 @@ noinst_PYTHON = \
qa_sig_source.py \
qa_single_pole_iir.py \
qa_single_pole_iir_cc.py \
+ qa_skiphead.py \
qa_unpack_k_bits.py
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_delay.py b/gnuradio-core/src/python/gnuradio/gr/qa_delay.py
new file mode 100755
index 000000000..8bef46355
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_delay.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 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
+import math
+
+class test_delay (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.fg = gr.flow_graph ()
+
+ def tearDown (self):
+ self.fg = None
+
+ def test_000 (self):
+ delta_t = 0
+ fg = self.fg
+ src_data = [float(x) for x in range(0, 100)]
+ expected_result = tuple(delta_t*[0.0] + src_data)
+
+ src = gr.vector_source_f(src_data)
+ op = gr.delay(gr.sizeof_float, delta_t)
+ dst = gr.vector_sink_f ()
+
+ fg.connect (src, op, dst)
+ fg.run ()
+ dst_data = dst.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_010 (self):
+ delta_t = 10
+ fg = self.fg
+ src_data = [float(x) for x in range(0, 100)]
+ expected_result = tuple(delta_t*[0.0] + src_data[0:-delta_t])
+
+ src = gr.vector_source_f(src_data)
+ op = gr.delay(gr.sizeof_float, delta_t)
+ dst = gr.vector_sink_f ()
+
+ fg.connect (src, op, dst)
+ fg.run ()
+ dst_data = dst.data ()
+ self.assertEqual (expected_result, dst_data)
+
+if __name__ == '__main__':
+ gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_skiphead.py b/gnuradio-core/src/python/gnuradio/gr/qa_skiphead.py
new file mode 100755
index 000000000..4a25f4921
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_skiphead.py
@@ -0,0 +1,102 @@
+#!/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
+
+class test_skiphead (gr_unittest.TestCase):
+
+ def setUp(self):
+ self.fg = gr.flow_graph ()
+ self.src_data = [int(x) for x in range(65536)]
+
+ def tearDown(self):
+ self.fg = None
+
+ def test_skip_0(self):
+ skip_cnt = 0
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.fg.connect (src1, op, dst1)
+ self.fg.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_1(self):
+ skip_cnt = 1
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.fg.connect (src1, op, dst1)
+ self.fg.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_1023(self):
+ skip_cnt = 1023
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.fg.connect (src1, op, dst1)
+ self.fg.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_6339(self):
+ skip_cnt = 6339
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.fg.connect (src1, op, dst1)
+ self.fg.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_12678(self):
+ skip_cnt = 12678
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.fg.connect (src1, op, dst1)
+ self.fg.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_all(self):
+ skip_cnt = len(self.src_data)
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.fg.connect (src1, op, dst1)
+ self.fg.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py b/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py
new file mode 100755
index 000000000..4a79cb629
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005 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
+
+class test_head (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.fg = gr.flow_graph ()
+
+ def tearDown (self):
+ self.fg = None
+
+ def help_stream_2ff(self, N, stream_sizes):
+ v0 = gr.vector_source_f(N*[1,], False)
+ v1 = gr.vector_source_f(N*[2,], False)
+
+ mux = gr.stream_mux(gr.sizeof_float, stream_sizes)
+
+ dst = gr.vector_sink_f ()
+
+ self.fg.connect (v0, (mux,0))
+ self.fg.connect (v1, (mux,1))
+ self.fg.connect (mux, dst)
+ self.fg.run ()
+
+ return dst.data ()
+
+ def help_stream_ramp_2ff(self, N, stream_sizes):
+ r1 = range(N)
+ r2 = range(N)
+ r2.reverse()
+
+ v0 = gr.vector_source_f(r1, False)
+ v1 = gr.vector_source_f(r2, False)
+
+ mux = gr.stream_mux(gr.sizeof_float, stream_sizes)
+
+ dst = gr.vector_sink_f ()
+
+ self.fg.connect (v0, (mux,0))
+ self.fg.connect (v1, (mux,1))
+ self.fg.connect (mux, dst)
+ self.fg.run ()
+
+ return dst.data ()
+
+ def test_stream_2NN_ff(self):
+ N = 40
+ stream_sizes = [10, 10]
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0)
+ self.assertEqual (exp_data, result_data)
+
+ def test_stream_ramp_2NN_ff(self):
+ N = 40
+ stream_sizes = [10, 10]
+ result_data = self.help_stream_ramp_2ff(N, stream_sizes)
+
+ exp_data = ( 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,
+ 39.0, 38.0, 37.0, 36.0, 35.0, 34.0, 33.0, 32.0, 31.0, 30.0,
+ 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0,
+ 29.0, 28.0, 27.0, 26.0, 25.0, 24.0, 23.0, 22.0, 21.0, 20.0,
+ 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
+ 19.0, 18.0, 17.0, 16.0, 15.0, 14.0, 13.0, 12.0, 11.0, 10.0,
+ 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0,
+ 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0)
+ self.assertEqual (exp_data, result_data)
+
+
+ def test_stream_2NM_ff(self):
+ N = 40
+ stream_sizes = [7, 9]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0)
+
+ self.assertEqual (exp_data, result_data)
+
+
+ def test_stream_2MN_ff(self):
+ N = 37
+ stream_sizes = [7, 9]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0)
+
+ self.assertEqual (exp_data, result_data)
+
+ def test_stream_2N0_ff(self):
+ N = 30
+ stream_sizes = [7, 0]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0)
+
+ self.assertEqual (exp_data, result_data)
+
+ def test_stream_20N_ff(self):
+ N = 30
+ stream_sizes = [0, 9]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 2.0, 2.0, 2.0)
+
+ self.assertEqual (exp_data, result_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py b/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
index e2b26306c..006ca6de2 100644
--- a/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
+++ b/gnuradio-core/src/python/gnuradio/ofdm_packet_utils.py
@@ -68,9 +68,6 @@ def conv_1_0_string_to_packed_binary_string(s):
return (''.join(r), padded)
-default_access_code = \
- conv_packed_binary_string_to_1_0_string('\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC')
-
def is_1_0_string(s):
if not isinstance(s, str):
return False
@@ -99,8 +96,7 @@ def make_header(payload_len, whitener_offset=0):
return struct.pack('!HH', val, val)
def make_packet(payload, samples_per_symbol, bits_per_symbol,
- access_code=default_access_code, pad_for_usrp=True,
- whitener_offset=0):
+ pad_for_usrp=True, whitener_offset=0, dowhiten=1):
"""
Build a packet, given access code, payload, and whitener offset
@@ -109,20 +105,14 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
@type samples_per_symbol: int
@param bits_per_symbol: (needed for padding calculation)
@type bits_per_symbol: int
- @param access_code: string of ascii 0's and 1's
@param whitener_offset offset into whitener string to use [0-16)
Packet will have access code at the beginning, followed by length, payload
and finally CRC-32.
"""
- if not is_1_0_string(access_code):
- raise ValueError, "access_code must be a string containing only 0's and 1's (%r)" % (access_code,)
-
if not whitener_offset >=0 and whitener_offset < 16:
raise ValueError, "whitener_offset must be between 0 and 15, inclusive (%i)" % (whitener_offset,)
- (packed_access_code, padded) = conv_1_0_string_to_packed_binary_string(access_code)
-
payload_with_crc = gru.gen_and_append_crc32(payload)
#print "outbound crc =", string_to_hex_list(payload_with_crc[-4:])
@@ -131,16 +121,18 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
if L > MAXLEN:
raise ValueError, "len(payload) must be in [0, %d]" % (MAXLEN,)
- #pkt = ''.join((packed_access_code, make_header(L, whitener_offset)),
- # whiten(payload_with_crc, whitener_offset), '\x55'))
- pkt_hd = ''.join((packed_access_code, make_header(L, whitener_offset)))
+ pkt_hd = make_header(L, whitener_offset)
pkt_dt = ''.join((payload_with_crc, '\x55'))
packet_length = len(pkt_hd) + len(pkt_dt)
if pad_for_usrp:
usrp_packing = _npadding_bytes(packet_length, samples_per_symbol, bits_per_symbol) * '\x55'
- pkt_dt = pkt_dt + usrp_packing
- pkt = pkt_hd + whiten(pkt_dt, whitener_offset)
+ pkt_dt = pkt_dt + usrp_packing
+
+ if(dowhiten):
+ pkt = pkt_hd + whiten(pkt_dt, whitener_offset)
+ else:
+ pkt = pkt_hd + pkt_dt
#print "make_packet: len(pkt) =", len(pkt)
@@ -168,13 +160,17 @@ def _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol):
return byte_modulus - r
-def unmake_packet(whitened_payload_with_crc, whitener_offset=0):
+def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dodewhiten=1):
"""
Return (ok, payload)
@param whitened_payload_with_crc: string
"""
- payload_with_crc = dewhiten(whitened_payload_with_crc, whitener_offset)
+ if dodewhiten:
+ payload_with_crc = dewhiten(whitened_payload_with_crc, whitener_offset)
+ else:
+ payload_with_crc = whitened_payload_with_crc
+
ok, payload = gru.check_crc32(payload_with_crc)
if 0: