summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--docs/doxygen/other/perf_counters.dox19
-rw-r--r--gnuradio-runtime/include/gnuradio/block.h5
-rw-r--r--gnuradio-runtime/include/gnuradio/block_detail.h3
-rw-r--r--gnuradio-runtime/lib/block.cc18
-rw-r--r--gnuradio-runtime/lib/block_detail.cc8
-rw-r--r--gnuradio-runtime/swig/block.i1
-rw-r--r--gnuradio-runtime/swig/gnuradio.i2
-rw-r--r--gr-analog/grc/analog_agc3_xx.xml8
-rw-r--r--gr-analog/include/gnuradio/analog/agc3_cc.h4
-rw-r--r--gr-analog/lib/agc3_cc_impl.cc65
-rw-r--r--gr-analog/lib/agc3_cc_impl.h3
-rw-r--r--gr-blocks/grc/blocks_block_tree.xml1
-rw-r--r--gr-blocks/grc/blocks_file_sink.xml16
-rw-r--r--gr-blocks/grc/blocks_stream_to_tagged_stream.xml64
-rw-r--r--gr-blocks/include/gnuradio/blocks/CMakeLists.txt3
-rw-r--r--gr-blocks/include/gnuradio/blocks/file_sink.h4
-rw-r--r--gr-blocks/include/gnuradio/blocks/file_sink_base.h3
-rw-r--r--gr-blocks/include/gnuradio/blocks/stream_to_tagged_stream.h62
-rw-r--r--gr-blocks/lib/CMakeLists.txt5
-rw-r--r--gr-blocks/lib/file_sink_base.cc14
-rw-r--r--gr-blocks/lib/file_sink_impl.cc8
-rw-r--r--gr-blocks/lib/file_sink_impl.h2
-rw-r--r--gr-blocks/lib/stream_to_tagged_stream_impl.cc74
-rw-r--r--gr-blocks/lib/stream_to_tagged_stream_impl.h53
-rwxr-xr-xgr-blocks/python/blocks/qa_stream_to_tagged_stream.py53
-rw-r--r--gr-blocks/swig/blocks_swig1.i3
-rw-r--r--gr-channels/grc/channels_channel_model.xml18
-rw-r--r--gr-channels/grc/channels_channel_model2.xml18
-rw-r--r--gr-channels/include/gnuradio/channels/channel_model.h9
-rw-r--r--gr-channels/include/gnuradio/channels/channel_model2.h4
-rw-r--r--gr-channels/lib/channel_model2_impl.cc13
-rw-r--r--gr-channels/lib/channel_model2_impl.h3
-rw-r--r--gr-channels/lib/channel_model_impl.cc14
-rw-r--r--gr-channels/lib/channel_model_impl.h3
-rw-r--r--gr-digital/doc/digital.dox457
-rw-r--r--gr-digital/examples/ofdm/ofdm_loopback.grc630
-rw-r--r--gr-digital/examples/ofdm/rx_ofdm.grc1329
-rw-r--r--gr-digital/examples/ofdm/tx_ofdm.grc1369
-rw-r--r--gr-digital/grc/digital_block_tree.xml4
-rw-r--r--gr-digital/grc/digital_constellation.xml (renamed from grc/blocks/variable_constellation.xml)22
-rw-r--r--gr-digital/grc/digital_constellation_modulator.xml111
-rw-r--r--gr-digital/grc/digital_constellation_rect.xml (renamed from grc/blocks/variable_constellation_rect.xml)22
-rw-r--r--gr-digital/grc/digital_constellation_soft_decoder_cf.xml25
-rw-r--r--gr-digital/grc/digital_ofdm_rx.xml18
-rw-r--r--gr-digital/grc/digital_ofdm_tx.xml18
-rw-r--r--gr-digital/include/gnuradio/digital/CMakeLists.txt3
-rw-r--r--gr-digital/include/gnuradio/digital/additive_scrambler_bb.h19
-rw-r--r--gr-digital/include/gnuradio/digital/constellation.h91
-rw-r--r--gr-digital/include/gnuradio/digital/constellation_soft_decoder_cf.h62
-rw-r--r--gr-digital/include/gnuradio/digital/packet_header_default.h11
-rw-r--r--gr-digital/include/gnuradio/digital/packet_header_ofdm.h26
-rw-r--r--gr-digital/lib/CMakeLists.txt1
-rw-r--r--gr-digital/lib/additive_scrambler_bb_impl.cc61
-rw-r--r--gr-digital/lib/additive_scrambler_bb_impl.h14
-rw-r--r--gr-digital/lib/constellation.cc153
-rw-r--r--gr-digital/lib/constellation_soft_decoder_cf_impl.cc78
-rw-r--r--gr-digital/lib/constellation_soft_decoder_cf_impl.h50
-rw-r--r--gr-digital/lib/packet_header_default.cc34
-rw-r--r--gr-digital/lib/packet_header_ofdm.cc40
-rw-r--r--gr-digital/python/digital/CMakeLists.txt6
-rw-r--r--gr-digital/python/digital/__init__.py6
-rw-r--r--gr-digital/python/digital/constellation_map_generator.py52
-rw-r--r--gr-digital/python/digital/ofdm_txrx.py99
-rw-r--r--gr-digital/python/digital/packet_utils.py10
-rw-r--r--gr-digital/python/digital/pkt.py11
-rwxr-xr-xgr-digital/python/digital/psk_constellations.py308
-rw-r--r--gr-digital/python/digital/qa_constellation.py82
-rw-r--r--gr-digital/python/digital/qa_constellation_soft_decoder_cf.py112
-rwxr-xr-xgr-digital/python/digital/qa_ofdm_txrx.py30
-rwxr-xr-xgr-digital/python/digital/qa_packet_headergenerator_bb.py8
-rwxr-xr-xgr-digital/python/digital/qa_packet_headerparser_b.py50
-rwxr-xr-xgr-digital/python/digital/qa_scrambler.py38
-rwxr-xr-xgr-digital/python/digital/qam_constellations.py521
-rw-r--r--gr-digital/python/digital/soft_dec_lut_gen.py232
-rwxr-xr-xgr-digital/python/digital/test_soft_decisions.py135
-rw-r--r--gr-digital/swig/digital_swig.i3
-rwxr-xr-xgr-uhd/apps/uhd_fft8
-rwxr-xr-xgr-uhd/apps/uhd_rx_cfile16
-rw-r--r--gr-uhd/apps/uhd_siggen_base.py8
-rw-r--r--gr-uhd/swig/uhd_swig.i5
-rw-r--r--gr-utils/python/modtool/gr-newmod/CMakeLists.txt7
-rw-r--r--gr-utils/python/modtool/gr-newmod/cmake/Modules/howtoConfig.cmake30
-rw-r--r--gr-utils/python/modtool/gr-newmod/examples/README4
-rw-r--r--gr-utils/python/modtool/modtool_add.py1
-rw-r--r--gr-utils/python/modtool/modtool_base.py1
-rw-r--r--grc/base/Block.py1
-rw-r--r--grc/base/Platform.py12
-rw-r--r--grc/blocks/blks2_packet_encoder.xml9
-rw-r--r--grc/grc_gnuradio/blks2/packet.py8
-rw-r--r--grc/gui/ActionHandler.py8
-rw-r--r--grc/gui/Actions.py7
-rw-r--r--grc/gui/Bars.py2
-rw-r--r--grc/gui/BlockTreeWindow.py173
-rw-r--r--grc/gui/DrawingArea.py17
-rw-r--r--grc/gui/MainWindow.py2
-rw-r--r--volk/kernels/volk/volk_32f_invsqrt_32f.h77
97 files changed, 5250 insertions, 2084 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5a561723b0..356ef0d4eb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,8 +41,8 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Set the version information here
set(VERSION_INFO_MAJOR_VERSION 3)
set(VERSION_INFO_API_COMPAT 7)
-set(VERSION_INFO_MINOR_VERSION 1)
-set(VERSION_INFO_MAINT_VERSION 0)
+set(VERSION_INFO_MINOR_VERSION 2)
+set(VERSION_INFO_MAINT_VERSION git)
include(GrVersion) #setup version info
# Append -O2 optimization flag for Debug builds
diff --git a/docs/doxygen/other/perf_counters.dox b/docs/doxygen/other/perf_counters.dox
index 518b04e780..c09f17c029 100644
--- a/docs/doxygen/other/perf_counters.dox
+++ b/docs/doxygen/other/perf_counters.dox
@@ -5,7 +5,7 @@
Each block can have a set of Performance Counters that the schedule
keeps track of. These counters measure and store information about
different performance metrics of their operation. The concept is
-fairly extensible, but currently, GNU Radio defines five types of
+fairly extensible, but currently, GNU Radio defines the following
Performance Counters:
\li noutput_items: number of items the block can produce.
@@ -13,20 +13,21 @@ Performance Counters:
\li input_buffers_full: % of how full each input buffer is.
\li output_buffers_full: % of how full each output buffer is.
\li work_time: number of CPU ticks during the call to general_work().
+\li work_time_total: Accumulated sum of work_time.
-For each Performance Counter, we can retrieve the instantaneous,
-average, and variance from the block. Access to these counters is done
-through a simple set of functions added to every block in the
-flowgraph:
+For each Performance Counter except the work_time_total, we can
+retrieve the instantaneous, average, and variance from the
+block. Access to these counters is done through a simple set of
+functions added to every block in the flowgraph:
\code
float pc_<name>[_<type>]();
\endcode
-In the above, the \<name\> field is one of the five counters in the
-above list of counters. The optional \<type\> suffix is either 'avg' to
-get the average value or 'var' to get the variance. Without a suffix,
-the function returns the most recent instantaneous value.
+In the above, the \<name\> field is one of the counters in the above
+list of counters. The optional \<type\> suffix is either 'avg' to get
+the average value or 'var' to get the variance. Without a suffix, the
+function returns the most recent instantaneous value.
We can also reset the Performance Counters back to zero to remove any
history of the current average and variance calculations for a
diff --git a/gnuradio-runtime/include/gnuradio/block.h b/gnuradio-runtime/include/gnuradio/block.h
index b8cbcfc552..5cd5dbb4a4 100644
--- a/gnuradio-runtime/include/gnuradio/block.h
+++ b/gnuradio-runtime/include/gnuradio/block.h
@@ -461,6 +461,11 @@ namespace gr {
float pc_work_time_var();
/*!
+ * \brief Gets total clock cycles spent in work.
+ */
+ float pc_work_time_total();
+
+ /*!
* \brief Resets the performance counters
*/
void reset_perf_counters();
diff --git a/gnuradio-runtime/include/gnuradio/block_detail.h b/gnuradio-runtime/include/gnuradio/block_detail.h
index b7531baf6d..b336cb86f7 100644
--- a/gnuradio-runtime/include/gnuradio/block_detail.h
+++ b/gnuradio-runtime/include/gnuradio/block_detail.h
@@ -227,6 +227,8 @@ namespace gr {
float pc_output_buffers_full_var(size_t which);
std::vector<float> pc_output_buffers_full_var();
float pc_work_time_var();
+
+ float pc_work_time_total();
tpb_detail d_tpb; // used by thread-per-block scheduler
int d_produce_or;
@@ -257,6 +259,7 @@ namespace gr {
float d_ins_work_time;
float d_avg_work_time;
float d_var_work_time;
+ float d_total_work_time;
float d_pc_counter;
block_detail(unsigned int ninputs, unsigned int noutputs);
diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc
index 7a55e09561..e76daefe48 100644
--- a/gnuradio-runtime/lib/block.cc
+++ b/gnuradio-runtime/lib/block.cc
@@ -635,6 +635,17 @@ namespace gr {
}
}
+ float
+ block::pc_work_time_total()
+ {
+ if(d_detail) {
+ return d_detail->pc_work_time_total();
+ }
+ else {
+ return 0;
+ }
+ }
+
void
block::reset_perf_counters()
{
@@ -712,6 +723,13 @@ namespace gr {
DISPTIME | DISPOPTSTRIP)));
d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "total work time", &block::pc_work_time_total,
+ pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
+ "", "Total clock cycles in calls to work", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
alias(), "input \% full", &block::pc_input_buffers_full,
pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
diff --git a/gnuradio-runtime/lib/block_detail.cc b/gnuradio-runtime/lib/block_detail.cc
index fd1240ae56..1020916ec2 100644
--- a/gnuradio-runtime/lib/block_detail.cc
+++ b/gnuradio-runtime/lib/block_detail.cc
@@ -272,6 +272,7 @@ namespace gr {
d_ins_work_time = diff;
d_avg_work_time = diff;
d_var_work_time = 0;
+ d_total_work_time = diff;
d_ins_nproduced = nproduced;
d_avg_nproduced = nproduced;
d_var_nproduced = 0;
@@ -300,6 +301,7 @@ namespace gr {
d_ins_work_time = diff;
d_avg_work_time = d_avg_work_time + d/d_pc_counter;
d_var_work_time = d_var_work_time + d*d;
+ d_total_work_time += diff;
d = nproduced - d_avg_nproduced;
d_ins_nproduced = nproduced;
@@ -493,4 +495,10 @@ namespace gr {
return d_var_work_time/(d_pc_counter-1);
}
+ float
+ block_detail::pc_work_time_total()
+ {
+ return d_total_work_time;
+ }
+
} /* namespace gr */
diff --git a/gnuradio-runtime/swig/block.i b/gnuradio-runtime/swig/block.i
index 7b7ac8ee43..1f9b70ce0c 100644
--- a/gnuradio-runtime/swig/block.i
+++ b/gnuradio-runtime/swig/block.i
@@ -89,6 +89,7 @@ class gr::block : public gr::basic_block
float pc_work_time();
float pc_work_time_avg();
float pc_work_time_var();
+ float pc_work_time_total();
// Methods to manage processor affinity.
void set_processor_affinity(const std::vector<int> &mask);
diff --git a/gnuradio-runtime/swig/gnuradio.i b/gnuradio-runtime/swig/gnuradio.i
index 0789d1ad82..c756ce9189 100644
--- a/gnuradio-runtime/swig/gnuradio.i
+++ b/gnuradio-runtime/swig/gnuradio.i
@@ -72,5 +72,7 @@
#include <gnuradio/block_gateway.h>
#include <gnuradio/feval.h>
#include <gnuradio/py_feval.h>
+#include <gnuradio/high_res_timer.h>
%}
+%include <gnuradio/high_res_timer.h>
diff --git a/gr-analog/grc/analog_agc3_xx.xml b/gr-analog/grc/analog_agc3_xx.xml
index 5ad4d7829a..1e6b9fd382 100644
--- a/gr-analog/grc/analog_agc3_xx.xml
+++ b/gr-analog/grc/analog_agc3_xx.xml
@@ -8,7 +8,7 @@
<name>AGC3</name>
<key>analog_agc3_xx</key>
<import>from gnuradio import analog</import>
- <make>analog.agc3_$(type.fcn)($attack_rate, $decay_rate, $reference, $gain)
+ <make>analog.agc3_$(type.fcn)($attack_rate, $decay_rate, $reference, $gain, $iir_update_decim)
self.$(id).set_max_gain($max_gain)</make>
<callback>set_attack_rate($attack_rate)</callback>
<callback>set_decay_rate($decay_rate)</callback>
@@ -60,6 +60,12 @@ self.$(id).set_max_gain($max_gain)</make>
<value>65536</value>
<type>real</type>
</param>
+ <param>
+ <name>IIR Update Decimation</name>
+ <key>iir_update_decim</key>
+ <value>1</value>
+ <type>real</type>
+ </param>
<sink>
<name>in</name>
<type>$type</type>
diff --git a/gr-analog/include/gnuradio/analog/agc3_cc.h b/gr-analog/include/gnuradio/analog/agc3_cc.h
index 9cd6e60e1e..eb542eae08 100644
--- a/gr-analog/include/gnuradio/analog/agc3_cc.h
+++ b/gr-analog/include/gnuradio/analog/agc3_cc.h
@@ -54,9 +54,11 @@ namespace gr {
* \param decay_rate the update rate of the loop when in decay mode.
* \param reference reference value to adjust signal power to.
* \param gain initial gain value.
+ * \param iir_update_decim stride by this number of samples before
+ * computing an IIR gain update
*/
static sptr make(float attack_rate = 1e-1, float decay_rate = 1e-2,
- float reference = 1.0, float gain = 1.0);
+ float reference = 1.0, float gain = 1.0, int iir_update_decim=1);
virtual float attack_rate() const = 0;
virtual float decay_rate() const = 0;
diff --git a/gr-analog/lib/agc3_cc_impl.cc b/gr-analog/lib/agc3_cc_impl.cc
index b8f1104c45..86e2212927 100644
--- a/gr-analog/lib/agc3_cc_impl.cc
+++ b/gr-analog/lib/agc3_cc_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2010,2012 Free Software Foundation, Inc.
+ * Copyright 2006,2010,2012,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,6 +24,7 @@
#include "config.h"
#endif
+#include <float.h>
#include <vector>
#include "agc3_cc_impl.h"
@@ -35,22 +36,23 @@ namespace gr {
agc3_cc::sptr
agc3_cc::make(float attack_rate, float decay_rate,
- float reference, float gain)
+ float reference, float gain, int iir_update_decim)
{
return gnuradio::get_initial_sptr
(new agc3_cc_impl(attack_rate, decay_rate,
- reference, gain));
+ reference, gain, iir_update_decim));
}
agc3_cc_impl::agc3_cc_impl(float attack_rate, float decay_rate,
- float reference, float gain)
+ float reference, float gain, int iir_update_decim)
: sync_block("agc3_cc",
io_signature::make(1, 1, sizeof(gr_complex)),
io_signature::make(1, 1, sizeof(gr_complex))),
d_attack(attack_rate), d_decay(decay_rate),
d_reference(reference), d_gain(gain), d_max_gain(65536),
- d_reset(true)
+ d_reset(true), d_iir_update_decim(iir_update_decim)
{
+ set_output_multiple(iir_update_decim*4);
const int alignment_multiple =
volk_get_alignment() / sizeof(gr_complex);
set_alignment(std::max(1, alignment_multiple));
@@ -60,6 +62,7 @@ namespace gr {
{
}
+
int
agc3_cc_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
@@ -67,17 +70,17 @@ namespace gr {
{
const gr_complex *in = (const gr_complex*)input_items[0];
gr_complex *out = (gr_complex*)output_items[0];
- // Compute magnitude of each sample
+
#ifdef __GNUC__
+ // Compute a linear average on reset (no expected)
+ if(__builtin_expect(d_reset, false)) {
float mags[noutput_items] __attribute__ ((aligned (16)));
volk_32fc_magnitude_32f(mags, &in[0], noutput_items);
- // Compute a linear average on reset (no expected)
- if(__builtin_expect(d_reset, false)) {
#else
- std::vector<float> mags(noutput_items);
- volk_32fc_magnitude_32f(&mags[0], &in[0], noutput_items);
- // Compute a linear average on reset (no expected)
+ // Compute a linear average on reset (no expected)
if(!d_reset) {
+ std::vector<float> mags(noutput_items);
+ volk_32fc_magnitude_32f(&mags[0], &in[0], noutput_items);
#endif
float mag(0.0);
for(int i=0; i<noutput_items; i++) {
@@ -100,13 +103,41 @@ namespace gr {
}
else {
// Otherwise perform a normal iir update
- for(int i=0; i<noutput_items; i++) {
- float newlevel = mags[i]; // abs(in[i]);
- float rate = (newlevel > d_reference/d_gain)?d_attack:d_decay;
- d_gain = newlevel==0?(d_gain*(1-rate)):(d_gain*(1-rate)) + (d_reference/newlevel)*rate;
- out[i] = in[i] * d_gain;
+#ifdef _MSC_VER
+ std::vector<float> mag_sq(noutput_items/d_iir_update_decim);
+ std::vector<float> inv_mag(noutput_items/d_iir_update_decim);
+#else
+ float mag_sq[noutput_items/d_iir_update_decim] __attribute__ ((aligned (16)));
+ float inv_mag[noutput_items/d_iir_update_decim] __attribute__ ((aligned (16)));
+#endif
+
+ // generate squared magnitudes at decimated rate (gather operation)
+ for(int i=0; i<noutput_items/d_iir_update_decim; i++){
+ int idx = i*d_iir_update_decim;
+ mag_sq[i] = in[idx].real()*in[idx].real() + in[idx].imag()*in[idx].imag();
}
- }
+
+ // compute inverse square roots
+ volk_32f_invsqrt_32f_a(&inv_mag[0], &mag_sq[0], noutput_items/d_iir_update_decim);
+
+ // apply updates
+ for(int i=0; i<noutput_items/d_iir_update_decim; i++){
+ float magi = inv_mag[i];
+#ifdef _MSC_VER
+ if(!_finite(magi)){
+#else
+ if(std::isfinite(magi)){
+#endif
+ float rate = (magi > d_gain/d_reference)?d_decay:d_attack;
+ d_gain = d_gain*(1-rate) + d_reference*magi*rate;
+ } else {
+ d_gain = d_gain*(1-d_decay);
+ }
+ for(int j=i*d_iir_update_decim; j<(i+1)*d_iir_update_decim; j++){
+ out[j] = in[j] * d_gain;
+ }
+ }
+ }
return noutput_items;
}
diff --git a/gr-analog/lib/agc3_cc_impl.h b/gr-analog/lib/agc3_cc_impl.h
index 77cc1978c5..a239370972 100644
--- a/gr-analog/lib/agc3_cc_impl.h
+++ b/gr-analog/lib/agc3_cc_impl.h
@@ -32,7 +32,7 @@ namespace gr {
{
public:
agc3_cc_impl(float attack_rate = 1e-1, float decay_rate = 1e-2,
- float reference = 1.0, float gain = 1.0);
+ float reference = 1.0, float gain = 1.0, int iir_update_decim=1);
~agc3_cc_impl();
float attack_rate() const { return d_attack; }
@@ -58,6 +58,7 @@ namespace gr {
float d_gain;
float d_max_gain;
bool d_reset;
+ int d_iir_update_decim;
};
} /* namespace analog */
diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml
index c6c797f52a..18e6a05213 100644
--- a/gr-blocks/grc/blocks_block_tree.xml
+++ b/gr-blocks/grc/blocks_block_tree.xml
@@ -183,6 +183,7 @@
<block>blocks_tag_gate</block>
<block>blocks_tagged_file_sink</block>
<block>blocks_tagged_stream_mux</block>
+ <block>blocks_stream_to_tagged_stream</block>
</cat>
<cat>
<name>Type Converters</name>
diff --git a/gr-blocks/grc/blocks_file_sink.xml b/gr-blocks/grc/blocks_file_sink.xml
index 75ef86a6b8..ece21fd2ae 100644
--- a/gr-blocks/grc/blocks_file_sink.xml
+++ b/gr-blocks/grc/blocks_file_sink.xml
@@ -8,7 +8,7 @@
<name>File Sink</name>
<key>blocks_file_sink</key>
<import>from gnuradio import blocks</import>
- <make>blocks.file_sink($type.size*$vlen, $file)
+ <make>blocks.file_sink($type.size*$vlen, $file, $append)
self.$(id).set_unbuffered($unbuffered)</make>
<callback>set_unbuffered($unbuffered)</callback>
<callback>open($file)</callback>
@@ -68,6 +68,20 @@ self.$(id).set_unbuffered($unbuffered)</make>
<key>True</key>
</option>
</param>
+ <param>
+ <name>Append file</name>
+ <key>append</key>
+ <value>False</value>
+ <type>bool</type>
+ <option>
+ <name>Append</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Overwrite</name>
+ <key>False</key>
+ </option>
+ </param>
<check>$vlen &gt; 0</check>
<sink>
diff --git a/gr-blocks/grc/blocks_stream_to_tagged_stream.xml b/gr-blocks/grc/blocks_stream_to_tagged_stream.xml
new file mode 100644
index 0000000000..cf35e7554c
--- /dev/null
+++ b/gr-blocks/grc/blocks_stream_to_tagged_stream.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<block>
+ <name>Stream to Tagged Stream</name>
+ <key>blocks_stream_to_tagged_stream</key>
+ <import>from gnuradio import blocks</import>
+ <make>blocks.stream_to_tagged_stream($type.size, $vlen, $packet_len, $len_tag_key)</make>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>size:gr.sizeof_gr_complex</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>size:gr.sizeof_float</opt>
+ </option>
+ <option>
+ <name>Int</name>
+ <key>int</key>
+ <opt>size:gr.sizeof_int</opt>
+ </option>
+ <option>
+ <name>Short</name>
+ <key>short</key>
+ <opt>size:gr.sizeof_short</opt>
+ </option>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>size:gr.sizeof_char</opt>
+ </option>
+ </param>
+ <param>
+ <name>Vector Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Packet Length</name>
+ <key>packet_len</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Length Tag Key</name>
+ <key>len_tag_key</key>
+ <value>"packet_len"</value>
+ <type>string</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ </source>
+</block>
diff --git a/gr-blocks/include/gnuradio/blocks/CMakeLists.txt b/gr-blocks/include/gnuradio/blocks/CMakeLists.txt
index de52e3e3e7..83338b771d 100644
--- a/gr-blocks/include/gnuradio/blocks/CMakeLists.txt
+++ b/gr-blocks/include/gnuradio/blocks/CMakeLists.txt
@@ -173,7 +173,7 @@ install(FILES
plateau_detector_fb.h
probe_rate.h
regenerate_bb.h
- repack_bits_bb.h
+ repack_bits_bb.h
repeat.h
rms_cf.h
rms_ff.h
@@ -183,6 +183,7 @@ install(FILES
socket_pdu.h
stream_mux.h
stream_to_streams.h
+ stream_to_tagged_stream.h
stream_to_vector.h
streams_to_stream.h
streams_to_vector.h
diff --git a/gr-blocks/include/gnuradio/blocks/file_sink.h b/gr-blocks/include/gnuradio/blocks/file_sink.h
index c1041683d3..177964682d 100644
--- a/gr-blocks/include/gnuradio/blocks/file_sink.h
+++ b/gr-blocks/include/gnuradio/blocks/file_sink.h
@@ -45,8 +45,10 @@ namespace gr {
* \brief Make a file sink.
* \param itemsize size of the input data items.
* \param filename name of the file to open and write output to.
+ * \param append if true, data is appended to the file instead of
+ * overwriting the initial content.
*/
- static sptr make(size_t itemsize, const char *filename);
+ static sptr make(size_t itemsize, const char *filename, bool append=false);
};
} /* namespace blocks */
diff --git a/gr-blocks/include/gnuradio/blocks/file_sink_base.h b/gr-blocks/include/gnuradio/blocks/file_sink_base.h
index 812da6dfae..253b5ea122 100644
--- a/gr-blocks/include/gnuradio/blocks/file_sink_base.h
+++ b/gr-blocks/include/gnuradio/blocks/file_sink_base.h
@@ -42,9 +42,10 @@ namespace gr {
bool d_is_binary;
boost::mutex d_mutex;
bool d_unbuffered;
+ bool d_append;
protected:
- file_sink_base(const char *filename, bool is_binary);
+ file_sink_base(const char *filename, bool is_binary, bool append);
public:
file_sink_base() {}
diff --git a/gr-blocks/include/gnuradio/blocks/stream_to_tagged_stream.h b/gr-blocks/include/gnuradio/blocks/stream_to_tagged_stream.h
new file mode 100644
index 0000000000..ccc85240c1
--- /dev/null
+++ b/gr-blocks/include/gnuradio/blocks/stream_to_tagged_stream.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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_BLOCKS_STREAM_TO_TAGGED_STREAM_H
+#define INCLUDED_BLOCKS_STREAM_TO_TAGGED_STREAM_H
+
+#include <gnuradio/blocks/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace blocks {
+
+ /*!
+ * \brief Converts a regular stream into a tagged stream.
+ * \ingroup blocks
+ *
+ * All this block does is add length tags in regular intervals.
+ * It can be used to connect a regular stream to a gr::tagged_stream_block.
+ */
+ class BLOCKS_API stream_to_tagged_stream : virtual public gr::sync_block
+ {
+ public:
+ typedef boost::shared_ptr<stream_to_tagged_stream> sptr;
+
+ /*!
+ * \param itemsize Item size
+ * \param vlen Vector length of the input items. Note that one vector is one item.
+ * \param packet_len Number of items per tagged stream packet. One tag is written every \p packet_len items.
+ * \param len_tag_key Key of the length tag.
+ */
+ static sptr make(
+ size_t itemsize,
+ int vlen,
+ unsigned packet_len,
+ const std::string &len_tag_key
+ );
+ };
+
+ } // namespace blocks
+} // namespace gr
+
+#endif /* INCLUDED_BLOCKS_STREAM_TO_TAGGED_STREAM_H */
+
diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt
index 1c7bd80ae0..6eded4a273 100644
--- a/gr-blocks/lib/CMakeLists.txt
+++ b/gr-blocks/lib/CMakeLists.txt
@@ -225,6 +225,7 @@ list(APPEND gr_blocks_sources
stream_mux_impl.cc
stream_pdu_base.cc
stream_to_streams_impl.cc
+ stream_to_tagged_stream_impl.cc
stream_to_vector_impl.cc
streams_to_stream_impl.cc
streams_to_vector_impl.cc
@@ -237,6 +238,7 @@ list(APPEND gr_blocks_sources
transcendental_impl.cc
tcp_connection.cc
tuntap_pdu_impl.cc
+ tag_gate_impl.cc
tagged_stream_mux_impl.cc
uchar_array_to_float.cc
uchar_to_float_impl.cc
@@ -285,8 +287,7 @@ list(APPEND blocks_libs
${LOG4CPP_LIBRARIES}
)
-add_library(gnuradio-blocks SHARED ${gr_blocks_sources}
- tag_gate_impl.cc)
+add_library(gnuradio-blocks SHARED ${gr_blocks_sources})
add_dependencies(gnuradio-blocks blocks_generated_includes)
target_link_libraries(gnuradio-blocks ${blocks_libs})
diff --git a/gr-blocks/lib/file_sink_base.cc b/gr-blocks/lib/file_sink_base.cc
index 42e2eae528..81bc94f351 100644
--- a/gr-blocks/lib/file_sink_base.cc
+++ b/gr-blocks/lib/file_sink_base.cc
@@ -53,8 +53,8 @@
namespace gr {
namespace blocks {
- file_sink_base::file_sink_base(const char *filename, bool is_binary)
- : d_fp(0), d_new_fp(0), d_updated(false), d_is_binary(is_binary)
+ file_sink_base::file_sink_base(const char *filename, bool is_binary, bool append)
+ : d_fp(0), d_new_fp(0), d_updated(false), d_is_binary(is_binary), d_append(append)
{
if (!open(filename))
throw std::runtime_error ("can't open file");
@@ -76,9 +76,13 @@ namespace gr {
// we use the open system call to get access to the O_LARGEFILE flag.
int fd;
- if((fd = ::open(filename,
- O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY,
- 0664)) < 0){
+ int flags;
+ if(d_append) {
+ flags = O_WRONLY|O_CREAT|O_APPEND|OUR_O_LARGEFILE|OUR_O_BINARY;
+ } else {
+ flags = O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY;
+ }
+ if((fd = ::open(filename, flags, 0664)) < 0){
perror(filename);
return false;
}
diff --git a/gr-blocks/lib/file_sink_impl.cc b/gr-blocks/lib/file_sink_impl.cc
index e78576e288..ab36dcd4e6 100644
--- a/gr-blocks/lib/file_sink_impl.cc
+++ b/gr-blocks/lib/file_sink_impl.cc
@@ -32,17 +32,17 @@ namespace gr {
namespace blocks {
file_sink::sptr
- file_sink::make(size_t itemsize, const char *filename)
+ file_sink::make(size_t itemsize, const char *filename, bool append)
{
return gnuradio::get_initial_sptr
- (new file_sink_impl(itemsize, filename));
+ (new file_sink_impl(itemsize, filename, append));
}
- file_sink_impl::file_sink_impl(size_t itemsize, const char *filename)
+ file_sink_impl::file_sink_impl(size_t itemsize, const char *filename, bool append)
: sync_block("file_sink",
io_signature::make(1, 1, itemsize),
io_signature::make(0, 0, 0)),
- file_sink_base(filename, true),
+ file_sink_base(filename, true, append),
d_itemsize(itemsize)
{
}
diff --git a/gr-blocks/lib/file_sink_impl.h b/gr-blocks/lib/file_sink_impl.h
index f86009419e..9e0c81569b 100644
--- a/gr-blocks/lib/file_sink_impl.h
+++ b/gr-blocks/lib/file_sink_impl.h
@@ -34,7 +34,7 @@ namespace gr {
size_t d_itemsize;
public:
- file_sink_impl(size_t itemsize, const char *filename);
+ file_sink_impl(size_t itemsize, const char *filename, bool append=false);
~file_sink_impl();
int work(int noutput_items,
diff --git a/gr-blocks/lib/stream_to_tagged_stream_impl.cc b/gr-blocks/lib/stream_to_tagged_stream_impl.cc
new file mode 100644
index 0000000000..08395bf653
--- /dev/null
+++ b/gr-blocks/lib/stream_to_tagged_stream_impl.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 <+YOU OR YOUR COMPANY+>.
+ *
+ * This 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.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; 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 <cstring>
+#include <gnuradio/io_signature.h>
+#include "stream_to_tagged_stream_impl.h"
+
+namespace gr {
+ namespace blocks {
+
+ stream_to_tagged_stream::sptr
+ stream_to_tagged_stream::make(size_t itemsize, int vlen, unsigned packet_len, const std::string &len_tag_key)
+ {
+ return gnuradio::get_initial_sptr
+ (new stream_to_tagged_stream_impl(itemsize, vlen, packet_len, len_tag_key));
+ }
+
+ stream_to_tagged_stream_impl::stream_to_tagged_stream_impl(size_t itemsize, int vlen, unsigned packet_len, const std::string &len_tag_key)
+ : gr::sync_block("stream_to_tagged_stream",
+ gr::io_signature::make(1, 1, itemsize * vlen),
+ gr::io_signature::make(1, 1, itemsize * vlen)),
+ d_itemsize(itemsize * vlen),
+ d_packet_len(packet_len),
+ d_packet_len_pmt(pmt::from_long(packet_len)),
+ d_len_tag_key(pmt::string_to_symbol(len_tag_key)),
+ d_next_tag_pos(0)
+ {}
+
+ stream_to_tagged_stream_impl::~stream_to_tagged_stream_impl()
+ {
+ }
+
+ int
+ stream_to_tagged_stream_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+ // Copy data
+ memcpy(out, in, noutput_items * d_itemsize);
+ // Add tags every d_packet_len
+ while(d_next_tag_pos < nitems_written(0) + noutput_items) {
+ add_item_tag(0, d_next_tag_pos, d_len_tag_key, d_packet_len_pmt);
+ d_next_tag_pos += d_packet_len;
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace blocks */
+} /* namespace gr */
+
diff --git a/gr-blocks/lib/stream_to_tagged_stream_impl.h b/gr-blocks/lib/stream_to_tagged_stream_impl.h
new file mode 100644
index 0000000000..106d90b86a
--- /dev/null
+++ b/gr-blocks/lib/stream_to_tagged_stream_impl.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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_BLOCKS_STREAM_TO_TAGGED_STREAM_IMPL_H
+#define INCLUDED_BLOCKS_STREAM_TO_TAGGED_STREAM_IMPL_H
+
+#include <gnuradio/blocks/stream_to_tagged_stream.h>
+
+namespace gr {
+ namespace blocks {
+
+ class stream_to_tagged_stream_impl : public stream_to_tagged_stream
+ {
+ private:
+ size_t d_itemsize;
+ unsigned d_packet_len;
+ pmt::pmt_t d_packet_len_pmt;
+ pmt::pmt_t d_len_tag_key;
+ uint64_t d_next_tag_pos;
+
+ public:
+ stream_to_tagged_stream_impl(size_t itemsize, int vlen, unsigned packet_len, const std::string &tag_len_key);
+ ~stream_to_tagged_stream_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } // namespace blocks
+} // namespace gr
+
+#endif /* INCLUDED_BLOCKS_STREAM_TO_TAGGED_STREAM_IMPL_H */
+
diff --git a/gr-blocks/python/blocks/qa_stream_to_tagged_stream.py b/gr-blocks/python/blocks/qa_stream_to_tagged_stream.py
new file mode 100755
index 0000000000..0d3f503abd
--- /dev/null
+++ b/gr-blocks/python/blocks/qa_stream_to_tagged_stream.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 202013 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.
+#
+
+from gnuradio import gr, gr_unittest
+from gnuradio import blocks
+
+class qa_stream_to_tagged_stream (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001_t (self):
+ src_data = (1, ) * 50
+ packet_len = 10L
+ len_tag_key = 'packet_len'
+ src = blocks.vector_source_f(src_data, False, 1)
+ tagger = blocks.stream_to_tagged_stream(gr.sizeof_float, 1, packet_len, len_tag_key)
+ sink = blocks.vector_sink_f()
+ self.tb.connect(src, tagger, sink)
+ self.tb.run ()
+ self.assertEqual(sink.data(), src_data)
+ tags = [gr.tag_to_python(x) for x in sink.tags()]
+ tags = sorted([(x.offset, x.key, x.value) for x in tags])
+ expected_tags = [(long(pos), 'packet_len', packet_len) for pos in range(0, 50, 10) ]
+ self.assertEqual(tags, expected_tags)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(qa_stream_to_tagged_stream, "qa_stream_to_tagged_stream.xml")
+
diff --git a/gr-blocks/swig/blocks_swig1.i b/gr-blocks/swig/blocks_swig1.i
index 431062e454..c87b4df03e 100644
--- a/gr-blocks/swig/blocks_swig1.i
+++ b/gr-blocks/swig/blocks_swig1.i
@@ -30,6 +30,7 @@
#include "gnuradio/blocks/skiphead.h"
#include "gnuradio/blocks/stream_mux.h"
#include "gnuradio/blocks/stream_to_streams.h"
+#include "gnuradio/blocks/stream_to_tagged_stream.h"
#include "gnuradio/blocks/stream_to_vector.h"
#include "gnuradio/blocks/streams_to_stream.h"
#include "gnuradio/blocks/streams_to_vector.h"
@@ -61,6 +62,7 @@
%include "gnuradio/blocks/skiphead.h"
%include "gnuradio/blocks/stream_mux.h"
%include "gnuradio/blocks/stream_to_streams.h"
+%include "gnuradio/blocks/stream_to_tagged_stream.h"
%include "gnuradio/blocks/stream_to_vector.h"
%include "gnuradio/blocks/streams_to_stream.h"
%include "gnuradio/blocks/streams_to_vector.h"
@@ -91,6 +93,7 @@
GR_SWIG_BLOCK_MAGIC2(blocks, skiphead);
GR_SWIG_BLOCK_MAGIC2(blocks, stream_mux);
GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_streams);
+GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_tagged_stream);
GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_vector);
GR_SWIG_BLOCK_MAGIC2(blocks, streams_to_stream);
GR_SWIG_BLOCK_MAGIC2(blocks, streams_to_vector);
diff --git a/gr-channels/grc/channels_channel_model.xml b/gr-channels/grc/channels_channel_model.xml
index fa881a10b5..909301de94 100644
--- a/gr-channels/grc/channels_channel_model.xml
+++ b/gr-channels/grc/channels_channel_model.xml
@@ -15,6 +15,7 @@
epsilon=$epsilon,
taps=$taps,
noise_seed=$seed,
+ block_tags=$block_tags
)</make>
<callback>set_noise_voltage($noise_voltage)</callback>
<callback>set_frequency_offset($freq_offset)</callback>
@@ -50,6 +51,23 @@
<value>0</value>
<type>int</type>
</param>
+ <param>
+ <name>Block Tag Propagation</name>
+ <key>block_tags</key>
+ <value>False</value>
+ <type>enum</type>
+ <hide>$block_tags.hide_block</hide>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ <opt>hide_block:</opt>
+ </option>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ <opt>hide_block:part</opt>
+ </option>
+ </param>
<sink>
<name>in</name>
<type>complex</type>
diff --git a/gr-channels/grc/channels_channel_model2.xml b/gr-channels/grc/channels_channel_model2.xml
index e8162f53d4..85355a1029 100644
--- a/gr-channels/grc/channels_channel_model2.xml
+++ b/gr-channels/grc/channels_channel_model2.xml
@@ -14,6 +14,7 @@
epsilon=$epsilon,
taps=$taps,
noise_seed=$seed,
+ block_tags=$block_tags
)</make>
<callback>set_noise_voltage($noise_voltage)</callback>
<callback>set_taps($taps)</callback>
@@ -42,6 +43,23 @@
<value>0</value>
<type>int</type>
</param>
+ <param>
+ <name>Block Tag Propagation</name>
+ <key>block_tags</key>
+ <value>False</value>
+ <type>enum</type>
+ <hide>$block_tags.hide_block</hide>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ <opt>hide_block:</opt>
+ </option>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ <opt>hide_block:part</opt>
+ </option>
+ </param>
<sink>
<name>in</name>
<type>complex</type>
diff --git a/gr-channels/include/gnuradio/channels/channel_model.h b/gr-channels/include/gnuradio/channels/channel_model.h
index 8b533ac7da..6a1e4a08cb 100644
--- a/gr-channels/include/gnuradio/channels/channel_model.h
+++ b/gr-channels/include/gnuradio/channels/channel_model.h
@@ -43,7 +43,10 @@ namespace gr {
* the AWGN noise source.
*
* Multipath can be approximated in this model by using a FIR
- * filter representation of a multipath delay profile..
+ * filter representation of a multipath delay profile.
+ *
+ * To simulate a channel with time-variant channel, use a
+ * gr::channels::channel_model2.
*/
class CHANNELS_API channel_model : virtual public hier_block2
{
@@ -64,12 +67,14 @@ namespace gr {
* the transmitter and receiver. 1.0 is no difference.
* \param taps Taps of a FIR filter to emulate a multipath delay profile.
* \param noise_seed A random number generator seed for the noise source.
+ * \param block_tags If true, tags will not be able to propagate through this block.
*/
static sptr make(double noise_voltage=0.0,
double frequency_offset=0.0,
double epsilon=1.0,
const std::vector<gr_complex> &taps=std::vector<gr_complex>(1,1),
- double noise_seed=0);
+ double noise_seed=0,
+ bool block_tags=false);
virtual void set_noise_voltage(double noise_voltage) = 0;
virtual void set_frequency_offset(double frequency_offset) = 0;
diff --git a/gr-channels/include/gnuradio/channels/channel_model2.h b/gr-channels/include/gnuradio/channels/channel_model2.h
index 05084931ee..6c52f34d81 100644
--- a/gr-channels/include/gnuradio/channels/channel_model2.h
+++ b/gr-channels/include/gnuradio/channels/channel_model2.h
@@ -81,11 +81,13 @@ namespace gr {
* the transmitter and receiver. 1.0 is no difference.
* \param taps Taps of a FIR filter to emulate a multipath delay profile.
* \param noise_seed A random number generator seed for the noise source.
+ * \param block_tags If true, tags will not be able to propagate through this block.
*/
static sptr make(double noise_voltage=0.0,
double epsilon=1.0,
const std::vector<gr_complex> &taps=std::vector<gr_complex>(1,1),
- double noise_seed=0);
+ double noise_seed=0,
+ bool block_tags=false);
virtual void set_noise_voltage(double noise_voltage) = 0;
virtual void set_taps(const std::vector<gr_complex> &taps) = 0;
diff --git a/gr-channels/lib/channel_model2_impl.cc b/gr-channels/lib/channel_model2_impl.cc
index 13eb033def..7533871de2 100644
--- a/gr-channels/lib/channel_model2_impl.cc
+++ b/gr-channels/lib/channel_model2_impl.cc
@@ -33,20 +33,23 @@ namespace gr {
channel_model2::make(double noise_voltage,
double epsilon,
const std::vector<gr_complex> &taps,
- double noise_seed)
+ double noise_seed,
+ bool block_tags)
{
return gnuradio::get_initial_sptr
(new channel_model2_impl(noise_voltage,
epsilon,
taps,
- noise_seed));
+ noise_seed,
+ block_tags));
}
// Hierarchical block constructor
channel_model2_impl::channel_model2_impl(double noise_voltage,
double epsilon,
const std::vector<gr_complex> &taps,
- double noise_seed)
+ double noise_seed,
+ bool block_tags)
: hier_block2("channel_model2",
io_signature::make2(3, 3, sizeof(gr_complex), sizeof(float)),
io_signature::make(1, 1, sizeof(gr_complex)))
@@ -78,6 +81,10 @@ namespace gr {
connect(d_mixer_offset, 0, d_noise_adder, 1);
connect(d_noise, 0, d_noise_adder, 0);
connect(d_noise_adder, 0, self(), 0);
+
+ if (block_tags) {
+ d_timing_offset->set_tag_propagation_policy(gr::block::TPP_DONT);
+ }
}
channel_model2_impl::~channel_model2_impl()
diff --git a/gr-channels/lib/channel_model2_impl.h b/gr-channels/lib/channel_model2_impl.h
index db2a667f9c..3bf1adb44e 100644
--- a/gr-channels/lib/channel_model2_impl.h
+++ b/gr-channels/lib/channel_model2_impl.h
@@ -55,7 +55,8 @@ namespace gr {
channel_model2_impl(double noise_voltage,
double epsilon,
const std::vector<gr_complex> &taps,
- double noise_seed);
+ double noise_seed,
+ bool block_tags);
~channel_model2_impl();
diff --git a/gr-channels/lib/channel_model_impl.cc b/gr-channels/lib/channel_model_impl.cc
index b232f9b235..7db4e6aa5c 100644
--- a/gr-channels/lib/channel_model_impl.cc
+++ b/gr-channels/lib/channel_model_impl.cc
@@ -32,14 +32,16 @@ namespace gr {
double frequency_offset,
double epsilon,
const std::vector<gr_complex> &taps,
- double noise_seed)
+ double noise_seed,
+ bool block_tags)
{
return gnuradio::get_initial_sptr
(new channel_model_impl(noise_voltage,
frequency_offset,
epsilon,
taps,
- noise_seed));
+ noise_seed,
+ block_tags));
}
// Hierarchical block constructor
@@ -47,7 +49,9 @@ namespace gr {
double frequency_offset,
double epsilon,
const std::vector<gr_complex> &taps,
- double noise_seed)
+ double noise_seed,
+ bool block_tags
+ )
: hier_block2("channel_model",
io_signature::make(1, 1, sizeof(gr_complex)),
io_signature::make(1, 1, sizeof(gr_complex)))
@@ -75,6 +79,10 @@ namespace gr {
connect(d_mixer_offset, 0, d_noise_adder, 1);
connect(d_noise, 0, d_noise_adder, 0);
connect(d_noise_adder, 0, self(), 0);
+
+ if (block_tags) {
+ d_timing_offset->set_tag_propagation_policy(gr::block::TPP_DONT);
+ }
}
channel_model_impl::~channel_model_impl()
diff --git a/gr-channels/lib/channel_model_impl.h b/gr-channels/lib/channel_model_impl.h
index da00e98da2..3faf6c3bbe 100644
--- a/gr-channels/lib/channel_model_impl.h
+++ b/gr-channels/lib/channel_model_impl.h
@@ -54,7 +54,8 @@ namespace gr {
double frequency_offset,
double epsilon,
const std::vector<gr_complex> &taps,
- double noise_seed);
+ double noise_seed,
+ bool block_tags);
~channel_model_impl();
diff --git a/gr-digital/doc/digital.dox b/gr-digital/doc/digital.dox
index 2809c6a943..48feda3485 100644
--- a/gr-digital/doc/digital.dox
+++ b/gr-digital/doc/digital.dox
@@ -20,4 +20,461 @@ by using:
help(digital)
\endcode
+\section digital_constellations Constellation Objects
+
+GNU Radio supports the creation and use of Constellation objects for
+many of its digital communications needs. We define these
+constellations with a set of constellation points in complex space and
+the symbol mappings to those points. For a constellation that has 4
+symbols, it then has log2(4) = 2 bits/symbol. We define this
+constellation with:
+
+<pre>
+ constel_points = [c0, c1, c2, c3]
+ symbols = [s0, s1, s2, s3]
+</pre>
+
+In this case: \f$c_i \in C\f$ and \f$s_i \in [00, 01, 10,
+11]\f$. Also, the mapping is a 1-to-1 for the items in both lists, so
+the symbol \f$s_0\f$ is positioned in complex space at the point
+\f$c_0\f$.
+
+In the code itself, the symbols are referred to as the
+'pre_diff_code' since this is the mapping before the application of
+differential modulation, if used.
+
+The constellation object classes are defined in constellation.h. There
+is a hierarchy of classes for different purposes and which represent
+special classes of constellations. The all derive from the virtual
+class gr::digital::constellation. All constellations we will make are
+based on classes derived from this base:
+
+<pre>
+gr::digital::constellation
+ --> gr::digital::constellation_calcdist
+ --> gr::digital::constellation_sector
+ --> gr::digital::constellation_rect
+ --> gr::digital::constellation_expl_rect
+ --> gr::digital::constellation_psk
+ --> gr::digital::constellation_bpsk
+ --> gr::digital::constellation_qpsk
+ --> gr::digital::constellation_dqpsk
+ --> gr::digital::constellation_8psk
+</pre>
+
+Each constellation class has a set of attributes and functions useful
+for manipulating the constellations and for converting symbols to and
+from complex points. One of the more important functions is the
+gr::digital::constellation::decision_maker function that takes in a
+sample in complex space and returns the symbol that it maps to. How
+this calculation is performed generally distinguishes the
+constellation classes from each other.
+
+The gr::digital::constellation_calcdist is the most generic
+constellation class we can create. This takes in the constellation
+points, symbol mapping, a rotational symmetry, and the number of
+dimensions. The decision_maker function takes in a complex sample x
+and calculates the Euclidean distance between x and each point in the
+constellation map of the object. The constellation point that has the
+minimum Euclidean distance to x is selected as the best match. The
+decision_maker will then return the symbol value that matches to this
+selected constellation point.
+
+We then have a concept of a constellation with a well-defined concept
+of sectors in the gr::digital::constellation_sector. This is farther
+refined if we know that the constellation is rectangular and can use
+the gr::digital::constellation_rect class. These classes have an
+overloaded decision_maker function that is specific to how the sectors
+are defined in the constructor. Essentially, the decision making math
+for this class is less costly than calculating the Euclidean distance
+for each point in the space. So if we can sectorize our constellation,
+using this class will be computationally cheaper.
+
+Finally, we have a set of pre-defined, hard-coded constellations for
+BPSK (gr::digital::constellation_bpsk), QPSK
+(gr::digital::constellation_qpsk), DQPSK
+(gr::digital::constellation_dqpsk), and 8PSK
+(gr::digital::constellation_8psk). These derive directly from
+gr::digital::constellation and specifically overload the decision_maker
+function. We have very simple metrics for calculating decisions for
+each of these constellations. For BPSK, we simply slice on the real
+axis. Samples are based solely on whether the real part of the complex
+symbol x is greater than or less than 0. Similar, simple, decision
+makers are defined for the others.
+
+Note that these specific constellations for the PSK modulations are
+defined for only one mapping of the constellation points to the
+symbols. Each is Gray coded, but for a specific Gray coding that is
+hard-coded into the class.
+
+
+\subsection grc_constellations Constellation Objects in GRC
+
+GRC provides two constellation representations that we can use to more
+easily define and interact with constellation objects. These are
+located in the 'Modulators' category as 'Constellation Object' and
+'Constellation Rect. Object'. These allow us to easily specify the
+constellation points, symbol list, and other properties of the
+constellation objects. They return the base() of the object, so the
+variable's ID can be used directly with blocks that accept
+constellation objects.
+
+These constellation blocks also allow us to specify the soft decision
+LUT if using the constellation object for soft decision outputs. The
+input can either be 'None' (default), a list of the soft bits that
+were generated externally or by another function, or 'auto' where the
+block will automatically calculate the soft decisions based on the
+constellation points and symbol map.
+
+
+\section digital_python_helpers Python Constellation Helper Functions
+
+A series of helper functions are defined in Python to create
+different, common constellations. There are various functions that
+have various levels of complexity in their definitions.
+
+\subsection digital_python_helpers_psk PSK Python Helpers
+
+There are two modules imported directly into gnuradio.digital. The
+first is gr-digital/python/digital/psk.py and the second is
+gr-digital/python/digital/psk_constellations.py. The
+gr-digital/python/digital/psk.py module defines the following
+constellations:
+
+<pre>
+ psk_constellation(m, mod_code, differential)
+</pre>
+
+This function defines a PSK modulation of order 'm' (that is, there
+are m number of constellation points / symbols). The 'mod_code' is
+either mod_codes.GRAY_CODE or mode_codes.NO_CODE to set the symbol
+mapping up as either Gray coded or not. The 'differential' argument is
+either True to use differential coding or False for non-differential
+coding.
+
+This function creates and returns a constellation object that can then
+be used by any block that takes a constellation
+(gr::digital::constellation_decoder_cb,
+gr::digital::constellation_receiver_cb,
+gr::digital::constellation_soft_decoder_cf, or
+gr::digital::lms_dd_equalizer_cc).
+
+The gr-digital/python/digital/psk.py module also holds functions
+similar to digital.psk_constellation but that create a full modulator
+and demodulator chain derived from digital.generic_mod_demod.
+
+<pre>
+ psk_mod(constellation_points, mod_code, differential, *args, **kwargs)
+ psk_demod(constellation_points, mod_code, differential, *args, **kwargs)
+</pre>
+
+The args and kwargs are parameters of the generic_mod or generic_demod
+passed directly to them. See \ref digital_generic_mod_demod for
+details of this interface.
+
+There is another Python file full of helper functions to create
+different constellations. This is found in the
+gr-digital/python/digital/psk_constellation.py file. This file
+provides functions that build the vectors of constellation points and
+symbol mappings that can be used to create a constellation
+object. These are particularly helpful when using the Constellation
+Obj. and Constellation Rect. GUI elements in GRC.
+
+The gr-digital/python/digital/psk_constellation.py file has extensive
+documentation that describes the naming scheme used for the different
+constellations that will not be repeated here. The main thing to
+understand is that these functions define constellations of the same
+order with different Gray code mappings. The function names are:
+
+<pre>
+ (const_points, symbol_map) = psk_M_0xk_<permutation>()
+</pre>
+
+Where M is the order of the modulation (2 for BPSK, 4 for QPSK,
+etc.), and k and \<permutation\> define a particular encoding for the
+Gray code mapping used. The documentation in the file explains how
+these two concepts define the Gray code mapping.
+
+These functions are also simply named "psk_M_n" when n is an integer
+from 0 to N-1 for however many mappings are defined for that
+modulation. Not all modulations are fully defined, and the value
+for n has no other meaning except as a counter.
+
+The functions return a tuple of lists. The first list in the tuple is
+the list of complex constellation points and the second list contains
+the symbols mapped to those points. These lists can then be passed to
+a constellation class directly to create a constellation of any Gray
+code mapping needed.
+
+While not all Gray code mappings of the modulations are defined, there
+is a generator function to automatically build any rotation of a basis
+constellation:
+
+<pre>
+ (const_points, symbol_map) = \
+ constellation_map_generator(basis_cpoints, basis_symbols, k, pi)
+</pre>
+
+We provide a basis constellation map and symbol map as the fundamental
+rotation of the constellation points. This function uses the k and pi
+inputs (see the discussion in psk_constellation.py for what these
+mean) to return a new rotation of the constellation's symbols. If the
+basis symbols are Gray coded than the output symbols will also be Gray
+coded. Note that this algorithm specifically depends on the
+constellation in complex space to be square to preserve the Gray code
+property.
+
+
+\subsection digital_python_helpers_qam QAM Python Helpers
+
+Similar to defining PSK modulations, GNU Radio also has helpers for
+some QAM modulations, found in gr-digital/python/digital/qam.py and
+gr-digital/python/digital/qam_constellations.py. Similar functions to
+what has been described for PSK exist here:
+
+<pre>
+ qam_constellation(constellation_points, differential, mod_code,
+ large_ampls_to_corners)
+ qam_mod(constellation_points, differential, mod_code, *args, **kwargs)
+ qam_demod(constellation_points, differential, mod_code,
+ large_ampls_to_corner, *args, **kwargs)
+</pre>
+
+The parameters to these functions is the same as for the PSK
+equivalents. The new argument 'large_ampls_to_corner' is defined in
+the documentation as:
+
+<pre>
+ large_ampls_to_corners: If this is set to True then when the
+ constellation is making decisions, points that are far outside
+ the constellation are mapped to the closest corner rather than
+ the closet constellation point. This can help with phase
+ locking.
+</pre>
+
+Similarly, gr-digital/python/digital/qam_constellations.py defines a of
+QAM constellation functions that return a tuple containing the
+constellation points and the symbol mappings. The naming scheme is
+defined in depth in the module itself and is similar to the equivalent
+set of PSK functions.
+
+Currently, only a subset of 16QAM symbol mappings are defined, but we
+can use of the constellation_map_generator function described in the
+previous section to define more mapping rotations for and square QAM
+modulation.
+
+
+\section digital_generic_mod_demod The Generic Modulator/Demodulator
+Hierarchical Blocks
+
+Since digital modulation and demodulation are complex functions, the
+different parts can be done by different existing GNU Radio blocks. We
+have combined these into a generic modulator and generic demodulator
+hierarchical blocks to make access and use much easier. This file can
+be found as gr-digital/python/digital/generic_mod_demod.py.
+
+\subsection digital_generic_mod Generic Modulator
+
+The modulator constructor looks like:
+
+<pre>
+ digital.generic_mod(constellation, differential, samples_per_symbol,
+ pre_diff_code, excess_bw, verbose, log)
+</pre>
+
+The 'constellation' arg is a constellation object as defined above in
+\ref digital_constellations and can represent any constellation
+mapping. The 'differential' arg is a bool to turn differential coding
+on/off. The block also performs pulse shaping and interpolates the
+pulse-shaped filter to some number of 'samples_per_symbol'. The pulse
+shaping is a root raised cosine filter defined by the excess
+bandwidth (or alpha) parameter called 'excess_bw.'
+
+We can also turn on a verbose mode to output information to the
+user. The 'log' parameter toggles logging data on/off. When logging is
+turned on, it stores every stage of the modulation to a different file
+so that each stage can be independently analyzed.
+
+
+\subsection digital_generic_demod Generic Demodulator
+
+The demodulator looks like:
+
+<pre>
+ digital.generic_demod(constellation, differential, samples_per_symbol,
+ pre_diff_code, excess_bw, freq_bw, timing_bw,
+ phase_bw, verbose, log)
+</pre>
+
+The additional parameters to the demodulator are the loop bandwidths
+for the different signal recovery loops used internally. There are
+separate loops for frequency acquisition, timing acquisition, and fine
+frequency / phase acquisition, controlled in tern by each of the
+three 'X_bw' arguments. Otherwise, the arguments are the same as the
+modulator.
+
+
+\subsection digital_generic_guts Guts of the Modulator and Demodulator
+
+The generic modulator looks like the following:
+
+<pre>
+ blocks.packed_to_unpacked_bb: takes in packed bytes
+ digital.map_bb: maps baseband symbols to the pre-differential encoding
+ digital.diff_encoder_bb: differentially encode symbols
+ digital.chunks_to_symbols_bc: convert symbols to complex samples
+ filter.pfb_arb_resampler_ccf: perform upsampling to samps/symbol and pulse shape
+</pre>
+
+The mapping and chunks-to-symbols stages are done using the
+information provided by the constellation object.
+
+Note that the modulator takes in packed bytes, which means that all 8
+bits per byte are used and unpacked into k bits per symbol.
+
+The generic demodulator looks like the following:
+
+<pre>
+ digital.fll_band_edge_cc: Performs coarse frequency correction
+ digital.pfb_clock_sync_ccf: Matched filtering and timing recovery
+ digital.constellation_receiver_cb: Phase tracking and decision making (hard bits)
+ digital.diff_decoder_bb: Differential decoding
+ digital.map_bb: Map to pre-differential symbols
+ blocks.unpack_k_bits_bb: Unpack k bits/symbol to a stream of bits
+</pre>
+
+This block outputs unpacked bits, so each output item represents a
+single bit of data. A block like 'pack_k_bits' can be used following
+this to convert the data back into bytes.
+
+
+\section digital_softbits Support for Soft Decisions
+
+To support soft decisions of the receivers instead of the current hard
+decisions, the constellation objects also accept a soft decision
+look-up table (LUT) or can be told to generate a LUT based on the
+constellation points and symbol map.
+
+All constellation objects can accept a new LUT using the
+gr::digital::constellation::set_soft_dec_lut function. This function
+takes in a LUT, which is a vector of floating point tuples (in C++ it
+is just a vector\<vector\<float\>\>) and a precision value that
+specifies how accurate the LUT is to a given number of bits.
+
+The constellation objects also have two functions to calculate the
+soft decisions from their constellation and symbol map. The
+gr::digital::constellation::calc_soft_dec takes a complex number (and
+optional noise power) and returns the soft decisions as a list of
+floats. This function is used internally in the
+gr::digital::constellation::gen_soft_dec_lut, which takes in the LUT's
+precision (as a number of bits) and an optional noise power estimate,
+if known. This function calculates the soft decisions itself. These
+functions are very expensive because each constellation point is taken
+into account during the calculation. We provide the
+gr::digital::constellation::set_soft_dec_lut in order to allow users
+to use one of the many known approximations to more quickly generate
+the soft decision LUT.
+
+The gr::digital::constellation::calc_soft_dec function could be used
+instead of drawing directly from a LUT, which is probably only
+important if the noise floor or channel estimates are likely to change
+and we want to account for this in the decisions. The basic
+implementation of the soft decision calculation is the full
+calculation based on the distance between the sample and all points in
+the constellation space. If using this function for real-time
+decisions, a new object should inherit from the
+gr::digital::constellation class (or whichever child class is being
+used) and redefine this function with a faster approximation
+calculation.
+
+Note: If no soft decision LUT is defined but
+gr::digital::constellation::soft_decision_maker is called then the
+full calculation from gr::digital::constellation::calc_soft_dec is
+used by default.
+
+The LUT is a list of tuples, where each index of the list is some
+quantized (to some number of bits of precision) point in the
+constellation space. At each index, there is a tuple of \e k soft
+bit values for a constellation with \e k bits/symbol.
+
+To help with this, the file
+gr-digital/python/digital/soft_dec_lut_gen.py can be used to create
+these tables. The function digital.soft_dec_table_generator(generator,
+precision) function generates a LUT based on some generator function
+and the number of bits of precision required. This file contains
+documentation explaining the system better. Or the
+digital.soft_dec_table(constel, symbols, prec, npwr=1) can be used
+which takes in the constellation map and symbols to do the full raw
+calculation of the softbits as opposed to a generator function.
+
+To further aid the LUT creation, the digital module also defines a
+number of functions that can be used as soft decision generators for
+the soft_dec_table function. These functions are found in
+psk_constellations.py and qam_constellations.py. These files were
+already mentioned as they contain a set of functions that return
+tuples of constellation points and Gray-mapped symbols for different
+modulations. But these files contain a second set of functions
+prefixed by 'sd_' which are soft decision LUT generator functions Each
+LUT generator takes in a complex value and returns the tuple of soft
+decisions for that point in complex space. To aid with this,
+soft_dec_lut_gen.py defines a 'calc_from_table' function that takes in
+a complex sample, the precision of the table, and the LUT itself and
+returns the tuple of soft decisions in the LUT that is closest to the
+given symbol. Each of these functions can be found directly from the
+'digital' Python module.
+
+The LUTs are defined from min to max constellation points in both the
+real and imaginary axes. That means that signals coming in outside of
+these bounds are clipped to 1. So there is no added certainty for
+values beyond these bounds.
+
+The gr::digital::constellation_soft_decoder_cf block takes in a
+constellation object where a soft decision LUT is defined. It takes in
+complex samples and produces a stream of floats of soft decisions. The
+soft decision outputs are not grouped together, it is just a stream of
+floats. So this block acts as an interpolator that takes in 1 complex
+sample and return \e k float for \e k bits per symbol.
+
+
+\subsection soft_dec_api Review of the Soft Decision API/Functions
+
+Files of interest:
+\li psk_constellations.py: PSK constellations and soft decision generators
+\li qam_constellations.py: QAM constellations and soft decision generators
+\li soft_dec_lut_gen.py: Functions to build soft decision LUTs and test them
+\li test_soft_decisions.py: A script that generates a random complex
+sample and calculates the soft decisions using various methods. Plots
+the sample against the full constellation. Requires matplotlib installed.
+
+Functions:
+\li digital.sd_psk_2_*: Returns (constellation, symbol_map) lists for
+different rotations for BPSK.
+\li digital.sd_psk_4_*: Returns (constellation, symbol_map) lists for
+different rotations for QPSK.
+\li digital.sd_qam_16_*: Returns (constellation, symbol_map) lists for
+different rotations for 16QAM.
+\li digital.soft_dec_table_generator: Takes in a generator function
+(like the digital.sd_XXX above) and creates a LUT to a specific precision.
+\li digital.soft_dec_table: Takes in a constellation/symbol map and
+uses digital.calc_soft_dec to generate a LUT to a specific precision.
+\li digital.calc_soft_dec: Takes a complex sample and calculates the
+soft decisions for a given constellation/symbol mapping.
+\li digital.calc_soft_dec_from_table: Given a sample and a LUT,
+returns the soft decisions of the LUT for the nearest point to the
+sample.
+
+C++ Interface:
+\li gr::digital::constellation::gen_soft_dec_lut: uses calc_soft_dec
+to internally generate a soft decision LUT.
+\li gr::digital::constellation::calc_soft_dec: calculates the soft
+decisions for a given sample from the full constellation/symbol map.
+\li gr::digital::constellation::set_soft_dec_lut: Set the soft
+decision LUT from an externally-calculated LUT.
+\li gr::digital::constellation::has_soft_dec_lut: has the LUT been
+set/generated or not.
+\li gr::digital::constellation::soft_decision_maker: Used by
+gr::digital::constellation_soft_decoder to convert samples to soft
+decisions. If a LUT is defined, uses it; else, uses calc_soft_dec.
+
+
*/
diff --git a/gr-digital/examples/ofdm/ofdm_loopback.grc b/gr-digital/examples/ofdm/ofdm_loopback.grc
index a6b3b147f1..ad8e4a3ef7 100644
--- a/gr-digital/examples/ofdm/ofdm_loopback.grc
+++ b/gr-digital/examples/ofdm/ofdm_loopback.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Tue Jun 11 22:44:34 2013</timestamp>
+ <timestamp>Tue Aug 27 15:09:37 2013</timestamp>
<block>
<key>options</key>
<param>
@@ -64,7 +64,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>len_tag_key</value>
+ <value>tx_signal</value>
</param>
<param>
<key>_enabled</key>
@@ -72,11 +72,34 @@
</param>
<param>
<key>value</key>
- <value>"packet_len"</value>
+ <value>[numpy.sin(2 * numpy.pi * 1.0/8 * x) for x in range(packet_len)]</value>
</param>
<param>
<key>_coordinate</key>
- <value>(345, 0)</value>
+ <value>(176, -1)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>packet_len</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>8*2</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(258, 64)</value>
</param>
<param>
<key>_rotation</key>
@@ -107,6 +130,29 @@
</param>
</block>
<block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>len_tag_key</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>"packet_len"</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(345, 0)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
<key>import</key>
<param>
<key>id</key>
@@ -153,10 +199,10 @@
</param>
</block>
<block>
- <key>wxgui_fftsink2</key>
+ <key>blocks_vector_to_stream</key>
<param>
<key>id</key>
- <value>wxgui_fftsink2_0</value>
+ <value>blocks_vector_to_stream_0</value>
</param>
<param>
<key>_enabled</key>
@@ -164,59 +210,121 @@
</param>
<param>
<key>type</key>
- <value>complex</value>
+ <value>byte</value>
</param>
<param>
- <key>title</key>
- <value>Rx Spectrum</value>
+ <key>num_items</key>
+ <value>4</value>
</param>
<param>
- <key>samp_rate</key>
- <value>100e3</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>baseband_freq</key>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>y_per_div</key>
- <value>10</value>
+ <key>_coordinate</key>
+ <value>(261, 140)</value>
</param>
<param>
- <key>y_divs</key>
- <value>10</value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_tag_debug</key>
<param>
- <key>ref_level</key>
+ <key>id</key>
+ <value>blocks_tag_debug_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>Rx Packets</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>display</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(345, 424)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>wxgui_scopesink2</key>
<param>
- <key>ref_scale</key>
- <value>2.0</value>
+ <key>id</key>
+ <value>wxgui_scopesink2_0</value>
</param>
<param>
- <key>fft_size</key>
- <value>1024</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>fft_rate</key>
- <value>15</value>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
- <key>peak_hold</key>
- <value>False</value>
+ <key>title</key>
+ <value>Scope Plot</value>
</param>
<param>
- <key>average</key>
- <value>False</value>
+ <key>samp_rate</key>
+ <value>1.0</value>
</param>
<param>
- <key>avg_alpha</key>
+ <key>v_scale</key>
<value>0</value>
</param>
<param>
- <key>win</key>
- <value>None</value>
+ <key>v_offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>t_scale</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ac_couple</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>xy_mode</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>1</value>
</param>
<param>
<key>win_size</key>
@@ -231,12 +339,20 @@
<value></value>
</param>
<param>
- <key>freqvar</key>
- <value>None</value>
+ <key>trig_mode</key>
+ <value>wxgui.TRIG_MODE_AUTO</value>
+ </param>
+ <param>
+ <key>y_axis_label</key>
+ <value>Counts</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(59, 384)</value>
+ <value>(550, 323)</value>
</param>
<param>
<key>_rotation</key>
@@ -244,54 +360,38 @@
</param>
</block>
<block>
- <key>variable_slider</key>
+ <key>blocks_stream_to_vector</key>
<param>
<key>id</key>
- <value>noise_voltage</value>
+ <value>blocks_stream_to_vector_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>label</key>
- <value>Noise Amplitude</value>
- </param>
- <param>
- <key>value</key>
- <value>0.01</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>min</key>
- <value>0</value>
+ <key>num_items</key>
+ <value>4</value>
</param>
<param>
- <key>max</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>num_steps</key>
- <value>100</value>
- </param>
- <param>
- <key>style</key>
- <value>wx.SL_HORIZONTAL</value>
- </param>
- <param>
- <key>converver</key>
- <value>float_converter</value>
- </param>
- <param>
- <key>grid_pos</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>notebook</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(695, 439)</value>
+ <value>(348, 347)</value>
</param>
<param>
<key>_rotation</key>
@@ -302,7 +402,7 @@
<key>variable_slider</key>
<param>
<key>id</key>
- <value>freq_offset</value>
+ <value>noise_voltage</value>
</param>
<param>
<key>_enabled</key>
@@ -310,19 +410,19 @@
</param>
<param>
<key>label</key>
- <value>Frequency Offset (Multiples of Sub-carrier spacing)</value>
+ <value>Noise Amplitude</value>
</param>
<param>
<key>value</key>
- <value>0</value>
+ <value>0.01</value>
</param>
<param>
<key>min</key>
- <value>-3</value>
+ <value>0</value>
</param>
<param>
<key>max</key>
- <value>3</value>
+ <value>1</value>
</param>
<param>
<key>num_steps</key>
@@ -346,7 +446,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(696, 264)</value>
+ <value>(707, 496)</value>
</param>
<param>
<key>_rotation</key>
@@ -354,10 +454,10 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>wxgui_fftsink2</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
@@ -368,79 +468,80 @@
<value>complex</value>
</param>
<param>
- <key>samples_per_second</key>
+ <key>title</key>
+ <value>Rx Spectrum</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
<value>100e3</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>baseband_freq</key>
+ <value>0</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(252, 212)</value>
+ <key>y_per_div</key>
+ <value>10</value>
</param>
<param>
- <key>_rotation</key>
- <value>180</value>
+ <key>y_divs</key>
+ <value>10</value>
</param>
- </block>
- <block>
- <key>digital_ofdm_rx</key>
<param>
- <key>id</key>
- <value>digital_ofdm_rx_0</value>
+ <key>ref_level</key>
+ <value>0</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>ref_scale</key>
+ <value>2.0</value>
</param>
<param>
- <key>fft_len</key>
- <value>fft_len</value>
+ <key>fft_size</key>
+ <value>1024</value>
</param>
<param>
- <key>cp_len</key>
- <value>fft_len/4</value>
+ <key>fft_rate</key>
+ <value>15</value>
</param>
<param>
- <key>packet_len_key</key>
- <value>"rx_len"</value>
+ <key>peak_hold</key>
+ <value>False</value>
</param>
<param>
- <key>occupied_carriers</key>
- <value>()</value>
+ <key>average</key>
+ <value>False</value>
</param>
<param>
- <key>pilot_carriers</key>
- <value>()</value>
+ <key>avg_alpha</key>
+ <value>0</value>
</param>
<param>
- <key>pilot_symbols</key>
- <value>()</value>
+ <key>win</key>
+ <value>None</value>
</param>
<param>
- <key>sync_word1</key>
- <value>()</value>
+ <key>win_size</key>
+ <value></value>
</param>
<param>
- <key>sync_word2</key>
- <value>()</value>
+ <key>grid_pos</key>
+ <value></value>
</param>
<param>
- <key>header_mod</key>
- <value>"BPSK"</value>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
- <key>payload_mod</key>
- <value>"QPSK"</value>
+ <key>freqvar</key>
+ <value>None</value>
</param>
<param>
- <key>log</key>
- <value>False</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(59, 258)</value>
+ <value>(71, 441)</value>
</param>
<param>
<key>_rotation</key>
@@ -448,22 +549,54 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>variable_slider</key>
<param>
<key>id</key>
- <value>packet_len</value>
+ <value>freq_offset</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
+ <key>label</key>
+ <value>Frequency Offset (Multiples of Sub-carrier spacing)</value>
+ </param>
+ <param>
<key>value</key>
- <value>8*2</value>
+ <value>0</value>
+ </param>
+ <param>
+ <key>min</key>
+ <value>-3</value>
+ </param>
+ <param>
+ <key>max</key>
+ <value>3</value>
+ </param>
+ <param>
+ <key>num_steps</key>
+ <value>100</value>
+ </param>
+ <param>
+ <key>style</key>
+ <value>wx.SL_HORIZONTAL</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(258, 64)</value>
+ <value>(708, 321)</value>
</param>
<param>
<key>_rotation</key>
@@ -471,33 +604,49 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>blocks_tag_gate</key>
<param>
<key>id</key>
- <value>tx_signal</value>
+ <value>blocks_tag_gate_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>[numpy.sin(2 * numpy.pi * 1.0/8 * x) for x in range(packet_len)]</value>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>propagate_tags</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(176, -1)</value>
+ <value>(523, 243)</value>
</param>
<param>
<key>_rotation</key>
- <value>0</value>
+ <value>180</value>
</param>
</block>
<block>
- <key>blocks_vector_to_stream</key>
+ <key>blocks_throttle</key>
<param>
<key>id</key>
- <value>blocks_vector_to_stream_0</value>
+ <value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
@@ -505,23 +654,31 @@
</param>
<param>
<key>type</key>
- <value>byte</value>
+ <value>complex</value>
</param>
<param>
- <key>num_items</key>
- <value>4</value>
+ <key>samples_per_second</key>
+ <value>100e3</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(261, 140)</value>
+ <value>(267, 243)</value>
</param>
<param>
<key>_rotation</key>
- <value>0</value>
+ <value>180</value>
</param>
</block>
<block>
@@ -555,39 +712,16 @@
<value>1</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(-1, 101)</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>_rotation</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>blocks_stream_to_vector</key>
- <param>
- <key>id</key>
- <value>blocks_stream_to_vector_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>byte</value>
- </param>
- <param>
- <key>num_items</key>
- <value>4</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
<param>
<key>_coordinate</key>
- <value>(336, 290)</value>
+ <value>(3, 124)</value>
</param>
<param>
<key>_rotation</key>
@@ -595,74 +729,46 @@
</param>
</block>
<block>
- <key>wxgui_scopesink2</key>
+ <key>channels_channel_model</key>
<param>
<key>id</key>
- <value>wxgui_scopesink2_0</value>
+ <value>channels_channel_model_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>float</value>
+ <key>noise_voltage</key>
+ <value>noise_voltage</value>
</param>
<param>
- <key>title</key>
- <value>Scope Plot</value>
+ <key>freq_offset</key>
+ <value>freq_offset * 1.0/fft_len</value>
</param>
<param>
- <key>samp_rate</key>
+ <key>epsilon</key>
<value>1.0</value>
</param>
<param>
- <key>v_scale</key>
- <value>0</value>
- </param>
- <param>
- <key>v_offset</key>
- <value>0</value>
+ <key>taps</key>
+ <value>1.0 + 1.0j</value>
</param>
<param>
- <key>t_scale</key>
+ <key>seed</key>
<value>0</value>
</param>
<param>
- <key>ac_couple</key>
- <value>False</value>
- </param>
- <param>
- <key>xy_mode</key>
- <value>False</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>1</value>
- </param>
- <param>
- <key>win_size</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>grid_pos</key>
- <value></value>
- </param>
- <param>
- <key>notebook</key>
- <value></value>
- </param>
- <param>
- <key>trig_mode</key>
- <value>wxgui.TRIG_MODE_AUTO</value>
- </param>
- <param>
- <key>y_axis_label</key>
- <value>Counts</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(538, 266)</value>
+ <value>(764, 93)</value>
</param>
<param>
<key>_rotation</key>
@@ -670,10 +776,10 @@
</param>
</block>
<block>
- <key>digital_ofdm_tx</key>
+ <key>digital_ofdm_rx</key>
<param>
<key>id</key>
- <value>digital_ofdm_tx_0</value>
+ <value>digital_ofdm_rx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -689,7 +795,7 @@
</param>
<param>
<key>packet_len_key</key>
- <value>len_tag_key</value>
+ <value>"rx_len"</value>
</param>
<param>
<key>occupied_carriers</key>
@@ -720,16 +826,24 @@
<value>"QPSK"</value>
</param>
<param>
- <key>rolloff</key>
- <value>0</value>
+ <key>scramble_bits</key>
+ <value>False</value>
</param>
<param>
<key>log</key>
<value>False</value>
</param>
<param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(464, 77)</value>
+ <value>(71, 315)</value>
</param>
<param>
<key>_rotation</key>
@@ -737,108 +851,78 @@
</param>
</block>
<block>
- <key>channels_channel_model</key>
+ <key>digital_ofdm_tx</key>
<param>
<key>id</key>
- <value>channels_channel_model_0</value>
+ <value>digital_ofdm_tx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>noise_voltage</key>
- <value>noise_voltage</value>
+ <key>fft_len</key>
+ <value>fft_len</value>
</param>
<param>
- <key>freq_offset</key>
- <value>freq_offset * 1.0/fft_len</value>
+ <key>cp_len</key>
+ <value>fft_len/4</value>
</param>
<param>
- <key>epsilon</key>
- <value>1.0</value>
+ <key>packet_len_key</key>
+ <value>len_tag_key</value>
</param>
<param>
- <key>taps</key>
- <value>1.0 + 1.0j</value>
+ <key>occupied_carriers</key>
+ <value>()</value>
</param>
<param>
- <key>seed</key>
- <value>0</value>
+ <key>pilot_carriers</key>
+ <value>()</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(747, 85)</value>
+ <key>pilot_symbols</key>
+ <value>()</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>sync_word1</key>
+ <value>()</value>
</param>
- </block>
- <block>
- <key>blocks_tag_gate</key>
<param>
- <key>id</key>
- <value>blocks_tag_gate_0</value>
+ <key>sync_word2</key>
+ <value>()</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>header_mod</key>
+ <value>"BPSK"</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>payload_mod</key>
+ <value>"QPSK"</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>rolloff</key>
+ <value>0</value>
</param>
<param>
- <key>propagate_tags</key>
+ <key>scramble_bits</key>
<value>False</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(508, 212)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>180</value>
- </param>
- </block>
- <block>
- <key>blocks_tag_debug</key>
- <param>
- <key>id</key>
- <value>blocks_tag_debug_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>byte</value>
- </param>
- <param>
- <key>name</key>
- <value>Rx Packets</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>1</value>
+ <key>log</key>
+ <value>False</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>display</key>
- <value>True</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(333, 367)</value>
+ <value>(488, 77)</value>
</param>
<param>
<key>_rotation</key>
@@ -858,20 +942,20 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>digital_ofdm_rx_0</sink_block_id>
+ <source_block_id>digital_ofdm_tx_0</source_block_id>
+ <sink_block_id>channels_channel_model_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+ <source_block_id>channels_channel_model_0</source_block_id>
+ <sink_block_id>blocks_tag_gate_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_rx_0</source_block_id>
- <sink_block_id>blocks_stream_to_vector_0</sink_block_id>
+ <source_block_id>blocks_stream_to_vector_0</source_block_id>
+ <sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@@ -882,26 +966,26 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_tag_gate_0</source_block_id>
- <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_block_id>digital_ofdm_rx_0</source_block_id>
+ <sink_block_id>blocks_stream_to_vector_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_stream_to_vector_0</source_block_id>
- <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_tx_0</source_block_id>
- <sink_block_id>channels_channel_model_0</sink_block_id>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>digital_ofdm_rx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>channels_channel_model_0</source_block_id>
- <sink_block_id>blocks_tag_gate_0</sink_block_id>
+ <source_block_id>blocks_tag_gate_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gr-digital/examples/ofdm/rx_ofdm.grc b/gr-digital/examples/ofdm/rx_ofdm.grc
index e38b84f65a..5a65ec8b17 100644
--- a/gr-digital/examples/ofdm/rx_ofdm.grc
+++ b/gr-digital/examples/ofdm/rx_ofdm.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Tue May 14 11:03:11 2013</timestamp>
+ <timestamp>Sun Oct 27 16:24:42 2013</timestamp>
<block>
<key>options</key>
<param>
@@ -61,22 +61,22 @@
</param>
</block>
<block>
- <key>import</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>import_1</value>
+ <value>payload_mod</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>import</key>
- <value>from gnuradio.digital.utils import tagged_streams</value>
+ <key>value</key>
+ <value>digital.constellation_qpsk()</value>
</param>
<param>
<key>_coordinate</key>
- <value>(163, 0)</value>
+ <value>(663, 1)</value>
</param>
<param>
<key>_rotation</key>
@@ -87,7 +87,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>fft_len</value>
+ <value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
@@ -95,11 +95,11 @@
</param>
<param>
<key>value</key>
- <value>64</value>
+ <value>10000</value>
</param>
<param>
<key>_coordinate</key>
- <value>(301, -1)</value>
+ <value>(170, 65)</value>
</param>
<param>
<key>_rotation</key>
@@ -110,7 +110,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>payload_mod</value>
+ <value>header_equalizer</value>
</param>
<param>
<key>_enabled</key>
@@ -118,11 +118,11 @@
</param>
<param>
<key>value</key>
- <value>digital.constellation_qpsk()</value>
+ <value>digital.ofdm_equalizer_simpledfe(fft_len, header_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(648, 0)</value>
+ <value>(931, 69)</value>
</param>
<param>
<key>_rotation</key>
@@ -133,7 +133,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>header_mod</value>
+ <value>payload_equalizer</value>
</param>
<param>
<key>_enabled</key>
@@ -141,11 +141,11 @@
</param>
<param>
<key>value</key>
- <value>digital.constellation_bpsk()</value>
+ <value>digital.ofdm_equalizer_simpledfe(fft_len, payload_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols, 1)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(490, 0)</value>
+ <value>(1112, 73)</value>
</param>
<param>
<key>_rotation</key>
@@ -156,7 +156,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>occupied_carriers</value>
+ <value>sync_word2</value>
</param>
<param>
<key>_enabled</key>
@@ -164,11 +164,11 @@
</param>
<param>
<key>value</key>
- <value>(range(-26, -21) + range(-20, -7) + range(-6, 0) + range(1, 7) + range(8, 21) + range(22, 27),)</value>
+ <value>[0j, 0j, 0j, 0j, 0j, 0j, (-1+0j), (-1+0j), (-1+0j), (-1+0j), (1+0j), (1+0j), (-1+0j), (-1+0j), (-1+0j), (1+0j), (-1+0j), (1+0j), (1+0j), (1 +0j), (1+0j), (1+0j), (-1+0j), (-1+0j), (-1+0j), (-1+0j), (-1+0j), (1+0j), (-1+0j), (-1+0j), (1+0j), (-1+0j), 0j, (1+0j), (-1+0j), (1+0j), (1+0j), (1+0j), (-1+0j), (1+0j), (1+0j), (1+0j), (-1+0j), (1+0j), (1+0j), (1+0j), (1+0j), (-1+0j), (1+0j), (-1+0j), (-1+0j), (-1+0j), (1+0j), (-1+0j), (1+0j), (-1+0j), (-1+0j), (-1+0j), (-1+0j), 0j, 0j, 0j, 0j, 0j]</value>
</param>
<param>
<key>_coordinate</key>
- <value>(598, 64)</value>
+ <value>(399, 66)</value>
</param>
<param>
<key>_rotation</key>
@@ -179,7 +179,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>pilot_carriers</value>
+ <value>sync_word1</value>
</param>
<param>
<key>_enabled</key>
@@ -187,11 +187,11 @@
</param>
<param>
<key>value</key>
- <value>((-21, -7, 7, 21,),)</value>
+ <value>[0., 0., 0., 0., 0., 0., 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., -1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., -1.41421356, 0., -1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 0., 0., 0., 0., 0.]</value>
</param>
<param>
<key>_coordinate</key>
- <value>(751, 64)</value>
+ <value>(255, 67)</value>
</param>
<param>
<key>_rotation</key>
@@ -202,7 +202,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>pilot_symbols</value>
+ <value>fft_len</value>
</param>
<param>
<key>_enabled</key>
@@ -210,11 +210,11 @@
</param>
<param>
<key>value</key>
- <value>((1, 1, 1, -1,),)</value>
+ <value>64</value>
</param>
<param>
<key>_coordinate</key>
- <value>(875, 65)</value>
+ <value>(301, -1)</value>
</param>
<param>
<key>_rotation</key>
@@ -225,7 +225,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>sync_word2</value>
+ <value>header_mod</value>
</param>
<param>
<key>_enabled</key>
@@ -233,11 +233,11 @@
</param>
<param>
<key>value</key>
- <value>(0, 0, 0, 0, 0, 1, 1, -1.0, -1, 1.0, 1, 1.0, -1, -1.0, -1, 1.0, 1, -1.0, 1, 1.0, 1, -1.0, -1, -1.0, -1, 1.0, -1, 1.0, -1, 1.0, 1, -1.0, 0, 1.0, 1, -1.0, 1, 1.0, -1, -1.0, 1, -1.0, -1, -1.0, 1, 1.0, 1, -1.0, 1, 1.0, -1, 1.0, -1, -1.0, -1, 1.0, 1, -1.0, 0, 0, 0, 0, 0, 0)</value>
+ <value>digital.constellation_bpsk()</value>
</param>
<param>
<key>_coordinate</key>
- <value>(457, 64)</value>
+ <value>(490, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -248,7 +248,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>sync_word1</value>
+ <value>packet_len</value>
</param>
<param>
<key>_enabled</key>
@@ -256,11 +256,11 @@
</param>
<param>
<key>value</key>
- <value>(0, 0, 0, 0, 0, 0, 0, -1.0, 0, 1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, -1.0, 0, 1.0, 0, 1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, -1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 0, 0, 0, 0, 0)</value>
+ <value>96</value>
</param>
<param>
<key>_coordinate</key>
- <value>(313, 64)</value>
+ <value>(1034, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -271,7 +271,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>samp_rate</value>
+ <value>pilot_carriers</value>
</param>
<param>
<key>_enabled</key>
@@ -279,11 +279,11 @@
</param>
<param>
<key>value</key>
- <value>3200000</value>
+ <value>((-21, -7, 7, 21,),)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(218, 64)</value>
+ <value>(692, 70)</value>
</param>
<param>
<key>_rotation</key>
@@ -291,22 +291,22 @@
</param>
</block>
<block>
- <key>virtual_sink</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>virtual_sink_0_0</value>
+ <value>pilot_symbols</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>stream_id</key>
- <value>Payload Stream</value>
+ <key>value</key>
+ <value>((1, 1, 1, -1,),)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(968, 374)</value>
+ <value>(813, 70)</value>
</param>
<param>
<key>_rotation</key>
@@ -314,22 +314,22 @@
</param>
</block>
<block>
- <key>virtual_sink</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>virtual_sink_0</value>
+ <value>occupied_carriers</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>stream_id</key>
- <value>Header Stream</value>
+ <key>value</key>
+ <value>(range(-26, -21) + range(-20, -7) + range(-6, 0) + range(1, 7) + range(8, 21) + range(22, 27),)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(969, 305)</value>
+ <value>(541, 70)</value>
</param>
<param>
<key>_rotation</key>
@@ -337,30 +337,22 @@
</param>
</block>
<block>
- <key>digital_ofdm_sync_sc_cfb</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>digital_ofdm_sync_sc_cfb_0</value>
+ <value>length_tag_key</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>fft_len</key>
- <value>fft_len</value>
- </param>
- <param>
- <key>cp_len</key>
- <value>fft_len/4</value>
- </param>
- <param>
- <key>use_even_carriers</key>
- <value>False</value>
+ <key>value</key>
+ <value>"frame_len"</value>
</param>
<param>
<key>_coordinate</key>
- <value>(244, 137)</value>
+ <value>(367, -1)</value>
</param>
<param>
<key>_rotation</key>
@@ -368,34 +360,22 @@
</param>
</block>
<block>
- <key>analog_noise_source_x</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>analog_noise_source_x_0</value>
+ <value>packet_length_tag_key</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>noise_type</key>
- <value>analog.GR_GAUSSIAN</value>
- </param>
- <param>
- <key>amp</key>
- <value>1</value>
- </param>
- <param>
- <key>seed</key>
- <value>0</value>
+ <key>value</key>
+ <value>"packet_len"</value>
</param>
<param>
<key>_coordinate</key>
- <value>(0, 220)</value>
+ <value>(1132, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -403,30 +383,22 @@
</param>
</block>
<block>
- <key>blocks_multiply_xx</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>blocks_multiply_xx_0</value>
+ <value>header_formatter</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>num_inputs</key>
- <value>2</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
+ <key>value</key>
+ <value>digital.packet_header_ofdm(occupied_carriers, n_syms=1, len_tag_key=packet_length_tag_key, frame_len_tag_key=length_tag_key, bits_per_header_sym=header_mod.bits_per_symbol(), bits_per_payload_sym=payload_mod.bits_per_symbol(), scramble_header=False)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(798, 137)</value>
+ <value>(855, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -434,30 +406,22 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>import</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>import_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>samples_per_second</key>
- <value>samp_rate</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
+ <key>import</key>
+ <value>from gnuradio.digital.utils import tagged_streams</value>
</param>
<param>
<key>_coordinate</key>
- <value>(186, 235)</value>
+ <value>(163, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -465,697 +429,651 @@
</param>
</block>
<block>
- <key>uhd_usrp_source</key>
+ <key>analog_random_source_x</key>
<param>
<key>id</key>
- <value>uhd_usrp_source_0</value>
+ <value>analog_random_source_x_0</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
+ <value>True</value>
</param>
<param>
<key>type</key>
- <value>fc32</value>
- </param>
- <param>
- <key>otw</key>
- <value></value>
- </param>
- <param>
- <key>stream_args</key>
- <value></value>
+ <value>byte</value>
</param>
<param>
- <key>dev_addr</key>
- <value></value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>sync</key>
- <value></value>
+ <key>max</key>
+ <value>255</value>
</param>
<param>
- <key>clock_rate</key>
- <value>0.0</value>
+ <key>num_samps</key>
+ <value>1000</value>
</param>
<param>
- <key>num_mboards</key>
- <value>1</value>
+ <key>repeat</key>
+ <value>True</value>
</param>
<param>
- <key>clock_source0</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>time_source0</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>sd_spec0</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(2, 167)</value>
</param>
<param>
- <key>clock_source1</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>analog_frequency_modulator_fc</key>
<param>
- <key>time_source1</key>
- <value></value>
+ <key>id</key>
+ <value>analog_frequency_modulator_fc_0</value>
</param>
<param>
- <key>sd_spec1</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>clock_source2</key>
- <value></value>
+ <key>sensitivity</key>
+ <value>-2.0/fft_len</value>
</param>
<param>
- <key>time_source2</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>sd_spec2</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>clock_source3</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(920, 171)</value>
</param>
<param>
- <key>time_source3</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
<param>
- <key>sd_spec3</key>
- <value></value>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
</param>
<param>
- <key>clock_source4</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>time_source4</key>
- <value></value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>sd_spec4</key>
- <value></value>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
</param>
<param>
- <key>clock_source5</key>
- <value></value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>time_source5</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>sd_spec5</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>clock_source6</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(440, 187)</value>
</param>
<param>
- <key>time_source6</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_delay</key>
<param>
- <key>sd_spec6</key>
- <value></value>
+ <key>id</key>
+ <value>blocks_delay_0</value>
</param>
<param>
- <key>clock_source7</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>time_source7</key>
- <value></value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>sd_spec7</key>
- <value></value>
+ <key>delay</key>
+ <value>fft_len+fft_len/4</value>
</param>
<param>
- <key>nchan</key>
+ <key>num_ports</key>
<value>1</value>
</param>
<param>
- <key>samp_rate</key>
- <value>samp_rate</value>
- </param>
- <param>
- <key>center_freq0</key>
- <value>0</value>
- </param>
- <param>
- <key>gain0</key>
- <value>0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>ant0</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw0</key>
- <value>0</value>
- </param>
- <param>
- <key>center_freq1</key>
- <value>0</value>
- </param>
- <param>
- <key>gain1</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant1</key>
- <value></value>
- </param>
- <param>
- <key>bw1</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(637, 294)</value>
</param>
<param>
- <key>center_freq2</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_multiply_xx</key>
<param>
- <key>gain2</key>
- <value>0</value>
+ <key>id</key>
+ <value>blocks_multiply_xx_0</value>
</param>
<param>
- <key>ant2</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>bw2</key>
- <value>0</value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>center_freq3</key>
- <value>0</value>
+ <key>num_inputs</key>
+ <value>2</value>
</param>
<param>
- <key>gain3</key>
- <value>0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>ant3</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw3</key>
- <value>0</value>
- </param>
- <param>
- <key>center_freq4</key>
- <value>0</value>
- </param>
- <param>
- <key>gain4</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant4</key>
- <value></value>
- </param>
- <param>
- <key>bw4</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(1117, 265)</value>
</param>
<param>
- <key>center_freq5</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_ofdm_sync_sc_cfb</key>
<param>
- <key>gain5</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_ofdm_sync_sc_cfb_0</value>
</param>
<param>
- <key>ant5</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>bw5</key>
- <value>0</value>
+ <key>fft_len</key>
+ <value>fft_len</value>
</param>
<param>
- <key>center_freq6</key>
- <value>0</value>
+ <key>cp_len</key>
+ <value>fft_len/4</value>
</param>
<param>
- <key>gain6</key>
- <value>0</value>
+ <key>use_even_carriers</key>
+ <value>False</value>
</param>
<param>
- <key>ant6</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw6</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq7</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(627, 175)</value>
</param>
<param>
- <key>gain7</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_packet_headerparser_b</key>
<param>
- <key>ant7</key>
- <value></value>
- </param>
- <param>
- <key>bw7</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_packet_headerparser_b_0</value>
</param>
<param>
- <key>center_freq8</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gain8</key>
- <value>0</value>
+ <key>header_formatter</key>
+ <value>header_formatter.base()</value>
</param>
<param>
- <key>ant8</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw8</key>
- <value>0</value>
- </param>
- <param>
- <key>center_freq9</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>gain9</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(634, 529)</value>
</param>
<param>
- <key>ant9</key>
- <value></value>
+ <key>_rotation</key>
+ <value>180</value>
</param>
+ </block>
+ <block>
+ <key>digital_constellation_decoder_cb</key>
<param>
- <key>bw9</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_constellation_decoder_cb_0</value>
</param>
<param>
- <key>center_freq10</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gain10</key>
- <value>0</value>
+ <key>constellation</key>
+ <value>header_mod.base()</value>
</param>
<param>
- <key>ant10</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw10</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq11</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(903, 530)</value>
</param>
<param>
- <key>gain11</key>
- <value>0</value>
+ <key>_rotation</key>
+ <value>180</value>
</param>
+ </block>
+ <block>
+ <key>fft_vxx</key>
<param>
- <key>ant11</key>
- <value></value>
+ <key>id</key>
+ <value>fft_vxx_0</value>
</param>
<param>
- <key>bw11</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>center_freq12</key>
- <value>0</value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>gain12</key>
- <value>0</value>
+ <key>fft_size</key>
+ <value>fft_len</value>
</param>
<param>
- <key>ant12</key>
- <value></value>
+ <key>forward</key>
+ <value>True</value>
</param>
<param>
- <key>bw12</key>
- <value>0</value>
+ <key>window</key>
+ <value>()</value>
</param>
<param>
- <key>center_freq13</key>
- <value>0</value>
+ <key>shift</key>
+ <value>True</value>
</param>
<param>
- <key>gain13</key>
- <value>0</value>
+ <key>nthreads</key>
+ <value>1</value>
</param>
<param>
- <key>ant13</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw13</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq14</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(217, 576)</value>
</param>
<param>
- <key>gain14</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>ant14</key>
- <value></value>
- </param>
- <param>
- <key>bw14</key>
- <value>0</value>
+ <key>id</key>
+ <value>virtual_sink_0</value>
</param>
<param>
- <key>center_freq15</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gain15</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>Header Stream</value>
</param>
<param>
- <key>ant15</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(1098, 414)</value>
</param>
<param>
- <key>bw15</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_stream_to_tagged_stream</key>
<param>
- <key>center_freq16</key>
- <value>0</value>
+ <key>id</key>
+ <value>blocks_stream_to_tagged_stream_0</value>
</param>
<param>
- <key>gain16</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant16</key>
- <value></value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>bw16</key>
- <value>0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>center_freq17</key>
- <value>0</value>
+ <key>packet_len</key>
+ <value>packet_len</value>
</param>
<param>
- <key>gain17</key>
- <value>0</value>
+ <key>len_tag_key</key>
+ <value>packet_length_tag_key</value>
</param>
<param>
- <key>ant17</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw17</key>
- <value>0</value>
- </param>
- <param>
- <key>center_freq18</key>
- <value>0</value>
- </param>
- <param>
- <key>gain18</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant18</key>
- <value></value>
- </param>
- <param>
- <key>bw18</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(171, 182)</value>
</param>
<param>
- <key>center_freq19</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_header_payload_demux</key>
<param>
- <key>gain19</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_header_payload_demux_0</value>
</param>
<param>
- <key>ant19</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>bw19</key>
- <value>0</value>
+ <key>header_len</key>
+ <value>3</value>
</param>
<param>
- <key>center_freq20</key>
- <value>0</value>
+ <key>items_per_symbol</key>
+ <value>fft_len</value>
</param>
<param>
- <key>gain20</key>
- <value>0</value>
+ <key>guard_interval</key>
+ <value>fft_len/4</value>
</param>
<param>
- <key>ant20</key>
- <value></value>
+ <key>length_tag_key</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>bw20</key>
- <value>0</value>
+ <key>trigger_tag_key</key>
+ <value>""</value>
</param>
<param>
- <key>center_freq21</key>
- <value>0</value>
+ <key>output_symbols</key>
+ <value>True</value>
</param>
<param>
- <key>gain21</key>
- <value>0</value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>ant21</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw21</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq22</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(775, 408)</value>
</param>
<param>
- <key>gain22</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_ofdm_chanest_vcvc</key>
<param>
- <key>ant22</key>
- <value></value>
+ <key>id</key>
+ <value>digital_ofdm_chanest_vcvc_0</value>
</param>
<param>
- <key>bw22</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>center_freq23</key>
- <value>0</value>
+ <key>sync_symbol1</key>
+ <value>sync_word1</value>
</param>
<param>
- <key>gain23</key>
- <value>0</value>
+ <key>sync_symbol2</key>
+ <value>sync_word2</value>
</param>
<param>
- <key>ant23</key>
- <value></value>
+ <key>n_data_symbols</key>
+ <value>1</value>
</param>
<param>
- <key>bw23</key>
+ <key>eq_noise_red_len</key>
<value>0</value>
</param>
<param>
- <key>center_freq24</key>
- <value>0</value>
+ <key>max_carr_offset</key>
+ <value>3</value>
</param>
<param>
- <key>gain24</key>
- <value>0</value>
+ <key>force_one_symbol</key>
+ <value>False</value>
</param>
<param>
- <key>ant24</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw24</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq25</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(442, 584)</value>
</param>
<param>
- <key>gain25</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_ofdm_frame_equalizer_vcvc</key>
<param>
- <key>ant25</key>
- <value></value>
+ <key>id</key>
+ <value>digital_ofdm_frame_equalizer_vcvc_0</value>
</param>
<param>
- <key>bw25</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>center_freq26</key>
- <value>0</value>
+ <key>fft_len</key>
+ <value>fft_len</value>
</param>
<param>
- <key>gain26</key>
- <value>0</value>
+ <key>cp_len</key>
+ <value>fft_len/4</value>
</param>
<param>
- <key>ant26</key>
- <value></value>
+ <key>equalizer</key>
+ <value>header_equalizer.base()</value>
</param>
<param>
- <key>bw26</key>
- <value>0</value>
+ <key>len_tag_key</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>center_freq27</key>
- <value>0</value>
+ <key>propagate_channel_state</key>
+ <value>True</value>
</param>
<param>
- <key>gain27</key>
- <value>0</value>
+ <key>fixed_frame_len</key>
+ <value>1</value>
</param>
<param>
- <key>ant27</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw27</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq28</key>
- <value>0</value>
- </param>
- <param>
- <key>gain28</key>
- <value>0</value>
- </param>
- <param>
- <key>ant28</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(675, 577)</value>
</param>
<param>
- <key>bw28</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>center_freq29</key>
- <value>0</value>
+ <key>id</key>
+ <value>virtual_source_1</value>
</param>
<param>
- <key>gain29</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant29</key>
- <value></value>
+ <key>stream_id</key>
+ <value>Payload Stream</value>
</param>
<param>
- <key>bw29</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(0, 732)</value>
</param>
<param>
- <key>center_freq30</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_ofdm_serializer_vcc</key>
<param>
- <key>gain30</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_ofdm_serializer_vcc_header</value>
</param>
<param>
- <key>ant30</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>bw30</key>
- <value>0</value>
+ <key>fft_len</key>
+ <value>fft_len</value>
</param>
<param>
- <key>center_freq31</key>
- <value>0</value>
+ <key>occupied_carriers</key>
+ <value>occupied_carriers</value>
</param>
<param>
- <key>gain31</key>
- <value>0</value>
+ <key>len_tag_key</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>ant31</key>
+ <key>packet_len_tag_key</key>
<value></value>
</param>
<param>
- <key>bw31</key>
- <value>0</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(0, 135)</value>
- </param>
- <param>
- <key>_rotation</key>
+ <key>symbols_skipped</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>blocks_delay</key>
<param>
- <key>id</key>
- <value>blocks_delay_0</value>
+ <key>carr_offset_key</key>
+ <value></value>
</param>
<param>
- <key>_enabled</key>
+ <key>input_is_shifted</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>delay</key>
- <value>fft_len+fft_len/4</value>
- </param>
- <param>
- <key>num_ports</key>
- <value>1</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(398, 235)</value>
+ <value>(914, 584)</value>
</param>
<param>
<key>_rotation</key>
@@ -1163,22 +1081,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>length_tag_key</value>
+ <value>virtual_sink_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>"frame_len"</value>
+ <key>stream_id</key>
+ <value>Payload Stream</value>
</param>
<param>
<key>_coordinate</key>
- <value>(367, -1)</value>
+ <value>(1094, 470)</value>
</param>
<param>
<key>_rotation</key>
@@ -1186,22 +1104,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>header_formatter</value>
+ <value>virtual_source_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>digital.packet_header_ofdm(occupied_carriers, 1, "packet_len", length_tag_key)</value>
+ <key>stream_id</key>
+ <value>Header Stream</value>
</param>
<param>
<key>_coordinate</key>
- <value>(811, -1)</value>
+ <value>(5, 606)</value>
</param>
<param>
<key>_rotation</key>
@@ -1209,89 +1127,50 @@
</param>
</block>
<block>
- <key>digital_header_payload_demux</key>
+ <key>fft_vxx</key>
<param>
<key>id</key>
- <value>digital_header_payload_demux_0</value>
+ <value>fft_vxx_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>header_len</key>
- <value>3</value>
- </param>
- <param>
- <key>items_per_symbol</key>
- <value>fft_len</value>
- </param>
- <param>
- <key>guard_interval</key>
- <value>fft_len/4</value>
- </param>
- <param>
- <key>length_tag_key</key>
- <value>length_tag_key</value>
- </param>
- <param>
- <key>trigger_tag_key</key>
- <value>""</value>
- </param>
- <param>
- <key>output_symbols</key>
- <value>True</value>
- </param>
- <param>
<key>type</key>
<value>complex</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(678, 298)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>digital_ofdm_chanest_vcvc</key>
- <param>
- <key>id</key>
- <value>digital_ofdm_chanest_vcvc_1</value>
+ <key>fft_size</key>
+ <value>fft_len</value>
</param>
<param>
- <key>_enabled</key>
+ <key>forward</key>
<value>True</value>
</param>
<param>
- <key>sync_symbol1</key>
- <value>sync_word1</value>
+ <key>window</key>
+ <value></value>
</param>
<param>
- <key>sync_symbol2</key>
- <value>sync_word2</value>
+ <key>shift</key>
+ <value>True</value>
</param>
<param>
- <key>n_data_symbols</key>
+ <key>nthreads</key>
<value>1</value>
</param>
<param>
- <key>eq_noise_red_len</key>
- <value>0</value>
- </param>
- <param>
- <key>max_carr_offset</key>
- <value>-1</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>force_one_symbol</key>
- <value>False</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(453, 520)</value>
+ <value>(221, 702)</value>
</param>
<param>
<key>_rotation</key>
@@ -1302,7 +1181,7 @@
<key>digital_ofdm_frame_equalizer_vcvc</key>
<param>
<key>id</key>
- <value>digital_ofdm_frame_equalizer_vcvc_0_0</value>
+ <value>digital_ofdm_frame_equalizer_vcvc_1</value>
</param>
<param>
<key>_enabled</key>
@@ -1318,19 +1197,31 @@
</param>
<param>
<key>equalizer</key>
- <value>digital.ofdm_equalizer_simpledfe(fft_len, header_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols).base()</value>
+ <value>payload_equalizer.base()</value>
</param>
<param>
<key>len_tag_key</key>
- <value>length_tag_name</value>
+ <value>length_tag_key</value>
</param>
<param>
<key>propagate_channel_state</key>
<value>True</value>
</param>
<param>
+ <key>fixed_frame_len</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(698, 520)</value>
+ <value>(672, 702)</value>
</param>
<param>
<key>_rotation</key>
@@ -1338,33 +1229,33 @@
</param>
</block>
<block>
- <key>digital_packet_headerparser_b</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>digital_packet_headerparser_b_0</value>
+ <value>virtual_sink_1_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>header_formatter</key>
- <value>header_formatter.formatter()</value>
+ <key>stream_id</key>
+ <value>Payload IQ</value>
</param>
<param>
<key>_coordinate</key>
- <value>(919, 501)</value>
+ <value>(1139, 732)</value>
</param>
<param>
<key>_rotation</key>
- <value>90</value>
+ <value>0</value>
</param>
</block>
<block>
<key>digital_ofdm_serializer_vcc</key>
<param>
<key>id</key>
- <value>digital_ofdm_serializer_vcc_0</value>
+ <value>digital_ofdm_serializer_vcc_payload</value>
</param>
<param>
<key>_enabled</key>
@@ -1384,23 +1275,31 @@
</param>
<param>
<key>packet_len_tag_key</key>
- <value>""</value>
+ <value>packet_length_tag_key</value>
</param>
<param>
<key>symbols_skipped</key>
- <value>0</value>
+ <value>1</value>
</param>
<param>
<key>carr_offset_key</key>
- <value>""</value>
+ <value></value>
</param>
<param>
<key>input_is_shifted</key>
<value>True</value>
</param>
<param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(187, 678)</value>
+ <value>(916, 710)</value>
</param>
<param>
<key>_rotation</key>
@@ -1408,45 +1307,34 @@
</param>
</block>
<block>
- <key>digital_constellation_decoder_cb</key>
+ <key>digital_crc32_bb</key>
<param>
<key>id</key>
- <value>digital_constellation_decoder_cb_0_0</value>
+ <value>digital_crc32_bb_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>constellation</key>
- <value>header_mod.base()</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(449, 702)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
+ <key>check</key>
+ <value>True</value>
</param>
- </block>
- <block>
- <key>virtual_source</key>
<param>
- <key>id</key>
- <value>virtual_source_0_0</value>
+ <key>lengthtagname</key>
+ <value>packet_length_tag_key</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>stream_id</key>
- <value>Payload Stream</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(0, 814)</value>
+ <value>(659, 841)</value>
</param>
<param>
<key>_rotation</key>
@@ -1454,38 +1342,42 @@
</param>
</block>
<block>
- <key>blocks_tag_debug</key>
+ <key>blocks_repack_bits_bb</key>
<param>
<key>id</key>
- <value>blocks_tag_debug_0</value>
+ <value>blocks_repack_bits_bb_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>byte</value>
+ <key>k</key>
+ <value>payload_mod.bits_per_symbol()</value>
</param>
<param>
- <key>name</key>
- <value>Rx Packets</value>
+ <key>l</key>
+ <value>8</value>
</param>
<param>
- <key>num_inputs</key>
- <value>1</value>
+ <key>len_tag_key</key>
+ <value>packet_length_tag_key</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>align_output</key>
+ <value>True</value>
</param>
<param>
- <key>display</key>
- <value>True</value>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(904, 948)</value>
+ <value>(430, 826)</value>
</param>
<param>
<key>_rotation</key>
@@ -1496,7 +1388,7 @@
<key>digital_constellation_decoder_cb</key>
<param>
<key>id</key>
- <value>digital_constellation_decoder_cb_0</value>
+ <value>digital_constellation_decoder_cb_1</value>
</param>
<param>
<key>_enabled</key>
@@ -1507,8 +1399,16 @@
<value>payload_mod.base()</value>
</param>
<param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(416, 956)</value>
+ <value>(183, 848)</value>
</param>
<param>
<key>_rotation</key>
@@ -1516,26 +1416,22 @@
</param>
</block>
<block>
- <key>digital_crc32_bb</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>digital_crc32_bb_0</value>
+ <value>virtual_source_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>check</key>
- <value>False</value>
- </param>
- <param>
- <key>lengthtagname</key>
- <value>"packet_len"</value>
+ <key>stream_id</key>
+ <value>Payload IQ</value>
</param>
<param>
<key>_coordinate</key>
- <value>(663, 948)</value>
+ <value>(1, 851)</value>
</param>
<param>
<key>_rotation</key>
@@ -1543,10 +1439,10 @@
</param>
</block>
<block>
- <key>fft_vxx</key>
+ <key>blocks_tag_debug</key>
<param>
<key>id</key>
- <value>fft_vxx_0</value>
+ <value>blocks_tag_debug_1</value>
</param>
<param>
<key>_enabled</key>
@@ -1554,54 +1450,31 @@
</param>
<param>
<key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>fft_size</key>
- <value>fft_len</value>
- </param>
- <param>
- <key>forward</key>
- <value>True</value>
- </param>
- <param>
- <key>window</key>
- <value></value>
+ <value>byte</value>
</param>
<param>
- <key>shift</key>
- <value>True</value>
+ <key>name</key>
+ <value>Rx Bytes</value>
</param>
<param>
- <key>nthreads</key>
+ <key>num_inputs</key>
<value>1</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(223, 512)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>virtual_source</key>
- <param>
- <key>id</key>
- <value>virtual_source_0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>_enabled</key>
+ <key>display</key>
<value>True</value>
</param>
<param>
- <key>stream_id</key>
- <value>Header Stream</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(1, 544)</value>
+ <value>(898, 841)</value>
</param>
<param>
<key>_rotation</key>
@@ -1609,65 +1482,50 @@
</param>
</block>
<block>
- <key>analog_frequency_modulator_fc</key>
+ <key>channels_channel_model</key>
<param>
<key>id</key>
- <value>analog_frequency_modulator_fc_0</value>
+ <value>channels_channel_model_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>sensitivity</key>
- <value>-2.0/fft_len</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(578, 133)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
+ <key>noise_voltage</key>
+ <value>0.1</value>
</param>
- </block>
- <block>
- <key>fft_vxx</key>
<param>
- <key>id</key>
- <value>fft_vxx_0_0</value>
+ <key>freq_offset</key>
+ <value>0 * 1.0/fft_len</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>epsilon</key>
+ <value>1.0</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
+ <key>taps</key>
+ <value>1.0</value>
</param>
<param>
- <key>fft_size</key>
- <value>fft_len</value>
+ <key>seed</key>
+ <value>0</value>
</param>
<param>
- <key>forward</key>
+ <key>block_tags</key>
<value>True</value>
</param>
<param>
- <key>window</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>shift</key>
- <value>True</value>
- </param>
- <param>
- <key>nthreads</key>
- <value>1</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(218, 782)</value>
+ <value>(303, 372)</value>
</param>
<param>
<key>_rotation</key>
@@ -1675,10 +1533,10 @@
</param>
</block>
<block>
- <key>digital_ofdm_serializer_vcc</key>
+ <key>digital_ofdm_tx</key>
<param>
<key>id</key>
- <value>digital_ofdm_serializer_vcc_1</value>
+ <value>digital_ofdm_tx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -1689,71 +1547,64 @@
<value>fft_len</value>
</param>
<param>
- <key>occupied_carriers</key>
- <value>occupied_carriers</value>
- </param>
- <param>
- <key>len_tag_key</key>
- <value>length_tag_key</value>
+ <key>cp_len</key>
+ <value>fft_len/4</value>
</param>
<param>
- <key>packet_len_tag_key</key>
- <value>"packet_len"</value>
+ <key>packet_len_key</key>
+ <value>packet_length_tag_key</value>
</param>
<param>
- <key>symbols_skipped</key>
- <value>0</value>
+ <key>occupied_carriers</key>
+ <value>occupied_carriers</value>
</param>
<param>
- <key>carr_offset_key</key>
- <value>""</value>
+ <key>pilot_carriers</key>
+ <value>pilot_carriers</value>
</param>
<param>
- <key>input_is_shifted</key>
- <value>True</value>
+ <key>pilot_symbols</key>
+ <value>pilot_symbols</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(778, 790)</value>
+ <key>sync_word1</key>
+ <value>sync_word1</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>sync_word2</key>
+ <value>sync_word2</value>
</param>
- </block>
- <block>
- <key>digital_ofdm_frame_equalizer_vcvc</key>
<param>
- <key>id</key>
- <value>digital_ofdm_frame_equalizer_vcvc_1</value>
+ <key>header_mod</key>
+ <value>"BPSK"</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>payload_mod</key>
+ <value>"QPSK"</value>
</param>
<param>
- <key>fft_len</key>
- <value>fft_len</value>
+ <key>rolloff</key>
+ <value>0</value>
</param>
<param>
- <key>cp_len</key>
- <value>fft_len/4</value>
+ <key>scramble_bits</key>
+ <value>False</value>
</param>
<param>
- <key>equalizer</key>
- <value>digital.ofdm_equalizer_simpledfe(fft_len, header_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols, 2).base()</value>
+ <key>log</key>
+ <value>True</value>
</param>
<param>
- <key>len_tag_key</key>
- <value>length_tag_key</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>propagate_channel_state</key>
- <value>True</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(474, 782)</value>
+ <value>(58, 327)</value>
</param>
<param>
<key>_rotation</key>
@@ -1761,39 +1612,33 @@
</param>
</block>
<connection>
- <source_block_id>digital_ofdm_frame_equalizer_vcvc_0_0</source_block_id>
- <sink_block_id>digital_ofdm_serializer_vcc_0</sink_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>blocks_stream_to_tagged_stream_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>virtual_source_0</source_block_id>
- <sink_block_id>fft_vxx_0</sink_block_id>
+ <source_block_id>blocks_stream_to_tagged_stream_0</source_block_id>
+ <sink_block_id>digital_ofdm_tx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_packet_headerparser_b_0</source_block_id>
- <sink_block_id>digital_header_payload_demux_0</sink_block_id>
- <source_key>header_data</source_key>
- <sink_key>header_data</sink_key>
- </connection>
- <connection>
- <source_block_id>digital_constellation_decoder_cb_0_0</source_block_id>
- <sink_block_id>digital_packet_headerparser_b_0</sink_block_id>
+ <source_block_id>digital_ofdm_tx_0</source_block_id>
+ <sink_block_id>channels_channel_model_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_serializer_vcc_0</source_block_id>
- <sink_block_id>digital_constellation_decoder_cb_0_0</sink_block_id>
+ <source_block_id>channels_channel_model_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_header_payload_demux_0</source_block_id>
- <sink_block_id>virtual_sink_0_0</sink_block_id>
- <source_key>1</source_key>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>digital_ofdm_sync_sc_cfb_0</sink_block_id>
+ <source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
@@ -1803,34 +1648,34 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>digital_ofdm_sync_sc_cfb_0</sink_block_id>
+ <source_block_id>digital_ofdm_sync_sc_cfb_0</source_block_id>
+ <sink_block_id>analog_frequency_modulator_fc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>uhd_usrp_source_0</source_block_id>
- <sink_block_id>digital_ofdm_sync_sc_cfb_0</sink_block_id>
+ <source_block_id>analog_frequency_modulator_fc_0</source_block_id>
+ <sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_noise_source_x_0</source_block_id>
- <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_block_id>blocks_multiply_xx_0</source_block_id>
+ <sink_block_id>digital_header_payload_demux_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>analog_frequency_modulator_fc_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_0</sink_block_id>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>blocks_delay_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_sync_sc_cfb_0</source_block_id>
- <sink_block_id>analog_frequency_modulator_fc_0</sink_block_id>
+ <source_block_id>blocks_delay_0</source_block_id>
+ <sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>0</sink_key>
+ <sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>digital_ofdm_sync_sc_cfb_0</source_block_id>
@@ -1839,74 +1684,98 @@
<sink_key>1</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_xx_0</source_block_id>
+ <source_block_id>digital_header_payload_demux_0</source_block_id>
+ <sink_block_id>virtual_sink_1</sink_block_id>
+ <source_key>1</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>digital_packet_headerparser_b_0</source_block_id>
<sink_block_id>digital_header_payload_demux_0</sink_block_id>
+ <source_key>header_data</source_key>
+ <sink_key>header_data</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>digital_ofdm_chanest_vcvc_0</source_block_id>
+ <sink_block_id>digital_ofdm_frame_equalizer_vcvc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_delay_0</source_block_id>
- <sink_block_id>blocks_multiply_xx_0</sink_block_id>
+ <source_block_id>digital_ofdm_frame_equalizer_vcvc_0</source_block_id>
+ <sink_block_id>digital_ofdm_serializer_vcc_header</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_throttle_0</source_block_id>
- <sink_block_id>blocks_delay_0</sink_block_id>
+ <source_block_id>digital_ofdm_serializer_vcc_header</source_block_id>
+ <sink_block_id>digital_constellation_decoder_cb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>uhd_usrp_source_0</source_block_id>
- <sink_block_id>blocks_delay_0</sink_block_id>
+ <source_block_id>digital_constellation_decoder_cb_0</source_block_id>
+ <sink_block_id>digital_packet_headerparser_b_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>fft_vxx_0</source_block_id>
- <sink_block_id>digital_ofdm_chanest_vcvc_1</sink_block_id>
+ <sink_block_id>digital_ofdm_chanest_vcvc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_chanest_vcvc_1</source_block_id>
- <sink_block_id>digital_ofdm_frame_equalizer_vcvc_0_0</sink_block_id>
+ <source_block_id>virtual_source_0</source_block_id>
+ <sink_block_id>fft_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_crc32_bb_0</source_block_id>
- <sink_block_id>blocks_tag_debug_0</sink_block_id>
+ <source_block_id>virtual_source_1</source_block_id>
+ <sink_block_id>fft_vxx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_constellation_decoder_cb_0</source_block_id>
- <sink_block_id>digital_crc32_bb_0</sink_block_id>
+ <source_block_id>digital_ofdm_serializer_vcc_payload</source_block_id>
+ <sink_block_id>virtual_sink_1_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_serializer_vcc_1</source_block_id>
- <sink_block_id>digital_constellation_decoder_cb_0</sink_block_id>
+ <source_block_id>digital_ofdm_frame_equalizer_vcvc_1</source_block_id>
+ <sink_block_id>digital_ofdm_serializer_vcc_payload</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>virtual_source_0_0</source_block_id>
- <sink_block_id>fft_vxx_0_0</sink_block_id>
+ <source_block_id>fft_vxx_1</source_block_id>
+ <sink_block_id>digital_ofdm_frame_equalizer_vcvc_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>fft_vxx_0_0</source_block_id>
- <sink_block_id>digital_ofdm_frame_equalizer_vcvc_1</sink_block_id>
+ <source_block_id>digital_crc32_bb_0</source_block_id>
+ <sink_block_id>blocks_tag_debug_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_frame_equalizer_vcvc_1</source_block_id>
- <sink_block_id>digital_ofdm_serializer_vcc_1</sink_block_id>
+ <source_block_id>blocks_repack_bits_bb_0</source_block_id>
+ <sink_block_id>digital_crc32_bb_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0</source_block_id>
+ <sink_block_id>digital_constellation_decoder_cb_1</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>digital_constellation_decoder_cb_1</source_block_id>
+ <sink_block_id>blocks_repack_bits_bb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gr-digital/examples/ofdm/tx_ofdm.grc b/gr-digital/examples/ofdm/tx_ofdm.grc
index dcaeed2e72..c2995d919e 100644
--- a/gr-digital/examples/ofdm/tx_ofdm.grc
+++ b/gr-digital/examples/ofdm/tx_ofdm.grc
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
- <timestamp>Tue May 14 10:52:12 2013</timestamp>
+ <timestamp>Sun Oct 27 16:23:43 2013</timestamp>
<block>
<key>options</key>
<param>
@@ -61,57 +61,22 @@
</param>
</block>
<block>
- <key>virtual_source</key>
- <param>
- <key>id</key>
- <value>virtual_source_0_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>stream_id</key>
- <value>Payload Bits</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(0, 458)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>blocks_tagged_stream_mux</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>blocks_tagged_stream_mux_0</value>
+ <value>length_tag_key</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>ninputs</key>
- <value>2</value>
- </param>
- <param>
- <key>lengthtagname</key>
- <value>length_tag_name</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
+ <key>value</key>
+ <value>"packet_len"</value>
</param>
<param>
<key>_coordinate</key>
- <value>(510, 428)</value>
+ <value>(352, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -119,22 +84,22 @@
</param>
</block>
<block>
- <key>virtual_sink</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>virtual_sink_0_0</value>
+ <value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>stream_id</key>
- <value>Payload Bits</value>
+ <key>value</key>
+ <value>100000</value>
</param>
<param>
<key>_coordinate</key>
- <value>(746, 312)</value>
+ <value>(255, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -142,45 +107,22 @@
</param>
</block>
<block>
- <key>virtual_source</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>virtual_source_0</value>
+ <value>rolloff</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>stream_id</key>
- <value>Header Bits</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(0, 384)</value>
- </param>
- <param>
- <key>_rotation</key>
+ <key>value</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>digital_packet_headergenerator_bb</key>
- <param>
- <key>id</key>
- <value>digital_packet_headergenerator_bb_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>header_formatter</key>
- <value>header_formatter.formatter()</value>
- </param>
<param>
<key>_coordinate</key>
- <value>(514, 231)</value>
+ <value>(898, -1)</value>
</param>
<param>
<key>_rotation</key>
@@ -188,34 +130,22 @@
</param>
</block>
<block>
- <key>blocks_repack_bits_bb</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>blocks_repack_bits_bb_0</value>
+ <value>payload_mod</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>k</key>
- <value>8</value>
- </param>
- <param>
- <key>l</key>
- <value>payload_mod.bits_per_symbol()</value>
- </param>
- <param>
- <key>len_tag_key</key>
- <value>length_tag_name</value>
- </param>
- <param>
- <key>align_output</key>
- <value>False</value>
+ <key>value</key>
+ <value>digital.constellation_qpsk()</value>
</param>
<param>
<key>_coordinate</key>
- <value>(522, 289)</value>
+ <value>(734, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -223,22 +153,22 @@
</param>
</block>
<block>
- <key>virtual_sink</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>header_bits</value>
+ <value>header_mod</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>stream_id</key>
- <value>Header Bits</value>
+ <key>value</key>
+ <value>digital.constellation_bpsk()</value>
</param>
<param>
<key>_coordinate</key>
- <value>(748, 231)</value>
+ <value>(567, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -246,26 +176,22 @@
</param>
</block>
<block>
- <key>digital_crc32_bb</key>
+ <key>variable</key>
<param>
<key>id</key>
- <value>digital_crc32_bb_0</value>
+ <value>packet_len</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>check</key>
- <value>False</value>
- </param>
- <param>
- <key>lengthtagname</key>
- <value>length_tag_name</value>
+ <key>value</key>
+ <value>96</value>
</param>
<param>
<key>_coordinate</key>
- <value>(242, 223)</value>
+ <value>(476, 0)</value>
</param>
<param>
<key>_rotation</key>
@@ -299,7 +225,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>length_tag_name</value>
+ <value>header_formatter</value>
</param>
<param>
<key>_enabled</key>
@@ -307,11 +233,11 @@
</param>
<param>
<key>value</key>
- <value>"packet_len"</value>
+ <value>digital.packet_header_ofdm(occupied_carriers, 1, length_tag_key)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(352, 0)</value>
+ <value>(708, 64)</value>
</param>
<param>
<key>_rotation</key>
@@ -322,7 +248,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>packet_len</value>
+ <value>pilot_carriers</value>
</param>
<param>
<key>_enabled</key>
@@ -330,11 +256,11 @@
</param>
<param>
<key>value</key>
- <value>96</value>
+ <value>((-21, -7, 7, 21,),)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(476, 0)</value>
+ <value>(480, 64)</value>
</param>
<param>
<key>_rotation</key>
@@ -345,7 +271,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>header_mod</value>
+ <value>occupied_carriers</value>
</param>
<param>
<key>_enabled</key>
@@ -353,11 +279,11 @@
</param>
<param>
<key>value</key>
- <value>digital.constellation_bpsk()</value>
+ <value>(range(-26, -21) + range(-20, -7) + range(-6, 0) + range(1, 7) + range(8, 21) + range(22, 27),)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(567, 0)</value>
+ <value>(329, 64)</value>
</param>
<param>
<key>_rotation</key>
@@ -368,7 +294,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>payload_mod</value>
+ <value>pilot_symbols</value>
</param>
<param>
<key>_enabled</key>
@@ -376,11 +302,11 @@
</param>
<param>
<key>value</key>
- <value>digital.constellation_qpsk()</value>
+ <value>((1, 1, 1, -1,),)</value>
</param>
<param>
<key>_coordinate</key>
- <value>(734, 0)</value>
+ <value>(601, 64)</value>
</param>
<param>
<key>_rotation</key>
@@ -391,7 +317,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>rolloff</value>
+ <value>sync_word2</value>
</param>
<param>
<key>_enabled</key>
@@ -399,11 +325,11 @@
</param>
<param>
<key>value</key>
- <value>0</value>
+ <value>[0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 0, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 0, 0, 0, 0, 0] </value>
</param>
<param>
<key>_coordinate</key>
- <value>(898, -1)</value>
+ <value>(496, 128)</value>
</param>
<param>
<key>_rotation</key>
@@ -414,7 +340,7 @@
<key>variable</key>
<param>
<key>id</key>
- <value>samp_rate</value>
+ <value>sync_word1</value>
</param>
<param>
<key>_enabled</key>
@@ -422,11 +348,11 @@
</param>
<param>
<key>value</key>
- <value>100000</value>
+ <value>[0., 0., 0., 0., 0., 0., 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., -1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., -1.41421356, 0., -1.41421356, 0., -1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 1.41421356, 0., -1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 1.41421356, 0., 0., 0., 0., 0., 0.]</value>
</param>
<param>
<key>_coordinate</key>
- <value>(255, 0)</value>
+ <value>(352, 128)</value>
</param>
<param>
<key>_rotation</key>
@@ -434,22 +360,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>sync_word2</value>
+ <value>virtual_source_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>(0, 0, 0, 0, 0, 1, 1, -1.0, -1, 1.0, 1, 1.0, -1, -1.0, -1, 1.0, 1, -1.0, 1, 1.0, 1, -1.0, -1, -1.0, -1, 1.0, -1, 1.0, -1, 1.0, 1, -1.0, 0, 1.0, 1, -1.0, 1, 1.0, -1, -1.0, 1, -1.0, -1, -1.0, 1, 1.0, 1, -1.0, 1, 1.0, -1, 1.0, -1, -1.0, -1, 1.0, 1, -1.0, 0, 0, 0, 0, 0, 0)</value>
+ <key>stream_id</key>
+ <value>Payload Bits</value>
</param>
<param>
<key>_coordinate</key>
- <value>(496, 128)</value>
+ <value>(0, 458)</value>
</param>
<param>
<key>_rotation</key>
@@ -457,22 +383,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>import</key>
<param>
<key>id</key>
- <value>sync_word1</value>
+ <value>import_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>(0, 0, 0, 0, 0, 0, 0, -1.0, 0, 1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, -1.0, 0, 1.0, 0, 1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, -1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, 1.0, 0, -1.0, 0, 1.0, 0, -1.0, 0, 0, 0, 0, 0, 0)</value>
+ <key>import</key>
+ <value>import numpy</value>
</param>
<param>
<key>_coordinate</key>
- <value>(352, 128)</value>
+ <value>(237, 93)</value>
</param>
<param>
<key>_rotation</key>
@@ -480,22 +406,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>import</key>
<param>
<key>id</key>
- <value>occupied_carriers</value>
+ <value>import_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>(range(-26, -21) + range(-20, -7) + range(-6, 0) + range(1, 7) + range(8, 21) + range(22, 27),)</value>
+ <key>import</key>
+ <value>from gnuradio.digital.utils import tagged_streams</value>
</param>
<param>
<key>_coordinate</key>
- <value>(329, 64)</value>
+ <value>(99, 93)</value>
</param>
<param>
<key>_rotation</key>
@@ -503,22 +429,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>import</key>
<param>
<key>id</key>
- <value>pilot_carriers</value>
+ <value>import_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>((-21, -7, 7, 21,),)</value>
+ <key>import</key>
+ <value>import random</value>
</param>
<param>
<key>_coordinate</key>
- <value>(480, 64)</value>
+ <value>(3, 94)</value>
</param>
<param>
<key>_rotation</key>
@@ -526,22 +452,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>virtual_source</key>
<param>
<key>id</key>
- <value>header_formatter</value>
+ <value>virtual_source_0_0_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>digital.packet_header_ofdm(occupied_carriers, 1, length_tag_name)</value>
+ <key>stream_id</key>
+ <value>Time Domain</value>
</param>
<param>
<key>_coordinate</key>
- <value>(708, 64)</value>
+ <value>(1, 747)</value>
</param>
<param>
<key>_rotation</key>
@@ -549,22 +475,22 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>pilot_symbols</value>
+ <value>virtual_sink_0_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>value</key>
- <value>((1, 1, 1, -1,),)</value>
+ <key>stream_id</key>
+ <value>Pre-OFDM</value>
</param>
<param>
<key>_coordinate</key>
- <value>(601, 64)</value>
+ <value>(745, 441)</value>
</param>
<param>
<key>_rotation</key>
@@ -572,68 +498,46 @@
</param>
</block>
<block>
- <key>import</key>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
<key>id</key>
- <value>import_0</value>
+ <value>digital_chunks_to_symbols_xx_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>import</key>
- <value>import numpy</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(237, 93)</value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>_rotation</key>
- <value>0</value>
+ <key>out_type</key>
+ <value>complex</value>
</param>
- </block>
- <block>
- <key>import</key>
<param>
- <key>id</key>
- <value>import_1</value>
+ <key>symbol_table</key>
+ <value>payload_mod.points()</value>
</param>
<param>
- <key>_enabled</key>
- <value>True</value>
+ <key>dimension</key>
+ <value>1</value>
</param>
<param>
- <key>import</key>
- <value>from gnuradio.digital.utils import tagged_streams</value>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(99, 93)</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>_rotation</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>import</key>
- <param>
- <key>id</key>
- <value>import_0_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>import</key>
- <value>import random</value>
- </param>
<param>
<key>_coordinate</key>
- <value>(3, 94)</value>
+ <value>(212, 450)</value>
</param>
<param>
<key>_rotation</key>
@@ -644,7 +548,7 @@
<key>virtual_source</key>
<param>
<key>id</key>
- <value>virtual_source_0_0_0_0</value>
+ <value>virtual_source_0_0_0</value>
</param>
<param>
<key>_enabled</key>
@@ -652,11 +556,11 @@
</param>
<param>
<key>stream_id</key>
- <value>Time Domain</value>
+ <value>Pre-OFDM</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1, 747)</value>
+ <value>(0, 578)</value>
</param>
<param>
<key>_rotation</key>
@@ -664,30 +568,22 @@
</param>
</block>
<block>
- <key>blocks_multiply_const_vxx</key>
+ <key>virtual_sink</key>
<param>
<key>id</key>
- <value>blocks_multiply_const_vxx_0</value>
+ <value>virtual_sink_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>const</key>
- <value>0.05</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
+ <key>stream_id</key>
+ <value>Time Domain</value>
</param>
<param>
<key>_coordinate</key>
- <value>(209, 747)</value>
+ <value>(855, 578)</value>
</param>
<param>
<key>_rotation</key>
@@ -695,10 +591,10 @@
</param>
</block>
<block>
- <key>wxgui_scopesink2</key>
+ <key>fft_vxx</key>
<param>
<key>id</key>
- <value>wxgui_scopesink2_0</value>
+ <value>fft_vxx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -709,60 +605,36 @@
<value>complex</value>
</param>
<param>
- <key>title</key>
- <value>Scope Plot</value>
- </param>
- <param>
- <key>samp_rate</key>
- <value>samp_rate</value>
- </param>
- <param>
- <key>v_scale</key>
- <value>0</value>
- </param>
- <param>
- <key>v_offset</key>
- <value>0</value>
- </param>
- <param>
- <key>t_scale</key>
- <value>0</value>
- </param>
- <param>
- <key>ac_couple</key>
- <value>False</value>
+ <key>fft_size</key>
+ <value>fft_len</value>
</param>
<param>
- <key>xy_mode</key>
+ <key>forward</key>
<value>False</value>
</param>
<param>
- <key>num_inputs</key>
- <value>1</value>
+ <key>window</key>
+ <value>()</value>
</param>
<param>
- <key>win_size</key>
- <value></value>
+ <key>shift</key>
+ <value>True</value>
</param>
<param>
- <key>grid_pos</key>
- <value></value>
+ <key>nthreads</key>
+ <value>1</value>
</param>
<param>
- <key>notebook</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>trig_mode</key>
- <value>wxgui.TRIG_MODE_AUTO</value>
- </param>
- <param>
- <key>y_axis_label</key>
- <value>Counts</value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(584, 724)</value>
+ <value>(414, 548)</value>
</param>
<param>
<key>_rotation</key>
@@ -770,10 +642,10 @@
</param>
</block>
<block>
- <key>blocks_throttle</key>
+ <key>blocks_multiply_const_vxx</key>
<param>
<key>id</key>
- <value>blocks_throttle_0</value>
+ <value>blocks_multiply_const_vxx_0</value>
</param>
<param>
<key>_enabled</key>
@@ -784,16 +656,24 @@
<value>complex</value>
</param>
<param>
- <key>samples_per_second</key>
- <value>samp_rate</value>
+ <key>const</key>
+ <value>0.05</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(402, 747)</value>
+ <value>(209, 747)</value>
</param>
<param>
<key>_rotation</key>
@@ -801,662 +681,670 @@
</param>
</block>
<block>
- <key>uhd_usrp_sink</key>
+ <key>digital_chunks_to_symbols_xx</key>
<param>
<key>id</key>
- <value>uhd_usrp_sink_0</value>
+ <value>digital_chunks_to_symbols_xx_0</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
- </param>
- <param>
- <key>type</key>
- <value>fc32</value>
- </param>
- <param>
- <key>otw</key>
- <value></value>
- </param>
- <param>
- <key>stream_args</key>
- <value></value>
+ <value>True</value>
</param>
<param>
- <key>dev_addr</key>
- <value></value>
+ <key>in_type</key>
+ <value>byte</value>
</param>
<param>
- <key>sync</key>
- <value></value>
+ <key>out_type</key>
+ <value>complex</value>
</param>
<param>
- <key>clock_rate</key>
- <value>0.0</value>
+ <key>symbol_table</key>
+ <value>header_mod.points()</value>
</param>
<param>
- <key>num_mboards</key>
+ <key>dimension</key>
<value>1</value>
</param>
<param>
- <key>clock_source0</key>
- <value></value>
- </param>
- <param>
- <key>time_source0</key>
- <value></value>
- </param>
- <param>
- <key>sd_spec0</key>
- <value></value>
- </param>
- <param>
- <key>clock_source1</key>
- <value></value>
+ <key>num_ports</key>
+ <value>1</value>
</param>
<param>
- <key>time_source1</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>sd_spec1</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>clock_source2</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(214, 376)</value>
</param>
<param>
- <key>time_source2</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>analog_random_source_x</key>
<param>
- <key>sd_spec2</key>
- <value></value>
+ <key>id</key>
+ <value>analog_random_source_x_0</value>
</param>
<param>
- <key>clock_source3</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>time_source3</key>
- <value></value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>sd_spec3</key>
- <value></value>
+ <key>min</key>
+ <value>0</value>
</param>
<param>
- <key>clock_source4</key>
- <value></value>
+ <key>max</key>
+ <value>255</value>
</param>
<param>
- <key>time_source4</key>
- <value></value>
+ <key>num_samps</key>
+ <value>1000</value>
</param>
<param>
- <key>sd_spec4</key>
- <value></value>
+ <key>repeat</key>
+ <value>True</value>
</param>
<param>
- <key>clock_source5</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>time_source5</key>
- <value></value>
+ <key>minoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>sd_spec5</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(13, 220)</value>
</param>
<param>
- <key>clock_source6</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_tagged_stream_mux</key>
<param>
- <key>time_source6</key>
- <value></value>
+ <key>id</key>
+ <value>blocks_tagged_stream_mux_0</value>
</param>
<param>
- <key>sd_spec6</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>clock_source7</key>
- <value></value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>time_source7</key>
- <value></value>
+ <key>ninputs</key>
+ <value>2</value>
</param>
<param>
- <key>sd_spec7</key>
- <value></value>
+ <key>lengthtagname</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>nchan</key>
+ <key>vlen</key>
<value>1</value>
</param>
<param>
- <key>samp_rate</key>
- <value>samp_rate</value>
- </param>
- <param>
- <key>center_freq0</key>
- <value>0</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>gain0</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant0</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(510, 428)</value>
</param>
<param>
- <key>bw0</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_ofdm_cyclic_prefixer</key>
<param>
- <key>center_freq1</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_ofdm_cyclic_prefixer_0</value>
</param>
<param>
- <key>gain1</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant1</key>
- <value></value>
+ <key>input_size</key>
+ <value>fft_len</value>
</param>
<param>
- <key>bw1</key>
- <value>0</value>
+ <key>cp_len</key>
+ <value>fft_len/4</value>
</param>
<param>
- <key>center_freq2</key>
- <value>0</value>
+ <key>rolloff</key>
+ <value>rolloff</value>
</param>
<param>
- <key>gain2</key>
- <value>0</value>
+ <key>tagname</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>ant2</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw2</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq3</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(632, 564)</value>
</param>
<param>
- <key>gain3</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_tag_gate</key>
<param>
- <key>ant3</key>
- <value></value>
- </param>
- <param>
- <key>bw3</key>
- <value>0</value>
+ <key>id</key>
+ <value>blocks_tag_gate_0</value>
</param>
<param>
- <key>center_freq4</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gain4</key>
- <value>0</value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>ant4</key>
- <value></value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>bw4</key>
- <value>0</value>
+ <key>propagate_tags</key>
+ <value>False</value>
</param>
<param>
- <key>center_freq5</key>
- <value>0</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>gain5</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant5</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(372, 747)</value>
</param>
<param>
- <key>bw5</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_repack_bits_bb</key>
<param>
- <key>center_freq6</key>
- <value>0</value>
+ <key>id</key>
+ <value>blocks_repack_bits_bb_0</value>
</param>
<param>
- <key>gain6</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant6</key>
- <value></value>
+ <key>k</key>
+ <value>8</value>
</param>
<param>
- <key>bw6</key>
- <value>0</value>
+ <key>l</key>
+ <value>payload_mod.bits_per_symbol()</value>
</param>
<param>
- <key>center_freq7</key>
- <value>0</value>
+ <key>len_tag_key</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>gain7</key>
- <value>0</value>
+ <key>align_output</key>
+ <value>False</value>
</param>
<param>
- <key>ant7</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw7</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq8</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(710, 301)</value>
</param>
<param>
- <key>gain8</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_packet_headergenerator_bb</key>
<param>
- <key>ant8</key>
- <value></value>
- </param>
- <param>
- <key>bw8</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_packet_headergenerator_bb_0</value>
</param>
<param>
- <key>center_freq9</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gain9</key>
- <value>0</value>
+ <key>header_formatter</key>
+ <value>header_formatter.formatter()</value>
</param>
<param>
- <key>ant9</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw9</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq10</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(703, 242)</value>
</param>
<param>
- <key>gain10</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_stream_to_tagged_stream</key>
<param>
- <key>ant10</key>
- <value></value>
+ <key>id</key>
+ <value>blocks_stream_to_tagged_stream_0</value>
</param>
<param>
- <key>bw10</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>center_freq11</key>
- <value>0</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>gain11</key>
- <value>0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>ant11</key>
- <value></value>
+ <key>packet_len</key>
+ <value>packet_len</value>
</param>
<param>
- <key>bw11</key>
- <value>0</value>
+ <key>len_tag_key</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>center_freq12</key>
- <value>0</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>gain12</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant12</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(193, 235)</value>
</param>
<param>
- <key>bw12</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>center_freq13</key>
- <value>0</value>
+ <key>id</key>
+ <value>header_bits</value>
</param>
<param>
- <key>gain13</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant13</key>
- <value></value>
+ <key>stream_id</key>
+ <value>Header Bits</value>
</param>
<param>
- <key>bw13</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(936, 243)</value>
</param>
<param>
- <key>center_freq14</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_sink</key>
<param>
- <key>gain14</key>
- <value>0</value>
+ <key>id</key>
+ <value>virtual_sink_0_0</value>
</param>
<param>
- <key>ant14</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>bw14</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>Payload Bits</value>
</param>
<param>
- <key>center_freq15</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(934, 324)</value>
</param>
<param>
- <key>gain15</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>ant15</key>
- <value></value>
+ <key>id</key>
+ <value>virtual_source_0</value>
</param>
<param>
- <key>bw15</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>center_freq16</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>Header Bits</value>
</param>
<param>
- <key>gain16</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(1, 382)</value>
</param>
<param>
- <key>ant16</key>
- <value></value>
+ <key>_rotation</key>
+ <value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_tag_debug</key>
<param>
- <key>bw16</key>
- <value>0</value>
+ <key>id</key>
+ <value>blocks_tag_debug_0</value>
</param>
<param>
- <key>center_freq17</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gain17</key>
- <value>0</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>ant17</key>
- <value></value>
+ <key>name</key>
+ <value>Rx'd Packets</value>
</param>
<param>
- <key>bw17</key>
- <value>0</value>
+ <key>num_inputs</key>
+ <value>1</value>
</param>
<param>
- <key>center_freq18</key>
- <value>0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>gain18</key>
- <value>0</value>
+ <key>display</key>
+ <value>True</value>
</param>
<param>
- <key>ant18</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw18</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(437, 872)</value>
</param>
<param>
- <key>center_freq19</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
<param>
- <key>gain19</key>
- <value>0</value>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
</param>
<param>
- <key>ant19</key>
- <value></value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>bw19</key>
- <value>0</value>
+ <key>type</key>
+ <value>complex</value>
</param>
<param>
- <key>center_freq20</key>
- <value>0</value>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
</param>
<param>
- <key>gain20</key>
- <value>0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
<param>
- <key>ant20</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw20</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>center_freq21</key>
- <value>0</value>
+ <key>_coordinate</key>
+ <value>(558, 747)</value>
</param>
<param>
- <key>gain21</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>virtual_source</key>
<param>
- <key>ant21</key>
- <value></value>
- </param>
- <param>
- <key>bw21</key>
- <value>0</value>
+ <key>id</key>
+ <value>virtual_source_1</value>
</param>
<param>
- <key>center_freq22</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>gain22</key>
- <value>0</value>
+ <key>stream_id</key>
+ <value>Tx Signal</value>
</param>
<param>
- <key>ant22</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(5, 879)</value>
</param>
<param>
- <key>bw22</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_crc32_bb</key>
<param>
- <key>center_freq23</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_crc32_bb_0</value>
</param>
<param>
- <key>gain23</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant23</key>
- <value></value>
+ <key>check</key>
+ <value>False</value>
</param>
<param>
- <key>bw23</key>
- <value>0</value>
+ <key>lengthtagname</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>center_freq24</key>
- <value>0</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>gain24</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant24</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(430, 235)</value>
</param>
<param>
- <key>bw24</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_ofdm_carrier_allocator_cvc</key>
<param>
- <key>center_freq25</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_ofdm_carrier_allocator_cvc_0</value>
</param>
<param>
- <key>gain25</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant25</key>
- <value></value>
+ <key>fft_len</key>
+ <value>fft_len</value>
</param>
<param>
- <key>bw25</key>
- <value>0</value>
+ <key>occupied_carriers</key>
+ <value>occupied_carriers</value>
</param>
<param>
- <key>center_freq26</key>
- <value>0</value>
+ <key>pilot_carriers</key>
+ <value>pilot_carriers</value>
</param>
<param>
- <key>gain26</key>
- <value>0</value>
+ <key>pilot_symbols</key>
+ <value>pilot_symbols</value>
</param>
<param>
- <key>ant26</key>
- <value></value>
+ <key>sync_words</key>
+ <value>(sync_word1, sync_word2)</value>
</param>
<param>
- <key>bw26</key>
- <value>0</value>
+ <key>len_tag_key</key>
+ <value>length_tag_key</value>
</param>
<param>
- <key>center_freq27</key>
- <value>0</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
- <key>gain27</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
- <key>ant27</key>
- <value></value>
+ <key>_coordinate</key>
+ <value>(192, 540)</value>
</param>
<param>
- <key>bw27</key>
+ <key>_rotation</key>
<value>0</value>
</param>
+ </block>
+ <block>
+ <key>digital_ofdm_rx</key>
<param>
- <key>center_freq28</key>
- <value>0</value>
+ <key>id</key>
+ <value>digital_ofdm_rx_0</value>
</param>
<param>
- <key>gain28</key>
- <value>0</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>ant28</key>
- <value></value>
+ <key>fft_len</key>
+ <value>fft_len</value>
</param>
<param>
- <key>bw28</key>
- <value>0</value>
+ <key>cp_len</key>
+ <value>fft_len/4</value>
</param>
<param>
- <key>center_freq29</key>
- <value>0</value>
+ <key>packet_len_key</key>
+ <value>"length"</value>
</param>
<param>
- <key>gain29</key>
- <value>0</value>
+ <key>occupied_carriers</key>
+ <value>occupied_carriers</value>
</param>
<param>
- <key>ant29</key>
- <value></value>
+ <key>pilot_carriers</key>
+ <value>pilot_carriers</value>
</param>
<param>
- <key>bw29</key>
- <value>0</value>
+ <key>pilot_symbols</key>
+ <value>pilot_symbols</value>
</param>
<param>
- <key>center_freq30</key>
- <value>0</value>
+ <key>sync_word1</key>
+ <value>sync_word1</value>
</param>
<param>
- <key>gain30</key>
- <value>0</value>
+ <key>sync_word2</key>
+ <value>sync_word2</value>
</param>
<param>
- <key>ant30</key>
- <value></value>
+ <key>header_mod</key>
+ <value>"BPSK"</value>
</param>
<param>
- <key>bw30</key>
- <value>0</value>
+ <key>payload_mod</key>
+ <value>"QPSK"</value>
</param>
<param>
- <key>center_freq31</key>
- <value>0</value>
+ <key>scramble_bits</key>
+ <value>False</value>
</param>
<param>
- <key>gain31</key>
- <value>0</value>
+ <key>log</key>
+ <value>False</value>
</param>
<param>
- <key>ant31</key>
+ <key>affinity</key>
<value></value>
</param>
<param>
- <key>bw31</key>
+ <key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
- <value>(401, 670)</value>
+ <value>(193, 802)</value>
</param>
<param>
<key>_rotation</key>
@@ -1467,7 +1355,7 @@
<key>virtual_sink</key>
<param>
<key>id</key>
- <value>virtual_sink_0_0_0</value>
+ <value>virtual_sink_1</value>
</param>
<param>
<key>_enabled</key>
@@ -1475,11 +1363,11 @@
</param>
<param>
<key>stream_id</key>
- <value>Pre-OFDM</value>
+ <value>Tx Signal</value>
</param>
<param>
<key>_coordinate</key>
- <value>(745, 441)</value>
+ <value>(771, 698)</value>
</param>
<param>
<key>_rotation</key>
@@ -1487,10 +1375,10 @@
</param>
</block>
<block>
- <key>blocks_vector_source_x</key>
+ <key>wxgui_scopesink2</key>
<param>
<key>id</key>
- <value>blocks_vector_source_x_0</value>
+ <value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
@@ -1498,105 +1386,67 @@
</param>
<param>
<key>type</key>
- <value>byte</value>
- </param>
- <param>
- <key>vector</key>
- <value>range(packet_len)</value>
- </param>
- <param>
- <key>tags</key>
- <value>tagged_streams.make_lengthtags((packet_len,), (0,), length_tag_name)</value>
- </param>
- <param>
- <key>repeat</key>
- <value>True</value>
+ <value>complex</value>
</param>
<param>
- <key>vlen</key>
- <value>1</value>
+ <key>title</key>
+ <value>Scope Plot</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(0, 215)</value>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
</param>
<param>
- <key>_rotation</key>
+ <key>v_scale</key>
<value>0</value>
</param>
- </block>
- <block>
- <key>digital_chunks_to_symbols_xx</key>
<param>
- <key>id</key>
- <value>digital_chunks_to_symbols_xx_0_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>in_type</key>
- <value>byte</value>
+ <key>v_offset</key>
+ <value>0</value>
</param>
<param>
- <key>out_type</key>
- <value>complex</value>
+ <key>t_scale</key>
+ <value>0</value>
</param>
<param>
- <key>symbol_table</key>
- <value>payload_mod.points()</value>
+ <key>ac_couple</key>
+ <value>False</value>
</param>
<param>
- <key>dimension</key>
- <value>1</value>
+ <key>xy_mode</key>
+ <value>False</value>
</param>
<param>
- <key>num_ports</key>
+ <key>num_inputs</key>
<value>1</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(212, 450)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>digital_chunks_to_symbols_xx</key>
- <param>
- <key>id</key>
- <value>digital_chunks_to_symbols_xx_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
+ <key>win_size</key>
+ <value></value>
</param>
<param>
- <key>in_type</key>
- <value>byte</value>
+ <key>grid_pos</key>
+ <value></value>
</param>
<param>
- <key>out_type</key>
- <value>complex</value>
+ <key>notebook</key>
+ <value></value>
</param>
<param>
- <key>symbol_table</key>
- <value>header_mod.points()</value>
+ <key>trig_mode</key>
+ <value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
- <key>dimension</key>
- <value>1</value>
+ <key>y_axis_label</key>
+ <value>Counts</value>
</param>
<param>
- <key>num_ports</key>
- <value>1</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(214, 376)</value>
+ <value>(773, 768)</value>
</param>
<param>
<key>_rotation</key>
@@ -1686,175 +1536,12 @@
<value>None</value>
</param>
<param>
- <key>_coordinate</key>
- <value>(402, 796)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>virtual_source</key>
- <param>
- <key>id</key>
- <value>virtual_source_0_0_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>stream_id</key>
- <value>Pre-OFDM</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(0, 578)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>digital_ofdm_carrier_allocator_cvc</key>
- <param>
- <key>id</key>
- <value>digital_ofdm_carrier_allocator_cvc_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>fft_len</key>
- <value>fft_len</value>
- </param>
- <param>
- <key>occupied_carriers</key>
- <value>occupied_carriers</value>
- </param>
- <param>
- <key>pilot_carriers</key>
- <value>pilot_carriers</value>
- </param>
- <param>
- <key>pilot_symbols</key>
- <value>pilot_symbols</value>
- </param>
- <param>
- <key>sync_words</key>
- <value>(sync_word1, sync_word2)</value>
- </param>
- <param>
- <key>len_tag_key</key>
- <value>length_tag_name</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(191, 540)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>digital_ofdm_cyclic_prefixer</key>
- <param>
- <key>id</key>
- <value>digital_ofdm_cyclic_prefixer_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>input_size</key>
- <value>fft_len</value>
- </param>
- <param>
- <key>cp_len</key>
- <value>fft_len/4</value>
- </param>
- <param>
- <key>rolloff</key>
- <value>rolloff</value>
- </param>
- <param>
- <key>tagname</key>
- <value>length_tag_name</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(631, 563)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>virtual_sink</key>
- <param>
- <key>id</key>
- <value>virtual_sink_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>stream_id</key>
- <value>Time Domain</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(855, 578)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>fft_vxx</key>
- <param>
- <key>id</key>
- <value>fft_vxx_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>fft_size</key>
- <value>fft_len</value>
- </param>
- <param>
- <key>forward</key>
- <value>False</value>
- </param>
- <param>
- <key>window</key>
- <value>()</value>
- </param>
- <param>
- <key>shift</key>
- <value>True</value>
- </param>
- <param>
- <key>nthreads</key>
- <value>1</value>
+ <key>affinity</key>
+ <value></value>
</param>
<param>
<key>_coordinate</key>
- <value>(414, 548)</value>
+ <value>(775, 862)</value>
</param>
<param>
<key>_rotation</key>
@@ -1880,40 +1567,52 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_crc32_bb_0</source_block_id>
- <sink_block_id>digital_packet_headergenerator_bb_0</sink_block_id>
+ <source_block_id>digital_chunks_to_symbols_xx_0_0</source_block_id>
+ <sink_block_id>blocks_tagged_stream_mux_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_0_0_0_0</source_block_id>
+ <sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_crc32_bb_0</source_block_id>
- <sink_block_id>blocks_repack_bits_bb_0</sink_block_id>
+ <source_block_id>virtual_source_0_0_0</source_block_id>
+ <sink_block_id>digital_ofdm_carrier_allocator_cvc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_packet_headergenerator_bb_0</source_block_id>
- <sink_block_id>header_bits</sink_block_id>
+ <source_block_id>digital_ofdm_carrier_allocator_cvc_0</source_block_id>
+ <sink_block_id>fft_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_repack_bits_bb_0</source_block_id>
- <sink_block_id>virtual_sink_0_0</sink_block_id>
+ <source_block_id>fft_vxx_0</source_block_id>
+ <sink_block_id>digital_ofdm_cyclic_prefixer_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_vector_source_x_0</source_block_id>
- <sink_block_id>digital_crc32_bb_0</sink_block_id>
+ <source_block_id>digital_ofdm_cyclic_prefixer_0</source_block_id>
+ <sink_block_id>virtual_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_chunks_to_symbols_xx_0_0</source_block_id>
- <sink_block_id>blocks_tagged_stream_mux_0</sink_block_id>
+ <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
+ <sink_block_id>blocks_tag_gate_0</sink_block_id>
<source_key>0</source_key>
- <sink_key>1</sink_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_tag_gate_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
@@ -1922,8 +1621,8 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>virtual_source_0_0_0_0</source_block_id>
- <sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>blocks_stream_to_tagged_stream_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@@ -1934,44 +1633,56 @@
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
- <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
- <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+ <source_block_id>blocks_stream_to_tagged_stream_0</source_block_id>
+ <sink_block_id>digital_crc32_bb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_multiply_const_vxx_0</source_block_id>
- <sink_block_id>uhd_usrp_sink_0</sink_block_id>
+ <source_block_id>digital_crc32_bb_0</source_block_id>
+ <sink_block_id>digital_packet_headergenerator_bb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>virtual_source_0_0_0</source_block_id>
- <sink_block_id>digital_ofdm_carrier_allocator_cvc_0</sink_block_id>
+ <source_block_id>digital_crc32_bb_0</source_block_id>
+ <sink_block_id>blocks_repack_bits_bb_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_carrier_allocator_cvc_0</source_block_id>
- <sink_block_id>fft_vxx_0</sink_block_id>
+ <source_block_id>digital_packet_headergenerator_bb_0</source_block_id>
+ <sink_block_id>header_bits</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>fft_vxx_0</source_block_id>
- <sink_block_id>digital_ofdm_cyclic_prefixer_0</sink_block_id>
+ <source_block_id>blocks_repack_bits_bb_0</source_block_id>
+ <sink_block_id>virtual_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>digital_ofdm_cyclic_prefixer_0</source_block_id>
- <sink_block_id>virtual_sink_0</sink_block_id>
+ <source_block_id>digital_ofdm_rx_0</source_block_id>
+ <sink_block_id>blocks_tag_debug_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>virtual_source_1</source_block_id>
+ <sink_block_id>digital_ofdm_rx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>virtual_sink_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gr-digital/grc/digital_block_tree.xml b/gr-digital/grc/digital_block_tree.xml
index d1033e8572..a5fba4ff4d 100644
--- a/gr-digital/grc/digital_block_tree.xml
+++ b/gr-digital/grc/digital_block_tree.xml
@@ -59,7 +59,10 @@
<block>digital_psk_demod</block>
<block>digital_qam_mod</block>
<block>digital_qam_demod</block>
+ <block>digital_constellation_modulator</block>
<block>digital_constellation_receiver_cb</block>
+ <block>variable_constellation</block>
+ <block>variable_constellation_rect</block>
</cat>
<cat>
<name>Packet Operators</name>
@@ -101,6 +104,7 @@
<block>digital_chunks_to_symbols_xx</block>
<block>digital_constellation_decoder_cb</block>
<block>digital_constellation_receiver_cb</block>
+ <block>digital_constellation_soft_decoder_cf</block>
<block>digital_diff_decoder_bb</block>
<block>digital_diff_encoder_bb</block>
<block>digital_diff_phasor_cc</block>
diff --git a/grc/blocks/variable_constellation.xml b/gr-digital/grc/digital_constellation.xml
index 7d23ede9be..8d2a34f1fa 100644
--- a/grc/blocks/variable_constellation.xml
+++ b/gr-digital/grc/digital_constellation.xml
@@ -11,7 +11,13 @@
<key>variable_constellation</key>
<category>Modulators</category>
<import>from gnuradio import digital</import>
- <var_make>self.$(id) = $(id) = digital.constellation_calcdist($const_points, $sym_map, $rot_sym, $dims).base()</var_make>
+ <var_make>self.$(id) = $(id) = digital.constellation_calcdist($const_points, $sym_map, $rot_sym, $dims).base()
+#if str($soft_dec_lut).lower() == '"auto"' or str($soft_dec_lut).lower() == "'auto'"
+self.$(id).gen_soft_dec_lut($precision)
+#else if str($soft_dec_lut) != 'None'
+self.$(id).set_soft_dec_lut($soft_dec_lut, $precision)
+#end if
+</var_make>
<make></make>
<!--<callback></callback>-->
@@ -48,4 +54,18 @@
<value>1</value>
<type>int</type>
</param>
+ <param>
+ <name>Soft Decisions Precision</name>
+ <key>precision</key>
+ <value>8</value>
+ <type>int</type>
+ <hide>part</hide>
+ </param>
+ <param>
+ <name>Soft Decisions LUT</name>
+ <key>soft_dec_lut</key>
+ <value>None</value>
+ <type>raw</type>
+ <hide>#if str($soft_dec_lut) == 'None' then 'part' else 'none'#</hide>
+ </param>
</block>
diff --git a/gr-digital/grc/digital_constellation_modulator.xml b/gr-digital/grc/digital_constellation_modulator.xml
new file mode 100644
index 0000000000..7b7ce24e47
--- /dev/null
+++ b/gr-digital/grc/digital_constellation_modulator.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright 2013 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.
+-->
+
+<!--
+###################################################
+## Modulates any given constellation object
+###################################################
+ -->
+<block>
+ <name>Constellation Modulator</name>
+ <key>digital_constellation_modulator</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.generic_mod(
+ constellation=$constellation,
+ differential=$differential,
+ samples_per_symbol=$samples_per_symbol,
+ pre_diff_code=True,
+ excess_bw=$excess_bw,
+ verbose=$verbose,
+ log=$log,
+ )</make>
+ <param>
+ <name>Constellation</name>
+ <key>constellation</key>
+ <type>raw</type>
+ </param>
+ <param>
+ <name>Differential Encoding</name>
+ <key>differential</key>
+ <value>True</value>
+ <type>bool</type>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ </param>
+ <param>
+ <name>Samples/Symbol</name>
+ <key>samples_per_symbol</key>
+ <value>2</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Excess BW</name>
+ <key>excess_bw</key>
+ <value>0.35</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Verbose</name>
+ <key>verbose</key>
+ <value>False</value>
+ <type>bool</type>
+ <hide>#if str($verbose) == 'False' then 'part' else 'none'#</hide>
+ <option>
+ <name>On</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Off</name>
+ <key>False</key>
+ </option>
+ </param>
+ <param>
+ <name>Logging</name>
+ <key>log</key>
+ <value>False</value>
+ <type>bool</type>
+ <hide>#if str($log) == 'False' then 'part' else 'none'#</hide>
+ <option>
+ <name>On</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Off</name>
+ <key>False</key>
+ </option>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/grc/blocks/variable_constellation_rect.xml b/gr-digital/grc/digital_constellation_rect.xml
index 5c136ee324..e6acc14bc4 100644
--- a/grc/blocks/variable_constellation_rect.xml
+++ b/gr-digital/grc/digital_constellation_rect.xml
@@ -11,9 +11,13 @@
<key>variable_constellation_rect</key>
<category>Modulators</category>
<import>from gnuradio import digital</import>
- <var_make>self.$(id) = $(id) = digital.constellation_rect($const_points, $sym_map, $rot_sym, $real_sect, $imag_sect, $w_real_sect, $w_imag_sect).base()</var_make>
+ <var_make>self.$(id) = $(id) = digital.constellation_rect($const_points, $sym_map, $rot_sym, $real_sect, $imag_sect, $w_real_sect, $w_imag_sect).base()
+#if str($softbits_lut) != 'None'
+self.$(id).set_softbits($softbits_lut, $precision)
+#end if
+</var_make>
<make></make>
- <!--<callback></callback>-->
+ <!--<callback>set_softbits($softbits_lut, $precision)</callback>-->
<!-- Required to 'trick' GRC into using this as a proper variable-->
<param>
@@ -66,4 +70,18 @@
<value>1</value>
<type>int</type>
</param>
+ <param>
+ <name>Soft bits precision</name>
+ <key>precision</key>
+ <value>8</value>
+ <type>int</type>
+ <hide>part</hide>
+ </param>
+ <param>
+ <name>Soft bits LUT</name>
+ <key>softbits_lut</key>
+ <value>None</value>
+ <type>raw</type>
+ <hide>#if str($softbits_lut) == 'None' then 'part' else 'none'#</hide>
+ </param>
</block>
diff --git a/gr-digital/grc/digital_constellation_soft_decoder_cf.xml b/gr-digital/grc/digital_constellation_soft_decoder_cf.xml
new file mode 100644
index 0000000000..6b0995acc9
--- /dev/null
+++ b/gr-digital/grc/digital_constellation_soft_decoder_cf.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Constellation Decoder, soft bits out
+###################################################
+ -->
+<block>
+ <name>Constellation Soft Decoder</name>
+ <key>digital_constellation_soft_decoder_cf</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.constellation_soft_decoder_cf($constellation)</make>
+ <param>
+ <name>Constellation Object</name>
+ <key>constellation</key>
+ <type>raw</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>float</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_ofdm_rx.xml b/gr-digital/grc/digital_ofdm_rx.xml
index 6f10a2e944..9c2bf65e9d 100644
--- a/gr-digital/grc/digital_ofdm_rx.xml
+++ b/gr-digital/grc/digital_ofdm_rx.xml
@@ -24,7 +24,8 @@
#end if
bps_header=$header_mod.bps,
bps_payload=$payload_mod.bps,
- debug_log=$log
+ debug_log=$log,
+ scramble_bits=$scramble_bits
)</make>
<param>
<name>FFT Length</name>
@@ -145,6 +146,21 @@
</option>
</param>
<param>
+ <name>Scramble Bits</name>
+ <key>scramble_bits</key>
+ <value>False</value>
+ <type>enum</type>
+ <hide> #if $scramble_bits then 'part' else 'none'#</hide>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ </param>
+ <param>
<name>Log Debug Info</name>
<key>log</key>
<value>False</value>
diff --git a/gr-digital/grc/digital_ofdm_tx.xml b/gr-digital/grc/digital_ofdm_tx.xml
index cde045d840..bad0b2b13d 100644
--- a/gr-digital/grc/digital_ofdm_tx.xml
+++ b/gr-digital/grc/digital_ofdm_tx.xml
@@ -24,7 +24,8 @@
bps_header=$header_mod.bps,
bps_payload=$payload_mod.bps,
rolloff=$rolloff,
- debug_log=$log
+ debug_log=$log,
+ scramble_bits=$scramble_bits
)</make>
<param>
<name>FFT Length</name>
@@ -151,6 +152,21 @@
<type>int</type>
</param>
<param>
+ <name>Scramble Bits</name>
+ <key>scramble_bits</key>
+ <value>False</value>
+ <type>enum</type>
+ <hide> #if $scramble_bits then 'part' else 'none'#</hide>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ </param>
+ <param>
<name>Log Debug Info</name>
<key>log</key>
<value>False</value>
diff --git a/gr-digital/include/gnuradio/digital/CMakeLists.txt b/gr-digital/include/gnuradio/digital/CMakeLists.txt
index 275da16d87..7515df7042 100644
--- a/gr-digital/include/gnuradio/digital/CMakeLists.txt
+++ b/gr-digital/include/gnuradio/digital/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2011,2012 Free Software Foundation, Inc.
+# Copyright 2011-2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -84,6 +84,7 @@ install(FILES
constellation.h
constellation_decoder_cb.h
constellation_receiver_cb.h
+ constellation_soft_decoder_cf.h
correlate_access_code_bb.h
correlate_access_code_tag_bb.h
costas_loop_cc.h
diff --git a/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h b/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h
index 73fd395d67..ac765121a8 100644
--- a/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h
+++ b/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h
@@ -36,14 +36,19 @@ namespace gr {
* Scramble an input stream using an LFSR.
*
* \details
- * This block works on the LSB only of the input data stream,
- * i.e., on an "unpacked binary" stream, and produces the same
- * format on its output.
+ * This block scrambles up to 8 bits per byte of the input
+ * data stream, starting at the LSB.
*
* The scrambler works by XORing the incoming bit stream by the
* output of the LFSR. Optionally, after 'count' bits have been
* processed, the shift register is reset to the seed value.
* This allows processing fixed length vectors of samples.
+ *
+ * Alternatively, the LFSR can be reset using a reset tag to
+ * scramble variable length vectors. However, it cannot be reset
+ * between bytes.
+ *
+ * For details on configuring the LFSR, see gr::digital::lfsr.
*/
class DIGITAL_API additive_scrambler_bb : virtual public sync_block
{
@@ -57,15 +62,17 @@ namespace gr {
* \param mask Polynomial mask for LFSR
* \param seed Initial shift register contents
* \param len Shift register length
- * \param count Number of bits after which shift register is reset, 0=never
- *
+ * \param count Number of bytes after which shift register is reset, 0=never
+ * \param bits_per_byte Number of bits per byte
+ * \param reset_tag_key When a tag with this key is detected, the shift register is reset (when this is set, count is ignored!)
*/
- static sptr make(int mask, int seed, int len, int count=0);
+ static sptr make(int mask, int seed, int len, int count=0, int bits_per_byte=1, const std::string &reset_tag_key="");
virtual int mask() const = 0;
virtual int seed() const = 0;
virtual int len() const = 0;
virtual int count() const = 0;
+ virtual int bits_per_byte() = 0;
};
} /* namespace digital */
diff --git a/gr-digital/include/gnuradio/digital/constellation.h b/gr-digital/include/gnuradio/digital/constellation.h
index 6ee274dd04..b2464aa856 100644
--- a/gr-digital/include/gnuradio/digital/constellation.h
+++ b/gr-digital/include/gnuradio/digital/constellation.h
@@ -120,6 +120,76 @@ namespace gr {
return shared_from_this();
}
+ /*! \brief Generates the soft decision LUT based on
+ * constellation and symbol map.
+ *
+ * \details Generates the soft decision LUT based on
+ * constellation and symbol map. It can be given a estimate of
+ * the noise power in the channel as \p npwr.
+ *
+ * \param precision Number of bits of precision on each axis.
+ * \param npwr Estimate of the noise power (if known).
+ *
+ * This is expensive to compute.
+ */
+ void gen_soft_dec_lut(int precision, float npwr=1.0);
+
+ /*! \brief Calculate soft decisions for the given \p sample.
+ *
+ * \details Calculate the soft decisions from the given \p sample
+ * at the given noise power \p npwr.
+ *
+ * This is a very costly algorithm (especially for higher order
+ * modulations) and should be used sparingly. It uses the
+ * gen_soft_dec_lut function to generate the LUT, which
+ * should be done once or if a large change in the noise floor
+ * is detected.
+ *
+ * Instead of using this function, generate the LUT using the
+ * gen_soft_dec_lut after creating the constellation object
+ * and then use the soft_decision_maker function to return the
+ * answer from the LUT.
+ *
+ * \param sample The complex sample to get the soft decisions.
+ * \param npwr Estimate of the noise power (if known).
+ */
+ virtual std::vector<float> calc_soft_dec(gr_complex sample, float npwr=1.0);
+
+ /*! \brief Define a soft decision look-up table.
+ *
+ * \details Define a soft decision look-up table (LUT). Because
+ * soft decisions can be calculated in various ways with various
+ * levels of accuracy and complexity, this function allows
+ * users to create a LUT in their own way.
+ *
+ * Setting the LUT here means that has_soft_dec_lut will return
+ * true. Decision vectors returned by soft_decision_maker will
+ * be calculated using this LUT.
+ *
+ * \param soft_dec_lut The soft decision LUT as a vector of
+ * tuples (vectors in C++) of soft decisions. Each
+ * element of the LUT is a vector of k-bit floats (where
+ * there are k bits/sample in the constellation).
+ * \param precision The number of bits of precision used when
+ * generating the LUT.
+ */
+ void set_soft_dec_lut(const std::vector< std::vector<float> > &soft_dec_lut,
+ int precision);
+
+ //! Returns True if the soft decision LUT has been defined, False otherwise.
+ bool has_soft_dec_lut();
+
+ /*! \brief Returns the soft decisions for the given \p sample.
+ *
+ * \details Returns the soft decisions for the given \p
+ * sample. If a LUT is defined for the object, the decisions
+ * will be calculated from there. Otherwise, this function will
+ * call calc_soft_dec directly to calculate the soft decisions.
+ *
+ * \param sample The complex sample to get the soft decisions.
+ */
+ std::vector<float> soft_decision_maker(gr_complex sample);
+
protected:
std::vector<gr_complex> d_constellation;
std::vector<int> d_pre_diff_code;
@@ -130,10 +200,17 @@ namespace gr {
//! The factor by which the user given constellation points were
//! scaled by to achieve an average amplitude of 1.
float d_scalefactor;
+ float d_re_min, d_re_max, d_im_min, d_im_max;
+
+ std::vector< std::vector<float> > d_soft_dec_lut;
+ int d_lut_precision;
+ float d_lut_scale;
float get_distance(unsigned int index, const gr_complex *sample);
unsigned int get_closest_point(const gr_complex *sample);
void calc_arity();
+
+ void max_min_axes();
};
/************************************************************/
@@ -418,6 +495,10 @@ namespace gr {
/*!
* \brief Digital constellation for QPSK
* \ingroup digital
+ *
+ * 01 | 11
+ * -------
+ * 00 | 10
*/
class DIGITAL_API constellation_qpsk : public constellation
{
@@ -446,6 +527,10 @@ namespace gr {
/*!
* \brief Digital constellation for DQPSK
* \ingroup digital
+ *
+ * 01 | 00
+ * -------
+ * 11 | 10
*/
class DIGITAL_API constellation_dqpsk : public constellation
{
@@ -474,6 +559,12 @@ namespace gr {
/*!
* \brief Digital constellation for 8PSK
* \ingroup digital
+ *
+ * 101 | 100
+ * 001 | 000
+ * -----------------
+ * 011 | 010
+ * 111 | 110
*/
class DIGITAL_API constellation_8psk : public constellation
{
diff --git a/gr-digital/include/gnuradio/digital/constellation_soft_decoder_cf.h b/gr-digital/include/gnuradio/digital/constellation_soft_decoder_cf.h
new file mode 100644
index 0000000000..433be3a8f9
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/constellation_soft_decoder_cf.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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_DIGITAL_CONSTELLATION_SOFT_DECODER_CF_H
+#define INCLUDED_DIGITAL_CONSTELLATION_SOFT_DECODER_CF_H
+
+#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/constellation.h>
+#include <gnuradio/sync_interpolator.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Constellation Decoder
+ * \ingroup symbol_coding_blk
+ *
+ * \details
+ * Decode a constellation's points from a complex space to soft
+ * bits based on the map and soft decision lUT of the \p
+ * consetllation object.
+ */
+ class DIGITAL_API constellation_soft_decoder_cf
+ : virtual public sync_interpolator
+ {
+ public:
+ // gr::digital::constellation_soft_decoder_cf::sptr
+ typedef boost::shared_ptr<constellation_soft_decoder_cf> sptr;
+
+ /*!
+ * \brief Make constellation decoder block.
+ *
+ * \param constellation A constellation derived from class
+ * 'constellation'. Use base() method to get a shared pointer to
+ * this base class type.
+ */
+ static sptr make(constellation_sptr constellation);
+ };
+
+ } /* namespace digital */
+} /* namespace gr */
+
+#endif /* INCLUDED_DIGITAL_CONSTELLATION_SOFT_DECODER_CF_H */
diff --git a/gr-digital/include/gnuradio/digital/packet_header_default.h b/gr-digital/include/gnuradio/digital/packet_header_default.h
index 0654a32a63..6567dd7626 100644
--- a/gr-digital/include/gnuradio/digital/packet_header_default.h
+++ b/gr-digital/include/gnuradio/digital/packet_header_default.h
@@ -25,6 +25,7 @@
#include <gnuradio/tags.h>
#include <gnuradio/digital/api.h>
#include <boost/enable_shared_from_this.hpp>
+#include <boost/crc.hpp>
namespace gr {
namespace digital {
@@ -69,12 +70,15 @@ namespace gr {
*
* Uses the following header format:
* Bits 0-11: The packet length (what was stored in the tag with key \p len_tag_key)
- * Bits 12-27: The header number (counts up everytime this function is called)
- * Bit 28: Even parity bit
+ * Bits 12-23: The header number (counts up everytime this function is called)
+ * Bit 24-31: 8-Bit CRC
* All other bits: Are set to zero
*
- * If the header length is smaller than 29, bits are simply left out. For this
+ * If the header length is smaller than 32, bits are simply left out. For this
* reason, they always start with the LSB.
+ *
+ * However, it is recommended to stay above 32 Bits, in order to have a working
+ * CRC.
*/
virtual bool header_formatter(
long packet_len,
@@ -104,6 +108,7 @@ namespace gr {
int d_bits_per_byte;
unsigned d_header_number;
unsigned d_mask;
+ boost::crc_optimal<8, 0x07, 0xFF, 0x00, false, false> d_crc_impl;
};
} // namespace digital
diff --git a/gr-digital/include/gnuradio/digital/packet_header_ofdm.h b/gr-digital/include/gnuradio/digital/packet_header_ofdm.h
index 4603450915..40255daf6d 100644
--- a/gr-digital/include/gnuradio/digital/packet_header_ofdm.h
+++ b/gr-digital/include/gnuradio/digital/packet_header_ofdm.h
@@ -45,17 +45,31 @@ namespace gr {
const std::string &frame_len_tag_key,
const std::string &num_tag_key,
int bits_per_header_sym,
- int bits_per_payload_sym);
+ int bits_per_payload_sym,
+ bool scramble_header);
~packet_header_ofdm();
/*!
+ * \brief Header formatter.
+ *
+ * Does the same as packet_header_default::header_formatter(), but
+ * optionally scrambles the bits (this is more important for OFDM to avoid
+ * PAPR spikes).
+ */
+ bool header_formatter(
+ long packet_len,
+ unsigned char *out,
+ const std::vector<tag_t> &tags
+ );
+
+ /*!
* \brief Inverse function to header_formatter().
*
* Does the same as packet_header_default::header_parser(), but
* adds another tag that stores the number of OFDM symbols in the
* packet.
* Note that there is usually no linear connection between the number
- * of OFDM symbols and the packet length, because, a packet might
+ * of OFDM symbols and the packet length because a packet might
* finish mid-OFDM-symbol.
*/
bool header_parser(
@@ -77,6 +91,8 @@ namespace gr {
* required to figure out how many OFDM symbols
* are necessary to encode the given number of
* bytes.
+ * \param scramble_header Set this to true to scramble the bits. This is highly
+ * recommended, as it reduces PAPR spikes.
*/
static sptr make(
const std::vector<std::vector<int> > &occupied_carriers,
@@ -85,15 +101,17 @@ namespace gr {
const std::string &frame_len_tag_key="frame_len",
const std::string &num_tag_key="packet_num",
int bits_per_header_sym=1,
- int bits_per_payload_sym=1
+ int bits_per_payload_sym=1,
+ bool scramble_header=false
);
protected:
- pmt::pmt_t d_frame_len_tag_key;
+ pmt::pmt_t d_frame_len_tag_key; //!< Tag key of the additional frame length tag
const std::vector<std::vector<int> > d_occupied_carriers; //!< Which carriers/symbols carry data
int d_syms_per_set; //!< Helper variable: Total number of elements in d_occupied_carriers
int d_bits_per_payload_sym;
+ std::vector<unsigned char> d_scramble_mask; //!< Bits are xor'd with this before tx'ing
};
} // namespace digital
diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt
index a17c91a85a..dee52308ca 100644
--- a/gr-digital/lib/CMakeLists.txt
+++ b/gr-digital/lib/CMakeLists.txt
@@ -120,6 +120,7 @@ list(APPEND digital_sources
constellation.cc
constellation_decoder_cb_impl.cc
constellation_receiver_cb_impl.cc
+ constellation_soft_decoder_cf_impl.cc
correlate_access_code_bb_impl.cc
correlate_access_code_tag_bb_impl.cc
costas_loop_cc_impl.cc
diff --git a/gr-digital/lib/additive_scrambler_bb_impl.cc b/gr-digital/lib/additive_scrambler_bb_impl.cc
index 8f2229e6b6..96e1fbbc25 100644
--- a/gr-digital/lib/additive_scrambler_bb_impl.cc
+++ b/gr-digital/lib/additive_scrambler_bb_impl.cc
@@ -31,23 +31,35 @@ namespace gr {
namespace digital {
additive_scrambler_bb::sptr
- additive_scrambler_bb::make(int mask, int seed, int len, int count)
+ additive_scrambler_bb::make (int mask, int seed,
+ int len, int count,
+ int bits_per_byte,
+ const std::string &reset_tag_key)
{
return gnuradio::get_initial_sptr(new additive_scrambler_bb_impl
- (mask, seed, len, count));
+ (mask, seed, len, count, bits_per_byte, reset_tag_key));
}
additive_scrambler_bb_impl::additive_scrambler_bb_impl(int mask,
int seed,
int len,
- int count)
+ int count,
+ int bits_per_byte,
+ const std::string &reset_tag_key)
: sync_block("additive_scrambler_bb",
io_signature::make(1, 1, sizeof(unsigned char)),
io_signature::make(1, 1, sizeof(unsigned char))),
d_lfsr(mask, seed, len),
- d_count(count),
- d_bits(0), d_len(len), d_seed(seed)
+ d_count(reset_tag_key.empty() ? count : -1),
+ d_bytes(0), d_len(len), d_seed(seed),
+ d_bits_per_byte(bits_per_byte), d_reset_tag_key(pmt::string_to_symbol(reset_tag_key))
{
+ if (d_count < -1) {
+ throw std::invalid_argument("count must be non-negative!");
+ }
+ if (d_bits_per_byte < 1 || d_bits_per_byte > 8) {
+ throw std::invalid_argument("bits_per_byte must be in [1, 8]");
+ }
}
additive_scrambler_bb_impl::~additive_scrambler_bb_impl()
@@ -78,6 +90,28 @@ namespace gr {
return d_count;
}
+ int additive_scrambler_bb_impl::_get_next_reset_index(int noutput_items, int last_reset_index /* = -1 */)
+ {
+ int reset_index = noutput_items; // This is a value that gets never reached in the for loop
+ if (d_count == -1) {
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_reset_tag_key);
+ for (unsigned i = 0; i < tags.size(); i++) {
+ int reset_pos = tags[i].offset - nitems_read(0);
+ if (reset_pos < reset_index && reset_pos > last_reset_index) {
+ reset_index = reset_pos;
+ };
+ }
+ } else {
+ if (last_reset_index == -1) {
+ reset_index = d_count - d_bytes;
+ } else {
+ reset_index = last_reset_index + d_count;
+ }
+ }
+ return reset_index;
+ }
+
int
additive_scrambler_bb_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
@@ -85,14 +119,19 @@ namespace gr {
{
const unsigned char *in = (const unsigned char *)input_items[0];
unsigned char *out = (unsigned char *)output_items[0];
+ int reset_index = _get_next_reset_index(noutput_items);
for(int i = 0; i < noutput_items; i++) {
- out[i] = in[i]^d_lfsr.next_bit();
- if(d_count > 0) {
- if(++d_bits == d_count) {
- d_lfsr.reset();
- d_bits = 0;
- }
+ unsigned char scramble_byte = 0x00;
+ for (int k = 0; k < d_bits_per_byte; k++) {
+ scramble_byte ^= (d_lfsr.next_bit() << k);
+ }
+ out[i] = in[i] ^ scramble_byte;
+ d_bytes++;
+ if (i == reset_index) {
+ d_lfsr.reset();
+ d_bytes = 0;
+ reset_index = _get_next_reset_index(noutput_items, reset_index);
}
}
diff --git a/gr-digital/lib/additive_scrambler_bb_impl.h b/gr-digital/lib/additive_scrambler_bb_impl.h
index b621637e67..a3b31c02bc 100644
--- a/gr-digital/lib/additive_scrambler_bb_impl.h
+++ b/gr-digital/lib/additive_scrambler_bb_impl.h
@@ -34,21 +34,27 @@ namespace gr {
{
private:
digital::lfsr d_lfsr;
- int d_count;
- int d_bits;
+ int d_count; //!< Reset the LFSR after this many bytes (not bits)
+ int d_bytes; //!< Count the processed bytes
int d_len;
int d_seed;
+ int d_bits_per_byte;
+ pmt::pmt_t d_reset_tag_key; //!< Reset the LFSR when this tag is received
+
+ int _get_next_reset_index(int noutput_items, int last_reset_index=-1);
public:
additive_scrambler_bb_impl(int mask, int seed,
- int len, int count=0);
+ int len, int count=0,
+ int bits_per_byte=1, const std::string &reset_tag_key="");
~additive_scrambler_bb_impl();
int mask() const;
int seed() const;
int len() const;
int count() const;
-
+ int bits_per_byte() { return d_bits_per_byte; };
+
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gr-digital/lib/constellation.cc b/gr-digital/lib/constellation.cc
index 2c70bb0944..ff86531f0f 100644
--- a/gr-digital/lib/constellation.cc
+++ b/gr-digital/lib/constellation.cc
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <float.h>
#include <stdexcept>
+#include <boost/format.hpp>
namespace gr {
namespace digital {
@@ -48,7 +49,9 @@ namespace gr {
d_constellation(constell),
d_pre_diff_code(pre_diff_code),
d_rotational_symmetry(rotational_symmetry),
- d_dimensionality(dimensionality)
+ d_dimensionality(dimensionality),
+ d_lut_precision(0),
+ d_lut_scale(0)
{
// Scale constellation points so that average magnitude is 1.
float summed_mag = 0;
@@ -59,7 +62,7 @@ namespace gr {
}
d_scalefactor = constsize/summed_mag;
for (unsigned int i=0; i<constsize; i++) {
- d_constellation[i] = d_constellation[i]*d_scalefactor;
+ d_constellation[i] = d_constellation[i]*d_scalefactor;
}
if(pre_diff_code.size() == 0)
d_apply_pre_diff_code = false;
@@ -233,10 +236,154 @@ namespace gr {
}
+ void
+ constellation::gen_soft_dec_lut(int precision, float npwr)
+ {
+ max_min_axes();
+ d_lut_scale = powf(2.0, static_cast<float>(precision));
+ float xstep = (d_re_max - d_re_min) / (d_lut_scale-1);
+ float ystep = (d_im_max - d_im_min) / (d_lut_scale-1);
+ d_soft_dec_lut.clear();
+
+ float y = d_im_min;
+ while(y < d_im_max) {
+ float x = d_re_min;
+ while(x < d_re_max) {
+ gr_complex pt = gr_complex(x, y);
+ d_soft_dec_lut.push_back(calc_soft_dec(pt, npwr));
+ x += xstep;
+ }
+ y += ystep;
+ }
+
+ d_lut_precision = precision;
+ }
+
+ std::vector<float>
+ constellation::calc_soft_dec(gr_complex sample, float npwr)
+ {
+ int M = static_cast<int>(d_constellation.size());
+ int k = static_cast<int>(log10f(static_cast<float>(M))/log10f(2.0));
+ std::vector<float> tmp(2*k, 0);
+ std::vector<float> s(k, 0);
+
+ float scale = d_scalefactor*d_scalefactor;
+
+ for(int i = 0; i < M; i++) {
+ // Calculate the distance between the sample and the current
+ // constellation point.
+ float dist = powf(std::abs(sample - d_constellation[i]), 2.0f);
+
+ // Calculate the probability factor from the distance and
+ // the scaled noise power.
+ float d = expf(-dist / (2.0*npwr*scale));
+
+ for(int j = 0; j < k; j++) {
+ // Get the bit at the jth index
+ int mask = 1 << j;
+ int bit = (d_pre_diff_code[i] & mask) >> j;
+
+ // If the bit is a 0, add to the probability of a zero
+ if(bit == 0)
+ tmp[2*j+0] += d;
+ // else, add to the probability of a one
+ else
+ tmp[2*j+1] += d;
+ }
+ }
+
+ // Calculate the log-likelihood ratio for all bits based on the
+ // probability of ones (tmp[2*i+1]) over the probability of a zero
+ // (tmp[2*i+0]).
+ for(int i = 0; i < k; i++) {
+ s[k-1-i] = (logf(tmp[2*i+1]) - logf(tmp[2*i+0])) * scale;
+ }
+
+ return s;
+ }
+
+ void
+ constellation::set_soft_dec_lut(const std::vector< std::vector<float> > &soft_dec_lut,
+ int precision)
+ {
+ max_min_axes();
+
+ d_soft_dec_lut = soft_dec_lut;
+ d_lut_precision = precision;
+ d_lut_scale = powf(2.0, static_cast<float>(precision));
+ }
+
+ bool
+ constellation::has_soft_dec_lut()
+ {
+ return d_soft_dec_lut.size() > 0;
+ }
+
+ std::vector<float>
+ constellation::soft_decision_maker(gr_complex sample)
+ {
+ if(has_soft_dec_lut()) {
+ float xre = sample.real();
+ float xim = sample.imag();
+
+ float xstep = (d_re_max-d_re_min) / d_lut_scale;
+ float ystep = (d_im_max-d_im_min) / d_lut_scale;
+
+ float xscale = (d_lut_scale / (d_re_max-d_re_min)) - xstep;
+ float yscale = (d_lut_scale / (d_im_max-d_im_min)) - ystep;
+
+ xre = floorf((-d_re_min + std::min(d_re_max, std::max(d_re_min, xre))) * xscale);
+ xim = floorf((-d_im_min + std::min(d_im_max, std::max(d_im_min, xim))) * yscale);
+ int index = static_cast<int>(d_lut_scale*xim + xre);
+
+ int max_index = d_lut_scale*d_lut_scale;
+ if(index > max_index) {
+ return d_soft_dec_lut[max_index-1];
+ }
+
+ if(index < 0)
+ throw std::runtime_error("constellation::soft_decision_maker: input sample out of range.");
+
+ return d_soft_dec_lut[index];
+ }
+ else {
+ return calc_soft_dec(sample);
+ }
+ }
+
+ void
+ constellation::max_min_axes()
+ {
+ // Find min/max of constellation for both real and imag axes.
+ d_re_min = 1e20;
+ d_im_min = 1e20;
+ d_re_max = -1e20;
+ d_im_max = -1e20;
+ for(size_t i = 0; i < d_constellation.size(); i++) {
+ if(d_constellation[i].real() > d_re_max)
+ d_re_max = d_constellation[i].real();
+ if(d_constellation[i].imag() > d_im_max)
+ d_im_max = d_constellation[i].imag();
+
+ if(d_constellation[i].real() < d_re_min)
+ d_re_min = d_constellation[i].real();
+ if(d_constellation[i].imag() < d_im_min)
+ d_im_min = d_constellation[i].imag();
+ }
+ if(d_im_min == 0)
+ d_im_min = d_re_min;
+ if(d_im_max == 0)
+ d_im_max = d_re_max;
+ if(d_re_min == 0)
+ d_re_min = d_im_min;
+ if(d_re_max == 0)
+ d_re_max = d_im_max;
+ }
+
/********************************************************************/
- constellation_calcdist::sptr
+ constellation_calcdist::sptr
constellation_calcdist::make(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
diff --git a/gr-digital/lib/constellation_soft_decoder_cf_impl.cc b/gr-digital/lib/constellation_soft_decoder_cf_impl.cc
new file mode 100644
index 0000000000..cd0a844119
--- /dev/null
+++ b/gr-digital/lib/constellation_soft_decoder_cf_impl.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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 "constellation_soft_decoder_cf_impl.h"
+#include <gnuradio/io_signature.h>
+
+namespace gr {
+ namespace digital {
+
+ constellation_soft_decoder_cf::sptr
+ constellation_soft_decoder_cf::make(constellation_sptr constellation)
+ {
+ return gnuradio::get_initial_sptr
+ (new constellation_soft_decoder_cf_impl(constellation));
+ }
+
+ constellation_soft_decoder_cf_impl::
+ constellation_soft_decoder_cf_impl(constellation_sptr constellation)
+ : sync_interpolator("constellation_soft_decoder_cf",
+ io_signature::make(1, 1, sizeof(gr_complex)),
+ io_signature::make(1, 1, sizeof(float)),
+ constellation->bits_per_symbol()),
+ d_constellation(constellation),
+ d_dim(constellation->dimensionality()),
+ d_bps(constellation->bits_per_symbol())
+ {
+ }
+
+ constellation_soft_decoder_cf_impl::~constellation_soft_decoder_cf_impl()
+ {
+ }
+
+ int
+ constellation_soft_decoder_cf_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ gr_complex const *in = (const gr_complex*)input_items[0];
+ float *out = (float*)output_items[0];
+
+ std::vector<float> bits;
+
+ // FIXME: figure out how to manage d_dim
+ for(int i = 0; i < noutput_items/d_bps; i++) {
+ bits = d_constellation->soft_decision_maker(in[i]);
+ for(size_t j = 0; j < bits.size(); j++) {
+ out[d_bps*i+j] = bits[j];
+ }
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/constellation_soft_decoder_cf_impl.h b/gr-digital/lib/constellation_soft_decoder_cf_impl.h
new file mode 100644
index 0000000000..8a1159b627
--- /dev/null
+++ b/gr-digital/lib/constellation_soft_decoder_cf_impl.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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_DIGITAL_CONSTELLATION_SOFT_DECODER_CF_IMPL_H
+#define INCLUDED_DIGITAL_CONSTELLATION_SOFT_DECODER_CF_IMPL_H
+
+#include <gnuradio/digital/constellation_soft_decoder_cf.h>
+
+namespace gr {
+ namespace digital {
+
+ class constellation_soft_decoder_cf_impl : public constellation_soft_decoder_cf
+ {
+ private:
+ constellation_sptr d_constellation;
+ unsigned int d_dim;
+ int d_bps;
+
+ public:
+ constellation_soft_decoder_cf_impl(constellation_sptr constellation);
+ ~constellation_soft_decoder_cf_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace digital */
+} /* namespace gr */
+
+#endif /* INCLUDED_DIGITAL_CONSTELLATION_SOFT_DECODER_CF_IMPL_H */
diff --git a/gr-digital/lib/packet_header_default.cc b/gr-digital/lib/packet_header_default.cc
index ef5f39dc97..12b8613b6d 100644
--- a/gr-digital/lib/packet_header_default.cc
+++ b/gr-digital/lib/packet_header_default.cc
@@ -69,27 +69,28 @@ namespace gr {
)
{
packet_len &= 0x0FFF;
+ d_crc_impl.reset();
+ d_crc_impl.process_bytes((void const *) &packet_len, 2);
+ d_crc_impl.process_bytes((void const *) &d_header_number, 2);
+ unsigned char crc = d_crc_impl();
memset(out, 0x00, d_header_len);
- int parity = 0;
int k = 0; // Position in out
for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) {
out[k] = (unsigned char) ((packet_len >> i) & d_mask);
- parity += out[k];
}
- for (int i = 0; i < 16 && k < d_header_len; i += d_bits_per_byte, k++) {
+ for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) {
out[k] = (unsigned char) ((d_header_number >> i) & d_mask);
- parity += out[k];
}
- if (k < d_header_len) {
- out[k] = (unsigned char) (parity % 2);
+ for (int i = 0; i < 8 && k < d_header_len; i += d_bits_per_byte, k++) {
+ out[k] = (unsigned char) ((crc >> i) & d_mask);
}
d_header_number++;
+ d_header_number &= 0x0FFF;
return true;
}
-
bool packet_header_default::header_parser(
const unsigned char *in,
std::vector<tag_t> &tags)
@@ -109,25 +110,30 @@ namespace gr {
return true;
}
if (d_num_tag_key == pmt::PMT_NIL) {
- k += 16;
+ k += 12;
} else {
- for (int i = 0; i < 16 && k < d_header_len; i += d_bits_per_byte, k++) {
+ for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) {
header_num |= (((int) in[k]) & d_mask) << i;
}
tag.key = d_num_tag_key;
tag.value = pmt::from_long(header_num);
tags.push_back(tag);
}
-
if (k >= d_header_len) {
return true;
}
- int parity = in[k];
- for (int i = 0; i < 28; i++) {
- parity += in[i];
+ d_crc_impl.reset();
+ d_crc_impl.process_bytes((void const *) &header_len, 2);
+ d_crc_impl.process_bytes((void const *) &header_num, 2);
+ unsigned char crc_calcd = d_crc_impl();
+ for (int i = 0; i < 8 && k < d_header_len; i += d_bits_per_byte, k++) {
+ if ( (((int) in[k]) & d_mask) != (((int) crc_calcd >> i) & d_mask) ) {
+ return false;
+ }
}
- return !(parity % 2);
+
+ return true;
}
} /* namespace digital */
diff --git a/gr-digital/lib/packet_header_ofdm.cc b/gr-digital/lib/packet_header_ofdm.cc
index f163657bab..4893b866e2 100644
--- a/gr-digital/lib/packet_header_ofdm.cc
+++ b/gr-digital/lib/packet_header_ofdm.cc
@@ -24,6 +24,7 @@
#endif
#include <gnuradio/digital/packet_header_ofdm.h>
+#include <gnuradio/digital/lfsr.h>
namespace gr {
namespace digital {
@@ -46,11 +47,13 @@ namespace gr {
const std::string &frame_len_tag_key,
const std::string &num_tag_key,
int bits_per_header_sym,
- int bits_per_payload_sym)
+ int bits_per_payload_sym,
+ bool scramble_header)
{
return packet_header_ofdm::sptr(
new packet_header_ofdm(
- occupied_carriers, n_syms, len_tag_key, frame_len_tag_key, num_tag_key, bits_per_header_sym, bits_per_payload_sym
+ occupied_carriers, n_syms, len_tag_key, frame_len_tag_key, num_tag_key,
+ bits_per_header_sym, bits_per_payload_sym, scramble_header
)
);
}
@@ -62,8 +65,9 @@ namespace gr {
const std::string &frame_len_tag_key,
const std::string &num_tag_key,
int bits_per_header_sym,
- int bits_per_payload_sym)
- : packet_header_default(
+ int bits_per_payload_sym,
+ bool scramble_header
+ ) : packet_header_default(
_get_header_len_from_occupied_carriers(occupied_carriers, n_syms),
len_tag_key,
num_tag_key,
@@ -71,23 +75,47 @@ namespace gr {
d_frame_len_tag_key(pmt::string_to_symbol(frame_len_tag_key)),
d_occupied_carriers(occupied_carriers),
d_syms_per_set(0),
- d_bits_per_payload_sym(bits_per_payload_sym)
+ d_bits_per_payload_sym(bits_per_payload_sym),
+ d_scramble_mask(d_header_len, 0)
{
for (unsigned i = 0; i < d_occupied_carriers.size(); i++) {
d_syms_per_set += d_occupied_carriers[i].size();
}
+
+ // Init scrambler mask
+ if (scramble_header) {
+ // These are just random values which already have OK PAPR:
+ gr::digital::lfsr shift_reg(0x8a, 0x6f, 7);
+ for (int i = 0; i < d_header_len; i++) {
+ for (int k = 0; k < bits_per_header_sym; k++) {
+ d_scramble_mask[i] ^= shift_reg.next_bit() << k;
+ }
+ }
+ }
}
packet_header_ofdm::~packet_header_ofdm()
{
}
+ bool packet_header_ofdm::header_formatter(long packet_len, unsigned char *out, const std::vector<tag_t> &tags)
+ {
+ bool ret_val = packet_header_default::header_formatter(packet_len, out, tags);
+ for (int i = 0; i < d_header_len; i++) {
+ out[i] ^= d_scramble_mask[i];
+ }
+ return ret_val;
+ }
bool packet_header_ofdm::header_parser(
const unsigned char *in,
std::vector<tag_t> &tags)
{
- if (!packet_header_default::header_parser(in, tags)) {
+ std::vector<unsigned char> in_descrambled(d_header_len, 0);
+ for (int i = 0; i < d_header_len; i++) {
+ in_descrambled[i] = in[i] ^ d_scramble_mask[i];
+ }
+ if (!packet_header_default::header_parser(&in_descrambled[0], tags)) {
return false;
}
int packet_len = 0; // # of bytes in this frame
diff --git a/gr-digital/python/digital/CMakeLists.txt b/gr-digital/python/digital/CMakeLists.txt
index 30066d9aac..e0cb77fb21 100644
--- a/gr-digital/python/digital/CMakeLists.txt
+++ b/gr-digital/python/digital/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2011-212 Free Software Foundation, Inc.
+# Copyright 2011-2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -26,6 +26,7 @@ GR_PYTHON_INSTALL(
FILES
__init__.py
bpsk.py
+ constellation_map_generator.py
cpm.py
crc.py
generic_mod_demod.py
@@ -43,9 +44,12 @@ GR_PYTHON_INSTALL(
packet_utils.py
pkt.py
psk.py
+ psk_constellations.py
qam.py
qamlike.py
+ qam_constellations.py
qpsk.py
+ soft_dec_lut_gen.py
DESTINATION ${GR_PYTHON_DIR}/gnuradio/digital
COMPONENT "digital_python"
)
diff --git a/gr-digital/python/digital/__init__.py b/gr-digital/python/digital/__init__.py
index 5059e4eec8..79b740644d 100644
--- a/gr-digital/python/digital/__init__.py
+++ b/gr-digital/python/digital/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011-2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -50,6 +50,10 @@ from ofdm_sync_ml import *
from ofdm_sync_pnac import *
from ofdm_sync_pn import *
from ofdm_txrx import ofdm_tx, ofdm_rx
+from soft_dec_lut_gen import *
+from psk_constellations import *
+from qam_constellations import *
+from constellation_map_generator import *
import packet_utils
import ofdm_packet_utils
diff --git a/gr-digital/python/digital/constellation_map_generator.py b/gr-digital/python/digital/constellation_map_generator.py
new file mode 100644
index 0000000000..bf689676c3
--- /dev/null
+++ b/gr-digital/python/digital/constellation_map_generator.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+def constellation_map_generator(basis_cpoints, basis_symbols, k, pi):
+ '''
+ Uses the a basis constellation provided (e.g., from
+ psk_constellation.psk_4()) and the the k and permutation index
+ (pi) to generate a new Gray-coded symbol map to the constellation
+ points provided in the basis.
+
+ The basis_cpoints are the constellation points of the basis
+ constellation, and basis_symbols are the symbols that correspond
+ to the constellation points.
+
+ The selection of k and pi will provide an automorphism the
+ hyperoctahedral group of the basis constellation.
+
+ This function returns a tuple of (constellation_points,
+ symbol_map). The constellation_points is a list of the
+ constellation points in complex space and the symbol_map is a list
+ of the log2(M)-bit symbols for the constellation points (i.e.,
+ symbol_map[i] are the bits associated with
+ constellation_points[i]).
+ '''
+ const_points, s = basis()
+ symbols = list()
+ for s_i in s:
+ tmp = 0
+ for i,p in enumerate(pi):
+ bit = (s_i >> i) & 0x1
+ tmp |= bit << p
+ symbols.append(tmp ^ k)
+ return (const_points, symbols)
diff --git a/gr-digital/python/digital/ofdm_txrx.py b/gr-digital/python/digital/ofdm_txrx.py
index a48a48db41..06e375e3d6 100644
--- a/gr-digital/python/digital/ofdm_txrx.py
+++ b/gr-digital/python/digital/ofdm_txrx.py
@@ -63,6 +63,7 @@ _seq_seed = 42
def _get_active_carriers(fft_len, occupied_carriers, pilot_carriers):
+ """ Returns a list of all carriers that at some point carry data or pilots. """
active_carriers = list()
for carrier in list(occupied_carriers[0]) + list(pilot_carriers[0]):
if carrier < 0:
@@ -134,6 +135,8 @@ class ofdm_tx(gr.hier_block2):
sync_word2: The second sync preamble symbol. This has to be filled entirely. Also used for
coarse frequency offset and channel estimation.
rolloff: The rolloff length in samples. Must be smaller than the CP.
+ debug_log: Write output into log files (Warning: creates lots of data!)
+ scramble_bits: Activates the scramblers (set this to True unless debugging)
"""
def __init__(self, fft_len=_def_fft_len, cp_len=_def_cp_len,
packet_length_tag_key=_def_packet_length_tag_key,
@@ -145,7 +148,8 @@ class ofdm_tx(gr.hier_block2):
sync_word1=None,
sync_word2=None,
rolloff=0,
- debug_log=False
+ debug_log=False,
+ scramble_bits=False
):
gr.hier_block2.__init__(self, "ofdm_tx",
gr.io_signature(1, 1, gr.sizeof_char),
@@ -159,7 +163,6 @@ class ofdm_tx(gr.hier_block2):
self.pilot_symbols = pilot_symbols
self.bps_header = bps_header
self.bps_payload = bps_payload
- n_sync_words = 1
self.sync_word1 = sync_word1
if sync_word1 is None:
self.sync_word1 = _make_sync_word1(fft_len, occupied_carriers, pilot_carriers)
@@ -167,15 +170,19 @@ class ofdm_tx(gr.hier_block2):
if len(sync_word1) != self.fft_len:
raise ValueError("Length of sync sequence(s) must be FFT length.")
self.sync_words = [self.sync_word1,]
- self.sync_word2 = ()
if sync_word2 is None:
self.sync_word2 = _make_sync_word2(fft_len, occupied_carriers, pilot_carriers)
+ else:
+ self.sync_word2 = sync_word2
if len(self.sync_word2):
if len(self.sync_word2) != fft_len:
raise ValueError("Length of sync sequence(s) must be FFT length.")
self.sync_word2 = list(self.sync_word2)
- n_sync_words = 2
self.sync_words.append(self.sync_word2)
+ if scramble_bits:
+ self.scramble_seed = 0x7f
+ else:
+ self.scramble_seed = 0x00 # We deactivate the scrambler by init'ing it with zeros
### Header modulation ################################################
crc = digital.crc32_bb(False, self.packet_length_tag_key)
header_constellation = _get_constellation(bps_header)
@@ -183,18 +190,34 @@ class ofdm_tx(gr.hier_block2):
formatter_object = digital.packet_header_ofdm(
occupied_carriers=occupied_carriers, n_syms=1,
bits_per_header_sym=self.bps_header,
- bits_per_payload_sym=self.bps_payload
+ bits_per_payload_sym=self.bps_payload,
+ scramble_header=scramble_bits
)
header_gen = digital.packet_headergenerator_bb(formatter_object.base(), self.packet_length_tag_key)
header_payload_mux = blocks.tagged_stream_mux(gr.sizeof_gr_complex*1, self.packet_length_tag_key)
- self.connect(self, crc, header_gen, header_mod, (header_payload_mux, 0))
+ self.connect(
+ self,
+ crc,
+ header_gen,
+ header_mod,
+ (header_payload_mux, 0)
+ )
if debug_log:
self.connect(header_gen, blocks.file_sink(1, 'tx-hdr.dat'))
### Payload modulation ###############################################
payload_constellation = _get_constellation(bps_payload)
payload_mod = digital.chunks_to_symbols_bc(payload_constellation.points())
+ payload_scrambler = digital.additive_scrambler_bb(
+ 0x8a,
+ self.scramble_seed,
+ 7,
+ 0, # Don't reset after fixed length (let the reset tag do that)
+ bits_per_byte=bps_payload,
+ reset_tag_key=self.packet_length_tag_key
+ )
self.connect(
crc,
+ payload_scrambler,
blocks.repack_bits_bb(
8, # Unpack 8 bits per byte
bps_payload,
@@ -226,8 +249,8 @@ class ofdm_tx(gr.hier_block2):
)
self.connect(header_payload_mux, allocator, ffter, cyclic_prefixer, self)
if debug_log:
- self.connect(allocator, blocks.file_sink(8*64, 'tx-post-allocator.dat'))
- self.connect(cyclic_prefixer, blocks.file_sink(8, 'tx-signal.dat'))
+ self.connect(allocator, blocks.file_sink(gr.sizeof_gr_complex * fft_len, 'tx-post-allocator.dat'))
+ self.connect(cyclic_prefixer, blocks.file_sink(gr.sizeof_gr_complex, 'tx-signal.dat'))
class ofdm_rx(gr.hier_block2):
@@ -262,7 +285,8 @@ class ofdm_rx(gr.hier_block2):
bps_payload=1,
sync_word1=None,
sync_word2=None,
- debug_log=False
+ debug_log=False,
+ scramble_bits=False
):
gr.hier_block2.__init__(self, "ofdm_rx",
gr.io_signature(1, 1, gr.sizeof_gr_complex),
@@ -291,6 +315,10 @@ class ofdm_rx(gr.hier_block2):
raise ValueError("Length of sync sequence(s) must be FFT length.")
self.sync_word2 = sync_word2
n_sync_words = 2
+ if scramble_bits:
+ self.scramble_seed = 0x7f
+ else:
+ self.scramble_seed = 0x00 # We deactivate the scrambler by init'ing it with zeros
### Sync ############################################################
sync_detect = digital.ofdm_sync_sc_cfb(fft_len, cp_len)
delay = blocks.delay(gr.sizeof_gr_complex, fft_len+cp_len)
@@ -315,8 +343,12 @@ class ofdm_rx(gr.hier_block2):
chanest = digital.ofdm_chanest_vcvc(self.sync_word1, self.sync_word2, 1)
header_constellation = _get_constellation(bps_header)
header_equalizer = digital.ofdm_equalizer_simpledfe(
- fft_len, header_constellation.base(),
- occupied_carriers, pilot_carriers, pilot_symbols, 0, 0
+ fft_len,
+ header_constellation.base(),
+ occupied_carriers,
+ pilot_carriers,
+ pilot_symbols,
+ symbols_skipped=0,
)
header_eq = digital.ofdm_frame_equalizer_vcvc(
header_equalizer.base(),
@@ -336,10 +368,19 @@ class ofdm_rx(gr.hier_block2):
frame_length_tag_key,
packet_num_tag_key,
bps_header,
- bps_payload
+ bps_payload,
+ scramble_header=scramble_bits
)
header_parser = digital.packet_headerparser_b(header_formatter.formatter())
- self.connect((hpd, 0), header_fft, chanest, header_eq, header_serializer, header_demod, header_parser)
+ self.connect(
+ (hpd, 0),
+ header_fft,
+ chanest,
+ header_eq,
+ header_serializer,
+ header_demod,
+ header_parser
+ )
self.msg_connect(header_parser, "header_data", hpd, "header_data")
if debug_log:
self.connect((chanest, 1), blocks.file_sink(gr.sizeof_gr_complex * fft_len, 'channel-estimate.dat'))
@@ -347,16 +388,18 @@ class ofdm_rx(gr.hier_block2):
self.connect((chanest, 0), blocks.tag_debug(gr.sizeof_gr_complex * fft_len, 'post-hdr-chanest'))
self.connect(header_eq, blocks.file_sink(gr.sizeof_gr_complex * fft_len, 'post-hdr-eq.dat'))
self.connect(header_serializer, blocks.file_sink(gr.sizeof_gr_complex, 'post-hdr-serializer.dat'))
- self.connect(header_demod, blocks.file_sink(1, 'post-hdr-demod.dat'))
+ self.connect(header_descrambler, blocks.file_sink(1, 'post-hdr-demod.dat'))
### Payload demod ####################################################
payload_fft = fft.fft_vcc(self.fft_len, True, (), True)
payload_constellation = _get_constellation(bps_payload)
payload_equalizer = digital.ofdm_equalizer_simpledfe(
- fft_len, payload_constellation.base(),
+ fft_len,
+ payload_constellation.base(),
occupied_carriers,
pilot_carriers,
pilot_symbols,
- 1 # Skip 1 symbol (that was already in the header)
+ symbols_skipped=1, # (that was already in the header)
+ alpha=0.1
)
payload_eq = digital.ofdm_frame_equalizer_vcvc(
payload_equalizer.base(),
@@ -370,11 +413,29 @@ class ofdm_rx(gr.hier_block2):
1 # Skip 1 symbol (that was already in the header)
)
payload_demod = digital.constellation_decoder_cb(payload_constellation.base())
+ self.payload_descrambler = digital.additive_scrambler_bb(
+ 0x8a,
+ self.scramble_seed,
+ 7,
+ 0, # Don't reset after fixed length
+ bits_per_byte=bps_payload,
+ reset_tag_key=self.packet_length_tag_key
+ )
repack = blocks.repack_bits_bb(bps_payload, 8, self.packet_length_tag_key, True)
- crc = digital.crc32_bb(True, self.packet_length_tag_key)
- self.connect((hpd, 1), payload_fft, payload_eq, payload_serializer, payload_demod, repack, crc, self)
+ self.crc = digital.crc32_bb(True, self.packet_length_tag_key)
+ self.connect(
+ (hpd, 1),
+ payload_fft,
+ payload_eq,
+ payload_serializer,
+ payload_demod,
+ repack,
+ self.payload_descrambler,
+ self.crc,
+ self
+ )
if debug_log:
- self.connect((hpd, 1), blocks.tag_debug(gr.sizeof_gr_complex*fft_len, 'post-hpd'));
+ self.connect((hpd, 1), blocks.tag_debug(gr.sizeof_gr_complex*fft_len, 'post-hpd'))
self.connect(payload_fft, blocks.file_sink(gr.sizeof_gr_complex*fft_len, 'post-payload-fft.dat'))
self.connect(payload_eq, blocks.file_sink(gr.sizeof_gr_complex*fft_len, 'post-payload-eq.dat'))
self.connect(payload_serializer, blocks.file_sink(gr.sizeof_gr_complex, 'post-payload-serializer.dat'))
diff --git a/gr-digital/python/digital/packet_utils.py b/gr-digital/python/digital/packet_utils.py
index 2929758ef0..865f3adbb4 100644
--- a/gr-digital/python/digital/packet_utils.py
+++ b/gr-digital/python/digital/packet_utils.py
@@ -71,7 +71,7 @@ def conv_1_0_string_to_packed_binary_string(s):
default_access_code = \
conv_packed_binary_string_to_1_0_string('\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC')
-preamble = \
+default_preamble = \
conv_packed_binary_string_to_1_0_string('\xA4\xF2')
def is_1_0_string(s):
@@ -102,8 +102,8 @@ def make_header(payload_len, whitener_offset=0):
return struct.pack('!HH', val, val)
def make_packet(payload, samples_per_symbol, bits_per_symbol,
- access_code=default_access_code, pad_for_usrp=True,
- whitener_offset=0, whitening=True):
+ preamble=default_preamble, access_code=default_access_code,
+ pad_for_usrp=True, whitener_offset=0, whitening=True):
"""
Build a packet, given access code, payload, and whitener offset
@@ -111,12 +111,16 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
payload: packet payload, len [0, 4096]
samples_per_symbol: samples per symbol (needed for padding calculation) (int)
bits_per_symbol: (needed for padding calculation) (int)
+ preamble: string of ascii 0's and 1's
access_code: string of ascii 0's and 1's
whitener_offset: offset into whitener string to use [0-16)
Packet will have access code at the beginning, followed by length, payload
and finally CRC-32.
"""
+ if not is_1_0_string(preamble):
+ raise ValueError, "preamble must be a string containing only 0's and 1's (%r)" % (preamble,)
+
if not is_1_0_string(access_code):
raise ValueError, "access_code must be a string containing only 0's and 1's (%r)" % (access_code,)
diff --git a/gr-digital/python/digital/pkt.py b/gr-digital/python/digital/pkt.py
index 434548906e..fbdcaa3a66 100644
--- a/gr-digital/python/digital/pkt.py
+++ b/gr-digital/python/digital/pkt.py
@@ -40,8 +40,8 @@ class mod_pkts(gr.hier_block2):
Send packets by calling send_pkt
"""
- def __init__(self, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True,
- use_whitener_offset=False, modulate=True):
+ def __init__(self, modulator, preamble=None, access_code=None, msgq_limit=2,
+ pad_for_usrp=True, use_whitener_offset=False, modulate=True):
"""
Hierarchical block for sending packets
@@ -72,6 +72,12 @@ class mod_pkts(gr.hier_block2):
if not packet_utils.is_1_0_string(access_code):
raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
self._access_code = access_code
+
+ if preamble is None:
+ preamble = packet_utils.default_preamble
+ if not packet_utils.is_1_0_string(preamble):
+ raise ValueError, "Invalid preamble %r. Must be string of 1's and 0's" % (preamble,)
+ self._preamble = preamble
# accepts messages from the outside world
self._pkt_input = blocks.message_source(gr.sizeof_char, msgq_limit)
@@ -91,6 +97,7 @@ class mod_pkts(gr.hier_block2):
pkt = packet_utils.make_packet(payload,
self._modulator.samples_per_symbol(),
self._modulator.bits_per_symbol(),
+ self._preamble,
self._access_code,
self._pad_for_usrp,
self._whitener_offset)
diff --git a/gr-digital/python/digital/psk_constellations.py b/gr-digital/python/digital/psk_constellations.py
new file mode 100755
index 0000000000..ee62c33a0c
--- /dev/null
+++ b/gr-digital/python/digital/psk_constellations.py
@@ -0,0 +1,308 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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 numpy
+from constellation_map_generator import *
+
+'''
+Note on the naming scheme. Each constellation is named using a prefix
+for the type of constellation, the order of the constellation, and a
+distinguishing feature, which comes in three modes:
+
+- No extra feature: the basic Gray-coded constellation map; others
+ will be derived from this type.
+- A single number: an indexed number to uniquely identify different
+ constellation maps.
+- 0xN_x0_x1..._xM: A permutation of the base constellation, explained
+ below.
+
+For rectangular constellations (BPSK, QPSK, QAM), we can define a
+hyperspace and look for all symmetries. This is also known as the
+automorphism group of the hypercube, aka the hyperoctahedral
+group. What this means is that we can easily define all possible
+rotations in terms of the first base mapping by creating the mapping:
+
+ f(x) = k XOR pi(x)
+
+The x is the bit string for the symbol we are altering. Then k is a
+bit string of n bits where n is the number of bits per symbol in the
+constellation (e.g., 2 for QPSK or 6 for QAM64). The pi is a
+permutation function specified as pi_0, pi_1..., pi_n-1. This permutes
+the bits from the base constellation symbol to a new code, which is
+then xor'd by k.
+
+The value of k is from 0 to 2^n-1 and pi is a list of all bit
+positions.
+
+The total number of Gray coded modulations is (2^n)*(n!).
+
+We create aliases for all possible naming schemes for the
+constellations. So if a hyperoctahedral group is defined, we also set
+this function equal to a function name using a unique ID number, and
+we always select one rotation as our basic rotation that the other
+rotations are based off of.
+'''
+
+# BPSK Constellation Mappings
+
+def psk_2_0x0():
+ '''
+ 0 | 1
+ '''
+ const_points = [-1, 1]
+ symbols = [0, 1]
+ return (const_points, symbols)
+psk_2 = psk_2_0x0 # Basic BPSK rotation
+psk_2_0 = psk_2 # First ID for BPSK rotations
+
+def psk_2_0x1():
+ '''
+ 1 | 0
+ '''
+ const_points = [-1, 1]
+ symbols = [1, 0]
+ return (const_points, symbols)
+psk_2_1 = psk_2_0x1
+
+
+############################################################
+# BPSK Soft bit LUT generators
+############################################################
+
+def sd_psk_2_0x0(x, Es=1):
+ '''
+ 0 | 1
+ '''
+ x_re = x.real
+ dist = Es*numpy.sqrt(2)
+ return [dist*x_re,]
+sd_psk_2 = sd_psk_2_0x0 # Basic BPSK rotation
+sd_psk_2_0 = sd_psk_2 # First ID for BPSK rotations
+
+def sd_psk_2_0x1(x, Es=1):
+ '''
+ 1 | 0
+ '''
+ x_re = [x.real,]
+ dist = Es*numpy.sqrt(2)
+ return -dist*x_re
+sd_psk_2_1 = sd_psk_2_0x1
+
+
+############################################################
+# QPSK Constellation Mappings
+############################################################
+
+def psk_4_0x0_0_1():
+ '''
+ 10 | 11
+ -------
+ 00 | 01
+ '''
+ const_points = [-1-1j, 1-1j,
+ -1+1j, 1+1j]
+ symbols = [0, 1, 2, 3]
+ return (const_points, symbols)
+psk_4 = psk_4_0x0_0_1
+psk_4_0 = psk_4
+
+def psk_4_0x1_0_1():
+ '''
+ 11 | 10
+ -------
+ 01 | 00
+ '''
+ k = 0x1
+ pi = [0, 1]
+ return constellation_map_generator(psk_4, k, pi)
+psk_4_1 = psk_4_0x1_0_1
+
+def psk_4_0x2_0_1():
+ '''
+ 00 | 01
+ -------
+ 10 | 11
+ '''
+ k = 0x2
+ pi = [0, 1]
+ return constellation_map_generator(psk_4, k, pi)
+psk_4_2 = psk_4_0x2_0_1
+
+def psk_4_0x3_0_1():
+ '''
+ 01 | 00
+ -------
+ 11 | 10
+ '''
+ k = 0x3
+ pi = [0, 1]
+ return constellation_map_generator(psk_4, k, pi)
+psk_4_3 = psk_4_0x3_0_1
+
+def psk_4_0x0_1_0():
+ '''
+ 01 | 11
+ -------
+ 00 | 10
+ '''
+ k = 0x0
+ pi = [1, 0]
+ return constellation_map_generator(psk_4, k, pi)
+psk_4_4 = psk_4_0x0_1_0
+
+def psk_4_0x1_1_0():
+ '''
+ 00 | 10
+ -------
+ 01 | 11
+ '''
+ k = 0x1
+ pi = [1, 0]
+ return constellation_map_generator(psk_4, k, pi)
+psk_4_5 = psk_4_0x1_1_0
+
+def psk_4_0x2_1_0():
+ '''
+ 11 | 01
+ -------
+ 10 | 00
+ '''
+ k = 0x2
+ pi = [1, 0]
+ return constellation_map_generator(psk_4, k, pi)
+psk_4_6 = psk_4_0x2_1_0
+
+def psk_4_0x3_1_0():
+ '''
+ 10 | 00
+ -------
+ 11 | 01
+ '''
+ k = 0x3
+ pi = [1, 0]
+ return constellation_map_generator(psk_4, k, pi)
+psk_4_7 = psk_4_0x3_1_0
+
+
+
+############################################################
+# QPSK Constellation Softbit LUT generators
+############################################################
+
+def sd_psk_4_0x0_0_1(x, Es=1):
+ '''
+ 10 | 11
+ -------
+ 00 | 01
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [dist*x_im, dist*x_re]
+sd_psk_4 = sd_psk_4_0x0_0_1
+sd_psk_4_0 = sd_psk_4
+
+def sd_psk_4_0x1_0_1(x, Es=1):
+ '''
+ 11 | 10
+ -------
+ 01 | 00
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [dist*x_im, -dist*x_re]
+sd_psk_4_1 = sd_psk_4_0x1_0_1
+
+def sd_psk_4_0x2_0_1(x, Es=1):
+ '''
+ 00 | 01
+ -------
+ 10 | 11
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [-dist*x_im, dist*x_re]
+sd_psk_4_2 = sd_psk_4_0x2_0_1
+
+def sd_psk_4_0x3_0_1(x, Es=1):
+ '''
+ 01 | 00
+ -------
+ 11 | 10
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [-dist*x_im, -dist*x_re]
+sd_psk_4_3 = sd_psk_4_0x3_0_1
+
+def sd_psk_4_0x0_1_0(x, Es=1):
+ '''
+ 01 | 11
+ -------
+ 00 | 10
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [dist*x_re, dist*x_im]
+sd_psk_4_4 = sd_psk_4_0x0_1_0
+
+def sd_psk_4_0x1_1_0(x, Es=1):
+ '''
+ 00 | 10
+ -------
+ 01 | 11
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [dist*x_re, -dist*x_im]
+sd_psk_4_5 = sd_psk_4_0x1_1_0
+
+
+def sd_psk_4_0x2_1_0(x, Es=1):
+ '''
+ 11 | 01
+ -------
+ 10 | 00
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [-dist*x_re, dist*x_im]
+sd_psk_4_6 = sd_psk_4_0x2_1_0
+
+def sd_psk_4_0x3_1_0(x, Es=1):
+ '''
+ 10 | 00
+ -------
+ 11 | 01
+ '''
+ x_re = x.real
+ x_im = x.imag
+ dist = Es*numpy.sqrt(2)
+ return [-dist*x_re, -dist*x_im]
+sd_psk_4_7 = sd_psk_4_0x3_1_0
+
diff --git a/gr-digital/python/digital/qa_constellation.py b/gr-digital/python/digital/qa_constellation.py
index 83a875af4b..00248f4f09 100644
--- a/gr-digital/python/digital/qa_constellation.py
+++ b/gr-digital/python/digital/qa_constellation.py
@@ -21,7 +21,7 @@
#
import random
-from cmath import exp, pi, log
+from cmath import exp, pi, log, sqrt
from gnuradio import gr, gr_unittest, digital, blocks
from gnuradio.digital.utils import mod_codes
@@ -185,6 +185,86 @@ class test_constellation(gr_unittest.TestCase):
first = constellation.bits_per_symbol()
self.assertEqual(self.src_data[first:len(data)], data[first:])
+ def test_soft_qpsk_gen(self):
+ prec = 8
+ constel, code = digital.psk_4_0()
+
+ rot_sym = 1
+ side = 2
+ width = 2
+ c = digital.constellation_rect(constel, code, rot_sym,
+ side, side, width, width)
+
+ # Get max energy/symbol in constellation
+ constel = c.points()
+ Es = max([abs(constel_i) for constel_i in constel])
+
+ table = digital.soft_dec_table_generator(digital.sd_psk_4_0, prec, Es)
+ c.set_soft_dec_lut(table, prec)
+
+ x = sqrt(2.0)/2.0
+ step = (x.real+x.real) / (2**prec - 1)
+ samples = [ -x-x*1j, -x+x*1j,
+ x+x*1j, x-x*1j,
+ (-x+128*step)+(-x+128*step)*1j,
+ (-x+64*step) +(-x+64*step)*1j, (-x+64*step) +(-x+192*step)*1j,
+ (-x+192*step)+(-x+192*step)*1j, (-x+192*step)+(-x+64*step)*1j,]
+
+ y_python_raw_calc = []
+ y_python_gen_calc = []
+ y_python_table = []
+ y_cpp_raw_calc = []
+ y_cpp_table = []
+ for sample in samples:
+ y_python_raw_calc += digital.calc_soft_dec(sample, constel, code)
+ y_python_gen_calc += digital.sd_psk_4_0(sample, Es)
+ y_python_table += digital.calc_soft_dec_from_table(sample, table, prec, Es)
+
+ y_cpp_raw_calc += c.calc_soft_dec(sample)
+ y_cpp_table += c.soft_decision_maker(sample)
+
+ self.assertFloatTuplesAlmostEqual(y_python_raw_calc, y_python_gen_calc, 4)
+ self.assertFloatTuplesAlmostEqual(y_python_raw_calc, y_python_table, 2)
+ self.assertFloatTuplesAlmostEqual(y_cpp_raw_calc, y_cpp_table, 4)
+
+ def test_soft_qpsk_calc(self):
+ prec = 8
+ constel, code = digital.psk_4_0()
+
+ rot_sym = 1
+ side = 2
+ width = 2
+ c = digital.constellation_rect(constel, code, rot_sym,
+ side, side, width, width)
+
+ # Get max energy/symbol in constellation
+ constel = c.points()
+ Es = max([abs(constel_i) for constel_i in constel])
+
+ table = digital.soft_dec_table(constel, code, prec)
+ c.gen_soft_dec_lut(prec)
+
+ x = sqrt(2.0)/2.0
+ step = (x.real+x.real) / (2**prec - 1)
+ samples = [ -x-x*1j, -x+x*1j,
+ x+x*1j, x-x*1j,
+ (-x+128*step)+(-x+128*step)*1j,
+ (-x+64*step) +(-x+64*step)*1j, (-x+64*step) +(-x+192*step)*1j,
+ (-x+192*step)+(-x+192*step)*1j, (-x+192*step)+(-x+64*step)*1j,]
+
+ y_python_raw_calc = []
+ y_python_table = []
+ y_cpp_raw_calc = []
+ y_cpp_table = []
+ for sample in samples:
+ y_python_raw_calc += digital.calc_soft_dec(sample, constel, code)
+ y_python_table += digital.calc_soft_dec_from_table(sample, table, prec, Es)
+
+ y_cpp_raw_calc += c.calc_soft_dec(sample)
+ y_cpp_table += c.soft_decision_maker(sample)
+
+ self.assertFloatTuplesAlmostEqual(y_python_raw_calc, y_python_table, 4)
+ self.assertFloatTuplesAlmostEqual(y_cpp_raw_calc, y_cpp_table, 4)
class mod_demod(gr.hier_block2):
def __init__(self, constellation, differential, rotation):
diff --git a/gr-digital/python/digital/qa_constellation_soft_decoder_cf.py b/gr-digital/python/digital/qa_constellation_soft_decoder_cf.py
new file mode 100644
index 0000000000..6cd757537a
--- /dev/null
+++ b/gr-digital/python/digital/qa_constellation_soft_decoder_cf.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+from gnuradio import gr, gr_unittest, digital, blocks
+from math import sqrt
+
+class test_constellation_soft_decoder(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_constellation_soft_decoder_cf_bpsk(self):
+ prec = 8
+ src_data = (0.5 + 0.5j, 0.1 - 1.2j, -0.8 - 0.1j, -0.45 + 0.8j,
+ 0.8 + 1.0j, -0.5 + 0.1j, 0.1 - 1.2j, 1+1j)
+ lut = digital.soft_dec_table_generator(digital.sd_psk_2_0x0, prec)
+ expected_result = list()
+ for s in src_data:
+ expected_result += digital.calc_soft_dec_from_table(s, lut, prec, Es=2/sqrt(2))
+
+ cnst_pts, code = digital.psk_2_0x0()
+ cnst = digital.constellation_calcdist(cnst_pts, code, 2, 1)
+ cnst.set_soft_dec_lut(lut, int(prec))
+ src = blocks.vector_source_c(src_data)
+ op = digital.constellation_soft_decoder_cf(cnst.base())
+ dst = blocks.vector_sink_f()
+
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run() # run the graph and wait for it to finish
+
+ actual_result = dst.data() # fetch the contents of the sink
+ #print "actual result", actual_result
+ #print "expected result", expected_result
+ self.assertFloatTuplesAlmostEqual(expected_result, actual_result, 4)
+
+ def test_constellation_soft_decoder_cf_qpsk(self):
+ prec = 8
+ src_data = (0.5 + 0.5j, 0.1 - 1.2j, -0.8 - 0.1j, -0.45 + 0.8j,
+ 0.8 + 1.0j, -0.5 + 0.1j, 0.1 - 1.2j, 1+1j)
+ lut = digital.soft_dec_table_generator(digital.sd_psk_4_0x0_0_1, prec)
+ expected_result = list()
+ for s in src_data:
+ expected_result += digital.calc_soft_dec_from_table(s, lut, prec)
+
+ cnst_pts,code = digital.psk_4_0x0_0_1()
+ cnst = digital.constellation_calcdist(cnst_pts, code, 2, 1)
+ cnst.set_soft_dec_lut(lut, int(prec))
+ src = blocks.vector_source_c(src_data)
+ op = digital.constellation_soft_decoder_cf(cnst.base())
+ dst = blocks.vector_sink_f()
+
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run() # run the graph and wait for it to finish
+
+ actual_result = dst.data() # fetch the contents of the sink
+ #print "actual result", actual_result
+ #print "expected result", expected_result
+ self.assertFloatTuplesAlmostEqual(expected_result, actual_result, 5)
+
+ def test_constellation_soft_decoder_cf_qam16(self):
+ prec = 8
+ src_data = (0.5 + 0.5j, 0.1 - 1.2j, -0.8 - 0.1j, -0.45 + 0.8j,
+ 0.8 + 1.0j, -0.5 + 0.1j, 0.1 - 1.2j, 1+1j)
+ lut = digital.soft_dec_table_generator(digital.sd_qam_16_0x0_0_1_2_3, prec)
+ expected_result = list()
+ for s in src_data:
+ expected_result += digital.calc_soft_dec_from_table(s, lut, prec)
+
+ cnst_pts = digital.qam_16_0x0_0_1_2_3()
+ cnst = digital.constellation_calcdist(cnst_pts[0], cnst_pts[1], 2, 1)
+ cnst.set_soft_dec_lut(lut, int(prec))
+ src = blocks.vector_source_c(src_data)
+ op = digital.constellation_soft_decoder_cf(cnst.base())
+ dst = blocks.vector_sink_f()
+
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run() # run the graph and wait for it to finish
+
+ actual_result = dst.data() # fetch the contents of the sink
+ #print "actual result", actual_result
+ #print "expected result", expected_result
+ self.assertFloatTuplesAlmostEqual(expected_result, actual_result, 5)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_constellation_soft_decoder, "test_constellation_soft_decoder.xml")
+
diff --git a/gr-digital/python/digital/qa_ofdm_txrx.py b/gr-digital/python/digital/qa_ofdm_txrx.py
index adf93ee356..6f5bd2ed10 100755
--- a/gr-digital/python/digital/qa_ofdm_txrx.py
+++ b/gr-digital/python/digital/qa_ofdm_txrx.py
@@ -31,11 +31,11 @@ from gnuradio.digital.utils import tagged_streams
LOG_DEBUG_INFO=False
class ofdm_tx_fg (gr.top_block):
- def __init__(self, data, len_tag_key):
+ def __init__(self, data, len_tag_key, scramble_bits=False):
gr.top_block.__init__(self, "ofdm_tx")
tx_data, tags = tagged_streams.packets_to_vectors((data,), len_tag_key)
src = blocks.vector_source_b(data, False, 1, tags)
- self.tx = ofdm_tx(packet_length_tag_key=len_tag_key, debug_log=LOG_DEBUG_INFO)
+ self.tx = ofdm_tx(packet_length_tag_key=len_tag_key, debug_log=LOG_DEBUG_INFO, scramble_bits=scramble_bits)
self.sink = blocks.vector_sink_c()
self.connect(src, self.tx, self.sink)
@@ -43,12 +43,12 @@ class ofdm_tx_fg (gr.top_block):
return self.sink.data()
class ofdm_rx_fg (gr.top_block):
- def __init__(self, samples, len_tag_key, channel=None, prepend_zeros=100):
+ def __init__(self, samples, len_tag_key, channel=None, prepend_zeros=100, scramble_bits=False):
gr.top_block.__init__(self, "ofdm_rx")
if prepend_zeros:
samples = (0,) * prepend_zeros + tuple(samples)
src = blocks.vector_source_c(tuple(samples) + (0,) * 1000)
- self.rx = ofdm_rx(frame_length_tag_key=len_tag_key, debug_log=LOG_DEBUG_INFO)
+ self.rx = ofdm_rx(frame_length_tag_key=len_tag_key, debug_log=LOG_DEBUG_INFO, scramble_bits=scramble_bits)
if channel is not None:
self.connect(src, channel, self.rx)
else:
@@ -113,6 +113,28 @@ class test_ofdm_txrx (gr_unittest.TestCase):
self.assertEqual(tuple(tx_fg.tx.sync_word2), tuple(rx_fg.rx.sync_word2))
self.assertEqual(test_data, rx_data)
+ def test_003_tx1packet_scramble(self):
+ """ Same as before, use scrambler. """
+ len_tag_key = 'frame_len'
+ n_bytes = 21
+ fft_len = 64
+ test_data = tuple([random.randint(0, 255) for x in range(n_bytes)])
+ # 1.0/fft_len is one sub-carrier, a fine freq offset stays below that
+ freq_offset = 1.0 / fft_len * 0.7
+ #channel = channels.channel_model(0.01, freq_offset)
+ channel = None
+ # Tx
+ tx_fg = ofdm_tx_fg(test_data, len_tag_key, scramble_bits=True)
+ tx_fg.run()
+ tx_samples = tx_fg.get_tx_samples()
+ # Rx
+ rx_fg = ofdm_rx_fg(tx_samples, len_tag_key, channel, prepend_zeros=100, scramble_bits=True)
+ rx_fg.run()
+ rx_data = rx_fg.get_rx_bytes()
+ self.assertEqual(tuple(tx_fg.tx.sync_word1), tuple(rx_fg.rx.sync_word1))
+ self.assertEqual(tuple(tx_fg.tx.sync_word2), tuple(rx_fg.rx.sync_word2))
+ self.assertEqual(test_data, rx_data)
+
def test_004_tx1packet_large_fO(self):
""" Transmit one packet, with slight AWGN and large frequency offset.
Check packet is received and no bit errors have occurred. """
diff --git a/gr-digital/python/digital/qa_packet_headergenerator_bb.py b/gr-digital/python/digital/qa_packet_headergenerator_bb.py
index 3697bd1eb7..bec0828e4b 100755
--- a/gr-digital/python/digital/qa_packet_headergenerator_bb.py
+++ b/gr-digital/python/digital/qa_packet_headergenerator_bb.py
@@ -81,10 +81,10 @@ class qa_packet_headergenerator_bb (gr_unittest.TestCase):
self.tb.connect(src, header, sink)
self.tb.run()
expected_data = (
- # | Number of symbols | Packet number | Parity
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ # | Number of symbols | Packet number | CRC
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1
)
self.assertEqual(sink.data(), expected_data)
diff --git a/gr-digital/python/digital/qa_packet_headerparser_b.py b/gr-digital/python/digital/qa_packet_headerparser_b.py
index abd23c8945..1844991bc0 100755
--- a/gr-digital/python/digital/qa_packet_headerparser_b.py
+++ b/gr-digital/python/digital/qa_packet_headerparser_b.py
@@ -38,13 +38,13 @@ class qa_packet_headerparser_b (gr_unittest.TestCase):
"""
First header: Packet length 4, packet num 0
Second header: Packet 2, packet num 1
- Third header: Invalid (parity bit does not check) (would be len 4, num 2)
+ Third header: Invalid (CRC does not check) (would be len 4, num 2)
"""
encoded_headers = (
- # | Number of bytes | Packet number | Parity
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
+ # | Number of bytes | Packet number | CRC
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
)
packet_len_tagname = "packet_len"
random_tag = gr.tag_t()
@@ -99,9 +99,9 @@ class qa_packet_headerparser_b (gr_unittest.TestCase):
2 bits per complex symbol, 32 carriers => 64 bits = 8 bytes per OFDM symbol
"""
encoded_headers = (
- # | Number of bytes | Packet number | Parity
- 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ # | Number of bytes | Packet number | CRC
+ 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0,
)
packet_len_tagname = "packet_len"
frame_len_tagname = "frame_len"
@@ -130,6 +130,40 @@ class qa_packet_headerparser_b (gr_unittest.TestCase):
self.assertEqual(msg1, {'packet_len': 193*4, 'frame_len': 25, 'packet_num': 0})
self.assertEqual(msg2, {'packet_len': 8*4, 'frame_len': 1, 'packet_num': 1})
+ def test_004_ofdm_scramble(self):
+ """
+ Test scrambling for OFDM header gen
+ """
+ header_len = 32
+ packet_length = 23
+ packet_len_tagname = "packet_len"
+ frame_len_tagname = "frame_len"
+ data, tags = tagged_streams.packets_to_vectors([range(packet_length),range(packet_length),], packet_len_tagname)
+ src = blocks.vector_source_b(data, False, 1, tags)
+ header_formatter = digital.packet_header_ofdm(
+ (range(32),), # 32 carriers are occupied (which doesn't matter here)
+ 1, # 1 OFDM symbol per header (= 32 bits)
+ packet_len_tagname,
+ frame_len_tagname,
+ "packet_num",
+ 1, # 1 bit per header symbols (BPSK)
+ 2, # 2 bits per payload symbol (QPSK)
+ scramble_header=True
+ )
+ header_gen = digital.packet_headergenerator_bb(header_formatter.base())
+ header_parser = digital.packet_headerparser_b(header_formatter.base())
+ sink = blocks.message_debug()
+ self.tb.connect(src, header_gen, header_parser)
+ self.tb.msg_connect(header_parser, "header_data", sink, "store")
+ self.tb.start()
+ time.sleep(1)
+ self.tb.stop()
+ self.tb.wait()
+ msg = pmt.to_python(sink.get_message(0))
+ self.assertEqual(msg, {'packet_len': packet_length, 'packet_num': 0, 'frame_len': 4})
+ msg = pmt.to_python(sink.get_message(1))
+ self.assertEqual(msg, {'packet_len': packet_length, 'packet_num': 1, 'frame_len': 4})
+
if __name__ == '__main__':
gr_unittest.run(qa_packet_headerparser_b, "qa_packet_headerparser_b.xml")
diff --git a/gr-digital/python/digital/qa_scrambler.py b/gr-digital/python/digital/qa_scrambler.py
index 05daebd389..4d35879b1f 100755
--- a/gr-digital/python/digital/qa_scrambler.py
+++ b/gr-digital/python/digital/qa_scrambler.py
@@ -21,6 +21,7 @@
#
from gnuradio import gr, gr_unittest, digital, blocks
+import pmt
class test_scrambler(gr_unittest.TestCase):
@@ -60,5 +61,42 @@ class test_scrambler(gr_unittest.TestCase):
self.tb.run()
self.assertEqual(src_data, dst.data())
+ def test_additive_scrambler_reset_3bpb(self):
+ src_data = (5,)*2000
+ src = blocks.vector_source_b(src_data, False)
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 3)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 3)
+ dst = blocks.vector_sink_b()
+ dst2 = blocks.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.connect(scrambler, dst2)
+ self.tb.run()
+ if not (src_data == dst.data()):
+ self.fail('Not equal.')
+ self.assertEqual(src_data, src_data)
+
+ def test_additive_scrambler_tags(self):
+ src_data = (1,)*1000
+ src = blocks.vector_source_b(src_data, False)
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ reset_tag_key = 'reset_lfsr'
+ reset_tag1 = gr.tag_t()
+ reset_tag1.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag1.offset = 17
+ reset_tag2 = gr.tag_t()
+ reset_tag2.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag2.offset = 110
+ reset_tag3 = gr.tag_t()
+ reset_tag3.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag3.offset = 523
+ src = blocks.vector_source_b(src_data, False, 1, (reset_tag1, reset_tag2, reset_tag3))
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 1, reset_tag_key)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 1, reset_tag_key)
+ dst = blocks.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(src_data, dst.data())
+
if __name__ == '__main__':
gr_unittest.run(test_scrambler, "test_scrambler.xml")
diff --git a/gr-digital/python/digital/qam_constellations.py b/gr-digital/python/digital/qam_constellations.py
new file mode 100755
index 0000000000..4e8ee08a61
--- /dev/null
+++ b/gr-digital/python/digital/qam_constellations.py
@@ -0,0 +1,521 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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 numpy
+from constellation_map_generator import *
+
+'''
+Note on the naming scheme. Each constellation is named using a prefix
+for the type of constellation, the order of the constellation, and a
+distinguishing feature, which comes in three modes:
+
+- No extra feature: the basic Gray-coded constellation map; others
+ will be derived from this type.
+- A single number: an indexed number to uniquely identify different
+ constellation maps.
+- 0xN_x0_x1..._xM: A permutation of the base constellation, explained
+ below.
+
+For rectangular constellations (BPSK, QPSK, QAM), we can define a
+hyperspace and look for all symmetries. This is also known as the
+automorphism group of the hypercube, aka the hyperoctahedral
+group. What this means is that we can easily define all possible
+rotations in terms of the first base mapping by creating the mapping:
+
+ f(x) = k XOR pi(x)
+
+The x is the bit string for the symbol we are altering. Then k is a
+bit string of n bits where n is the number of bits per symbol in the
+constellation (e.g., 2 for QPSK or 6 for QAM64). The pi is a
+permutation function specified as pi_0, pi_1..., pi_n-1. This permutes
+the bits from the base constellation symbol to a new code, which is
+then xor'd by k.
+
+The value of k is from 0 to 2^n-1 and pi is a list of all bit
+positions.
+
+The permutation are given for b0_b1_b2_... for the total number of
+bits. In the constellation diagrams shown in the comments, the bit
+ordering is shown as [b3b2b1b0]. Bit values returned from the soft bit
+LUTs are in the order [b3, b2, b1, b0].
+
+
+The total number of Gray coded modulations is (2^n)*(n!).
+
+We create aliases for all possible naming schemes for the
+constellations. So if a hyperoctahedral group is defined, we also set
+this function equal to a function name using a unique ID number, and
+we always select one rotation as our basic rotation that the other
+rotations are based off of.
+
+For 16QAM:
+ - n = 4
+ - (2^n)*(n!) = 384
+ - k \in [0x0, 0xF]
+ - pi = 0, 1, 2, 3
+ 0, 1, 3, 2
+ 0, 2, 1, 3
+ 0, 2, 3, 1
+ 0, 3, 1, 2
+ 0, 3, 2, 1
+ 1, 0, 2, 3
+ 1, 0, 3, 2
+ 1, 2, 0, 3
+ 1, 2, 3, 0
+ 1, 3, 0, 2
+ 1, 3, 2, 0
+ 2, 0, 1, 3
+ 2, 0, 3, 1
+ 2, 1, 0, 3
+ 2, 1, 3, 0
+ 2, 3, 0, 1
+ 2, 3, 1, 0
+ 3, 0, 1, 2
+ 3, 0, 2, 1
+ 3, 1, 0, 2
+ 3, 1, 2, 0
+ 3, 2, 0, 1
+ 3, 2, 1, 0
+'''
+
+def qam_16_0x0_0_1_2_3():
+ '''
+ 0010 0110 | 1110 1010
+
+ 0011 0111 | 1111 1011
+ -----------------------
+ 0001 0101 | 1101 1001
+
+ 0000 0100 | 1100 1000
+ '''
+ const_points = [-3-3j, -1-3j, 1-3j, 3-3j,
+ -3-1j, -1-1j, 1-1j, 3-1j,
+ -3+1j, -1+1j, 1+1j, 3+1j,
+ -3+3j, -1+3j, 1+3j, 3+3j]
+ symbols = [0x0, 0x4, 0xC, 0x8,
+ 0x1, 0x5, 0xD, 0x9,
+ 0x3, 0x7, 0xF, 0xB,
+ 0x2, 0x6, 0xE, 0xA]
+ return (const_points, symbols)
+qam_16 = qam_16_0x0_0_1_2_3
+qam_16_0 = qam_16
+
+def qam_16_0x1_0_1_2_3():
+ '''
+ 0011 0111 | 1111 1011
+
+ 0010 0110 | 1110 1010
+ -----------------------
+ 0000 0100 | 1100 1000
+
+ 0001 0101 | 1101 1001
+ '''
+ k = 0x1
+ pi = [0, 1, 2, 3]
+ return constellation_map_generator(qam_16, k, pi)
+qam_16_1 = qam_16_0x1_0_1_2_3
+
+def qam_16_0x2_0_1_2_3():
+ '''
+ 0000 0100 | 1100 1000
+
+ 0001 0101 | 1101 1001
+ -----------------------
+ 0011 0111 | 1111 1011
+
+ 0010 0110 | 1110 1010
+ '''
+ k = 0x2
+ pi = [0, 1, 2, 3]
+ return constellation_map_generator(qam_16, k, pi)
+qam_16_2 = qam_16_0x2_0_1_2_3
+
+def qam_16_0x3_0_1_2_3():
+ '''
+ 0001 0101 | 1101 1001
+
+ 0000 0100 | 1100 1000
+ -----------------------
+ 0010 0110 | 1110 1010
+
+ 0011 0111 | 1111 1011
+ '''
+ k = 0x3
+ pi = [0, 1, 2, 3]
+ return constellation_map_generator(qam_16, k, pi)
+qam_16_3 = qam_16_0x3_0_1_2_3
+
+
+def qam_16_0x0_1_0_2_3():
+ '''
+ 0001 0101 | 1101 1001
+
+ 0011 0111 | 1111 1011
+ -----------------------
+ 0010 0110 | 1110 1010
+
+ 0000 0100 | 1100 1000
+ '''
+ k = 0x0
+ pi = [1, 0, 2, 3]
+ return constellation_map_generator(qam_16, k, pi)
+qam_16_4 = qam_16_0x0_1_0_2_3
+
+def qam_16_0x1_1_0_2_3():
+ '''
+ 0000 0100 | 1100 1000
+
+ 0010 0110 | 1110 1010
+ -----------------------
+ 0011 0111 | 1111 1011
+
+ 0001 0101 | 1101 1001
+ '''
+ k = 0x1
+ pi = [1, 0, 2, 3]
+ return constellation_map_generator(qam_16, k, pi)
+qam_16_5 = qam_16_0x1_1_0_2_3
+
+def qam_16_0x2_1_0_2_3():
+ '''
+ 0011 0111 | 1111 1011
+
+ 0001 0101 | 1101 1001
+ -----------------------
+ 0000 0100 | 1100 1000
+
+ 0010 0110 | 1110 1010
+ '''
+ k = 0x2
+ pi = [1, 0, 2, 3]
+ return constellation_map_generator(qam_16, k, pi)
+qam_16_6 = qam_16_0x2_1_0_2_3
+
+def qam_16_0x3_1_0_2_3():
+ '''
+ 0010 0110 | 1110 1010
+
+ 0000 0100 | 1100 1000
+ -----------------------
+ 0001 0101 | 1101 1001
+
+ 0011 0111 | 1111 1011
+ '''
+ k = 0x3
+ pi = [1, 0, 2, 3]
+ return constellation_map_generator(qam_16, k, pi)
+qam_16_7 = qam_16_0x3_1_0_2_3
+
+
+# Soft bit LUT generators
+
+def sd_qam_16_0x0_0_1_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0010 0110 | 1110 1010
+
+ 0011 0111 | 1111 1011
+ -----------------------
+ 0001 0101 | 1101 1001
+
+ 0000 0100 | 1100 1000
+ '''
+
+ dist = Es*numpy.sqrt(2)
+ boundary = dist/3.0
+ dist0 = dist/6.0
+# print "Sample: ", x
+# print "Es: ", Es
+# print "Distance: ", dist
+# print "Boundary: ", boundary
+# print "1st Bound: ", dist0
+
+ x_re = x.real
+ x_im = x.imag
+
+ if x_re < -boundary:
+ b3 = boundary*(x_re + dist0)
+ elif x_re < boundary:
+ b3 = x_re
+ else:
+ b3 = boundary*(x_re - dist0)
+
+ if x_im < -boundary:
+ b1 = boundary*(x_im + dist0)
+ elif x_im < boundary:
+ b1 = x_im
+ else:
+ b1 = boundary*(x_im - dist0)
+
+ b2 = -abs(x_re) + boundary
+ b0 = -abs(x_im) + boundary
+
+ return [(Es/2)*b3, (Es/2)*b2, (Es/2)*b1, (Es/2)*b0]
+sd_qam_16 = sd_qam_16_0x0_0_1_2_3
+sd_qam_16_0 = sd_qam_16
+
+def sd_qam_16_0x1_0_1_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0011 0111 | 1111 1011
+
+ 0010 0110 | 1110 1010
+ -----------------------
+ 0000 0100 | 1100 1000
+
+ 0001 0101 | 1101 1001
+ '''
+ x_re = 3*x.real
+ x_im = 3*x.imag
+
+ if x_re < -2:
+ b3 = 2*(x_re + 1)
+ elif x_re < 2:
+ b3 = x_re
+ else:
+ b3 = 2*(x_re - 1)
+
+ if x_im < -2:
+ b1 = 2*(x_im + 1)
+ elif x_im < 2:
+ b1 = x_im
+ else:
+ b1 = 2*(x_im - 1)
+
+ b2 = -abs(x_re) + 2
+ b0 = +abs(x_im) - 2
+
+ return [b3, b2, b1, b0]
+sd_qam_16_1 = sd_qam_16_0x1_0_1_2_3
+
+def sd_qam_16_0x2_0_1_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0000 0100 | 1100 1000
+
+ 0001 0101 | 1101 1001
+ -----------------------
+ 0011 0111 | 1111 1011
+
+ 0010 0110 | 1110 1010
+ '''
+
+ x_re = 3*x.real
+ x_im = 3*x.imag
+
+ if x_re < -2:
+ b3 = 2*(x_re + 1)
+ elif x_re < 2:
+ b3 = x_re
+ else:
+ b3 = 2*(x_re - 1)
+
+ if x_im < -2:
+ b1 = -2*(x_im + 1)
+ elif x_im < 2:
+ b1 = -x_im
+ else:
+ b1 = -2*(x_im - 1)
+
+ b2 = -abs(x_re) + 2
+ b0 = -abs(x_im) + 2
+
+ return [b3, b2, b1, b0]
+sd_qam_16_2 = sd_qam_16_0x2_0_1_2_3
+
+def sd_qam_16_0x3_0_1_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0001 0101 | 1101 1001
+
+ 0000 0100 | 1100 1000
+ -----------------------
+ 0010 0110 | 1110 1010
+
+ 0011 0111 | 1111 1011
+ '''
+ x_re = 3*x.real
+ x_im = 3*x.imag
+
+ if x_re < -2:
+ b3 = 2*(x_re + 1)
+ elif x_re < 2:
+ b3 = x_re
+ else:
+ b3 = 2*(x_re - 1)
+
+ if x_im < -2:
+ b1 = -2*(x_im + 1)
+ elif x_im < 2:
+ b1 = -x_im
+ else:
+ b1 = -2*(x_im - 1)
+
+ b2 = -abs(x_re) + 2
+ b0 = +abs(x_im) - 2
+
+ return [b3, b2, b1, b0]
+sd_qam_16_3 = sd_qam_16_0x3_0_1_2_3
+
+def sd_qam_16_0x0_1_0_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0001 0101 | 1101 1001
+
+ 0011 0111 | 1111 1011
+ -----------------------
+ 0010 0110 | 1110 1010
+
+ 0000 0100 | 1100 1000
+ '''
+ x_re = 3*x.real
+ x_im = 3*x.imag
+
+ if x_re < -2:
+ b3 = 2*(x_re + 1)
+ elif x_re < 2:
+ b3 = x_re
+ else:
+ b3 = 2*(x_re - 1)
+
+ if x_im < -2:
+ b0 = 2*(x_im + 1)
+ elif x_im < 2:
+ b0 = x_im
+ else:
+ b0 = 2*(x_im - 1)
+
+ b2 = -abs(x_re) + 2
+ b1 = -abs(x_im) + 2
+
+ return [b3, b2, b1, b0]
+sd_qam_16_4 = sd_qam_16_0x0_1_0_2_3
+
+def sd_qam_16_0x1_1_0_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0000 0100 | 1100 1000
+
+ 0010 0110 | 1110 1010
+ -----------------------
+ 0011 0111 | 1111 1011
+
+ 0001 0101 | 1101 1001
+ '''
+ x_re = 3*x.real
+ x_im = 3*x.imag
+
+ if x_re < -2:
+ b3 = 2*(x_re + 1)
+ elif x_re < 2:
+ b3 = x_re
+ else:
+ b3 = 2*(x_re - 1)
+
+ if x_im < -2:
+ b0 = -2*(x_im + 1)
+ elif x_im < 2:
+ b0 = -x_im
+ else:
+ b0 = -2*(x_im - 1)
+
+ b2 = -abs(x_re) + 2
+ b1 = -abs(x_im) + 2
+
+ return [b3, b2, b1, b0]
+sd_qam_16_5 = sd_qam_16_0x1_1_0_2_3
+
+def sd_qam_16_0x2_1_0_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0011 0111 | 1111 1011
+
+ 0001 0101 | 1101 1001
+ -----------------------
+ 0000 0100 | 1100 1000
+
+ 0010 0110 | 1110 1010
+ '''
+ x_re = 3*x.real
+ x_im = 3*x.imag
+
+ if x_re < -2:
+ b3 = 2*(x_re + 1)
+ elif x_re < 2:
+ b3 = x_re
+ else:
+ b3 = 2*(x_re - 1)
+
+ if x_im < -2:
+ b0 = 2*(x_im + 1)
+ elif x_im < 2:
+ b0 = x_im
+ else:
+ b0 = 2*(x_im - 1)
+
+ b2 = -abs(x_re) + 2
+ b1 = +abs(x_im) - 2
+
+ return [b3, b2, b1, b0]
+sd_qam_16_6 = sd_qam_16_0x2_1_0_2_3
+
+def sd_qam_16_0x3_1_0_2_3(x, Es=1):
+ '''
+ Soft bit LUT generator for constellation:
+
+ 0010 0110 | 1110 1010
+
+ 0000 0100 | 1100 1000
+ -----------------------
+ 0001 0101 | 1101 1001
+
+ 0011 0111 | 1111 1011
+ '''
+ x_re = 3*x.real
+ x_im = 3*x.imag
+
+ if x_re < -2:
+ b3 = 2*(x_re + 1)
+ elif x_re < 2:
+ b3 = x_re
+ else:
+ b3 = 2*(x_re - 1)
+
+ if x_im < -2:
+ b0 = -2*(x_im + 1)
+ elif x_im < 2:
+ b0 = -x_im
+ else:
+ b0 = -2*(x_im - 1)
+
+ b2 = -abs(x_re) + 2
+ b1 = +abs(x_im) - 2
+
+ return [b3, b2, b1, b0]
+sd_qam_16_7 = sd_qam_16_0x3_1_0_2_3
diff --git a/gr-digital/python/digital/soft_dec_lut_gen.py b/gr-digital/python/digital/soft_dec_lut_gen.py
new file mode 100644
index 0000000000..24d8bbdc2e
--- /dev/null
+++ b/gr-digital/python/digital/soft_dec_lut_gen.py
@@ -0,0 +1,232 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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 numpy
+
+def soft_dec_table_generator(soft_dec_gen, prec, Es=1):
+ '''
+ Builds a LUT that is a list of tuples. The tuple represents the
+ soft decisions for the constellation/bit mapping at any given
+ point in the complex space, (x,y).
+
+ The table is built to a precision specified by the 'prec'
+ argument. There are (2x2)^prec samples in the sample space, so we
+ get the precision of 2^prec samples in both the real and imaginary
+ axes.
+
+ The space is represented where index 0 is the bottom left corner
+ and the maximum index is the upper left. The table index for a
+ surface space with 4 bits of precision looks like the following:
+
+ 240 241 242 243 244 245 246 247 | 248 249 250 251 252 253 254 255
+ 224 225 226 227 228 229 230 231 | 232 233 234 235 236 237 238 239
+ 208 209 210 211 212 213 214 215 | 216 217 218 219 220 221 222 223
+ 192 193 194 195 196 197 198 199 | 200 201 202 203 204 205 206 207
+ 176 177 178 179 180 181 182 183 | 184 185 186 187 188 189 190 191
+ 160 161 162 163 164 165 166 167 | 168 169 170 171 172 173 174 175
+ 144 145 146 147 148 149 150 151 | 152 153 154 155 156 157 158 159
+ 128 129 130 131 132 133 134 135 | 136 137 138 139 140 141 142 143
+ -----------------------------------------------------------------
+ 112 113 114 115 116 117 118 119 | 120 121 122 123 124 125 126 127
+ 96 97 98 99 100 101 102 103 | 104 105 106 107 108 109 110 111
+ 80 81 82 83 84 85 86 87 | 88 89 90 91 92 93 94 95
+ 64 65 66 67 68 69 70 71 | 72 73 74 75 76 77 78 79
+ 48 49 50 51 52 53 54 55 | 56 57 58 59 60 61 62 63
+ 32 33 34 35 36 37 38 39 | 40 41 42 43 44 45 46 47
+ 16 17 18 19 20 21 22 23 | 24 25 26 27 28 29 30 31
+ 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15
+
+ We then calculate coordinates from -1 to 1 with 2^prec points for
+ both the x and y axes. We then sample starting at (-1, -1) and
+ move left to right on the x-axis and then move up a row on the
+ y-axis. For every point in this sampled space, we calculate the
+ soft decisions for the given constellation/mapping. This is done
+ by passing in the function 'soft_dec_gen' as an argument to this
+ function. This takes in the x/y coordinates and outputs the soft
+ decisions. These soft decisions are stored into the list at the
+ index from the above table as a tuple.
+
+ The function 'calc_from_table' takes in a point and reverses this
+ operation. It converts the point from the coordinates (-1,-1) to
+ (1,1) into an index value in the table and returns the tuple of
+ soft decisions at that index.
+
+ Es is the energy per symbol. This is passed to the function to
+ provide the bounds when calling the generator function since they
+ don't know how the constellation was normalized. Using the
+ (maximum) energy per symbol for constellation allows us to provide
+ any scaling of the constellation (normalized to sum to 1,
+ normalized so the outside points sit on +/-1, etc.) but still
+ calculate the soft decisions as we would given the full
+ constellation.
+ '''
+
+ npts = 2.0**prec
+ maxd = Es*numpy.sqrt(2)/2
+ yrng = numpy.linspace(-maxd, maxd, npts)
+ xrng = numpy.linspace(-maxd, maxd, npts)
+
+ table = []
+ for y in yrng:
+ for x in xrng:
+ pt = complex(x, y)
+ decs = soft_dec_gen(pt, Es)
+ table.append(decs)
+ return table
+
+def soft_dec_table(constel, symbols, prec, npwr=1):
+ '''
+ Similar in nature to soft_dec_table_generator above. Instead, this
+ takes in the constellation and symbol points along with the noise
+ power estimate and uses calc_soft_dec (below) to generate the
+ LUT.
+
+ Instead of assuming that the constellation is normalied (e.g., all
+ points are between -1 and 1), this function calculates the min/max
+ of both the real and imaginary axes and uses those when
+ constructing the LUT. So when using this version of the LUT, the
+ samples and the constellations must be working on the same
+ magnitudes.
+
+ Because this uses the calc_soft_dec function, it can be quite
+ a bit more expensive to generate the LUT, though it should be
+ one-time work.
+ '''
+
+ re_min = min(numpy.array(constel).real)
+ im_min = min(numpy.array(constel).imag)
+ re_max = max(numpy.array(constel).real)
+ im_max = max(numpy.array(constel).imag)
+
+ npts = 2.0**prec
+ yrng = numpy.linspace(im_min, im_max, npts)
+ xrng = numpy.linspace(re_min, re_max, npts)
+
+ table = []
+ for y in yrng:
+ for x in xrng:
+ pt = complex(x, y)
+ decs = calc_soft_dec(pt, constel, symbols, npwr)
+ table.append(decs)
+ return table
+
+def calc_soft_dec_from_table(sample, table, prec, Es=1):
+ '''
+ Takes in a complex sample and converts it from the coordinates
+ (-1,-1) to (1,1) into an index value. The index value points to a
+ location in the provided LUT 'table' and returns the soft
+ decisions tuple at that index.
+
+ sample: the complex sample to calculate the soft decisions
+ from.
+
+ table: the LUT.
+
+ prec: the precision used when generating the LUT.
+
+ Es: the energy per symbol. This is passed to the function to
+ provide the bounds when calling the generator function since they
+ don't know how the constellation was normalized. Using the
+ (maximum) energy per symbol for constellation allows us to provide
+ any scaling of the constellation (normalized to sum to 1,
+ normalized so the outside points sit on +/-1, etc.) but still
+ calculate the soft decisions as we would given the full
+ constellation.
+ '''
+ lut_scale = 2**prec
+ maxd = Es*numpy.sqrt(2)/2
+ step = 2*maxd / lut_scale
+ scale = (lut_scale) / (2*maxd) - step
+
+ xre = sample.real
+ xim = sample.imag
+ xre = int((maxd + min(maxd, max(-maxd, xre))) * scale)
+ xim = int((maxd + min(maxd, max(-maxd, xim))) * scale)
+ index = int(xre + lut_scale*xim)
+
+ max_index = lut_scale**2
+ if(index > max_index):
+ return table[0];
+
+ if(index < 0):
+ raise RuntimeError("calc_from_table: input sample out of range.")
+
+ return table[index]
+
+def calc_soft_dec(sample, constel, symbols, npwr=1):
+ '''
+ This function takes in any consteallation and symbol symbol set
+ (where symbols[i] is the set of bits at constellation point
+ constel[i] and an estimate of the noise power and produces the
+ soft decisions for the given sample.
+
+ If known, the noise power of the received sample may be passed in
+ to this function as npwr.
+
+ This is an incredibly costly algorthm because it must calculate
+ the Euclidean distance between the sample and all points in the
+ constellation to build up its probability
+ calculations. Conversely, it should work for any given
+ constellation/symbol map.
+
+ The function returns a vector of k soft decisions. Decisions less
+ than 0 are more likely to indicate a '0' bit and decisions greater
+ than 0 are more likely to indicate a '1' bit.
+ '''
+
+ M = len(constel)
+ k = int(numpy.log2(M))
+ tmp = 2*k*[0,]
+ s = k*[0,]
+
+ # Find a scaling factor for the constellation, however it was normalized.
+ constel = numpy.array(constel)
+ scale = min(min(abs(constel.real)), min(abs(constel.imag)))
+
+ for i in range(M):
+ # Calculate the distance between the sample and the current
+ # constellation point.
+ dist = abs(sample - constel[i])**2
+
+ # Calculate the probability factor from the distance and the
+ # scaled noise power.
+ d = numpy.exp(-dist/(2*npwr*scale**2))
+
+ for j in range(k):
+ # Get the bit at the jth index
+ mask = 1<<j
+ bit = (symbols[i] & mask) >> j
+
+ # If the bit is a 0, add to the probability of a zero
+ if(bit == 0):
+ tmp[2*j+0] += d
+ # else, add to the probability of a one
+ else:
+ tmp[2*j+1] += d
+
+ # Calculate the log-likelihood ratio for all bits based on the
+ # probability of ones (tmp[2*i+1]) over the probability of a zero
+ # (tmp[2*i+0]).
+ for i in range(k):
+ s[k-1-i] = (numpy.log(tmp[2*i+1]) - numpy.log(tmp[2*i+0])) * scale**2
+
+ return s
diff --git a/gr-digital/python/digital/test_soft_decisions.py b/gr-digital/python/digital/test_soft_decisions.py
new file mode 100755
index 0000000000..78714100b7
--- /dev/null
+++ b/gr-digital/python/digital/test_soft_decisions.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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 numpy, pylab, sys
+from gnuradio import digital
+from soft_dec_lut_gen import *
+from psk_constellations import *
+from qam_constellations import *
+
+def test_qpsk(i, sample, prec):
+ qpsk_const_list = [psk_4_0, psk_4_1, psk_4_2, psk_4_3,
+ psk_4_4, psk_4_5, psk_4_6, psk_4_7]
+ qpsk_lut_gen_list = [sd_psk_4_0, sd_psk_4_1, sd_psk_4_2, sd_psk_4_3,
+ sd_psk_4_4, sd_psk_4_5, sd_psk_4_6, sd_psk_4_7]
+
+ constel, code = qpsk_const_list[i]()
+ qpsk_lut_gen = qpsk_lut_gen_list[i]
+
+ rot_sym = 1
+ side = 2
+ width = 2
+ c = digital.constellation_rect(constel, code, rot_sym,
+ side, side, width, width)
+
+ # Get max energy/symbol in constellation
+ constel = c.points()
+ Es = max([numpy.sqrt(constel_i.real**2 + constel_i.imag**2) for constel_i in constel])
+
+ #table = soft_dec_table_generator(qpsk_lut_gen, prec, Es)
+ table = soft_dec_table(constel, code, prec)
+
+ c.gen_soft_dec_lut(prec)
+ #c.set_soft_dec_lut(table, prec)
+
+ y_python_gen_calc = qpsk_lut_gen(sample, Es)
+ y_python_table = calc_soft_dec_from_table(sample, table, prec, Es)
+ y_python_raw_calc = calc_soft_dec(sample, constel, code)
+ y_cpp_table = c.soft_decision_maker(sample)
+ y_cpp_raw_calc = c.calc_soft_dec(sample)
+
+ return (y_python_gen_calc, y_python_table, y_python_raw_calc,
+ y_cpp_table, y_cpp_raw_calc, constel, code, c)
+
+def test_qam16(i, sample, prec):
+ sample = sample/1
+ qam_const_list = [qam_16_0, ]
+ qam_lut_gen_list = [sd_qam_16_0, ]
+
+ constel, code = qam_const_list[i]()
+ qam_lut_gen = qam_lut_gen_list[i]
+
+ rot_sym = 4
+ side = 2
+ width = 2
+ c = digital.constellation_rect(constel, code, rot_sym,
+ side, side, width, width)
+
+ # Get max energy/symbol in constellation
+ constel = c.points()
+ Es = max([abs(constel_i) for constel_i in constel])
+
+ #table = soft_dec_table_generator(qam_lut_gen, prec, Es)
+ table = soft_dec_table(constel, code, prec, 1)
+
+ #c.gen_soft_dec_lut(prec)
+ c.set_soft_dec_lut(table, prec)
+
+ y_python_gen_calc = qam_lut_gen(sample, Es)
+ y_python_table = calc_soft_dec_from_table(sample, table, prec, Es)
+ y_python_raw_calc = calc_soft_dec(sample, constel, code, 1)
+ y_cpp_table = c.soft_decision_maker(sample)
+ y_cpp_raw_calc = c.calc_soft_dec(sample)
+
+ return (y_python_gen_calc, y_python_table, y_python_raw_calc,
+ y_cpp_table, y_cpp_raw_calc, constel, code, c)
+
+if __name__ == "__main__":
+
+ index = 0
+ prec = 8
+
+ x_re = 2*numpy.random.random()-1
+ x_im = 2*numpy.random.random()-1
+ x = x_re + x_im*1j
+ #x = -1 + -0.j
+
+ if 1:
+ y_python_gen_calc, y_python_table, y_python_raw_calc, \
+ y_cpp_table, y_cpp_raw_calc, constel, code, c \
+ = test_qpsk(index, x, prec)
+ else:
+ y_python_gen_calc, y_python_table, y_python_raw_calc, \
+ y_cpp_table, y_cpp_raw_calc, constel, code, c \
+ = test_qam16(index, x, prec)
+
+ k = numpy.log2(len(constel))
+
+ print "Sample: ", x
+ print "Python Generator Calculated: ", (y_python_gen_calc)
+ print "Python Generator Table: ", (y_python_table)
+ print "Python Raw calc: ", (y_python_raw_calc)
+ print "C++ Table calc: ", (y_cpp_table)
+ print "C++ Raw calc: ", (y_cpp_raw_calc)
+
+ fig = pylab.figure(1)
+ sp1 = fig.add_subplot(1,1,1)
+ sp1.plot([c.real for c in constel],
+ [c.imag for c in constel], 'bo')
+ sp1.plot(x.real, x.imag, 'ro')
+ sp1.set_xlim([-1.5, 1.5])
+ sp1.set_ylim([-1.5, 1.5])
+ fill = int(numpy.log2(len(constel)))
+ for i,c in enumerate(constel):
+ sp1.text(1.2*c.real, 1.2*c.imag, bin(code[i])[2:].zfill(fill),
+ ha='center', va='center', size=18)
+ pylab.show()
diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i
index fb0b97aa11..b16200c2f6 100644
--- a/gr-digital/swig/digital_swig.i
+++ b/gr-digital/swig/digital_swig.i
@@ -51,6 +51,7 @@
#include "gnuradio/digital/constellation.h"
#include "gnuradio/digital/constellation_decoder_cb.h"
#include "gnuradio/digital/constellation_receiver_cb.h"
+#include "gnuradio/digital/constellation_soft_decoder_cf.h"
#include "gnuradio/digital/correlate_access_code_bb.h"
#include "gnuradio/digital/correlate_access_code_tag_bb.h"
#include "gnuradio/digital/costas_loop_cc.h"
@@ -120,6 +121,7 @@
%include "gnuradio/digital/constellation.h"
%include "gnuradio/digital/constellation_decoder_cb.h"
%include "gnuradio/digital/constellation_receiver_cb.h"
+%include "gnuradio/digital/constellation_soft_decoder_cf.h"
%include "gnuradio/digital/correlate_access_code_bb.h"
%include "gnuradio/digital/correlate_access_code_tag_bb.h"
%include "gnuradio/digital/costas_loop_cc.h"
@@ -184,6 +186,7 @@ GR_SWIG_BLOCK_MAGIC2(digital, clock_recovery_mm_ff);
GR_SWIG_BLOCK_MAGIC2(digital, cma_equalizer_cc);
GR_SWIG_BLOCK_MAGIC2(digital, constellation_decoder_cb);
GR_SWIG_BLOCK_MAGIC2(digital, constellation_receiver_cb);
+GR_SWIG_BLOCK_MAGIC2(digital, constellation_soft_decoder_cf);
GR_SWIG_BLOCK_MAGIC2(digital, correlate_access_code_bb);
GR_SWIG_BLOCK_MAGIC2(digital, correlate_access_code_tag_bb);
GR_SWIG_BLOCK_MAGIC2(digital, costas_loop_cc);
diff --git a/gr-uhd/apps/uhd_fft b/gr-uhd/apps/uhd_fft
index 41da61aca3..9edd75288f 100755
--- a/gr-uhd/apps/uhd_fft
+++ b/gr-uhd/apps/uhd_fft
@@ -200,12 +200,12 @@ class app_top_block(stdgui2.std_top_block):
callback=self.set_gain)
try:
- mboard_id = self.u.get_usrp_info().get("mboard_id")
- mboard_serial = self.u.get_usrp_info().get("mboard_serial")
+ mboard_id = self.u.get_usrp_info()["mboard_id"]
+ mboard_serial = self.u.get_usrp_info()["mboard_serial"]
if mboard_serial == "":
mboard_serial = "no serial"
- dboard_subdev_name = self.u.get_usrp_info().get("rx_subdev_name")
- dboard_serial = self.u.get_usrp_info().get("rx_serial")
+ dboard_subdev_name = self.u.get_usrp_info()["rx_subdev_name"]
+ dboard_serial = self.u.get_usrp_info()["rx_serial"]
if dboard_serial == "":
dboard_serial = "no serial"
subdev = self.u.get_subdev_spec()
diff --git a/gr-uhd/apps/uhd_rx_cfile b/gr-uhd/apps/uhd_rx_cfile
index 9f5ef19893..d727d8752a 100755
--- a/gr-uhd/apps/uhd_rx_cfile
+++ b/gr-uhd/apps/uhd_rx_cfile
@@ -95,19 +95,19 @@ class rx_cfile_block(gr.top_block):
try:
info = self._u.get_usrp_info()
- mboard_id = info.get("mboard_id").split(" ")[0]
- if info.get("mboard_serial") == "":
+ mboard_id = info["mboard_id"].split(" ")[0]
+ if info["mboard_serial"] == "":
mboard_serial = "no serial"
else:
- mboard_serial = info.get("mboard_serial")
+ mboard_serial = info["mboard_serial"]
- rx_id = info.get("rx_id").split(" ")[0]
- if info.get("rx_serial") == "":
+ rx_id = info["rx_id"].split(" ")[0]
+ if info["rx_serial"] == "":
rx_serial = "no serial"
else:
- rx_serial = info.get("rx_serial")
- rx_antenna = info.get("rx_antenna")
- rx_subdev_spec = info.get("rx_subdev_spec")
+ rx_serial = info["rx_serial"]
+ rx_antenna = info["rx_antenna"]
+ rx_subdev_spec = info["rx_subdev_spec"]
print "Motherboard: %s (%s)" % (mboard_id, mboard_serial)
if "B200" in mboard_id or "B210" in mboard_id:
diff --git a/gr-uhd/apps/uhd_siggen_base.py b/gr-uhd/apps/uhd_siggen_base.py
index 84dff1f504..0245c007b7 100644
--- a/gr-uhd/apps/uhd_siggen_base.py
+++ b/gr-uhd/apps/uhd_siggen_base.py
@@ -112,12 +112,12 @@ class top_block(gr.top_block, pubsub):
# Setup USRP Configuration value
try:
usrp_info = self._u.get_usrp_info()
- mboard_id = usrp_info.get("mboard_id")
- mboard_serial = usrp_info.get("mboard_serial")
+ mboard_id = usrp_info["mboard_id"]
+ mboard_serial = usrp_info["mboard_serial"]
if mboard_serial == "":
mboard_serial = "no serial"
- dboard_subdev_name = usrp_info.get("tx_subdev_name")
- dboard_serial = usrp_info.get("tx_serial")
+ dboard_subdev_name = usrp_info["tx_subdev_name"]
+ dboard_serial = usrp_info["tx_serial"]
if dboard_serial == "":
dboard_serial = "no serial"
subdev = self._u.get_subdev_spec()
diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i
index de5b8c2dad..c98416f307 100644
--- a/gr-uhd/swig/uhd_swig.i
+++ b/gr-uhd/swig/uhd_swig.i
@@ -64,6 +64,11 @@
%include <uhd/types/dict.hpp>
%template(string_string_dict_t) uhd::dict<std::string, std::string>; //define after dict
+%extend uhd::dict<std::string, std::string>{
+ std::string __getitem__(std::string key) {return (*self)[key];}
+ void __setitem__(std::string key, std::string val) {(*self)[key] = val;}
+};
+
%include <uhd/types/device_addr.hpp>
%include <uhd/types/io_type.hpp>
diff --git a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
index 7ff80ff7ac..2dac3461a8 100644
--- a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
+++ b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
@@ -146,3 +146,10 @@ add_subdirectory(python)
add_subdirectory(grc)
add_subdirectory(apps)
add_subdirectory(docs)
+
+########################################################################
+# Install cmake search helper for this library
+########################################################################
+install(FILES cmake/Modules/howtoConfig.cmake
+ DESTINATION lib/cmake/howto
+)
diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/howtoConfig.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/howtoConfig.cmake
new file mode 100644
index 0000000000..329a007608
--- /dev/null
+++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/howtoConfig.cmake
@@ -0,0 +1,30 @@
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(PC_HOWTO howto)
+
+FIND_PATH(
+ HOWTO_INCLUDE_DIRS
+ NAMES howto/api.h
+ HINTS $ENV{HOWTO_DIR}/include
+ ${PC_HOWTO_INCLUDEDIR}
+ PATHS ${CMAKE_INSTALL_PREEFIX}/include
+ /usr/local/include
+ /usr/include
+)
+
+FIND_LIBRARY(
+ HOWTO_LIBRARIES
+ NAMES gnuradio-howto
+ HINTS $ENV{HOWTO_DIR}/lib
+ ${PC_HOWTO_LIBDIR}
+ PATHS ${CMAKE_INSTALL_PREFIX}/lib
+ ${CMAKE_INSTALL_PREFIX}/lib64
+ /usr/local/lib
+ /usr/local/lib64
+ /usr/lib
+ /usr/lib64
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(HOWTO DEFAULT_MSG HOWTO_LIBRARIES HOWTO_INCLUDE_DIRS)
+MARK_AS_ADVANCED(HOWTO_LIBRARIES HOWTO_INCLUDE_DIRS)
+
diff --git a/gr-utils/python/modtool/gr-newmod/examples/README b/gr-utils/python/modtool/gr-newmod/examples/README
new file mode 100644
index 0000000000..c012bdfa0a
--- /dev/null
+++ b/gr-utils/python/modtool/gr-newmod/examples/README
@@ -0,0 +1,4 @@
+It is considered good practice to add examples in here to demonstrate the
+functionality of your OOT module. Python scripts, GRC flow graphs or other
+code can go here.
+
diff --git a/gr-utils/python/modtool/modtool_add.py b/gr-utils/python/modtool/modtool_add.py
index 10f89c569d..60748e3f1b 100644
--- a/gr-utils/python/modtool/modtool_add.py
+++ b/gr-utils/python/modtool/modtool_add.py
@@ -193,6 +193,7 @@ class ModToolAdd(ModTool):
Cheetah.Template.Template(
Templates['qa_cmakeentry36'],
searchList={'basename': os.path.splitext(fname_qa_cc)[0],
+ 'upperbasename': os.path.splitext(fname_qa_cc)[0].upper(),
'filename': fname_qa_cc,
'modname': self._info['modname']
}
diff --git a/gr-utils/python/modtool/modtool_base.py b/gr-utils/python/modtool/modtool_base.py
index 577985b6f3..f8fc8639c4 100644
--- a/gr-utils/python/modtool/modtool_base.py
+++ b/gr-utils/python/modtool/modtool_base.py
@@ -125,6 +125,7 @@ class ModTool(object):
self._info['includedir'] = 'include'
self._file['cminclude'] = os.path.join(self._info['includedir'], 'CMakeLists.txt')
self._file['cmswig'] = os.path.join('swig', 'CMakeLists.txt')
+ self._file['cmfind'] = os.path.join('cmake', 'Modules', 'howtoConfig.cmake')
def _check_directory(self, directory):
""" Guesses if dir is a valid GNU Radio module directory by looking for
diff --git a/grc/base/Block.py b/grc/base/Block.py
index 9736c0ac44..970cf516fe 100644
--- a/grc/base/Block.py
+++ b/grc/base/Block.py
@@ -192,6 +192,7 @@ class Block(Element):
def get_name(self): return self._name
def get_key(self): return self._key
def get_category(self): return self._category
+ def set_category(self, cat): self._category = cat
def get_doc(self): return ''
def get_ports(self): return self.get_sources() + self.get_sinks()
def get_ports_gui(self): return self.filter_bus_port(self.get_sources()) + self.filter_bus_port(self.get_sinks());
diff --git a/grc/base/Platform.py b/grc/base/Platform.py
index bb80e29552..88cbf32b89 100644
--- a/grc/base/Platform.py
+++ b/grc/base/Platform.py
@@ -143,15 +143,15 @@ class Platform(_Element):
print >> sys.stderr, 'Warning: Block key "%s" not found when loading category tree.'%(block_key)
continue
block = self.get_block(block_key)
- #if it exists, the block's category overrides the block tree
- if not block.get_category(): block_tree.add_block(parent, block)
- #load the block tree
+ #if it exists, the block's category shall not be overridden by the xml tree
+ if not block.get_category(): block.set_category(parent)
+ #load the block tree and update the categories for each block
for block_tree_file in self._block_tree_files:
- #recursivly add all blocks in the tree
+ #recursivly put categories in blocks
load_category(ParseXML.from_file(block_tree_file).find('cat'))
- #add all other blocks, use the catgory tag
+ #add blocks to block tree
for block in self.get_blocks():
- #blocks with empty categories are in the xml block tree or hidden
+ #blocks with empty categories are hidden
if not block.get_category(): continue
block_tree.add_block(block.get_category(), block)
diff --git a/grc/blocks/blks2_packet_encoder.xml b/grc/blocks/blks2_packet_encoder.xml
index b184ebd31c..88e1ba350c 100644
--- a/grc/blocks/blks2_packet_encoder.xml
+++ b/grc/blocks/blks2_packet_encoder.xml
@@ -11,6 +11,7 @@
<make>grc_blks2.packet_mod_$(type.fcn)(grc_blks2.packet_encoder(
samples_per_symbol=$samples_per_symbol,
bits_per_symbol=$bits_per_symbol,
+ preamble=$preamble,
access_code=$access_code,
pad_for_usrp=$pad_for_usrp,
),
@@ -58,6 +59,12 @@
<type>int</type>
</param>
<param>
+ <name>Preamble</name>
+ <key>preamble</key>
+ <value></value>
+ <type>string</type>
+ </param>
+ <param>
<name>Access Code</name>
<key>access_code</key>
<value></value>
@@ -93,6 +100,8 @@
<doc>
Packet encoder block, for use with the gnuradio modulator blocks: gmsk, dpsk, qam.
+Preamble: string of 1's and 0's, leave blank for automatic.
+
Access Code: string of 1's and 0's, leave blank for automatic.
Payload Length: 0 for automatic.
diff --git a/grc/grc_gnuradio/blks2/packet.py b/grc/grc_gnuradio/blks2/packet.py
index 10dd002471..872f08ca2e 100644
--- a/grc/grc_gnuradio/blks2/packet.py
+++ b/grc/grc_gnuradio/blks2/packet.py
@@ -68,7 +68,7 @@ class packet_encoder(gr.hier_block2):
Hierarchical block for wrapping packet-based modulators.
"""
- def __init__(self, samples_per_symbol, bits_per_symbol, access_code='', pad_for_usrp=True):
+ def __init__(self, samples_per_symbol, bits_per_symbol, preamble='', access_code='', pad_for_usrp=True):
"""
packet_mod constructor.
@@ -83,10 +83,15 @@ class packet_encoder(gr.hier_block2):
self._samples_per_symbol = samples_per_symbol
self._bits_per_symbol = bits_per_symbol
self._pad_for_usrp = pad_for_usrp
+ if not preamble: #get preamble
+ preamble = packet_utils.default_preamble
if not access_code: #get access code
access_code = packet_utils.default_access_code
+ if not packet_utils.is_1_0_string(preamble):
+ raise ValueError, "Invalid preamble %r. Must be string of 1's and 0's" % (preamble,)
if not packet_utils.is_1_0_string(access_code):
raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
+ self._preamble = preamble
self._access_code = access_code
self._pad_for_usrp = pad_for_usrp
#create blocks
@@ -113,6 +118,7 @@ class packet_encoder(gr.hier_block2):
payload,
self._samples_per_symbol,
self._bits_per_symbol,
+ self._preamble,
self._access_code,
self._pad_for_usrp
)
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index 71d62fc8f5..87576ccae1 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -83,6 +83,8 @@ class ActionHandler:
Returns:
false to let gtk handle the key action
"""
+ # prevent key event stealing while the search box is active
+ if self.main_window.btwin.search_entry.has_focus(): return False
if not self.get_focus_flag(): return False
return Actions.handle_key_press(event)
@@ -121,6 +123,8 @@ class ActionHandler:
if Preferences.file_open() in self.init_file_paths:
self.main_window.new_page(Preferences.file_open(), show=True)
if not self.get_page(): self.main_window.new_page() #ensure that at least a blank page exists
+
+ self.main_window.btwin.search_entry.hide()
elif action == Actions.APPLICATION_QUIT:
if self.main_window.close_pages():
gtk.main_quit()
@@ -442,6 +446,9 @@ class ActionHandler:
self.platform.loadblocks()
self.main_window.btwin.clear();
self.platform.load_block_tree(self.main_window.btwin);
+ elif action == Actions.FIND_BLOCKS:
+ self.main_window.btwin.search_entry.show()
+ self.main_window.set_focus(self.main_window.btwin.search_entry)
elif action == Actions.OPEN_HIER:
bn = [];
for b in self.get_flow_graph().get_selected_blocks():
@@ -484,6 +491,7 @@ class ActionHandler:
Actions.BUSSIFY_SOURCES.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
Actions.BUSSIFY_SINKS.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
Actions.RELOAD_BLOCKS.set_sensitive(True)
+ Actions.FIND_BLOCKS.set_sensitive(True)
#set the exec and stop buttons
self.update_exec_stop()
#saved status
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index a70109c021..5daf45def8 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -290,6 +290,13 @@ RELOAD_BLOCKS = Action(
tooltip='Reload Blocks',
stock_id=gtk.STOCK_REFRESH
)
+FIND_BLOCKS = Action(
+ label='Find Blocks',
+ tooltip='Search for a block by bame or key',
+ stock_id=gtk.STOCK_FIND,
+ keypresses=(gtk.keysyms.f, gtk.gdk.CONTROL_MASK,
+ gtk.keysyms.slash, NO_MODS_MASK),
+)
OPEN_HIER = Action(
label='Open H_ier',
tooltip='Open the source of the selected hierarchical block',
diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py
index e2b7f4f9bc..92d87c8809 100644
--- a/grc/gui/Bars.py
+++ b/grc/gui/Bars.py
@@ -50,6 +50,7 @@ TOOLBAR_LIST = (
Actions.BLOCK_ENABLE,
Actions.BLOCK_DISABLE,
None,
+ Actions.FIND_BLOCKS,
Actions.RELOAD_BLOCKS,
Actions.OPEN_HIER,
Actions.BUSSIFY_SOURCES,
@@ -88,6 +89,7 @@ MENU_BAR_LIST = (
]),
(gtk.Action('View', '_View', None, None), [
Actions.ERRORS_WINDOW_DISPLAY,
+ Actions.FIND_BLOCKS,
]),
(gtk.Action('Build', '_Build', None, None), [
Actions.FLOW_GRAPH_GEN,
diff --git a/grc/gui/BlockTreeWindow.py b/grc/gui/BlockTreeWindow.py
index ced6429c62..2173cb0d98 100644
--- a/grc/gui/BlockTreeWindow.py
+++ b/grc/gui/BlockTreeWindow.py
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
from Constants import DEFAULT_BLOCKS_WINDOW_WIDTH, DND_TARGETS
+import Actions
import Utils
import pygtk
pygtk.require('2.0')
@@ -46,7 +47,7 @@ class BlockTreeWindow(gtk.VBox):
Create a tree view of the possible blocks in the platform.
The tree view nodes will be category names, the leaves will be block names.
A mouse double click or button press action will trigger the add block event.
-
+
Args:
platform: the particular platform will all block prototypes
get_flow_graph: get the selected flow graph
@@ -54,21 +55,33 @@ class BlockTreeWindow(gtk.VBox):
gtk.VBox.__init__(self)
self.platform = platform
self.get_flow_graph = get_flow_graph
- #make the tree model for holding blocks
+
+ # search entry
+ self.search_entry = gtk.Entry()
+ self.search_entry.set_icon_from_stock(gtk.ENTRY_ICON_PRIMARY, gtk.STOCK_FIND)
+ self.search_entry.set_icon_activatable(gtk.ENTRY_ICON_PRIMARY, False)
+ self.search_entry.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, gtk.STOCK_CLOSE)
+ self.search_entry.connect('icon-release', self._handle_icon_event)
+ self.search_entry.connect('changed', self._update_search_tree)
+ self.search_entry.connect('key-press-event', self._handle_search_key_press)
+ self.pack_start(self.search_entry, False)
+
+ #make the tree model for holding blocks and a temporary one for search results
self.treestore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
+ self.treestore_search = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
+
self.treeview = gtk.TreeView(self.treestore)
self.treeview.set_enable_search(False) #disable pop up search box
+ self.treeview.set_search_column(-1) # really disable search
+ self.treeview.set_headers_visible(False)
self.treeview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
self.treeview.connect('button-press-event', self._handle_mouse_button_press)
- selection = self.treeview.get_selection()
- selection.set_mode('single')
- selection.connect('changed', self._handle_selection_change)
+ self.treeview.connect('key-press-event', self._handle_search_key_press)
+
+ self.treeview.get_selection().set_mode('single')
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn('Blocks', renderer, text=NAME_INDEX)
self.treeview.append_column(column)
- #setup the search
- self.treeview.set_enable_search(True)
- self.treeview.set_search_equal_func(self._handle_search)
#try to enable the tooltips (available in pygtk 2.12 and above)
try: self.treeview.set_tooltip_column(DOC_INDEX)
except: pass
@@ -84,51 +97,48 @@ class BlockTreeWindow(gtk.VBox):
scrolled_window.add_with_viewport(self.treeview)
scrolled_window.set_size_request(DEFAULT_BLOCKS_WINDOW_WIDTH, -1)
self.pack_start(scrolled_window)
- #add button
- self.add_button = gtk.Button(None, gtk.STOCK_ADD)
- self.add_button.connect('clicked', self._handle_add_button)
- self.pack_start(self.add_button, False)
#map categories to iters, automatic mapping for root
self._categories = {tuple(): None}
+ self._categories_search = {tuple(): None}
#add blocks and categories
self.platform.load_block_tree(self)
- #initialize
- self._update_add_button()
def clear(self):
self.treestore.clear();
self._categories = {tuple(): None}
-
############################################################
## Block Tree Methods
############################################################
- def add_block(self, category, block=None):
+ def add_block(self, category, block=None, treestore=None, categories=None):
"""
Add a block with category to this selection window.
Add only the category when block is None.
-
+
Args:
category: the category list or path string
block: the block object or None
"""
+ if treestore is None: treestore = self.treestore
+ if categories is None: categories = self._categories
+
if isinstance(category, str): category = category.split('/')
category = tuple(filter(lambda x: x, category)) #tuple is hashable
#add category and all sub categories
for i, cat_name in enumerate(category):
sub_category = category[:i+1]
- if sub_category not in self._categories:
- iter = self.treestore.insert_before(self._categories[sub_category[:-1]], None)
- self.treestore.set_value(iter, NAME_INDEX, '[ %s ]'%cat_name)
- self.treestore.set_value(iter, KEY_INDEX, '')
- self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(CAT_MARKUP_TMPL, cat=cat_name))
- self._categories[sub_category] = iter
+ if sub_category not in categories:
+ iter = treestore.insert_before(categories[sub_category[:-1]], None)
+ treestore.set_value(iter, NAME_INDEX, '[ %s ]'%cat_name)
+ treestore.set_value(iter, KEY_INDEX, '')
+ treestore.set_value(iter, DOC_INDEX, Utils.parse_template(CAT_MARKUP_TMPL, cat=cat_name))
+ categories[sub_category] = iter
#add block
if block is None: return
- iter = self.treestore.insert_before(self._categories[category], None)
- self.treestore.set_value(iter, NAME_INDEX, block.get_name())
- self.treestore.set_value(iter, KEY_INDEX, block.get_key())
- self.treestore.set_value(iter, DOC_INDEX, Utils.parse_template(DOC_MARKUP_TMPL, doc=block.get_doc()))
+ iter = treestore.insert_before(categories[category], None)
+ treestore.set_value(iter, NAME_INDEX, block.get_name())
+ treestore.set_value(iter, KEY_INDEX, block.get_key())
+ treestore.set_value(iter, DOC_INDEX, Utils.parse_template(DOC_MARKUP_TMPL, doc=block.get_doc()))
############################################################
## Helper Methods
@@ -136,7 +146,7 @@ class BlockTreeWindow(gtk.VBox):
def _get_selected_block_key(self):
"""
Get the currently selected block key.
-
+
Returns:
the key of the selected block or a empty string
"""
@@ -144,39 +154,84 @@ class BlockTreeWindow(gtk.VBox):
treestore, iter = selection.get_selected()
return iter and treestore.get_value(iter, KEY_INDEX) or ''
- def _update_add_button(self):
- """
- Update the add button's sensitivity.
- The button should be active only if a block is selected.
- """
- key = self._get_selected_block_key()
- self.add_button.set_sensitive(bool(key))
-
def _add_selected_block(self):
"""
Add the selected block with the given key to the flow graph.
"""
key = self._get_selected_block_key()
- if key: self.get_flow_graph().add_new_block(key)
+ if key:
+ self.get_flow_graph().add_new_block(key)
+ return True
+ return False
+
+ def _expand_category(self):
+ treestore, iter = self.treeview.get_selection().get_selected()
+ if iter and treestore.iter_has_child(iter):
+ path = self.treestore.get_path(iter)
+ self.treeview.expand_to_path(path)
############################################################
## Event Handlers
############################################################
- def _handle_search(self, model, column, key, iter):
- #determine which blocks match the search key
- blocks = self.get_flow_graph().get_parent().get_blocks()
- matching_blocks = filter(lambda b: key in b.get_key() or key in b.get_name().lower(), blocks)
- #remove the old search category
- try: self.treestore.remove(self._categories.pop((self._search_category, )))
- except (KeyError, AttributeError): pass #nothing to remove
- #create a search category
- if not matching_blocks: return
- self._search_category = 'Search: %s'%key
- for block in matching_blocks: self.add_block(self._search_category, block)
- #expand the search category
- path = self.treestore.get_path(self._categories[(self._search_category, )])
- self.treeview.collapse_all()
- self.treeview.expand_row(path, open_all=False)
+ def _handle_icon_event(self, widget, icon, event):
+ if icon == gtk.ENTRY_ICON_PRIMARY:
+ pass
+ elif icon == gtk.ENTRY_ICON_SECONDARY:
+ widget.set_text('')
+ self.search_entry.hide()
+
+ def _update_search_tree(self, widget):
+ key = widget.get_text().lower()
+ if not key:
+ self.treeview.set_model(self.treestore)
+ self.treeview.collapse_all()
+ else:
+ blocks = self.get_flow_graph().get_parent().get_blocks()
+ matching_blocks = filter(lambda b: key in b.get_key().lower() or key in b.get_name().lower(), blocks)
+
+ self.treestore_search.clear()
+ self._categories_search = {tuple(): None}
+ for block in matching_blocks:
+ self.add_block(block.get_category() or 'None', block,
+ self.treestore_search, self._categories_search)
+ self.treeview.set_model(self.treestore_search)
+ self.treeview.expand_all()
+
+ def _handle_search_key_press(self, widget, event):
+ """Handle Return and Escape key events in search entry and treeview"""
+ if event.keyval == gtk.keysyms.Return:
+ # add block on enter
+
+ if widget == self.search_entry:
+ # Get the first block in the search tree and add it
+ selected = self.treestore_search.get_iter_first()
+ while self.treestore_search.iter_children(selected):
+ selected = self.treestore_search.iter_children(selected)
+ if selected is not None:
+ key = self.treestore_search.get_value(selected, KEY_INDEX)
+ if key: self.get_flow_graph().add_new_block(key)
+ elif widget == self.treeview:
+ self._add_selected_block() or self._expand_category()
+ else:
+ return False # propagate event
+
+ elif event.keyval == gtk.keysyms.Escape:
+ # reset the search
+ self.search_entry.set_text('')
+ self.search_entry.hide()
+
+ elif event.state & gtk.gdk.CONTROL_MASK and event.keyval == gtk.keysyms.f:
+ # propagation doesn't work although treeview search is disabled =(
+ # manually trigger action...
+ Actions.FIND_BLOCKS.activate()
+
+ elif event.keyval == gtk.keysyms.slash:
+ Actions.FIND_BLOCKS.activate()
+
+ else:
+ return False # propagate event
+
+ return True
def _handle_drag_get_data(self, widget, drag_context, selection_data, info, time):
"""
@@ -194,17 +249,3 @@ class BlockTreeWindow(gtk.VBox):
"""
if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
self._add_selected_block()
-
- def _handle_selection_change(self, selection):
- """
- Handle a selection change in the tree view.
- If a selection changes, set the add button sensitive.
- """
- self._update_add_button()
-
- def _handle_add_button(self, widget):
- """
- Handle the add button clicked signal.
- Call add selected block.
- """
- self._add_selected_block()
diff --git a/grc/gui/DrawingArea.py b/grc/gui/DrawingArea.py
index 64be4d3ea6..1313e90420 100644
--- a/grc/gui/DrawingArea.py
+++ b/grc/gui/DrawingArea.py
@@ -51,7 +51,8 @@ class DrawingArea(gtk.DrawingArea):
gtk.gdk.POINTER_MOTION_MASK | \
gtk.gdk.BUTTON_RELEASE_MASK | \
gtk.gdk.LEAVE_NOTIFY_MASK | \
- gtk.gdk.ENTER_NOTIFY_MASK
+ gtk.gdk.ENTER_NOTIFY_MASK | \
+ gtk.gdk.FOCUS_CHANGE_MASK
)
#setup drag and drop
self.drag_dest_set(gtk.DEST_DEFAULT_ALL, DND_TARGETS, gtk.gdk.ACTION_COPY)
@@ -59,9 +60,11 @@ class DrawingArea(gtk.DrawingArea):
#setup the focus flag
self._focus_flag = False
self.get_focus_flag = lambda: self._focus_flag
- def _handle_focus_event(widget, event, focus_flag): self._focus_flag = focus_flag
- self.connect('leave-notify-event', _handle_focus_event, False)
- self.connect('enter-notify-event', _handle_focus_event, True)
+ def _handle_notify_event(widget, event, focus_flag): self._focus_flag = focus_flag
+ self.connect('leave-notify-event', _handle_notify_event, False)
+ self.connect('enter-notify-event', _handle_notify_event, True)
+ self.set_can_focus(True)
+ self.connect('focus-out-event', self._handle_focus_lost_event)
def new_pixmap(self, width, height): return gtk.gdk.Pixmap(self.window, width, height, -1)
def get_pixbuf(self):
@@ -83,6 +86,7 @@ class DrawingArea(gtk.DrawingArea):
"""
Forward button click information to the flow graph.
"""
+ self.grab_focus()
self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
if event.button == 1: self._flow_graph.handle_mouse_selector_press(
double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
@@ -133,3 +137,8 @@ class DrawingArea(gtk.DrawingArea):
gc = self.window.new_gc()
self._flow_graph.draw(gc, self._pixmap)
self.window.draw_drawable(gc, self._pixmap, 0, 0, 0, 0, -1, -1)
+
+ def _handle_focus_lost_event(self, widget, event):
+ self._flow_graph.unselect()
+ self._flow_graph.update_selected()
+ self._flow_graph.queue_draw() \ No newline at end of file
diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py
index 677f202e1f..dd378ad079 100644
--- a/grc/gui/MainWindow.py
+++ b/grc/gui/MainWindow.py
@@ -304,7 +304,7 @@ class MainWindow(gtk.Window):
def get_focus_flag(self):
"""
Get the focus flag from the current page.
-
+
Returns:
the focus flag
"""
diff --git a/volk/kernels/volk/volk_32f_invsqrt_32f.h b/volk/kernels/volk/volk_32f_invsqrt_32f.h
new file mode 100644
index 0000000000..17dfe3b9c6
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_invsqrt_32f.h
@@ -0,0 +1,77 @@
+#ifndef INCLUDED_volk_32f_invsqrt_32f_a_H
+#define INCLUDED_volk_32f_invsqrt_32f_a_H
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <math.h>
+
+static inline float Q_rsqrt( float number )
+{
+ long i;
+ float x2, y;
+ const float threehalfs = 1.5F;
+
+ x2 = number * 0.5F;
+ y = number;
+ i = * ( long * ) &y; // evil floating point bit level hacking
+ i = 0x5f3759df - ( i >> 1 ); // what the fuck?
+ y = * ( float * ) &i;
+ y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
+// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
+
+ return y;
+}
+
+#ifdef LV_HAVE_SSE
+#include <xmmintrin.h>
+/*!
+ \brief Sqrts the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be invsqrted
+ \param num_points The number of values in aVector and bVector to be invsqrted together and stored into cVector
+*/
+static inline void volk_32f_invsqrt_32f_a_sse(float* cVector, const float* aVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m128 aVal, cVal;
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_load_ps(aPtr);
+
+ cVal = _mm_rsqrt_ps(aVal);
+
+ _mm_store_ps(cPtr,cVal); // Store the results back into the C container
+
+ aPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *cPtr++ = Q_rsqrt(*aPtr++);
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Sqrts the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be invsqrted
+ \param num_points The number of values in aVector and bVector to be invsqrted together and stored into cVector
+*/
+static inline void volk_32f_invsqrt_32f_generic(float* cVector, const float* aVector, unsigned int num_points){
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ unsigned int number = 0;
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = Q_rsqrt(*aPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_32f_invsqrt_32f_a_H */