[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r7324 - in gnuradio/trunk: . gnuradio-core/src/lib/gen
From: |
trondeau |
Subject: |
[Commit-gnuradio] r7324 - in gnuradio/trunk: . gnuradio-core/src/lib/general gnuradio-core/src/python/gnuradio/blks2impl gnuradio-core/src/python/gnuradio/blksimpl gnuradio-core/src/utils gnuradio-examples/python/ofdm |
Date: |
Wed, 2 Jan 2008 10:35:36 -0700 (MST) |
Author: trondeau
Date: 2008-01-02 10:35:35 -0700 (Wed, 02 Jan 2008)
New Revision: 7324
Added:
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.i
gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.i
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py
gnuradio/trunk/gnuradio-core/src/utils/README
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_char.py
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_c.py
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_f.py
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_int.py
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_short.py
gnuradio/trunk/gnuradio-examples/python/ofdm/gr_plot_ofdm.py
Removed:
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py
gnuradio/trunk/gnuradio-core/src/utils/gr_read_binary.py
Modified:
gnuradio/trunk/AUTHORS
gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am
gnuradio/trunk/gnuradio-core/src/lib/general/general.i
gnuradio/trunk/gnuradio-core/src/lib/general/gr_math.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_const.py
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_float.py
gnuradio/trunk/gnuradio-core/src/utils/gr_plot_iq.py
gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m
gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
Log:
Merging ofdm2 branch -r7047:7321 into trunk. This updates the OFDM code to
hier_block2 in blks2impl and removed from blksimpl. The new code
implements a decision feedback sync loop to lock the phase/freq, removes two
unnecessary premables and performs frame sync and equalization off
single preamble symbol. Also adds/updates Python plotting tools and a
branchless clip algorithm in gr_math.h.
Modified: gnuradio/trunk/AUTHORS
===================================================================
--- gnuradio/trunk/AUTHORS 2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/AUTHORS 2008-01-02 17:35:35 UTC (rev 7324)
@@ -11,3 +11,4 @@
Joshua Lackey <address@hidden> Original GMSK implementation.
Johnathan Corgan <address@hidden> Build system, ongoing stuff, release manager
Bdale Garbee <address@hidden> Debian release packages
+Tom Rondeau <address@hidden> Mostly digital waveforms and a little
bit of trouble
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am 2008-01-02
17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am 2008-01-02
17:35:35 UTC (rev 7324)
@@ -96,7 +96,7 @@
gr_nop.cc \
gr_null_sink.cc \
gr_null_source.cc \
- gr_ofdm_correlator.cc \
+ gr_ofdm_frame_acquisition.cc \
gr_ofdm_cyclic_prefixer.cc \
gr_ofdm_demapper_vcb.cc \
gr_ofdm_mapper_bcv.cc \
@@ -109,6 +109,7 @@
gr_ofdm_sampler.cc \
gr_pa_2x2_phase_combiner.cc \
gr_packet_sink.cc \
+ gr_peak_detector2_fb.cc \
gr_phase_modulator_fc.cc \
gr_pll_carriertracking_cc.cc \
gr_pll_freqdet_cf.cc \
@@ -239,7 +240,7 @@
gr_nop.h \
gr_null_sink.h \
gr_null_source.h \
- gr_ofdm_correlator.h \
+ gr_ofdm_frame_acquisition.h \
gr_ofdm_cyclic_prefixer.h \
gr_ofdm_demapper_vcb.h \
gr_ofdm_mapper_bcv.h \
@@ -252,6 +253,7 @@
gr_ofdm_sampler.h \
gr_pa_2x2_phase_combiner.h \
gr_packet_sink.h \
+ gr_peak_detector2_fb.h \
gr_phase_modulator_fc.h \
gr_pll_carriertracking_cc.h \
gr_pll_freqdet_cf.h \
@@ -383,7 +385,7 @@
gr_nop.i \
gr_null_sink.i \
gr_null_source.i \
- gr_ofdm_correlator.i \
+ gr_ofdm_frame_acquisition.i \
gr_ofdm_cyclic_prefixer.i \
gr_ofdm_demapper_vcb.i \
gr_ofdm_mapper_bcv.i \
@@ -396,6 +398,7 @@
gr_ofdm_sampler.i \
gr_pa_2x2_phase_combiner.i \
gr_packet_sink.i \
+ gr_peak_detector2_fb.i \
gr_phase_modulator_fc.i \
gr_pll_carriertracking_cc.i \
gr_pll_freqdet_cf.i \
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/general.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/general.i 2008-01-02
17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/general.i 2008-01-02
17:35:35 UTC (rev 7324)
@@ -93,7 +93,7 @@
#include <gr_probe_avg_mag_sqrd_cf.h>
#include <gr_probe_avg_mag_sqrd_f.h>
#include <gr_probe_signal_f.h>
-#include <gr_ofdm_correlator.h>
+#include <gr_ofdm_frame_acquisition.h>
#include <gr_ofdm_cyclic_prefixer.h>
#include <gr_ofdm_bpsk_demapper.h>
#include <gr_ofdm_mapper_bcv.h>
@@ -128,6 +128,7 @@
#include <gr_bin_statistics_f.h>
#include <gr_glfsr_source_b.h>
#include <gr_glfsr_source_f.h>
+#include <gr_peak_detector2_fb.h>
%}
%include "gr_nop.i"
@@ -201,7 +202,7 @@
%include "gr_probe_avg_mag_sqrd_cf.i"
%include "gr_probe_avg_mag_sqrd_f.i"
%include "gr_probe_signal_f.i"
-%include "gr_ofdm_correlator.i"
+%include "gr_ofdm_frame_acquisition.i"
%include "gr_ofdm_cyclic_prefixer.i"
%include "gr_ofdm_bpsk_demapper.i"
%include "gr_ofdm_mapper_bcv.i"
@@ -236,3 +237,4 @@
%include "gr_bin_statistics_f.i"
%include "gr_glfsr_source_b.i"
%include "gr_glfsr_source_f.i"
+%include "gr_peak_detector2_fb.i"
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_math.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_math.h 2008-01-02
17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_math.h 2008-01-02
17:35:35 UTC (rev 7324)
@@ -64,4 +64,17 @@
return gr_fast_atan2f(z.imag(), z.real());
}
+
+/* This bounds x by +/- clip without a branch */
+
+static inline float gr_branchless_clip(float x, float clip)
+{
+ float x1 = fabsf(x+clip);
+ float x2 = fabsf(x-clip);
+ x1 -= x2;
+ return 0.5*x1;
+}
+
+
+
#endif /* _GR_MATH_H_ */
Deleted: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.cc
Deleted: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.h
Deleted: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_correlator.i
Copied:
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc (from
rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.cc
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,223 @@
+/* -*- c++ -*- */
+/*
+ * 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 3, 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_acquisition.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <gr_math.h>
+
+#define VERBOSE 0
+#define M_TWOPI (2*M_PI)
+#define MAX_NUM_SYMBOLS 1000
+
+gr_ofdm_frame_acquisition_sptr
+gr_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int
fft_length,
+ unsigned int cplen,
+ const std::vector<gr_complex> &known_symbol,
+ unsigned int max_fft_shift_len)
+{
+ return gr_ofdm_frame_acquisition_sptr (new gr_ofdm_frame_acquisition
(occupied_carriers, fft_length, cplen,
+
known_symbol, max_fft_shift_len));
+}
+
+gr_ofdm_frame_acquisition::gr_ofdm_frame_acquisition (unsigned
occupied_carriers, unsigned int fft_length,
+ unsigned int cplen,
+ const
std::vector<gr_complex> &known_symbol,
+ unsigned int
max_fft_shift_len)
+ : gr_block ("ofdm_frame_acquisition",
+ gr_make_io_signature2 (2, 2, sizeof(gr_complex)*fft_length,
sizeof(char)),
+ gr_make_io_signature2 (2, 2,
sizeof(gr_complex)*occupied_carriers, sizeof(char))),
+ d_occupied_carriers(occupied_carriers),
+ d_fft_length(fft_length),
+ d_cplen(cplen),
+ d_freq_shift_len(max_fft_shift_len),
+ d_known_symbol(known_symbol),
+ d_coarse_freq(0),
+ d_phase_count(0)
+{
+ d_symbol_phase_diff.resize(d_fft_length);
+ d_known_phase_diff.resize(d_occupied_carriers);
+ d_hestimate.resize(d_occupied_carriers);
+
+ unsigned int i = 0, j = 0;
+
+ std::fill(d_known_phase_diff.begin(), d_known_phase_diff.end(), 0);
+ for(i = 0; i < d_known_symbol.size()-2; i+=2) {
+ d_known_phase_diff[i] = fabs(gr_fast_atan2f(d_known_symbol[i]) -
gr_fast_atan2f(d_known_symbol[i+2]));
+ }
+
+ d_phase_lut = new gr_complex[(2*d_freq_shift_len+1) * MAX_NUM_SYMBOLS];
+ for(i = 0; i <= 2*d_freq_shift_len; i++) {
+ for(j = 0; j < MAX_NUM_SYMBOLS; j++) {
+ d_phase_lut[j + i*MAX_NUM_SYMBOLS] =
gr_expj(-M_TWOPI*d_cplen/d_fft_length*(i-d_freq_shift_len)*j);
+ }
+ }
+}
+
+gr_ofdm_frame_acquisition::~gr_ofdm_frame_acquisition(void)
+{
+ delete [] d_phase_lut;
+}
+
+void
+gr_ofdm_frame_acquisition::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] = 1;
+}
+
+gr_complex
+gr_ofdm_frame_acquisition::coarse_freq_comp(int freq_delta, int symbol_count)
+{
+ // return
gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count),
+ // sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count));
+
+ return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count);
+
+ //return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) +
symbol_count];
+}
+
+
+
+bool
+gr_ofdm_frame_acquisition::correlate(const gr_complex *symbol, int
zeros_on_left)
+{
+ unsigned int i = 0, j = 0;
+
+ std::fill(d_symbol_phase_diff.begin(), d_symbol_phase_diff.end(), 0);
+ for(i = 0; i < d_fft_length-2; i++) {
+ d_symbol_phase_diff[i] = fabs(gr_fast_atan2f(symbol[i]) -
gr_fast_atan2f(symbol[i+2]));
+ }
+
+ int index = 0;
+ float max = 0, sum=0;
+ for(i = zeros_on_left - d_freq_shift_len; i < zeros_on_left +
d_freq_shift_len; i+=2) {
+ sum = 0;
+ for(j = 0; j < d_occupied_carriers; j++) {
+ sum += (d_known_phase_diff[j] * d_symbol_phase_diff[i+j]);
+ }
+ if(fabs(sum) > max) {
+ max = sum;
+ index = i;
+ }
+ }
+
+ d_coarse_freq = index - zeros_on_left;
+
+ if(VERBOSE) {
+ fprintf(stderr, "Coarse Freq Offset: %d\n", d_coarse_freq);
+ for(i = 0; i < 40; i++) {
+ fprintf(stderr, "%+.4f %+.4f\n", d_known_phase_diff[i],
+ d_symbol_phase_diff[zeros_on_left+d_coarse_freq+i]);
+ }
+ }
+
+ return true; //FIXME: don't need ot return anything now
+}
+
+void
+gr_ofdm_frame_acquisition::calculate_equalizer(const gr_complex *symbol, int
zeros_on_left)
+{
+ unsigned int i=0;
+
+ // Set first tap of equalizer
+ d_hestimate[0] = d_known_symbol[0] /
+ (coarse_freq_comp(d_coarse_freq,1)*symbol[zeros_on_left+d_coarse_freq]);
+
+ // set every even tap based on known symbol
+ // linearly interpolate between set carriers to set zero-filled carriers
+ // FIXME: is this the best way to set this?
+ for(i = 2; i < d_occupied_carriers; i+=2) {
+ d_hestimate[i] = d_known_symbol[i] /
+
(coarse_freq_comp(d_coarse_freq,1)*(symbol[i+zeros_on_left+d_coarse_freq]));
+ d_hestimate[i-1] = (d_hestimate[i] + d_hestimate[i-2]) / gr_complex(2.0,
0.0);
+ }
+
+ // with even number of carriers; last equalizer tap is wrong
+ if(!(d_occupied_carriers & 1)) {
+ d_hestimate[d_occupied_carriers-1] = d_hestimate[d_occupied_carriers-2];
+ }
+
+ if(VERBOSE) {
+ fprintf(stderr, "Equalizer setting:\n");
+ for(i = 0; i < d_occupied_carriers; i++) {
+ gr_complex sym =
coarse_freq_comp(d_coarse_freq,1)*symbol[i+zeros_on_left+d_coarse_freq];
+ gr_complex output = sym * d_hestimate[i];
+ fprintf(stderr, "sym: %+.4f + j%+.4f ks: %+.4f + j%+.4f eq: %+.4f +
j%+.4f ==> %+.4f + j%+.4f\n",
+ sym .real(), sym.imag(),
+ d_known_symbol[i].real(), d_known_symbol[i].imag(),
+ d_hestimate[i].real(), d_hestimate[i].imag(),
+ output.real(), output.imag());
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+int
+gr_ofdm_frame_acquisition::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *symbol = (const gr_complex *)input_items[0];
+ const char *trigger = (const char *)input_items[1];
+
+ gr_complex *out = (gr_complex *) output_items[0];
+ char *sig = (char *) output_items[1];
+
+ int unoccupied_carriers = d_fft_length - d_occupied_carriers;
+ int zeros_on_left = (int)ceil(unoccupied_carriers/2.0);
+
+ int found = 0;
+ for(int i = 0; i < ninput_items[1]; i++) {
+ found += trigger[i];
+ }
+
+ if(found) {
+ d_phase_count = 1;
+ correlate(symbol, zeros_on_left);
+ calculate_equalizer(symbol, zeros_on_left);
+ sig[0] = 1;
+ }
+ else {
+ sig[0] = 0;
+ }
+
+ for(unsigned int i = 0; i < d_occupied_carriers; i++) {
+ out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count)
+ *symbol[i+zeros_on_left+d_coarse_freq];
+ }
+
+ d_phase_count++;
+ if(d_phase_count == MAX_NUM_SYMBOLS) {
+ d_phase_count = 1;
+ }
+
+ consume(0,1);
+ consume(1,ninput_items[1]);
+ return 1;
+}
Copied:
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.h (from
rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.h
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.h
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,118 @@
+/* -*- c++ -*- */
+/*
+ * 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 3, 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_ACQUISITION_H
+#define INCLUDED_GR_OFDM_FRAME_ACQUISITION_H
+
+
+#include <gr_block.h>
+#include <vector>
+
+class gr_ofdm_frame_acquisition;
+typedef boost::shared_ptr<gr_ofdm_frame_acquisition>
gr_ofdm_frame_acquisition_sptr;
+
+gr_ofdm_frame_acquisition_sptr
+gr_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int
fft_length,
+ unsigned int cplen,
+ const std::vector<gr_complex> &known_symbol,
+ unsigned int max_fft_shift_len=10);
+
+/*!
+ * \brief take a vector of complex constellation points in from an FFT
+ * and performs a correlation and equalization.
+ * \inblock blocks
+ *
+ * This block takes the output of an FFT of a received OFDM symbol and finds
the
+ * start of a frame based on two known symbols. It also looks at the
surrounding
+ * bins in the FFT output for the correlation in case there is a large
frequency
+ * shift in the data. This block assumes that the fine frequency shift has
already
+ * been corrected and that the samples fall in the middle of one FFT bin.
+ *
+ * It then uses one of those known
+ * 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.
+ */
+
+class gr_ofdm_frame_acquisition : public gr_block
+{
+ /*!
+ * \brief Build an OFDM correlator and equalizer.
+ * \param occupied_carriers The number of subcarriers with data in the
received symbol
+ * \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
+ * start of a frame after known_symbol1 (usually
a BPSK PN sequence).
+ * Both of these start symbols are differentially
correlated to compensate
+ * for phase changes between symbols.
+ * \param max_fft_shift_len Set's the maximum distance you can look
between bins for correlation
+ */
+ friend gr_ofdm_frame_acquisition_sptr
+ gr_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int
fft_length,
+ unsigned int cplen,
+ const std::vector<gr_complex> &known_symbol,
+ unsigned int max_fft_shift_len);
+
+protected:
+ gr_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int
fft_length,
+ unsigned int cplen,
+ const std::vector<gr_complex> &known_symbol,
+ unsigned int max_fft_shift_len);
+
+ private:
+ unsigned char slicer(gr_complex x);
+ bool correlate(const gr_complex *symbol, int zeros_on_left);
+ void calculate_equalizer(const gr_complex *symbol, int zeros_on_left);
+ gr_complex coarse_freq_comp(int freq_delta, int count);
+
+ unsigned int d_occupied_carriers; // !< \brief number of subcarriers with
data
+ 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_symbol; // !< \brief known symbols at start
of frame
+ std::vector<float> d_known_phase_diff; // !< \brief factor used in
correlation from known symbol
+ std::vector<float> d_symbol_phase_diff; // !< \brief factor used in
correlation from received symbol
+ std::vector<gr_complex> d_hestimate; // !< channel estimate
+ 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
+
+ gr_complex *d_phase_lut; // !< look-up table for coarse frequency
compensation
+
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
+ public:
+ /*!
+ * \brief Return an estimate of the SNR of the channel
+ */
+ float snr() { return d_snr_est; }
+
+ ~gr_ofdm_frame_acquisition(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);
+};
+
+
+#endif
Copied:
gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.i (from
rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.i
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_acquisition.i
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * 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 3, 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.
+ */
+
+#include <vector>
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_acquisition);
+
+gr_ofdm_frame_acquisition_sptr
+gr_make_ofdm_frame_acquisition (unsigned int occupied_carriers,
+ unsigned int fft_length,
+ unsigned int cplen,
+ const std::vector<gr_complex> &known_symbol,
+ unsigned int max_fft_shift_len=4);
+
+class gr_ofdm_frame_acquisition : public gr_sync_decimator
+{
+ protected:
+ gr_ofdm_frame_acquisition (unsigned int occupied_carriers,
+ unsigned int fft_length,
+ unsigned int cplen,
+ const std::vector<gr_complex> &known_symbol,
+ unsigned int max_fft_shift_len);
+
+ public:
+ float snr() { return d_snr_est; }
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc
2008-01-02 17:35:35 UTC (rev 7324)
@@ -26,8 +26,12 @@
#include <gr_ofdm_frame_sink.h>
#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <gr_math.h>
+#include <math.h>
#include <cstdio>
#include <stdexcept>
+#include <iostream>
#define VERBOSE 0
@@ -55,6 +59,11 @@
d_header = 0;
d_headerbytelen_cnt = 0;
+
+ // Resetting PLL
+ d_freq = 0.0;
+ d_phase = 0.0;
+ fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0));
}
inline void
@@ -96,7 +105,11 @@
unsigned char *out)
{
unsigned int i=0, bytes_produced=0;
+ gr_complex carrier;
+ carrier=gr_expj(d_phase);
+
+ gr_complex accum_error = 0.0;
while(i < d_occupied_carriers) {
if(d_nresid > 0) {
d_partial_byte |= d_resid;
@@ -106,8 +119,23 @@
}
while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
- //fprintf(stderr, "%f+j%f = %d\n", in[i].real(), in[i].imag(),
slicer(in[i]));
- unsigned char bits = slicer(in[i++]);
+ gr_complex sigrot = in[i]*carrier*d_dfe[i];
+
+ if(d_derotated_output != NULL){
+ d_derotated_output[i] = sigrot;
+ }
+
+ unsigned char bits = slicer(sigrot);
+
+ gr_complex closest_sym = d_sym_position[bits];
+
+ accum_error += sigrot * conj(closest_sym);
+
+ // FIX THE FOLLOWING STATEMENT
+ if (norm(sigrot)> 0.001) d_dfe[i] +=
d_eq_gain*(closest_sym/sigrot-d_dfe[i]);
+
+ i++;
+
if((8 - d_byte_offset) >= d_nbits) {
d_partial_byte |= bits << (d_byte_offset);
d_byte_offset += d_nbits;
@@ -130,7 +158,18 @@
d_partial_byte = 0;
}
}
+ //std::cerr << "accum_error " << accum_error << std::endl;
+ float angle = arg(accum_error);
+
+ d_freq = d_freq - d_freq_gain*angle;
+ d_phase = d_phase + d_freq - d_phase_gain*angle;
+ if (d_phase >= 2*M_PI) d_phase -= 2*M_PI;
+ if (d_phase <0) d_phase += 2*M_PI;
+
+ //if(VERBOSE)
+ // std::cerr << angle << "\t" << d_freq << "\t" << d_phase << "\t" <<
std::endl;
+
return bytes_produced;
}
@@ -138,24 +177,30 @@
gr_ofdm_frame_sink_sptr
gr_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
const std::vector<unsigned char> &sym_value_out,
- gr_msg_queue_sptr target_queue, unsigned int
occupied_carriers)
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_carriers,
+ float phase_gain, float freq_gain)
{
return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(sym_position,
sym_value_out,
- target_queue,
occupied_carriers));
+ target_queue,
occupied_carriers,
+ phase_gain, freq_gain));
}
gr_ofdm_frame_sink::gr_ofdm_frame_sink(const std::vector<gr_complex>
&sym_position,
const std::vector<unsigned char>
&sym_value_out,
- gr_msg_queue_sptr target_queue, unsigned
int occupied_carriers)
+ gr_msg_queue_sptr target_queue, unsigned
int occupied_carriers,
+ float phase_gain, float freq_gain)
: 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)),
+ gr_make_io_signature (1, 1,
sizeof(gr_complex)*occupied_carriers)),
d_target_queue(target_queue), d_occupied_carriers(occupied_carriers),
d_byte_offset(0), d_partial_byte(0),
- d_resid(0), d_nresid(0)
+ d_resid(0),
d_nresid(0),d_phase(0),d_freq(0),d_phase_gain(phase_gain),d_freq_gain(freq_gain),
+ d_eq_gain(0.05)
{
d_bytes_out = new unsigned char[d_occupied_carriers];
+ d_dfe.resize(occupied_carriers);
+ fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0));
set_sym_value_out(sym_position, sym_value_out);
@@ -179,7 +224,7 @@
d_sym_position = sym_position;
d_sym_value_out = sym_value_out;
- d_nbits = (unsigned long)(log10(d_sym_value_out.size()) / log10(2));
+ d_nbits = (unsigned long)ceil(log10(d_sym_value_out.size()) / log10(2.0));
return true;
}
@@ -194,12 +239,16 @@
const char *sig = (const char *) input_items[1];
unsigned int j = 0;
unsigned int bytes=0;
+
+ // If the output is connected, send it the derotated symbols
+ if(output_items.size() >= 1)
+ d_derotated_output = (gr_complex *)output_items[0];
+ else
+ d_derotated_output = NULL;
if (VERBOSE)
fprintf(stderr,">>> Entering state machine\n");
-
- bytes = demapper(&in[0], d_bytes_out);
-
+
switch(d_state) {
case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
@@ -212,6 +261,10 @@
break;
case STATE_HAVE_SYNC:
+ // only demod after getting the preamble signal; otherwise, the
+ // equalizer taps will screw with the PLL performance
+ bytes = demapper(&in[0], d_bytes_out);
+
if (VERBOSE) {
if(sig[0])
printf("ERROR -- Found SYNC in HAVE_SYNC\n");
@@ -258,6 +311,8 @@
break;
case STATE_HAVE_HEADER:
+ bytes = demapper(&in[0], d_bytes_out);
+
if (VERBOSE) {
if(sig[0])
printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n",
d_packetlen_cnt, d_packetlen);
@@ -288,6 +343,6 @@
assert(0);
} // switch
-
+
return 1;
}
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.h
2008-01-02 17:35:35 UTC (rev 7324)
@@ -32,7 +32,8 @@
gr_ofdm_frame_sink_sptr
gr_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position,
const std::vector<unsigned char> &sym_value_out,
- gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
+ float phase_gain=0.25, float freq_gain=0.25*0.25/4.0);
/*!
* \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs
@@ -47,7 +48,8 @@
friend gr_ofdm_frame_sink_sptr
gr_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position,
const std::vector<unsigned char> &sym_value_out,
- gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
+ float phase_gain, float freq_gain);
private:
enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
@@ -71,17 +73,26 @@
int d_packet_whitener_offset; // offset into whitener string
to use
int d_packetlen_cnt; // how many so far
+ gr_complex * d_derotated_output; // Pointer to output stream to send
deroated symbols out
+
std::vector<gr_complex> d_sym_position;
std::vector<unsigned char> d_sym_value_out;
+ std::vector<gr_complex> d_dfe;
unsigned int d_nbits;
unsigned char d_resid;
unsigned int d_nresid;
+ float d_phase;
+ float d_freq;
+ float d_phase_gain;
+ float d_freq_gain;
+ float d_eq_gain;
protected:
gr_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
const std::vector<unsigned char> &sym_value_out,
- gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
+ float phase_gain, float freq_gain);
void enter_search();
void enter_have_sync();
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.i
2008-01-02 17:35:35 UTC (rev 7324)
@@ -25,14 +25,16 @@
gr_ofdm_frame_sink_sptr
gr_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
const std::vector<unsigned char> &sym_value_out,
- gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
+ float phase_gain=0.25, float freq_gain=0.25*0.25/4);
class gr_ofdm_frame_sink : public gr_sync_block
{
protected:
gr_ofdm_frame_sink(const std::vector<gr_complex> &sym_position,
const std::vector<unsigned char> &sym_value_out,
- gr_msg_queue_sptr target_queue, unsigned int
occupied_tones);
+ gr_msg_queue_sptr target_queue, unsigned int
occupied_tones,
+ float phase_gain, float freq_gain);
public:
~gr_ofdm_frame_sink();
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc
2008-01-02 17:35:35 UTC (rev 7324)
@@ -54,8 +54,8 @@
{
if (!(d_occupied_carriers <= d_fft_length))
throw std::invalid_argument("gr_ofdm_mapper_bcv: occupied carriers must be
<= fft_length");
-
- d_nbits = (unsigned long)(log10(d_constellation.size()) / log10(2));
+
+ d_nbits = (unsigned long)ceil(log10(d_constellation.size()) / log10(2.0));
}
gr_ofdm_mapper_bcv::~gr_ofdm_mapper_bcv(void)
Modified: gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_ofdm_sampler.cc
2008-01-02 17:35:35 UTC (rev 7324)
@@ -65,22 +65,26 @@
gr_complex *optr = (gr_complex *) output_items[0];
- int found=0;
+ int found=0, index=0;
int i=d_fft_length-1;
- while(!found && i<std::min(ninput_items[0],ninput_items[1]) ) {
- if(trigger[i])
+ // FIXME: This is where we miss if the regeneration happens too soon.
+ //while(!found && i<std::min(ninput_items[0],ninput_items[1]) ) {
+ while(i<std::min(ninput_items[0],ninput_items[1]) ) {
+ if(trigger[i]) {
found = 1;
+ index = i++;
+ }
else
i++;
}
-
+
if(found) {
- assert(i-d_fft_length+1 >= 0);
- for(int j=i-d_fft_length+1;j<=i;j++)
+ assert(index-d_fft_length+1 >= 0);
+ for(int j=index - d_fft_length + 1; j <= index; j++)
*optr++ = iptr[j];
- consume_each(i-d_fft_length+2);
+ consume_each(index - d_fft_length + 2);
//printf("OFDM Sampler found: ninput_items: %d/%d noutput_items: %d
consumed: %d found: %d\n",
// ninput_items[0], ninput_items[1], noutput_items, (i-d_fft_length+2),
found);
}
Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,106 @@
+/* -*- 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 3, 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_peak_detector2_fb.h>
+#include <gr_io_signature.h>
+
+gr_peak_detector2_fb_sptr
+gr_make_peak_detector2_fb (float threshold_factor_rise,
+ int look_ahead, float alpha)
+{
+ return gr_peak_detector2_fb_sptr (new gr_peak_detector2_fb
(threshold_factor_rise,
+ look_ahead, alpha));
+}
+
+gr_peak_detector2_fb::gr_peak_detector2_fb (float threshold_factor_rise,
+ int look_ahead, float alpha)
+ : gr_sync_block ("peak_detector2_fb",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature2 (1, 2, sizeof(char), sizeof(float))),
+ d_threshold_factor_rise(threshold_factor_rise),
+ d_look_ahead(look_ahead), d_alpha(alpha), d_avg(0.0f), d_found(false)
+{
+}
+
+int
+gr_peak_detector2_fb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items) {
+ float *iptr = (float *) input_items[0];
+ char *optr = (char *) output_items[0];
+
+ assert(noutput_items >= 2);
+
+ memset(optr, 0, noutput_items*sizeof(char));
+
+ for (int i = 0; i < noutput_items; i++) {
+
+ if (!d_found) {
+ // Have not yet detected presence of peak
+ if (iptr[i] > d_avg * (1.0f + d_threshold_factor_rise)) {
+ d_found = true;
+ d_look_ahead_remaining = d_look_ahead;
+ d_peak_val = -(float)INFINITY;
+ }
+ else {
+ d_avg = d_alpha*iptr[i] + (1.0f - d_alpha)*d_avg;
+ }
+ }
+ else {
+ // Detected presence of peak
+ if (iptr[i] > d_peak_val) {
+ d_peak_val = iptr[i];
+ d_peak_ind = i;
+ }
+ else if (d_look_ahead_remaining <= 0) {
+ optr[d_peak_ind] = 1;
+ d_found = false;
+ d_avg = iptr[i];
+ }
+
+ // Have not yet located peak, loop and keep searching.
+ d_look_ahead_remaining--;
+ }
+
+ // Every iteration of the loop, write debugging signal out if
+ // connected:
+ if (output_items.size() == 2) {
+ float *sigout = (float *) output_items[1];
+ sigout[i] = d_avg;
+ }
+ } // loop
+
+ if (!d_found)
+ return noutput_items;
+
+ // else if detected presence, keep searching during the next call to work.
+ int tmp = d_peak_ind;
+ d_peak_ind = 1;
+
+ return tmp - 1;
+}
+
+
Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,108 @@
+/* -*- 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 3, 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_peak_detector2_FB_H
+#define INCLUDED_gr_peak_detector2_FB_H
+
+#include <gr_sync_block.h>
+
+class gr_peak_detector2_fb;
+typedef boost::shared_ptr<gr_peak_detector2_fb> gr_peak_detector2_fb_sptr;
+
+gr_peak_detector2_fb_sptr gr_make_peak_detector2_fb (float
threshold_factor_rise = 7,
+ int look_ahead = 1000,
+ float alpha = 0.001);
+
+/*!
+ * \brief Detect the peak of a signal
+ * \ingroup block
+ *
+ * If a peak is detected, this block outputs a 1,
+ * or it outputs 0's. A separate debug output may be connected, to
+ * view the internal EWMA described below.
+ *
+ * \param threshold_factor_rise The threshold factor determins when a peak
+ * is present. An EWMA average of the signal is calculated and when the
+ * value of the signal goes over threshold_factor_rise*average, we
+ * call the peak.
+ * \param look_ahead The look-ahead value is used when the threshold is
+ * found to locate the peak within this range.
+ * \param alpha The gain value of a single-pole moving average filter
+ */
+
+class gr_peak_detector2_fb : public gr_sync_block
+{
+ friend gr_peak_detector2_fb_sptr
+ gr_make_peak_detector2_fb (float threshold_factor_rise, int look_ahead,
float alpha);
+
+ gr_peak_detector2_fb (float threshold_factor_rise, int look_ahead, float
alpha);
+
+private:
+ float d_threshold_factor_rise;
+ int d_look_ahead;
+ int d_look_ahead_remaining;
+ int d_peak_ind;
+ float d_peak_val;
+ float d_alpha;
+ float d_avg;
+ bool d_found;
+
+public:
+
+ /*! \brief Set the threshold factor value for the rise time
+ * \param thr new threshold factor
+ */
+ void set_threshold_factor_rise(float thr) { d_threshold_factor_rise = thr; }
+
+ /*! \brief Set the look-ahead factor
+ * \param look new look-ahead factor
+ */
+ void set_look_ahead(int look) { d_look_ahead = look; }
+
+ /*! \brief Set the running average alpha
+ * \param alpha new alpha for running average
+ */
+ void set_alpha(int alpha) { d_alpha = alpha; }
+
+ /*! \brief Get the threshold factor value for the rise time
+ * \return threshold factor
+ */
+ float threshold_factor_rise() { return d_threshold_factor_rise; }
+
+ /*! \brief Get the look-ahead factor value
+ * \return look-ahead factor
+ */
+ int look_ahead() { return d_look_ahead; }
+
+ /*! \brief Get the alpha value of the running average
+ * \return alpha
+ */
+ float alpha() { return d_alpha; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
+
+
Copied: gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.i
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/lib/general/gr_peak_detector2_fb.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.i
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/general/gr_peak_detector2_fb.i
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,45 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,peak_detector2_fb)
+
+ gr_peak_detector2_fb_sptr gr_make_peak_detector2_fb (float
threshold_factor_rise = 7,
+ int look_ahead = 1000,
+ float alpha=0.001);
+
+class gr_peak_detector2_fb : public gr_sync_block
+{
+private:
+ gr_peak_detector2_fb (float threshold_factor_rise, int look_ahead, float
alpha);
+
+public:
+ void set_threshold_factor_rise(float thr) { d_threshold_factor_rise = thr; }
+ void set_look_ahead(int look) { d_look_ahead = look; }
+ void set_alpha(int alpha) { d_avg_alpha = alpha; }
+
+ float threshold_factor_rise() { return d_threshold_factor_rise; }
+ int look_ahead() { return d_look_ahead; }
+ float alpha() { return d_avg_alpha; }
+};
+
+
Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am
2008-01-02 17:35:35 UTC (rev 7324)
@@ -40,6 +40,12 @@
cpm.py \
nbfm_rx.py \
nbfm_tx.py \
+ ofdm.py \
+ ofdm_receiver.py \
+ ofdm_sync_fixed.py \
+ ofdm_sync_pn.py \
+ ofdm_sync_pnac.py \
+ ofdm_sync_ml.py \
pkt.py \
psk.py \
qam.py \
Copied: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,311 @@
+#!/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 3, 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, ofdm_packet_utils
+import gnuradio.gr.gr_threading as _threading
+import psk, qam
+
+from gnuradio.blks2impl.ofdm_receiver import ofdm_receiver
+
+
+# /////////////////////////////////////////////////////////////////////////////
+# mod/demod with packets as i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+class ofdm_mod(gr.hier_block2):
+ """
+ Modulates an OFDM stream. Based on the options fft_length, occupied_tones,
and
+ cp_length, this block creates OFDM symbols using a specified modulation
option.
+
+ Send packets by calling send_pkt
+ """
+ def __init__(self, options, msgq_limit=2, pad_for_usrp=True):
+ """
+ Hierarchical block for sending packets
+
+ Packets to be sent are enqueued by calling send_pkt.
+ The output is the complex modulated signal at baseband.
+
+ @param options: pass modulation options from higher layers (fft
length, occupied tones, etc.)
+ @param msgq_limit: maximum number of messages in message queue
+ @type msgq_limit: int
+ @param pad_for_usrp: If true, packets are padded such that they end up
a multiple of 128 samples
+ """
+
+ gr.hier_block2.__init__(self, "ofdm_mod",
+ gr.io_signature(0, 0, 0), # Input
signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) #
Output signature
+
+ self._pad_for_usrp = pad_for_usrp
+ self._modulation = options.modulation
+ self._fft_length = options.fft_length
+ self._occupied_tones = options.occupied_tones
+ self._cp_length = options.cp_length
+
+ win = [] #[1 for i in range(self._fft_length)]
+
+ # Use freq domain to get doubled-up known symbol for correlation in
time domain
+ zeros_on_left = int(math.ceil((self._fft_length -
self._occupied_tones)/2.0))
+ ksfreq = known_symbols_4512_3[0:self._occupied_tones]
+ for i in range(len(ksfreq)):
+ if((zeros_on_left + i) & 1):
+ ksfreq[i] = 0
+
+ # hard-coded known symbols
+ preambles = (ksfreq,)
+# known_symbols_4512_1[0:self._occupied_tones],
+# known_symbols_4512_2[0:self._occupied_tones])
+
+ padded_preambles = list()
+ for pre in preambles:
+ padded = self._fft_length*[0,]
+ padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre
+ padded_preambles.append(padded)
+
+ symbol_length = options.fft_length + options.cp_length
+
+ mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16,
"qam64": 64, "qam256": 256}
+ arity = mods[self._modulation]
+
+ rot = 1
+ if self._modulation == "qpsk":
+ rot = (0.707+0.707j)
+
+ if(self._modulation.find("psk") >= 0):
+ rotated_const = map(lambda pt: pt * rot,
psk.gray_constellation[arity])
+ elif(self._modulation.find("qam") >= 0):
+ rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+ #print rotated_const
+ self._pkt_input = gr.ofdm_mapper_bcv(rotated_const, msgq_limit,
+ options.occupied_tones,
options.fft_length)
+
+ self.preambles = gr.ofdm_insert_preamble(self._fft_length,
padded_preambles)
+ self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
+ self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length,
symbol_length)
+ self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length))
+
+ self.connect((self._pkt_input, 0), (self.preambles, 0))
+ self.connect((self._pkt_input, 1), (self.preambles, 1))
+ self.connect(self.preambles, self.ifft, self.cp_adder, self.scale,
self)
+
+ if options.verbose:
+ self._print_verbage()
+
+ if options.log:
+ self.connect(self._pkt_input,
gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
+ "ofdm_mapper_c.dat"))
+ self.connect(self.preambles,
gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
+ "ofdm_preambles.dat"))
+ self.connect(self.ifft,
gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
+ "ofdm_ifft_c.dat"))
+ self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex,
+ "ofdm_cp_adder_c.dat"))
+
+ def send_pkt(self, payload='', eof=False):
+ """
+ Send the payload.
+
+ @param payload: data to send
+ @type payload: string
+ """
+ if eof:
+ msg = gr.message(1) # tell self._pkt_input we're not sending any
more packets
+ else:
+ # print "original_payload =", string_to_hex_list(payload)
+ pkt = ofdm_packet_utils.make_packet(payload, 1, 1,
self._pad_for_usrp, whitening=True)
+
+ #print "pkt =", string_to_hex_list(pkt)
+ msg = gr.message_from_string(pkt)
+ self._pkt_input.msgq().insert_tail(msg)
+
+ def add_options(normal, expert):
+ """
+ Adds OFDM-specific options to the Options Parser
+ """
+ normal.add_option("-m", "--modulation", type="string", default="bpsk",
+ help="set modulation type (bpsk, qpsk, 8psk,
qam{16,64}) [default=%default]")
+ expert.add_option("", "--fft-length", type="intx", default=512,
+ help="set the number of FFT bins [default=%default]")
+ expert.add_option("", "--occupied-tones", type="intx", default=200,
+ help="set the number of occupied FFT bins
[default=%default]")
+ expert.add_option("", "--cp-length", type="intx", default=128,
+ help="set the number of bits in the cyclic prefix
[default=%default]")
+ # Make a static method to call before instantiation
+ add_options = staticmethod(add_options)
+
+ def _print_verbage(self):
+ """
+ Prints information about the OFDM modulator
+ """
+ print "\nOFDM Modulator:"
+ print "Modulation Type: %s" % (self._modulation)
+ print "FFT length: %3d" % (self._fft_length)
+ print "Occupied Tones: %3d" % (self._occupied_tones)
+ print "CP length: %3d" % (self._cp_length)
+
+
+class ofdm_demod(gr.hier_block2):
+ """
+ Demodulates a received OFDM stream. Based on the options fft_length,
occupied_tones, and
+ cp_length, this block performs synchronization, FFT, and demodulation of
incoming OFDM
+ symbols and passes packets up the a higher layer.
+
+ The input is complex baseband. When packets are demodulated, they are
passed to the
+ app via the callback.
+ """
+
+ def __init__(self, options, callback=None):
+ """
+ Hierarchical block for demodulating and deframing packets.
+
+ The input is the complex modulated signal at baseband.
+ Demodulated packets are sent to the handler.
+
+ @param options: pass modulation options from higher layers (fft
length, occupied tones, etc.)
+ @param callback: function of two args: ok, payload
+ @type callback: ok: bool; payload: string
+ """
+ gr.hier_block2.__init__(self, "ofdm_demod",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), #
Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) #
Output signature
+
+
+ self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY
+
+ self._modulation = options.modulation
+ self._fft_length = options.fft_length
+ self._occupied_tones = options.occupied_tones
+ self._cp_length = options.cp_length
+ self._snr = options.snr
+
+ # Use freq domain to get doubled-up known symbol for correlation in
time domain
+ ksfreq = known_symbols_4512_3[0:self._occupied_tones]
+ for i in range(len(ksfreq)):
+ if(i&1):
+ ksfreq[i] = 0
+
+ # hard-coded known symbols
+ preambles = (ksfreq,)
+ #known_symbols_4512_1[0:self._occupied_tones],
+ #known_symbols_4512_2[0:self._occupied_tones])
+
+ symbol_length = self._fft_length + self._cp_length
+ self.ofdm_recv = ofdm_receiver(self._fft_length, self._cp_length,
+ self._occupied_tones, self._snr,
preambles,
+ options.log)
+
+ mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16,
"qam64": 64, "qam256": 256}
+ arity = mods[self._modulation]
+
+ rot = 1
+ if self._modulation == "qpsk":
+ rot = (0.707+0.707j)
+
+ if(self._modulation.find("psk") >= 0):
+ rotated_const = map(lambda pt: pt * rot,
psk.gray_constellation[arity])
+ elif(self._modulation.find("qam") >= 0):
+ rotated_const = map(lambda pt: pt * rot, qam.constellation[arity])
+ #print rotated_const
+ self.ofdm_demod = gr.ofdm_frame_sink(rotated_const, range(arity),
+ self._rcvd_pktq,
+ self._occupied_tones,
+ 0.25, 0.25*.25/4.0)
+
+ self.connect(self, self.ofdm_recv)
+ self.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
+ self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
+
+ # added output signature to work around bug, though it might not be a
bad
+ # thing to export, anyway
+ self.connect(self.ofdm_recv.chan_filt, self)
+
+ if options.log:
+ self.connect(self.ofdm_demod,
gr.file_sink(gr.sizeof_gr_complex*self._occupied_tones,
"ofdm_frame_sink_c.dat"))
+ else:
+ self.connect(self.ofdm_demod,
gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones))
+
+ if options.verbose:
+ self._print_verbage()
+
+ self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
+
+ def add_options(normal, expert):
+ """
+ Adds OFDM-specific options to the Options Parser
+ """
+ normal.add_option("-m", "--modulation", type="string", default="bpsk",
+ help="set modulation type (bpsk or qpsk)
[default=%default]")
+ expert.add_option("", "--fft-length", type="intx", default=512,
+ help="set the number of FFT bins [default=%default]")
+ expert.add_option("", "--occupied-tones", type="intx", default=200,
+ help="set the number of occupied FFT bins
[default=%default]")
+ expert.add_option("", "--cp-length", type="intx", default=128,
+ help="set the number of bits in the cyclic prefix
[default=%default]")
+ # Make a static method to call before instantiation
+ add_options = staticmethod(add_options)
+
+ def _print_verbage(self):
+ """
+ Prints information about the OFDM demodulator
+ """
+ print "\nOFDM Demodulator:"
+ print "Modulation Type: %s" % (self._modulation)
+ print "FFT length: %3d" % (self._fft_length)
+ print "Occupied Tones: %3d" % (self._occupied_tones)
+ print "CP length: %3d" % (self._cp_length)
+
+
+
+class _queue_watcher_thread(_threading.Thread):
+ def __init__(self, rcvd_pktq, callback):
+ _threading.Thread.__init__(self)
+ self.setDaemon(1)
+ self.rcvd_pktq = rcvd_pktq
+ self.callback = callback
+ self.keep_running = True
+ self.start()
+
+
+ def run(self):
+ while self.keep_running:
+ msg = self.rcvd_pktq.delete_head()
+ ok, payload = ofdm_packet_utils.unmake_packet(msg.to_string())
+ if self.callback:
+ self.callback(ok, payload)
+
+# Generating known symbols with:
+# i = [2*random.randint(0,1)-1 for i in range(4512)]
+
+known_symbols_200_1 = [1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0,
1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0,
-1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
-1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0,
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0,
-1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0,
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0,
1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0,
-1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0,
-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, 1.0, -1.0]
+
+known_symbols_200_2 = [-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0,
1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0,
1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0,
-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0,
1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0,
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,
1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0,
1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0,
1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0,
1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0]
+
+
+known_symbols_4512_1 = [-1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1,
-1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1,
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1,
1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1,
1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1,
1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1,
-1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1,
-1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1,
-1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1,
-1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1,
-1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1,
-1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1,
1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1,
-1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1,
-1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1,
-1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1,
1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1,
1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1,
1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1,
1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1,
1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1,
-1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1,
1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1,
-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1,
1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1,
-1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1,
1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1,
-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1,
1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1,
1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1,
1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1,
1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1,
-1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1,
1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1,
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1,
-1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1,
-1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1,
1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1,
1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1,
-1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1,
-1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1,
-1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1,
-1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1,
-1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1,
1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1,
-1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1,
1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1,
1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1,
1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1,
1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1,
1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1,
-1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1,
1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1,
-1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1,
-1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1,
1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1,
1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1,
-1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1,
-1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1,
1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1,
-1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1,
1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1,
-1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1,
1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1,
-1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1,
1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1,
-1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1,
1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1,
1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1,
-1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1,
-1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1,
1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1,
-1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1,
-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1,
1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1,
-1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1,
-1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1,
1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
-1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1,
1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1,
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1,
1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1,
1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1,
-1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1,
-1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1,
1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1,
-1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1,
-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1,
-1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1,
-1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1,
1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1,
-1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1,
1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1,
-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1,
-1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1,
-1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1,
1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1,
1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1,
-1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1,
-1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1,
-1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1,
-1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1,
-1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1,
1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1,
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1,
-1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1,
-1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1,
-1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1,
1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1,
-1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1,
-1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1,
-1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1,
-1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1,
1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1,
-1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1,
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1,
1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1,
-1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1,
1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1,
-1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1,
-1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1,
1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1,
-1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1,
-1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1,
-1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1,
1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1,
-1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1,
1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1,
-1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1,
-1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1,
-1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1,
1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1,
1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1,
-1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1,
-1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1,
1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1,
-1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1,
-1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1,
-1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1,
1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1,
1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1,
-1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1,
-1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1,
1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1,
-1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1,
-1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1,
-1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1,
-1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1,
-1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1,
1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1,
-1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1,
1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1,
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1,
-1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1,
-1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1,
1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1,
1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1,
-1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1,
-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1,
1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1,
1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1,
-1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1,
1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1,
-1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1,
1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1,
-1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1,
1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1,
1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1,
-1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1,
1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1,
1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1,
1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1,
-1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1,
1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1,
-1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1,
1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1,
-1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1,
-1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1,
-1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1,
-1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1,
-1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
-1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1,
-1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1,
-1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1,
-1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1,
-1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1,
-1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1,
-1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1,
1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1,
-1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1,
1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1,
1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1,
1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1]
+
+known_symbols_4512_2 = [1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1,
-1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1,
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1,
1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1,
-1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1,
-1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1,
1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1,
-1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1,
-1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1,
-1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1,
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1,
-1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1,
1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1,
-1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1,
1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1,
-1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1,
-1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1,
-1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1,
1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1,
-1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1,
1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1,
-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1,
-1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1,
-1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1,
-1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1,
-1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1,
1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1,
1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1,
-1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1,
-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1,
-1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1,
-1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1,
-1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1,
1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1,
1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1,
1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1,
1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1,
1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1,
-1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1,
1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1,
-1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1,
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1,
1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1,
-1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1,
-1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1,
-1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1,
-1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1,
1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1,
1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1,
1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1,
-1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1,
-1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1,
-1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1,
1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1,
-1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1,
1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1,
-1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1,
-1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1,
-1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1,
1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1,
1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1,
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1,
-1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1,
1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1,
-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1,
1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1,
-1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1,
-1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1,
1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1,
1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1,
-1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1,
-1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1,
1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1,
-1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1,
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1,
1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1,
1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1,
-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1,
-1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1,
1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1,
1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1,
-1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1,
-1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1,
-1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1,
-1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1,
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1,
1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1,
1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1,
1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1,
-1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1,
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1,
1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1,
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1,
-1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1,
1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1,
1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1,
-1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1,
1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1,
1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1,
1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1,
-1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1,
-1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1,
-1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1,
-1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1,
1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1,
-1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1,
-1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1,
-1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1,
1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1,
-1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1,
-1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1,
-1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1,
1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1,
1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1,
-1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1,
-1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1,
1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1,
-1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1,
-1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1,
1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1,
1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1,
-1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1,
1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1,
1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1,
-1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1,
-1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1,
1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1,
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1,
1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1,
1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1,
1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1,
1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1,
1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1,
-1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1,
-1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1,
1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1,
1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1,
1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1,
-1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1,
1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1,
-1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
-1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1,
-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1,
1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1,
-1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1,
1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1,
-1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1,
1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1,
-1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1,
1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1,
1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1,
-1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1,
-1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1,
1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1,
-1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1,
-1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1,
1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1,
1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1,
1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1,
-1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1,
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1,
-1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1,
1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1,
-1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1,
-1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1,
1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1,
1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1,
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1,
-1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1,
-1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1,
-1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1,
-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1,
-1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1,
-1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1,
-1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1,
-1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1,
1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1,
1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1,
-1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1,
-1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1,
1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1,
1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1,
-1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1,
-1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1,
-1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1,
1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1,
-1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1,
1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1,
-1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1,
-1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1,
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1,
1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1,
1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1,
-1, -1, 1, 1, 1, 1, -1, -1]
+
+
+known_symbols_4512_impulse = 4512*[1,]
+
+known_symbols_4512_3 = [-1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1,
-1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1,
-1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1,
-1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1,
-1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1,
-1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1,
1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1,
-1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1,
1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1,
1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1,
1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1,
-1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1,
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1,
1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1,
1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1,
-1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1,
-1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1,
-1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1,
-1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1,
1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1,
1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1,
-1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1,
-1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1,
1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1,
1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1,
1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1,
1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1,
1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1,
1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1,
-1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1,
-1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1,
-1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1,
-1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1,
-1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1,
1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1,
1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1,
1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1,
1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1,
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1,
-1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1,
1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1,
-1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1,
-1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1,
-1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1,
1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1,
-1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1,
1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1,
1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1,
1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1,
1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1,
1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1,
-1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1,
1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
-1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1,
1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1,
-1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1,
1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1,
1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1,
-1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1,
1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1,
-1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1,
1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1,
-1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1,
1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1,
-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1,
1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1,
1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1,
-1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1,
-1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1,
-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1,
1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1,
1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1,
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1,
-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1,
-1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1,
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1,
1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1,
-1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1,
1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1,
1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1,
1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1,
-1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1,
1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1,
-1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1,
-1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1,
1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1,
1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1,
-1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1,
1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1,
1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1,
-1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1,
-1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1,
-1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1,
1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1,
1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1,
-1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1,
-1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1,
-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1,
1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1,
-1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1,
1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1,
-1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1,
-1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1,
1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1,
1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1,
1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1,
-1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1,
1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1,
1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1,
-1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1,
-1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1,
1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1,
1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1,
-1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1,
-1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1,
-1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1,
-1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1,
1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1,
-1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1,
1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1,
-1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1,
-1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1,
1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1,
-1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1,
1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1,
1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1,
-1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1,
1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1,
-1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1,
1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1,
-1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1,
-1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1,
-1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1,
-1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1,
-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1,
-1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1,
1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1,
1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1,
1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1,
1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1,
1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1,
-1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1,
-1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1,
-1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1,
1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1,
1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1,
-1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1,
1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1,
1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1,
-1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
-1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1,
-1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1,
1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1,
1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1,
-1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1,
-1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1,
-1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1,
1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1,
-1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1,
-1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1,
-1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1,
-1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1,
-1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1,
-1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1,
1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1,
-1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1,
1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1,
-1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1,
1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1,
1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1,
1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1,
1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1,
-1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1,
1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1,
-1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1,
1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1,
-1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1,
1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1,
-1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1,
-1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1,
1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1,
-1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1,
-1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1,
-1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1,
1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1,
-1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1,
-1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1,
1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1,
1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1,
1, -1, 1, -1]
Copied:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_receiver.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,112 @@
+#!/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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from numpy import fft
+from gnuradio import gr
+from gnuradio.blks2impl.ofdm_sync_ml import ofdm_sync_ml
+from gnuradio.blks2impl.ofdm_sync_pn import ofdm_sync_pn
+from gnuradio.blks2impl.ofdm_sync_pnac import ofdm_sync_pnac
+from gnuradio.blks2impl.ofdm_sync_fixed import ofdm_sync_fixed
+
+class ofdm_receiver(gr.hier_block2):
+ """
+ Performs receiver synchronization on OFDM symbols.
+
+ The receiver performs channel filtering as well as symbol, frequency, and
phase synchronization.
+ The synchronization routines are available in three flavors: preamble
correlator (Schmidl and Cox),
+ modifid preamble correlator with autocorrelation (not yet working), and
cyclic prefix correlator
+ (Van de Beeks).
+ """
+
+ def __init__(self, fft_length, cp_length, occupied_tones, snr, ks,
logging=False):
+ """
+ Hierarchical block for receiving OFDM symbols.
+
+ The input is the complex modulated signal at baseband.
+ Synchronized packets are sent back to the demodulator.
+
+ @param fft_length: total number of subcarriers
+ @type fft_length: int
+ @param cp_length: length of cyclic prefix as specified in subcarriers
(<= fft_length)
+ @type cp_length: int
+ @param occupied_tones: number of subcarriers used for data
+ @type occupied_tones: int
+ @param snr: estimated signal to noise ratio used to guide cyclic
prefix synchronizer
+ @type snr: float
+ @param ks: known symbols used as preambles to each packet
+ @type ks: list of lists
+ @param logging: turn file logging on or off
+ @type logging: bool
+ """
+
+ gr.hier_block2.__init__(self, "ofdm_receiver",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), #
Input signature
+ gr.io_signature2(2, 2,
gr.sizeof_gr_complex*occupied_tones, gr.sizeof_char)) # Output signature
+
+ 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)]
+
+ zeros_on_left = int(math.ceil((fft_length - occupied_tones)/2.0))
+ zeros_on_right = fft_length - occupied_tones - zeros_on_left
+ ks0 = zeros_on_left*[0.0,]
+ ks0.extend(ks[0])
+ ks0.extend(zeros_on_right*[0.0,])
+
+ ks0time = fft.ifft(ks0)
+ # ADD SCALING FACTOR
+ ks0time = ks0time.tolist()
+
+ SYNC = "pn"
+ if SYNC == "ml":
+ self.ofdm_sync = ofdm_sync_ml(fft_length, cp_length, snr, logging)
+ elif SYNC == "pn":
+ self.ofdm_sync = ofdm_sync_pn(fft_length, cp_length, logging)
+ elif SYNC == "pnac":
+ self.ofdm_sync = ofdm_sync_pnac(fft_length, cp_length, ks0time)
+ elif SYNC == "fixed":
+ self.ofdm_sync = ofdm_sync_fixed(fft_length, cp_length, logging)
+
+ self.fft_demod = gr.fft_vcc(fft_length, True, win, True)
+ self.ofdm_frame_acq = gr.ofdm_frame_acquisition(occupied_tones,
fft_length,
+ cp_length, ks[0])
+
+ self.connect(self, self.chan_filt)
+ self.connect(self.chan_filt, self.ofdm_sync, self.fft_demod,
(self.ofdm_frame_acq,0))
+ self.connect((self.ofdm_sync,1), (self.ofdm_frame_acq,1))
+ self.connect((self.ofdm_frame_acq,0), (self,0))
+ self.connect((self.ofdm_frame_acq,1), (self,1))
+
+ if logging:
+ self.connect(self.chan_filt, gr.file_sink(gr.sizeof_gr_complex,
"chan_filt_c.dat"))
+ self.connect(self.fft_demod,
gr.file_sink(gr.sizeof_gr_complex*fft_length, "fft_out_c.dat"))
+ self.connect(self.ofdm_frame_acq,
+ gr.file_sink(gr.sizeof_gr_complex*occupied_tones,
"ofdm_frame_acq_c.dat"))
+ self.connect((self.ofdm_frame_acq,1), gr.file_sink(1,
"found_corr_b.dat"))
Copied:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py)
===================================================================
---
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py
(rev 0)
+++
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_fixed.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,49 @@
+#!/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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from gnuradio import gr
+
+class ofdm_sync_fixed(gr.hier_block2):
+ def __init__(self, fft_length, cp_length, logging=False):
+
+ gr.hier_block2.__init__(self, "ofdm_sync_fixed",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), #
Input signature
+ gr.io_signature2(2, 2,
gr.sizeof_gr_complex*fft_length, gr.sizeof_char)) # Output signature
+
+ # Use a fixed trigger point instead of sync block
+ symbol_length = fft_length + cp_length
+ data = (symbol_length)*[0,]
+ data[(symbol_length)-1] = 1
+ self.peak_trigger = gr.vector_source_b(data, True)
+ self.sampler = gr.ofdm_sampler(fft_length, symbol_length)
+
+ self.connect(self, (self.sampler,0))
+ self.connect(self.peak_trigger, (self.sampler,1))
+ self.connect(self.sampler, (self,0))
+ self.connect(self.peak_trigger, (self,1))
+
+ if logging:
+ self.connect(self.peak_trigger, gr.file_sink(gr.sizeof_char,
"ofdm_sync_fixed-peaks_b.dat"))
+ self.connect(self.sampler,
gr.file_sink(gr.sizeof_gr_complex*fft_length,
+
"ofdm_sync_fixed-sampler_c.dat"))
+
Copied:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_ml.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,142 @@
+#!/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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from gnuradio import gr
+
+class ofdm_sync_ml(gr.hier_block2):
+ def __init__(self, fft_length, cp_length, snr, logging):
+ ''' Maximum Likelihood OFDM synchronizer:
+ J. van de Beek, M. Sandell, and P. O. Borjesson, "ML Estimation
+ of Time and Frequency Offset in OFDM Systems," IEEE Trans.
+ Signal Processing, vol. 45, no. 7, pp. 1800-1805, 1997.
+ '''
+
+ # FIXME: change the output signature
+ # should be the output of the divider (the normalized peaks) and
+ # the angle value out of the sample and hold block
+ # move sampler out of this block
+
+ gr.hier_block2.__init__(self, "ofdm_sync_ml",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), #
Input signature
+ gr.io_signature(1, 1,
gr.sizeof_gr_complex*fft_length)) # Output signature
+
+ 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
+
+ self.connect(self, self.input)
+
+ # Create a delay line
+ self.delay = gr.delay(gr.sizeof_gr_complex, fft_length)
+ self.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.connect(self.input,self.magsqrd1)
+ self.connect(self.delay,self.magsqrd2)
+ self.connect(self.magsqrd1,(self.adder,0))
+ self.connect(self.magsqrd2,(self.adder,1))
+ self.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.connect(self.input,(self.mixer,1))
+ self.connect(self.delay,self.conjg,(self.mixer,0))
+ self.connect(self.mixer,self.movingsum2,self.c2mag)
+ self.connect(self.movingsum2,self.angle)
+
+ # ML Sync output arg, need to find maximum point of this
+ self.diff = gr.sub_ff()
+ self.connect(self.c2mag,(self.diff,0))
+ self.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.pk_detect = gr.peak_detector2_fb()
+ self.sample_and_hold = gr.sample_and_hold_ff()
+ self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+ self.sigmix = gr.multiply_cc()
+
+ # Mix the signal with an NCO controlled by the sync loop
+ self.connect(self.input, (self.sigmix,0))
+ self.connect(self.nco, (self.sigmix,1))
+ self.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.connect(self.diff, self.pk_detect)
+
+ use_dpll = 1
+ if use_dpll:
+ self.dpll = gr.dpll_bb(float(symbol_length),0.01)
+ self.connect(self.pk_detect, self.dpll)
+ self.connect(self.dpll, (self.sampler,1))
+ self.connect(self.dpll, (self.sample_and_hold,1))
+ else:
+ self.connect(self.pk_detect, (self.sampler,1))
+ self.connect(self.pk_detect, (self.sample_and_hold,1))
+
+ self.connect(self.angle, (self.sample_and_hold,0))
+ self.connect(self.sample_and_hold, self.nco)
+
+ self.connect(self.sampler, self)
+
+ if logging:
+ self.connect(self.diff, gr.file_sink(gr.sizeof_float,
"ofdm_sync_ml-theta_f.dat"))
+ self.connect(self.angle, gr.file_sink(gr.sizeof_float,
"ofdm_sync_ml-epsilon_f.dat"))
+ self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char,
"ofdm_sync_ml-peaks_b.dat"))
+ if use_dpll:
+ self.connect(self.dpll, gr.file_sink(gr.sizeof_char,
"ofdm_sync_ml-dpll_b.dat"))
+
+ self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex,
"ofdm_sync_ml-sigmix_c.dat"))
+ self.connect(self.sampler,
gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_ml-sampler_c.dat"))
+ self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float,
"ofdm_sync_ml-sample_and_hold_f.dat"))
+ self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex,
"ofdm_sync_ml-nco_c.dat"))
+ self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex,
"ofdm_sync_ml-input_c.dat"))
+
Copied:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pn.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,146 @@
+#!/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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from numpy import fft
+from gnuradio import gr
+
+class ofdm_sync_pn(gr.hier_block2):
+ def __init__(self, fft_length, cp_length, logging=False):
+ """
+ OFDM synchronization using PN Correlation:
+ T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing
+ Synchonization for OFDM," IEEE Trans. Communications, vol. 45,
+ no. 12, 1997.
+ """
+
+ gr.hier_block2.__init__(self, "ofdm_sync_pn",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), #
Input signature
+ gr.io_signature2(2, 2,
gr.sizeof_gr_complex*fft_length, gr.sizeof_char)) # Output signature
+
+ # FIXME: when converting to hier_block2's, the output signature
+ # should be the output of the divider (the normalized peaks) and
+ # the angle value out of the sample and hold block
+
+ self.input = gr.add_const_cc(0)
+
+ symbol_length = fft_length + cp_length
+
+ # PN Sync
+
+ # Create a delay line
+ self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)
+
+ # Correlation from ML Sync
+ self.conjg = gr.conjugate_cc();
+ self.corr = gr.multiply_cc();
+
+ # Create a moving sum filter for the corr output
+ if 1:
+ moving_sum_taps = [1.0 for i in range(fft_length//2)]
+ self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
+ else:
+ moving_sum_taps = [complex(1.0,0.0) for i in range(fft_length//2)]
+ self.moving_sum_filter = gr.fft_filter_ccc(1,moving_sum_taps)
+
+ # Create a moving sum filter for the input
+ self.inputmag2 = gr.complex_to_mag_squared()
+ movingsum2_taps = [1.0 for i in range(fft_length//2)]
+
+ if 1:
+ self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
+ else:
+ self.inputmovingsum = gr.fft_filter_fff(1,movingsum2_taps)
+
+ self.square = gr.multiply_ff()
+ self.normalize = gr.divide_ff()
+
+ # Get magnitude (peaks) and angle (phase/freq error)
+ self.c2mag = gr.complex_to_mag_squared()
+ self.angle = gr.complex_to_arg()
+
+ self.sample_and_hold = gr.sample_and_hold_ff()
+
+ # Mix the signal with an NCO controlled by the sync loop
+ nco_sensitivity = -2.0/fft_length
+ self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+ self.sigmix = gr.multiply_cc()
+
+ #ML measurements input to sampler block and detect
+ self.sub1 = gr.add_const_ff(-1)
+ self.pk_detect = gr.peak_detector_fb(0.20, 0.20, 30, 0.001)
+ #self.pk_detect = gr.peak_detector2_fb()
+ #self.pk_detect = gr.threshold_detector_fb(0.5)
+ self.regen = gr.regenerate_bb(symbol_length)
+
+ # FIXME: If sampler doesn't get proper input, it can completely
+ # stall the flowgraph.
+ self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+
+ self.connect(self, self.input)
+
+ self.connect(self.input, self.delay)
+ self.connect(self.input, (self.corr,0))
+ self.connect(self.delay, self.conjg)
+ self.connect(self.conjg, (self.corr,1))
+ self.connect(self.corr, self.moving_sum_filter)
+ self.connect(self.moving_sum_filter, self.c2mag)
+ self.connect(self.moving_sum_filter, self.angle)
+ self.connect(self.angle, (self.sample_and_hold,0))
+ self.connect(self.sample_and_hold, self.nco)
+
+ self.connect(self.input, (self.sigmix,0))
+ self.connect(self.nco, (self.sigmix,1))
+ self.connect(self.sigmix, (self.sampler,0))
+
+ self.connect(self.input, self.inputmag2, self.inputmovingsum)
+ self.connect(self.inputmovingsum, (self.square,0))
+ self.connect(self.inputmovingsum, (self.square,1))
+ self.connect(self.square, (self.normalize,1))
+ self.connect(self.c2mag, (self.normalize,0))
+
+ # Create a moving sum filter for the corr output
+ matched_filter_taps = [1.0/cp_length for i in range(cp_length)]
+ self.matched_filter = gr.fir_filter_fff(1,matched_filter_taps)
+ self.connect(self.normalize, self.matched_filter)
+
+ self.connect(self.matched_filter, self.sub1, self.pk_detect)
+ self.connect(self.pk_detect, self.regen)
+ self.connect(self.regen, (self.sampler,1))
+ self.connect(self.pk_detect, (self.sample_and_hold,1))
+
+ # Set output from sampler
+ self.connect(self.sampler, (self,0))
+ self.connect(self.pk_detect, (self,1))
+
+ if logging:
+ self.connect(self.matched_filter, gr.file_sink(gr.sizeof_float,
"ofdm_sync_pn-mf_f.dat"))
+ self.connect(self.normalize, gr.file_sink(gr.sizeof_float,
"ofdm_sync_pn-theta_f.dat"))
+ self.connect(self.angle, gr.file_sink(gr.sizeof_float,
"ofdm_sync_pn-epsilon_f.dat"))
+ self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char,
"ofdm_sync_pn-peaks_b.dat"))
+ self.connect(self.regen, gr.file_sink(gr.sizeof_char,
"ofdm_sync_pn-regen_b.dat"))
+ self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex,
"ofdm_sync_pn-sigmix_c.dat"))
+ self.connect(self.sampler,
gr.file_sink(gr.sizeof_gr_complex*fft_length, "ofdm_sync_pn-sampler_c.dat"))
+ self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float,
"ofdm_sync_pn-sample_and_hold_f.dat"))
+ self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex,
"ofdm_sync_pn-nco_c.dat"))
+ self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex,
"ofdm_sync_pn-input_c.dat"))
+
Copied:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py
(from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py)
===================================================================
---
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py
(rev 0)
+++
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blks2impl/ofdm_sync_pnac.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,131 @@
+#!/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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from numpy import fft
+from gnuradio import gr
+
+class ofdm_sync_pnac(gr.hier_block2):
+ def __init__(self, fft_length, cp_length, ks):
+
+ # FIXME: change the output signature
+ # should be the output of the divider (the normalized peaks) and
+ # the angle value out of the sample and hold block
+ # move sampler out of this block
+
+ gr.hier_block2.__init__(self, "ofdm_sync_pnac",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), #
Input signature
+ gr.io_signature(1, 1,
gr.sizeof_gr_complex*fft_length)) # Output signature
+
+
+ self.input = gr.add_const_cc(0)
+
+ symbol_length = fft_length + cp_length
+
+ # PN Sync
+
+ # autocorrelate with the known symbol
+ ks = ks[0:fft_length//2]
+ ks.reverse()
+ self.crosscorr_filter = gr.fir_filter_ccc(1, ks)
+ self.connect(self.crosscorr_filter, gr.file_sink(gr.sizeof_gr_complex,
"crosscorr.dat"))
+
+ # Create a delay line
+ self.delay = gr.delay(gr.sizeof_gr_complex, fft_length/2)
+
+ # Correlation from ML Sync
+ self.conjg = gr.conjugate_cc();
+ self.corr = gr.multiply_cc();
+
+ # Create a moving sum filter for the corr output
+ moving_sum_taps = [1.0 for i in range(fft_length//2)]
+ self.moving_sum_filter = gr.fir_filter_ccf(1,moving_sum_taps)
+
+ # Create a moving sum filter for the input
+ self.inputmag2 = gr.complex_to_mag_squared()
+ movingsum2_taps = [1.0 for i in range(fft_length/2)]
+ self.inputmovingsum = gr.fir_filter_fff(1,movingsum2_taps)
+ self.square = gr.multiply_ff()
+ self.normalize = gr.divide_ff()
+
+ # Get magnitude (peaks) and angle (phase/freq error)
+ self.c2mag = gr.complex_to_mag_squared()
+ self.angle = gr.complex_to_arg()
+
+ self.sample_and_hold = gr.sample_and_hold_ff()
+
+ # Mix the signal with an NCO controlled by the sync loop
+ nco_sensitivity = -1.0/fft_length
+ self.nco = gr.frequency_modulator_fc(nco_sensitivity)
+ self.sigmix = gr.multiply_cc()
+
+ #ML measurements input to sampler block and detect
+ self.sub1 = gr.add_const_ff(-1)
+ self.pk_detect = gr.peak_detector_fb(0.2, 0.25, 30, 0.0005)
+
+ self.sampler = gr.ofdm_sampler(fft_length,symbol_length)
+
+ self.connect(self, self.input)
+ self.connect(self.input, self.crosscorr_filter)
+ self.connect(self.crosscorr_filter, self.delay)
+ self.connect(self.crosscorr_filter, (self.corr,0))
+ self.connect(self.delay, self.conjg)
+ self.connect(self.conjg, (self.corr,1))
+ self.connect(self.corr, self.moving_sum_filter)
+ self.connect(self.moving_sum_filter, self.c2mag)
+ self.connect(self.moving_sum_filter, self.angle)
+ self.connect(self.angle, (self.sample_and_hold,0))
+ self.connect(self.sample_and_hold, self.nco)
+
+ self.connect(self.input, (self.sigmix,0))
+ self.connect(self.nco, (self.sigmix,1))
+ self.connect(self.sigmix, (self.sampler,0))
+
+ self.connect(self.input, self.inputmag2, self.inputmovingsum)
+ self.connect(self.inputmovingsum, (self.square,0))
+ self.connect(self.inputmovingsum, (self.square,1))
+ self.connect(self.square, (self.normalize,1))
+ self.connect(self.c2mag, (self.normalize,0))
+ self.connect(self.normalize, self.sub1, self.pk_detect)
+
+ self.connect(self.pk_detect, (self.sampler,1))
+ self.connect(self.pk_detect, (self.sample_and_hold,1))
+
+ self.connect(self.sampler, self)
+
+ if 1:
+ self.connect(self.normalize, gr.file_sink(gr.sizeof_float,
+
"ofdm_sync_pnac-theta_f.dat"))
+ self.connect(self.angle, gr.file_sink(gr.sizeof_float,
+
"ofdm_sync_pnac-epsilon_f.dat"))
+ self.connect(self.pk_detect, gr.file_sink(gr.sizeof_char,
+
"ofdm_sync_pnac-peaks_b.dat"))
+ self.connect(self.sigmix, gr.file_sink(gr.sizeof_gr_complex,
+
"ofdm_sync_pnac-sigmix_c.dat"))
+ self.connect(self.sampler,
gr.file_sink(gr.sizeof_gr_complex*fft_length,
+
"ofdm_sync_pnac-sampler_c.dat"))
+ self.connect(self.sample_and_hold, gr.file_sink(gr.sizeof_float,
+
"ofdm_sync_pnac-sample_and_hold_f.dat"))
+ self.connect(self.nco, gr.file_sink(gr.sizeof_gr_complex,
+ "ofdm_sync_pnac-nco_c.dat"))
+ self.connect(self.input, gr.file_sink(gr.sizeof_gr_complex,
+
"ofdm_sync_pnac-input_c.dat"))
Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
2008-01-02 17:35:35 UTC (rev 7324)
@@ -40,12 +40,6 @@
cpm.py \
nbfm_rx.py \
nbfm_tx.py \
- ofdm.py \
- ofdm_receiver.py \
- ofdm_sync_fixed.py \
- ofdm_sync_ml.py \
- ofdm_sync_pnac.py \
- ofdm_sync_pn.py \
pkt.py \
psk.py \
qam.py \
Deleted: gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm.py
Deleted:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_receiver.py
Deleted:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_fixed.py
Deleted:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_ml.py
Deleted:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pn.py
Deleted:
gnuradio/trunk/gnuradio-core/src/python/gnuradio/blksimpl/ofdm_sync_pnac.py
Copied: gnuradio/trunk/gnuradio-core/src/utils/README (from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/utils/README)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/README
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/utils/README 2008-01-02 17:35:35 UTC
(rev 7324)
@@ -0,0 +1,40 @@
+* gr_plot_*.py:
+These are a collection of Python scripts to enable viewing and analysis of
files produced by GNU Radio flow graphs. Most of them work off complex data
produced by digital waveforms.
+
+
+** gr_plot_float.py:
+Takes a GNU Radio floating point binary file and displays the samples versus
time. You can set the block size to specify how many points to read in at a
time and the start position in the file.
+
+By default, the system assumes a sample rate of 1, so in time, each sample is
plotted versus the sample number. To set a true time axis, set the sample rate
(-R or --sample-rate) to the sample rate used when capturing the samples.
+
+
+
+** gr_plot_iq.py:
+Takes a GNU Radio complex binary file and displays the I&Q data versus time.
You can set the block size to specify how many points to read in at a time and
the start position in the file.
+
+By default, the system assumes a sample rate of 1, so in time, each sample is
plotted versus the sample number. To set a true time axis, set the sample rate
(-R or --sample-rate) to the sample rate used when capturing the samples.
+
+
+
+** gr_plot_const.py:
+Takes a GNU Radio complex binary file and displays the I&Q data versus time
and the constellation plot (I vs. Q). You can set the block size to specify how
many points to read in at a time and the start position in the file.
+
+By default, the system assumes a sample rate of 1, so in time, each sample is
plotted versus the sample number. To set a true time axis, set the sample rate
(-R or --sample-rate) to the sample rate used when capturing the samples.
+
+
+
+** gr_plot_fft_c.py:
+Takes a GNU Radio complex binary file and displays the I&Q data versus time as
well as the frequency domain (FFT) plot. The y-axis values are plotted assuming
volts as the amplitude of the I&Q streams and converted into dBm in the
frequency domain (the 1/N power adjustment out of the FFT is performed
internally).
+
+The script plots a certain block of data at a time, specified on the command
line as -B or --block. This value defaults to 1000. The start position in the
file can be set by specifying -s or --start and defaults to 0 (the start of the
file).
+
+By default, the system assumes a sample rate of 1, so in time, each sample is
plotted versus the sample number. To set a true time and frequency axis, set
the sample rate (-R or --sample-rate) to the sample rate used when capturing
the samples.
+
+
+
+** gr_plot_fft_f.py:
+Takes a GNU Radio floating point binary file and displays the samples versus
time as well as the frequency domain (FFT) plot. The y-axis values are plotted
assuming volts as the amplitude of the I&Q streams and converted into dBm in
the frequency domain (the 1/N power adjustment out of the FFT is performed
internally).
+
+The script plots a certain block of data at a time, specified on the command
line as -B or --block. This value defaults to 1000. The start position in the
file can be set by specifying -s or --start and defaults to 0 (the start of the
file).
+
+By default, the system assumes a sample rate of 1, so in time, each sample is
plotted versus the sample number. To set a true time and frequency axis, set
the sample rate (-R or --sample-rate) to the sample rate used when capturing
the samples.
Copied: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_char.py (from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/utils/gr_plot_char.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_char.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_char.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -0,0 +1,165 @@
+#!/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 3, 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 scipy
+from pylab import *
+from optparse import OptionParser
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_fft_c:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.94, ("File: %s" % filename),
weight="heavy", size=self.text_size)
+ self.text_file_pos = figtext(0.10, 0.88, "File Position: ",
weight="heavy", size=self.text_size)
+ self.text_block = figtext(0.40, 0.88, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=self.text_size)
+ self.text_sr = figtext(0.60, 0.88, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=self.text_size)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_f.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" % (self.hfile.tell()))
+ f = scipy.fromfile(self.hfile, dtype=scipy.int8,
count=self.block_length)
+ #print "Read in %d items" % len(self.f)
+ if(len(f) == 0):
+ print "End of File"
+ else:
+ self.f = f
+ self.time = [i*(1/self.sample_rate) for i in range(len(self.f))]
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(8*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_f = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.875,
0.6])
+ self.sp_f.set_title(("Amplitude"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_f.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_f.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_f = plot(self.time, self.f, 'bo-')
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_f[0].set_data([self.time, self.f])
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 2*self.block_length ):
+ self.hfile.seek(-2*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
+def main():
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio floating point binary file and displays
the samples versus time. You can set the block size to specify how many points
to read in at a time and the start position in the file. By default, the system
assumes a sample rate of 1, so in time, each sample is plotted versus the
sample number. To set a true time axis, set the sample rate (-R or
--sample-rate) to the sample rate used when capturing the samples."
+
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+ filename = args[0]
+
+ dc = draw_fft_c(filename, options)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
Modified: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_const.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_const.py 2008-01-02
17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_const.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -20,89 +20,172 @@
# Boston, MA 02110-1301, USA.
#
-import pylab, math
+import scipy
from pylab import *
-import struct, sys
+from matplotlib.font_manager import fontManager, FontProperties
from optparse import OptionParser
-import gr_read_binary
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
-class zoom:
- def __init__(self, xdata, reals, imags, sp_iq, sp_const, plot_const,
manager):
- self.sp_iq = sp_iq
- self.sp_const = sp_const
- self.xaxis = xdata
- self.reals = reals
- self.imags = imags
- self.plot_const = plot_const
- self.manager = manager
+class draw_constellation:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.95, ("File: %s" % filename),
weight="heavy", size=16)
+ self.text_file_pos = figtext(0.10, 0.90, "File Position: ",
weight="heavy", size=16)
+ self.text_block = figtext(0.40, 0.90, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=16)
+ self.text_sr = figtext(0.60, 0.90, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=16)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
self.xlim = self.sp_iq.get_xlim()
-
- def __call__(self, event):
+
+ self.manager = get_current_fig_manager()
+ connect('draw_event', self.zoom)
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" %
(self.hfile.tell()//8))
+ iq = scipy.fromfile(self.hfile, dtype=scipy.complex64,
count=self.block_length)
+ #print "Read in %d items" % len(iq)
+ if(len(iq) == 0):
+ print "End of File"
+ else:
+ self.reals = [r.real for r in iq]
+ self.imags = [i.imag for i in iq]
+
+ self.time = [i*(1/self.sample_rate) for i in
range(len(self.reals))]
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(16*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_iq = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.4,
0.6])
+ self.sp_iq.set_title(("I&Q"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_iq.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_iq.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_iq = plot(self.time, self.reals, 'bo-', self.time,
self.imags, 'ro-')
+ self.sp_iq.axis([min(self.time), max(self.time),
+ 1.5*min([min(self.reals), min(self.imags)]),
+ 1.5*max([max(self.reals), max(self.imags)])])
+
+ # Subplot for constellation plot
+ self.sp_const = self.fig.add_subplot(2,2,1, position=[0.575, 0.2, 0.4,
0.6])
+ self.sp_const.set_title(("Constellation"),
fontsize=self.title_font_size, fontweight="bold")
+ self.sp_const.set_xlabel("Inphase", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_const.set_ylabel("Qaudrature", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_const = plot(self.reals, self.imags, 'bo')
+ self.sp_const.axis([-2, 2, -2, 2])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_iq[0].set_data([self.time, self.reals])
+ self.plot_iq[1].set_data([self.time, self.imags])
+ self.sp_iq.axis([min(self.time), max(self.time),
+ 1.5*min([min(self.reals), min(self.imags)]),
+ 1.5*max([max(self.reals), max(self.imags)])])
+
+ self.plot_const[0].set_data([self.reals, self.imags])
+ self.sp_const.axis([-2, 2, -2, 2])
+ draw()
+
+ def zoom(self, event):
newxlim = self.sp_iq.get_xlim()
-
if(newxlim != self.xlim):
self.xlim = newxlim
- r = self.reals[int(self.xlim[0]) : int(self.xlim[1])]
- i = self.imags[int(self.xlim[0]) : int(self.xlim[1])]
+ r = self.reals[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
+ i = self.imags[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
self.plot_const[0].set_data(r, i)
self.sp_const.axis([-2, 2, -2, 2])
self.manager.canvas.draw()
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 16*self.block_length ):
+ self.hfile.seek(-16*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
def main():
- usage="%prog: [options] output_filename"
- parser = OptionParser(conflict_handler="resolve", usage=usage)
- parser.add_option("-s", "--size", type="int", default=None,
- help="Specify the number of points to plot
[default=%default]")
- parser.add_option("", "--skip", type="int", default=None,
- help="Specify the number of points to skip
[default=%default]")
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio complex binary file and displays the I&Q
data versus time and the constellation plot (I vs. Q). You can set the block
size to specify how many points to read in at a time and the start position in
the file. By default, the system assumes a sample rate of 1, so in time, each
sample is plotted versus the sample number. To set a true time axis, set the
sample rate (-R or --sample-rate) to the sample rate used when capturing the
samples."
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
(options, args) = parser.parse_args ()
if len(args) != 1:
parser.print_help()
raise SystemExit, 1
filename = args[0]
- iq = gr_read_binary.read_complex_binary(filename)
+ dc = draw_constellation(filename, options)
- if(options.skip is None):
- options.skip = 0
-
- if((options.size is None) or ((options.skip+options.size) > len(iq[0]))):
- options.size = len(iq[0]) - options.skip
-
- reals = iq[0][options.skip : options.skip + options.size]
- imags = iq[1][options.skip : options.skip + options.size]
- x = range(options.skip, options.skip + options.size)
-
- # PLOT
- f = figure(1, figsize=(16, 12), facecolor='w')
- rcParams['xtick.labelsize'] = 16
- rcParams['ytick.labelsize'] = 16
-
- # Subplot for real and imaginary parts of signal
- sp1 = f.add_subplot(2,1,1)
- sp1.set_title(("I&Q"), fontsize=26, fontweight="bold")
- sp1.set_xlabel("Time (s)", fontsize=20, fontweight="bold")
- sp1.set_ylabel("Amplitude (V)", fontsize=20, fontweight="bold")
- plot(x, reals, 'bo-', x, imags, 'ro-')
-
- # Subplot for constellation plot
- sp2 = f.add_subplot(2,1,2)
- sp2.set_title(("Constellation"), fontsize=26, fontweight="bold")
- sp2.set_xlabel("Inphase", fontsize=20, fontweight="bold")
- sp2.set_ylabel("Qaudrature", fontsize=20, fontweight="bold")
- p2 = plot(reals, imags, 'bo')
- sp2.axis([-2, 2, -2, 2])
-
- manager = get_current_fig_manager()
- zm = zoom(x, reals, imags, sp1, sp2, p2, manager)
- connect('draw_event', zm)
-
- show()
-
if __name__ == "__main__":
try:
main()
Copied: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_c.py (from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/utils/gr_plot_fft_c.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_c.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_c.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -0,0 +1,221 @@
+#!/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 3, 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 scipy
+from pylab import *
+from optparse import OptionParser
+from scipy import fftpack
+from math import log10
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_fft_c:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.94, ("File: %s" % filename),
weight="heavy", size=self.text_size)
+ self.text_file_pos = figtext(0.10, 0.88, "File Position: ",
weight="heavy", size=self.text_size)
+ self.text_block = figtext(0.40, 0.88, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=self.text_size)
+ self.text_sr = figtext(0.60, 0.88, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=self.text_size)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_iq.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ connect('draw_event', self.zoom)
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" %
(self.hfile.tell()//8))
+ self.iq = scipy.fromfile(self.hfile, dtype=scipy.complex64,
count=self.block_length)
+ #print "Read in %d items" % len(self.iq)
+ if(len(self.iq) == 0):
+ print "End of File"
+ else:
+ self.reals = [r.real for r in self.iq]
+ self.imags = [i.imag for i in self.iq]
+
+ self.iq_fft = self.dofft(self.iq)
+
+ self.time = [i*(1/self.sample_rate) for i in
range(len(self.reals))]
+ self.freq = self.calc_freq(self.time, self.sample_rate)
+
+
+ def dofft(self, iq):
+ N = len(iq)
+ iq_fft = fftpack.fftshift(scipy.fft(iq)) # fft and shift axis
+ iq_fft = [20*log10(abs(i/N)) for i in iq_fft] # convert to decibels,
adjust power
+ return iq_fft
+
+ def calc_freq(self, time, sample_rate):
+ N = len(time)
+ Fs = 1.0 / (max(time) - min(time))
+ Fn = 0.5 * sample_rate
+ freq = [-Fn + i*Fs for i in range(N)]
+ return freq
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(16*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_iq = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.4,
0.6])
+ self.sp_iq.set_title(("I&Q"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_iq.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_iq.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_iq = plot(self.time, self.reals, 'bo-', self.time,
self.imags, 'ro-')
+ self.sp_iq.set_ylim([1.5*min([min(self.reals), min(self.imags)]),
+ 1.5*max([max(self.reals), max(self.imags)])])
+
+ # Subplot for constellation plot
+ self.sp_fft = self.fig.add_subplot(2,2,1, position=[0.575, 0.2, 0.4,
0.6])
+ self.sp_fft.set_title(("FFT"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_fft.set_xlabel("Frequency (Hz)",
fontsize=self.label_font_size, fontweight="bold")
+ self.sp_fft.set_ylabel("Power (dBm)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_fft = plot(self.freq, self.iq_fft, '-bo')
+ self.sp_fft.set_ylim([min(self.iq_fft)-10, max(self.iq_fft)+10])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_iq[0].set_data([self.time, self.reals])
+ self.plot_iq[1].set_data([self.time, self.imags])
+ self.sp_iq.set_ylim([1.5*min([min(self.reals), min(self.imags)]),
+ 1.5*max([max(self.reals), max(self.imags)])])
+
+ self.plot_fft[0].set_data([self.freq, self.iq_fft])
+ self.sp_fft.set_ylim([min(self.iq_fft)-10, max(self.iq_fft)+10])
+
+ draw()
+
+ def zoom(self, event):
+ newxlim = self.sp_iq.get_xlim()
+ if(newxlim != self.xlim):
+ self.xlim = newxlim
+ xmin = max(0, int(ceil(self.sample_rate*self.xlim[0])))
+ xmax = min(int(ceil(self.sample_rate*self.xlim[1])), len(self.iq))
+
+ iq = self.iq[xmin : xmax]
+ time = self.time[xmin : xmax]
+
+ iq_fft = self.dofft(iq)
+ freq = self.calc_freq(time, self.sample_rate)
+
+ self.plot_fft[0].set_data(freq, iq_fft)
+ self.sp_fft.axis([min(freq), max(freq),
+ min(iq_fft)-10, max(iq_fft)+10])
+
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 16*self.block_length ):
+ self.hfile.seek(-16*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
+def main():
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio complex binary file and displays the I&Q
data versus time as well as the frequency domain (FFT) plot. The y-axis values
are plotted assuming volts as the amplitude of the I&Q streams and converted
into dBm in the frequency domain (the 1/N power adjustment out of the FFT is
performed internally). The script plots a certain block of data at a time,
specified on the command line as -B or --block. This value defaults to 1000.
The start position in the file can be set by specifying -s or --start and
defaults to 0 (the start of the file). By default, the system assumes a sample
rate of 1, so in time, each sample is plotted versus the sample number. To set
a true time and frequency axis, set the sample rate (-R or --sample-rate) to
the sample rate used when capturing the samples."
+
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+ filename = args[0]
+
+ dc = draw_fft_c(filename, options)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
+
+
Copied: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_f.py (from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/utils/gr_plot_fft_f.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_f.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_fft_f.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -0,0 +1,223 @@
+#!/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 3, 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 scipy
+from pylab import *
+from optparse import OptionParser
+from scipy import fftpack
+from math import log10
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_fft_f:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.94, ("File: %s" % filename),
weight="heavy", size=self.text_size)
+ self.text_file_pos = figtext(0.10, 0.88, "File Position: ",
weight="heavy", size=self.text_size)
+ self.text_block = figtext(0.40, 0.88, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=self.text_size)
+ self.text_sr = figtext(0.60, 0.88, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=self.text_size)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_f.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ connect('draw_event', self.zoom)
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" %
(self.hfile.tell()//4))
+ self.floats = scipy.fromfile(self.hfile, dtype=scipy.float32,
count=self.block_length)
+ #print "Read in %d items" % len(self.floats)
+ if(len(self.floats) == 0):
+ print "End of File"
+ else:
+ self.f_fft = self.dofft(self.floats)
+
+ self.time = [i*(1/self.sample_rate) for i in
range(len(self.floats))]
+ self.freq = self.calc_freq(self.time, self.sample_rate)
+
+ def dofft(self, f):
+ N = len(f)
+ f_fft = fftpack.fftshift(scipy.fft(f)) # fft and shift axis
+ f_dB = list()
+ for f in f_fft:
+ try:
+ f_dB.append(20*log10(abs(f/N))) # convert to decibels, adjust
power
+ except OverflowError: # protect against taking
log(0)
+ f = 1e-14 # not sure if this is the
best way to do this
+ f_dB.append(20*log10(abs(f/N)))
+
+ return f_dB
+
+ def calc_freq(self, time, sample_rate):
+ N = len(time)
+ Fs = 1.0 / (max(time) - min(time))
+ Fn = 0.5 * sample_rate
+ freq = [-Fn + i*Fs for i in range(N)]
+ return freq
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(16*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_f = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.4,
0.6])
+ self.sp_f.set_title(("Amplitude"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_f.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_f.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_f = plot(self.time, self.floats, 'bo-')
+ self.sp_f.set_ylim([1.5*min(self.floats),
+ 1.5*max(self.floats)])
+
+ # Subplot for constellation plot
+ self.sp_fft = self.fig.add_subplot(2,2,1, position=[0.575, 0.2, 0.4,
0.6])
+ self.sp_fft.set_title(("FFT"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_fft.set_xlabel("Frequency (Hz)",
fontsize=self.label_font_size, fontweight="bold")
+ self.sp_fft.set_ylabel("Power (dBm)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_fft = plot(self.freq, self.f_fft, '-bo')
+ self.sp_fft.set_ylim([min(self.f_fft)-10, max(self.f_fft)+10])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_f[0].set_data([self.time, self.floats])
+ self.sp_f.set_ylim([1.5*min(self.floats),
+ 1.5*max(self.floats)])
+
+ self.plot_fft[0].set_data([self.freq, self.f_fft])
+ self.sp_fft.set_ylim([min(self.f_fft)-10, max(self.f_fft)+10])
+
+ draw()
+
+ def zoom(self, event):
+ newxlim = self.sp_f.get_xlim()
+ if(newxlim != self.xlim):
+ self.xlim = newxlim
+ xmin = max(0, int(ceil(self.sample_rate*self.xlim[0])))
+ xmax = min(int(ceil(self.sample_rate*self.xlim[1])),
len(self.floats))
+
+ f = self.floats[xmin : xmax]
+ time = self.time[xmin : xmax]
+
+ f_fft = self.dofft(f)
+ freq = self.calc_freq(time, self.sample_rate)
+
+ self.plot_fft[0].set_data(freq, f_fft)
+ self.sp_fft.axis([min(freq), max(freq),
+ min(f_fft)-10, max(f_fft)+10])
+
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 8*self.block_length ):
+ self.hfile.seek(-8*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
+def main():
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio floating point binary file and displays
the sample data versus time as well as the frequency domain (FFT) plot. The
y-axis values are plotted assuming volts as the amplitude of the I&Q streams
and converted into dBm in the frequency domain (the 1/N power adjustment out of
the FFT is performed internally). The script plots a certain block of data at a
time, specified on the command line as -B or --block. This value defaults to
1000. The start position in the file can be set by specifying -s or --start and
defaults to 0 (the start of the file). By default, the system assumes a sample
rate of 1, so in time, each sample is plotted versus the sample number. To set
a true time and frequency axis, set the sample rate (-R or --sample-rate) to
the sample rate used when capturing the samples."
+
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+ filename = args[0]
+
+ dc = draw_fft_f(filename, options)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
+
+
Modified: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_float.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_float.py 2008-01-02
17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_float.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -20,56 +20,146 @@
# Boston, MA 02110-1301, USA.
#
-import pylab, math
+import scipy
from pylab import *
-import struct, sys
from optparse import OptionParser
-import gr_read_binary
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+class draw_fft_c:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.94, ("File: %s" % filename),
weight="heavy", size=self.text_size)
+ self.text_file_pos = figtext(0.10, 0.88, "File Position: ",
weight="heavy", size=self.text_size)
+ self.text_block = figtext(0.40, 0.88, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=self.text_size)
+ self.text_sr = figtext(0.60, 0.88, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=self.text_size)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_f.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" %
(self.hfile.tell()//4))
+ f = scipy.fromfile(self.hfile, dtype=scipy.float32,
count=self.block_length)
+ #print "Read in %d items" % len(self.f)
+ if(len(f) == 0):
+ print "End of File"
+ else:
+ self.f = f
+ self.time = [i*(1/self.sample_rate) for i in range(len(self.f))]
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(8*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_f = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.875,
0.6])
+ self.sp_f.set_title(("Amplitude"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_f.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_f.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_f = plot(self.time, self.f, 'bo-')
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_f[0].set_data([self.time, self.f])
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 8*self.block_length ):
+ self.hfile.seek(-8*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
def main():
- usage="%prog: [options] output_filename"
- parser = OptionParser(conflict_handler="resolve", usage=usage)
- parser.add_option("-s", "--size", type="int", default=None,
- help="Specify the number of points to plot
[default=%default]")
- parser.add_option("", "--skip", type="int", default=None,
- help="Specify the number of points to skip
[default=%default]")
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio floating point binary file and displays
the samples versus time. You can set the block size to specify how many points
to read in at a time and the start position in the file. By default, the system
assumes a sample rate of 1, so in time, each sample is plotted versus the
sample number. To set a true time axis, set the sample rate (-R or
--sample-rate) to the sample rate used when capturing the samples."
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
(options, args) = parser.parse_args ()
if len(args) != 1:
parser.print_help()
raise SystemExit, 1
filename = args[0]
- fl = gr_read_binary.read_float_binary(filename)
+ dc = draw_fft_c(filename, options)
- if(options.skip is None):
- options.skip = 0
-
- if((options.size is None) or ((options.skip+options.size) > len(iq[0]))):
- options.size = len(fl) - options.skip
-
- x = range(options.skip, options.skip + options.size)
-
- # PLOT REAL AND IMAGINARY PARTS
-
- f = figure(1, figsize=(16, 12), facecolor='w')
- rcParams['xtick.labelsize'] = 16
- rcParams['ytick.labelsize'] = 16
-
- sp1 = f.add_subplot(1,1,1)
- sp1.set_title(("GNU Radio Float"), fontsize=26, fontweight="bold")
- sp1.set_xlabel("Time (s)", fontsize=20, fontweight="bold")
- sp1.set_ylabel("Amplitude (V)", fontsize=20, fontweight="bold")
- plot(x, fl, 'bo-')
-
- show()
-
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
pass
-
-
Copied: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_int.py (from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/utils/gr_plot_int.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_int.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_int.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -0,0 +1,165 @@
+#!/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 3, 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 scipy
+from pylab import *
+from optparse import OptionParser
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_fft_c:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.94, ("File: %s" % filename),
weight="heavy", size=self.text_size)
+ self.text_file_pos = figtext(0.10, 0.88, "File Position: ",
weight="heavy", size=self.text_size)
+ self.text_block = figtext(0.40, 0.88, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=self.text_size)
+ self.text_sr = figtext(0.60, 0.88, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=self.text_size)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_f.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" %
(self.hfile.tell()//4))
+ f = scipy.fromfile(self.hfile, dtype=scipy.int32,
count=self.block_length)
+ #print "Read in %d items" % len(self.f)
+ if(len(f) == 0):
+ print "End of File"
+ else:
+ self.f = f
+ self.time = [i*(1/self.sample_rate) for i in range(len(self.f))]
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(8*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_f = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.875,
0.6])
+ self.sp_f.set_title(("Amplitude"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_f.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_f.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_f = plot(self.time, self.f, 'bo-')
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_f[0].set_data([self.time, self.f])
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 8*self.block_length ):
+ self.hfile.seek(-8*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
+def main():
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio floating point binary file and displays
the samples versus time. You can set the block size to specify how many points
to read in at a time and the start position in the file. By default, the system
assumes a sample rate of 1, so in time, each sample is plotted versus the
sample number. To set a true time axis, set the sample rate (-R or
--sample-rate) to the sample rate used when capturing the samples."
+
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+ filename = args[0]
+
+ dc = draw_fft_c(filename, options)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
Modified: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_iq.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_iq.py 2008-01-02
17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_iq.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -20,53 +20,145 @@
# Boston, MA 02110-1301, USA.
#
-import pylab, math
+import scipy
from pylab import *
-import struct, sys
from optparse import OptionParser
-import gr_read_binary
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+class draw_fft:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.94, ("File: %s" % filename),
weight="heavy", size=self.text_size)
+ self.text_file_pos = figtext(0.10, 0.88, "File Position: ",
weight="heavy", size=self.text_size)
+ self.text_block = figtext(0.40, 0.88, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=self.text_size)
+ self.text_sr = figtext(0.60, 0.88, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=self.text_size)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_iq.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" %
(self.hfile.tell()//8))
+ self.iq = scipy.fromfile(self.hfile, dtype=scipy.complex64,
count=self.block_length)
+ #print "Read in %d items" % len(self.iq)
+ if(len(self.iq) == 0):
+ print "End of File"
+ else:
+ self.reals = [r.real for r in self.iq]
+ self.imags = [i.imag for i in self.iq]
+ self.time = [i*(1/self.sample_rate) for i in
range(len(self.reals))]
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(16*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_iq = self.fig.add_subplot(2,1,1, position=[0.075, 0.14, 0.85,
0.67])
+ self.sp_iq.set_title(("I&Q"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_iq.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_iq.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_iq = plot(self.time, self.reals, 'bo-', self.time,
self.imags, 'ro-')
+ self.sp_iq.set_ylim([1.5*min([min(self.reals), min(self.imags)]),
+ 1.5*max([max(self.reals), max(self.imags)])])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_iq[0].set_data([self.time, self.reals])
+ self.plot_iq[1].set_data([self.time, self.imags])
+ self.sp_iq.set_ylim([1.5*min([min(self.reals), min(self.imags)]),
+ 1.5*max([max(self.reals), max(self.imags)])])
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 16*self.block_length ):
+ self.hfile.seek(-16*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
def main():
- usage="%prog: [options] output_filename"
- parser = OptionParser(conflict_handler="resolve", usage=usage)
- parser.add_option("-s", "--size", type="int", default=None,
- help="Specify the number of points to plot
[default=%default]")
- parser.add_option("", "--skip", type="int", default=None,
- help="Specify the number of points to skip
[default=%default]")
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio complex binary file and displays the I&Q
data versus time. You can set the block size to specify how many points to read
in at a time and the start position in the file. By default, the system assumes
a sample rate of 1, so in time, each sample is plotted versus the sample
number. To set a true time axis, set the sample rate (-R or --sample-rate) to
the sample rate used when capturing the samples."
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
(options, args) = parser.parse_args ()
if len(args) != 1:
parser.print_help()
raise SystemExit, 1
filename = args[0]
- iq = gr_read_binary.read_complex_binary(filename)
+ dc = draw_fft(filename, options)
- if(options.skip is None):
- options.skip = 0
-
- if((options.size is None) or ((options.skip+options.size) > len(iq[0]))):
- options.size = len(iq[0]) - options.skip
-
- reals = iq[0][options.skip : options.skip + options.size]
- imags = iq[1][options.skip : options.skip + options.size]
- x = range(options.skip, options.skip + options.size)
-
- # PLOT REAL AND IMAGINARY PARTS
-
- f = figure(1, figsize=(16, 12), facecolor='w')
- rcParams['xtick.labelsize'] = 16
- rcParams['ytick.labelsize'] = 16
-
- sp1 = f.add_subplot(1,1,1)
- sp1.set_title(("I&Q"), fontsize=26, fontweight="bold")
- sp1.set_xlabel("Time (s)", fontsize=20, fontweight="bold")
- sp1.set_ylabel("Amplitude (V)", fontsize=20, fontweight="bold")
- plot(x, reals, 'bo-', x, imags, 'ro-')
-
- show()
-
if __name__ == "__main__":
try:
main()
Copied: gnuradio/trunk/gnuradio-core/src/utils/gr_plot_short.py (from rev 7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-core/src/utils/gr_plot_short.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/utils/gr_plot_short.py
(rev 0)
+++ gnuradio/trunk/gnuradio-core/src/utils/gr_plot_short.py 2008-01-02
17:35:35 UTC (rev 7324)
@@ -0,0 +1,165 @@
+#!/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 3, 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 scipy
+from pylab import *
+from optparse import OptionParser
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_fft_c:
+ def __init__(self, filename, options):
+ self.hfile = open(filename, "r")
+ self.block_length = options.block
+ self.start = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(16, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_file = figtext(0.10, 0.94, ("File: %s" % filename),
weight="heavy", size=self.text_size)
+ self.text_file_pos = figtext(0.10, 0.88, "File Position: ",
weight="heavy", size=self.text_size)
+ self.text_block = figtext(0.40, 0.88, ("Block Size: %d" %
self.block_length),
+ weight="heavy", size=self.text_size)
+ self.text_sr = figtext(0.60, 0.88, ("Sample Rate: %.2f" %
self.sample_rate),
+ weight="heavy", size=self.text_size)
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_f.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_file_pos.set_text("File Position: %d" %
(self.hfile.tell()//2))
+ f = scipy.fromfile(self.hfile, dtype=scipy.int16,
count=self.block_length)
+ #print "Read in %d items" % len(self.f)
+ if(len(f) == 0):
+ print "End of File"
+ else:
+ self.f = f
+ self.time = [i*(1/self.sample_rate) for i in range(len(self.f))]
+
+ def make_plots(self):
+ # if specified on the command-line, set file pointer
+ self.hfile.seek(8*self.start, 1)
+
+ self.get_data()
+
+ # Subplot for real and imaginary parts of signal
+ self.sp_f = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.875,
0.6])
+ self.sp_f.set_title(("Amplitude"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_f.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_f.set_ylabel("Amplitude (V)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_f = plot(self.time, self.f, 'bo-')
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+
+ draw()
+
+ def update_plots(self):
+ self.plot_f[0].set_data([self.time, self.f])
+ self.sp_f.set_ylim([1.5*min(self.f),
+ 1.5*max(self.f)])
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ if(self.hfile.tell() >= 4*self.block_length ):
+ self.hfile.seek(-4*self.block_length, 1)
+ else:
+ self.hfile.seek(-self.hfile.tell(),1)
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
+def main():
+ usage="%prog: [options] input_filename"
+ description = "Takes a GNU Radio floating point binary file and displays
the samples versus time. You can set the block size to specify how many points
to read in at a time and the start position in the file. By default, the system
assumes a sample rate of 1, so in time, each sample is plotted versus the
sample number. To set a true time axis, set the sample rate (-R or
--sample-rate) to the sample rate used when capturing the samples."
+
+ parser = OptionParser(conflict_handler="resolve", usage=usage,
description=description)
+ parser.add_option("-B", "--block", type="int", default=1000,
+ help="Specify the block size [default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify where to start in the file
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+ filename = args[0]
+
+ dc = draw_fft_c(filename, options)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
Deleted: gnuradio/trunk/gnuradio-core/src/utils/gr_read_binary.py
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -20,7 +20,7 @@
# Boston, MA 02110-1301, USA.
#
-from gnuradio import gr, blks
+from gnuradio import gr, blks2
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser
@@ -32,9 +32,9 @@
from receive_path import receive_path
-class my_graph(gr.flow_graph):
+class my_top_block(gr.top_block):
def __init__(self, callback, options):
- gr.flow_graph.__init__(self)
+ gr.top_block.__init__(self)
if not options.channel_off:
SNR = 10.0**(options.snr/10.0)
@@ -67,22 +67,24 @@
z = [0,]
self.zeros = gr.vector_source_c(z, True)
- self.txpath = transmit_path(self, options)
+ self.txpath = transmit_path(options)
- self.mux = gr.stream_mux(gr.sizeof_gr_complex, stream_size)
+ #self.mux = gr.stream_mux(gr.sizeof_gr_complex, stream_size)
self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate)
- self.channel = blks.channel_model(self, noise_voltage,
frequency_offset,
- options.clockrate_ratio, taps)
- self.rxpath = receive_path(self, callback, options)
+ self.channel = blks2.channel_model(noise_voltage, frequency_offset,
+ options.clockrate_ratio, taps)
+ self.rxpath = receive_path(callback, options)
- self.connect(self.zeros, (self.mux,0))
- self.connect(self.txpath, (self.mux,1))
- self.connect(self.mux, self.throttle, self.channel, self.rxpath)
-
+ #self.connect(self.zeros, (self.mux,0))
+ #self.connect(self.txpath, (self.mux,1))
+ #self.connect(self.mux, self.throttle, self.channel, self.rxpath)
+ #self.connect(self.mux, self.throttle, self.rxpath)
+ self.connect(self.txpath, self.throttle, self.channel, self.rxpath)
+
if options.log:
self.connect(self.txpath, gr.file_sink(gr.sizeof_gr_complex,
"txpath.dat"))
- self.connect(self.mux, gr.file_sink(gr.sizeof_gr_complex,
"mux.dat"))
- self.connect(self.channel, gr.file_sink(gr.sizeof_gr_complex,
"channel.dat"))
+ #self.connect(self.mux, gr.file_sink(gr.sizeof_gr_complex,
"mux.dat"))
+ #self.connect(self.channel, gr.file_sink(gr.sizeof_gr_complex,
"channel.dat"))
# /////////////////////////////////////////////////////////////////////////////
# main
@@ -95,7 +97,7 @@
n_right = 0
def send_pkt(payload='', eof=False):
- return fg.txpath.send_pkt(payload, eof)
+ return tb.txpath.send_pkt(payload, eof)
def rx_callback(ok, payload):
global n_rcvd, n_right
@@ -139,20 +141,20 @@
transmit_path.add_options(parser, expert_grp)
receive_path.add_options(parser, expert_grp)
- blks.ofdm_mod.add_options(parser, expert_grp)
- blks.ofdm_demod.add_options(parser, expert_grp)
+ blks2.ofdm_mod.add_options(parser, expert_grp)
+ blks2.ofdm_demod.add_options(parser, expert_grp)
(options, args) = parser.parse_args ()
# build the graph
- fg = my_graph(rx_callback, options)
+ tb = my_top_block(rx_callback, options)
r = gr.enable_realtime_scheduling()
# if r != gr.RT_OK:
# print "Warning: failed to enable realtime scheduling"
-
- fg.start() # start flow graph
+ tb.start() # start flow graph
+
# generate and send packets
nbytes = int(1e6 * options.megabytes)
n = 0
@@ -173,7 +175,7 @@
pktno += 1
send_pkt(eof=True)
- fg.wait() # wait for it to finish
+ tb.wait() # wait for it to finish
if __name__ == '__main__':
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_rx.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -20,21 +20,21 @@
# Boston, MA 02110-1301, USA.
#
-from gnuradio import gr, blks
+from gnuradio import gr, blks2
from gnuradio import usrp
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
from optparse import OptionParser
-import random, time, struct, sys
+import struct, sys
# from current dir
from receive_path import receive_path
import fusb_options
-class usrp_graph(gr.flow_graph):
+class my_top_block(gr.top_block):
def __init__(self, callback, options):
- gr.flow_graph.__init__(self)
+ gr.top_block.__init__(self)
self._rx_freq = options.rx_freq # receiver's center
frequency
self._rx_gain = options.rx_gain # receiver's gain
@@ -61,10 +61,10 @@
self.set_auto_tr(True) # enable Auto Transmit/Receive
switching
# Set up receive path
- self.rxpath = receive_path(self, callback, options)
+ self.rxpath = receive_path(callback, options)
self.connect(self.u, self.rxpath)
-
+
def _setup_usrp_source(self):
self.u = usrp.source_c (fusb_block_size=self._fusb_block_size,
fusb_nblocks=self._fusb_nblocks)
@@ -187,23 +187,23 @@
parser.add_option("","--discontinuous", action="store_true", default=False,
help="enable discontinuous")
- usrp_graph.add_options(parser, expert_grp)
+ my_top_block.add_options(parser, expert_grp)
receive_path.add_options(parser, expert_grp)
- blks.ofdm_mod.add_options(parser, expert_grp)
- blks.ofdm_demod.add_options(parser, expert_grp)
+ blks2.ofdm_mod.add_options(parser, expert_grp)
+ blks2.ofdm_demod.add_options(parser, expert_grp)
fusb_options.add_options(expert_grp)
(options, args) = parser.parse_args ()
# build the graph
- fg = usrp_graph(rx_callback, options)
+ tb = my_top_block(rx_callback, options)
r = gr.enable_realtime_scheduling()
if r != gr.RT_OK:
print "Warning: failed to enable realtime scheduling"
- fg.start() # start flow graph
- fg.wait() # wait for it to finish
+ tb.start() # start flow graph
+ tb.wait() # wait for it to finish
if __name__ == '__main__':
try:
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/benchmark_ofdm_tx.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -20,7 +20,7 @@
# Boston, MA 02110-1301, USA.
#
-from gnuradio import gr, blks
+from gnuradio import gr, blks2
from gnuradio import usrp
from gnuradio import eng_notation
from gnuradio.eng_option import eng_option
@@ -33,9 +33,9 @@
from pick_bitrate import pick_tx_bitrate
import fusb_options
-class usrp_graph(gr.flow_graph):
+class my_top_block(gr.top_block):
def __init__(self, options):
- gr.flow_graph.__init__(self)
+ gr.top_block.__init__(self)
self._tx_freq = options.tx_freq # tranmitter's
center frequency
self._tx_subdev_spec = options.tx_subdev_spec # daughterboard to
use
@@ -53,10 +53,10 @@
# copy the final answers back into options for use by modulator
#options.bitrate = self._bitrate
- self.txpath = transmit_path(self, options)
+ self.txpath = transmit_path(options)
self.connect(self.txpath, self.u)
-
+
def _setup_usrp_sink(self):
"""
Creates a USRP sink, determines the settings for best bitrate,
@@ -167,7 +167,7 @@
def main():
def send_pkt(payload='', eof=False):
- return fg.txpath.send_pkt(payload, eof)
+ return tb.txpath.send_pkt(payload, eof)
parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
expert_grp = parser.add_option_group("Expert")
@@ -178,23 +178,23 @@
parser.add_option("","--discontinuous", action="store_true", default=False,
help="enable discontinuous mode")
- usrp_graph.add_options(parser, expert_grp)
+ my_top_block.add_options(parser, expert_grp)
transmit_path.add_options(parser, expert_grp)
- blks.ofdm_mod.add_options(parser, expert_grp)
- blks.ofdm_demod.add_options(parser, expert_grp)
+ blks2.ofdm_mod.add_options(parser, expert_grp)
+ blks2.ofdm_demod.add_options(parser, expert_grp)
fusb_options.add_options(expert_grp)
(options, args) = parser.parse_args ()
# build the graph
- fg = usrp_graph(options)
-
+ tb = my_top_block(options)
+
r = gr.enable_realtime_scheduling()
if r != gr.RT_OK:
print "Warning: failed to enable realtime scheduling"
- fg.start() # start flow graph
-
+ tb.start() # start flow graph
+
# generate and send packets
nbytes = int(1e6 * options.megabytes)
n = 0
@@ -210,7 +210,7 @@
pktno += 1
send_pkt(eof=True)
- fg.wait() # wait for it to finish
+ tb.wait() # wait for it to finish
if __name__ == '__main__':
try:
Copied: gnuradio/trunk/gnuradio-examples/python/ofdm/gr_plot_ofdm.py (from rev
7320,
gnuradio/branches/developers/trondeau/ofdm2/gnuradio-examples/python/ofdm/gr_plot_ofdm.py)
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/gr_plot_ofdm.py
(rev 0)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/gr_plot_ofdm.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -0,0 +1,268 @@
+#!/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 3, 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 scipy, pylab, math
+import struct, sys
+from pylab import *
+from matplotlib.font_manager import fontManager, FontProperties
+from optparse import OptionParser
+from scipy import fftpack
+from math import log10
+
+matplotlib.interactive(True)
+matplotlib.use('TkAgg')
+
+class draw_constellation:
+ def __init__(self, options):
+ derot_file = "ofdm_frame_sink_c.dat"
+ acq_file = "ofdm_frame_acq_c.dat"
+ fft_file = "fft_out_c.dat"
+
+ self.h_derot_file = open(derot_file, "r")
+ self.h_acq_file = open(acq_file, "r")
+ self.h_fft_file = open(fft_file, "r")
+
+ self.occ_tones = options.occ_tones
+ self.fft_size = options.fft_size
+ self.symbol = options.start
+ self.sample_rate = options.sample_rate
+
+ self.axis_font_size = 16
+ self.label_font_size = 18
+ self.title_font_size = 20
+ self.text_size = 22
+
+ # Setup PLOT
+ self.fig = figure(1, figsize=(14, 9), facecolor='w')
+ rcParams['xtick.labelsize'] = self.axis_font_size
+ rcParams['ytick.labelsize'] = self.axis_font_size
+
+ self.text_sym = figtext(0.05, 0.95, ("Symbol: %s" % self.symbol),
weight="heavy", size=self.text_size)
+
+ self.make_plots()
+
+ self.button_left_axes = self.fig.add_axes([0.45, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_left = Button(self.button_left_axes, "<")
+ self.button_left_callback =
self.button_left.on_clicked(self.button_left_click)
+
+ self.button_right_axes = self.fig.add_axes([0.50, 0.01, 0.05, 0.05],
frameon=True)
+ self.button_right = Button(self.button_right_axes, ">")
+ self.button_right_callback =
self.button_right.on_clicked(self.button_right_click)
+
+ self.xlim = self.sp_eq.get_xlim()
+
+ self.manager = get_current_fig_manager()
+ #connect('draw_event', self.zoom)
+ connect('key_press_event', self.click)
+ show()
+
+ def get_data(self):
+ self.text_sym.set_text("Symbol: %d" % (self.symbol))
+
+ derot_data = scipy.fromfile(self.h_derot_file, dtype=scipy.complex64,
count=self.occ_tones)
+ acq_data = scipy.fromfile(self.h_acq_file, dtype=scipy.complex64,
count=self.occ_tones)
+ fft_data = scipy.fromfile(self.h_fft_file, dtype=scipy.complex64,
count=self.fft_size)
+ if(len(acq_data) == 0):
+ print "End of File"
+ else:
+ self.acq_data_reals = [r.real for r in acq_data]
+ self.acq_data_imags = [i.imag for i in acq_data]
+ self.derot_data_reals = [r.real for r in derot_data]
+ self.derot_data_imags = [i.imag for i in derot_data]
+
+ self.unequalized_angle = [math.atan2(x.imag, x.real) for x in
fft_data]
+ self.equalized_angle = [math.atan2(x.imag, x.real) for x in
acq_data]
+ self.derot_equalized_angle = [math.atan2(x.imag, x.real) for x in
derot_data]
+
+ self.time = [i*(1/self.sample_rate) for i in range(len(acq_data))]
+ ffttime = [i*(1/self.sample_rate) for i in range(len(fft_data))]
+
+ self.freq = self.get_freq(ffttime, self.sample_rate)
+
+ for i in range(len(fft_data)):
+ if(abs(fft_data[i]) == 0.0):
+ fft_data[i] = complex(1e-6,1e-6)
+ self.fft_data = [20*log10(abs(f)) for f in fft_data]
+
+ def get_freq(self, time, sample_rate, T=1):
+ N = len(time)
+ Fs = 1.0 / (max(time) - min(time))
+ Fn = 0.5 * sample_rate
+ freq = [-Fn + i*Fs for i in range(N)]
+ return freq
+
+ def make_plots(self):
+ self.h_acq_file.seek(8*self.symbol*self.occ_tones, 0)
+ self.h_fft_file.seek(8*self.symbol*self.fft_size, 0)
+ self.h_derot_file.seek(8*self.symbol*self.occ_tones, 0)
+
+ self.get_data()
+
+ # Subplot: constellation of rotated symbols
+ self.sp_const = self.fig.add_subplot(4,1,1, position=[0.15, 0.55, 0.3,
0.35])
+ self.sp_const.set_title(("Constellation"),
fontsize=self.title_font_size, fontweight="bold")
+ self.sp_const.set_xlabel("Inphase", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_const.set_ylabel("Qaudrature", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_const = plot(self.acq_data_reals, self.acq_data_imags, 'bo')
+ self.plot_const += plot(self.derot_data_reals, self.derot_data_imags,
'ro')
+ self.sp_const.axis([-2, 2, -2, 2])
+
+ # Subplot: unequalized angle
+ self.sp_uneq = self.fig.add_subplot(4,2,1, position=[0.575, 0.55, 0.3,
0.35])
+ self.sp_uneq.set_title(("Unequalized Angle"),
fontsize=self.title_font_size, fontweight="bold")
+ self.sp_uneq.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_uneq.set_ylabel("Angle", fontsize=self.label_font_size,
fontweight="bold")
+ uneqscale = range(len(self.unequalized_angle))
+ self.plot_uneq = plot(uneqscale, self.unequalized_angle, 'bo')
+
+ # Subplot: equalized angle
+ self.sp_eq = self.fig.add_subplot(4,1,2, position=[0.15, 0.1, 0.3,
0.35])
+ self.sp_eq.set_title(("Equalized Angle"),
fontsize=self.title_font_size, fontweight="bold")
+ self.sp_eq.set_xlabel("Time (s)", fontsize=self.label_font_size,
fontweight="bold")
+ self.sp_eq.set_ylabel("Angle", fontsize=self.label_font_size,
fontweight="bold")
+ eqscale = range(len(self.equalized_angle))
+ self.plot_eq = plot(eqscale, self.equalized_angle, 'bo')
+ self.plot_eq += plot(eqscale, self.derot_equalized_angle, 'ro',
markersize=4)
+
+ # Subplot: FFT
+ self.sp_fft = self.fig.add_subplot(4,2,2, position=[0.575, 0.1, 0.3,
0.35])
+ self.sp_fft.set_title(("FFT"), fontsize=self.title_font_size,
fontweight="bold")
+ self.sp_fft.set_xlabel("Frequency (MHz)",
fontsize=self.label_font_size, fontweight="bold")
+ self.sp_fft.set_ylabel("Power (dBm)", fontsize=self.label_font_size,
fontweight="bold")
+ self.plot_fft = plot(self.freq, self.fft_data, '-bo')
+
+ draw()
+
+ def update_plots(self):
+ eqscale = range(len(self.equalized_angle))
+ uneqscale = range(len(self.unequalized_angle))
+ self.plot_eq[0].set_data([eqscale, self.equalized_angle])
+ self.plot_eq[1].set_data([eqscale, self.derot_equalized_angle])
+ self.plot_uneq[0].set_data([uneqscale, self.unequalized_angle])
+ self.sp_eq.set_ylim([-4, 4])
+ self.sp_uneq.set_ylim([-4, 4])
+
+ #self.sp_iq.axis([min(self.time), max(self.time),
+ # 1.5*min([min(self.acq_data_reals),
min(self.acq_data_imags)]),
+ # 1.5*max([max(self.acq_data_reals),
max(self.acq_data_imags)])])
+
+ self.plot_const[0].set_data([self.acq_data_reals, self.acq_data_imags])
+ self.plot_const[1].set_data([self.derot_data_reals,
self.derot_data_imags])
+ self.sp_const.axis([-2, 2, -2, 2])
+
+ self.plot_fft[0].set_data([self.freq, self.fft_data])
+
+ draw()
+
+ def zoom(self, event):
+ newxlim = self.sp_eq.get_xlim()
+ if(newxlim != self.xlim):
+ self.xlim = newxlim
+ r = self.reals[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
+ i = self.imags[int(ceil(self.xlim[0])) : int(ceil(self.xlim[1]))]
+
+ self.plot_const[0].set_data(r, i)
+ self.sp_const.axis([-2, 2, -2, 2])
+ self.manager.canvas.draw()
+ draw()
+
+ def click(self, event):
+ forward_valid_keys = [" ", "down", "right"]
+ backward_valid_keys = ["up", "left"]
+
+ if(find(event.key, forward_valid_keys)):
+ self.step_forward()
+
+ elif(find(event.key, backward_valid_keys)):
+ self.step_backward()
+
+ def button_left_click(self, event):
+ self.step_backward()
+
+ def button_right_click(self, event):
+ self.step_forward()
+
+ def step_forward(self):
+ self.symbol += 1
+ self.get_data()
+ self.update_plots()
+
+ def step_backward(self):
+ # Step back in file position
+ self.symbol -= 1
+ if(self.h_acq_file.tell() >= 16*self.occ_tones):
+ self.h_acq_file.seek(-16*self.occ_tones, 1)
+ else:
+ self.symbol = 0
+ self.h_acq_file.seek(-self.h_acq_file.tell(),1)
+
+
+ if(self.h_derot_file.tell() >= 16*self.occ_tones):
+ self.h_derot_file.seek(-16*self.occ_tones, 1)
+ else:
+ self.symbol = 0
+ self.h_derot_file.seek(-self.h_derot_file.tell(),1)
+
+
+ if(self.h_fft_file.tell() >= 16*self.fft_size):
+ self.h_fft_file.seek(-16*self.fft_size, 1)
+ else:
+ self.symbol = 0
+ self.h_fft_file.seek(-self.h_fft_file.tell(),1)
+
+ self.get_data()
+ self.update_plots()
+
+
+
+#FIXME: there must be a way to do this with a Python builtin
+def find(item_in, list_search):
+ for l in list_search:
+ if item_in == l:
+ return True
+ return False
+
+def main():
+ usage="%prog: [options]"
+
+ parser = OptionParser(conflict_handler="resolve", usage=usage)
+ parser.add_option("", "--fft-size", type="int", default=512,
+ help="Specify the size of the FFT [default=%default]")
+ parser.add_option("", "--occ-tones", type="int", default=200,
+ help="Specify the number of occupied tones
[default=%default]")
+ parser.add_option("-s", "--start", type="int", default=0,
+ help="Specify the starting symbol to plot
[default=%default]")
+ parser.add_option("-R", "--sample-rate", type="float", default=1.0,
+ help="Set the sampler rate of the data
[default=%default]")
+
+ (options, args) = parser.parse_args ()
+
+ dc = draw_constellation(options)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
+
+
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m 2008-01-02
17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/plot_ofdm.m 2008-01-02
17:35:35 UTC (rev 7324)
@@ -1,13 +1,22 @@
function plot_ofdm(fft_size, occ_tones)
-ofdm = read_complex_binary('ofdm_corr_out_c.dat');
+ofdm = read_complex_binary('ofdm_frame_acq_c.dat');
ofdm_split = split_vect(ofdm, occ_tones);
+ofdm_derot = read_complex_binary('ofdm_frame_sink_c.dat');
+ofdm_derot_split = split_vect(ofdm_derot, occ_tones);
+
fftc = read_complex_binary('fft_out_c.dat');
fftc_split = split_vect(fftc, fft_size);
+size(ofdm_split)
+size(ofdm_derot_split)
+disp "DEROTATED SPLIT"
+ofdm_derot(1:100)
+
+
figure(1)
-set(gcf, 'Position', [50 50 1000 600]);
+#set(gcf, 'Position', [50 50 1000 600]);
a = size(ofdm_split);
if nargin == 3
@@ -19,47 +28,47 @@
maxcount = a(1);
end
-for i = 1:20000
+for i = 1:size(ofdm_split)[0]
x = ofdm_split(i,:);
y = fftc_split(i+1,:);
- subplot(2,2,1)
- plot(real(x), imag(x), 'bo')
- set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+ subplot(2,2,1);
+ plot(real(x), imag(x), 'bo');
+ #set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
axis([-1.5, 1.5, -1.5, 1.5])
- title('I&Q Constellation', 'FontSize', 36);
- xlabel('Inphase', 'FontSize', 32);
- ylabel('Quadrature', 'FontSize', 32);
+ #title('I&Q Constellation', 'FontSize', 36);
+ #xlabel('Inphase', 'FontSize', 32);
+ #ylabel('Quadrature', 'FontSize', 32);
- subplot(2,2,3)
- plot(angle(x*j), 'bo')
- set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+ subplot(2,2,3);
+ plot(angle(x*j), 'bo');
+ #set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
axis([0, occ_tones, -3.5, 3.5])
- title('Equalized Symbol Angle', 'FontSize', 36);
- xlabel('Bin Number (Occ. Tones)', 'FontSize', 32);
- ylabel('Symbol Angle', 'FontSize', 32);
+ #title('Equalized Symbol Angle', 'FontSize', 36);
+ #xlabel('Bin Number (Occ. Tones)', 'FontSize', 32);
+ #ylabel('Symbol Angle', 'FontSize', 32);
- subplot(2,2,2)
- plot(angle(y*j), 'bo')
- set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+ subplot(2,2,2);
+ plot(angle(y*j), 'bo');
+ #set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
axis([0, fft_size, -3.5, 3.5])
- title('Unequalized Symbol Angle', 'FontSize', 36);
- xlabel('Bin Number (FFT Size)', 'FontSize', 32);
- ylabel('Symbol Angle', 'FontSize', 32);
+ #title('Unequalized Symbol Angle', 'FontSize', 36);
+ #xlabel('Bin Number (FFT Size)', 'FontSize', 32);
+ #ylabel('Symbol Angle', 'FontSize', 32);
Y = 20*log10(abs(y) ./ max(abs(y)));
- subplot(2,2,4)
- plot(Y, 'b-')
- set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
+ subplot(2,2,4);
+ plot(Y, 'b-');
+ #set(gca, 'FontSize', 30, 'FontWeight', 'Bold');
axis([0, fft_size, -50, 1]);
- title('Frequency Domain of Unequalized Rx', 'FontSize', 36);
- xlabel('Bin Number (FFT Size)', 'FontSize', 32);
- ylabel('Power (dB)', 'FontSize', 32);
+ #title('Frequency Domain of Unequalized Rx', 'FontSize', 36);
+ #xlabel('Bin Number (FFT Size)', 'FontSize', 32);
+ #ylabel('Power (dB)', 'FontSize', 32);
- % N = 20*log10(var(abs(x)-1))
+ #N = 20*log10(var(abs(x)-1));
disp(sprintf('Symbol Number: %d\n', i))
-% disp(sprintf('\tFreq Error: %f\n', anglesh_pn(1+(i-1)*fft_size)))
+ #disp(sprintf('\tFreq Error: %f\n', anglesh_pn(1+(i-1)*fft_size)))
pause
end
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/receive_path.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -20,7 +20,7 @@
# Boston, MA 02110-1301, USA.
#
-from gnuradio import gr, gru, blks
+from gnuradio import gr, gru, blks2
from gnuradio import usrp
from gnuradio import eng_notation
import copy
@@ -33,9 +33,14 @@
# receive path
# /////////////////////////////////////////////////////////////////////////////
-class receive_path(gr.hier_block):
- def __init__(self, fg, rx_callback, options):
+class receive_path(gr.hier_block2):
+ def __init__(self, rx_callback, options):
+ gr.hier_block2.__init__(self, "receive_path",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), #
Input signature
+ gr.io_signature(0, 0, 0)) # Output signature
+
+
options = copy.copy(options) # make a copy so we can destructively
modify
self._verbose = options.verbose
@@ -44,20 +49,20 @@
# receiver
self.ofdm_rx = \
- blks.ofdm_demod(fg, options, callback=self._rx_callback)
+ blks2.ofdm_demod(options, callback=self._rx_callback)
# Carrier Sensing Blocks
alpha = 0.001
thresh = 30 # in dB, will have to adjust
self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
- fg.connect(self.ofdm_rx.ofdm_recv.chan_filt, self.probe)
+ self.connect(self, self.ofdm_rx)
+ self.connect(self.ofdm_rx, self.probe)
+
# Display some information about the setup
if self._verbose:
self._print_verbage()
- gr.hier_block.__init__(self, fg, self.ofdm_rx, None)
-
def carrier_sensed(self):
"""
Return True if we think carrier is present.
Modified: gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
2008-01-02 17:04:44 UTC (rev 7323)
+++ gnuradio/trunk/gnuradio-examples/python/ofdm/transmit_path.py
2008-01-02 17:35:35 UTC (rev 7324)
@@ -19,7 +19,7 @@
# Boston, MA 02110-1301, USA.
#
-from gnuradio import gr, gru, blks
+from gnuradio import gr, gru, blks2
from gnuradio import usrp
from gnuradio import eng_notation
@@ -30,19 +30,23 @@
# transmit path
# /////////////////////////////////////////////////////////////////////////////
-class transmit_path(gr.hier_block):
- def __init__(self, fg, options):
+class transmit_path(gr.hier_block2):
+ def __init__(self, options):
'''
See below for what options should hold
'''
+ gr.hier_block2.__init__(self, "transmit_path",
+ gr.io_signature(0, 0, 0), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) #
Output signature
+
options = copy.copy(options) # make a copy so we can destructively
modify
- self._verbose = options.verbose
+ self._verbose = options.verbose # turn verbose mode on/off
self._tx_amplitude = options.tx_amplitude # digital amplitude sent
to USRP
self.ofdm_tx = \
- blks.ofdm_mod(fg, options, msgq_limit=4,
pad_for_usrp=False)
+ blks2.ofdm_mod(options, msgq_limit=4, pad_for_usrp=False)
self.amp = gr.multiply_const_cc(1)
self.set_tx_amplitude(self._tx_amplitude)
@@ -52,8 +56,7 @@
self._print_verbage()
# Create and setup transmit path flow graph
- fg.connect(self.ofdm_tx, self.amp)
- gr.hier_block.__init__(self, fg, None, self.amp)
+ self.connect(self.ofdm_tx, self.amp, self)
def set_tx_amplitude(self, ampl):
"""
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7324 - in gnuradio/trunk: . gnuradio-core/src/lib/general gnuradio-core/src/python/gnuradio/blks2impl gnuradio-core/src/python/gnuradio/blksimpl gnuradio-core/src/utils gnuradio-examples/python/ofdm,
trondeau <=