diff options
46 files changed, 4599 insertions, 911 deletions
diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml index 04fe1f6955..64eacfa91e 100644 --- a/gr-blocks/grc/blocks_block_tree.xml +++ b/gr-blocks/grc/blocks_block_tree.xml @@ -163,6 +163,7 @@ <cat> <name>Stream Tag Tools</name> <block>blocks_tag_debug</block> + <block>blocks_tag_gate</block> <block>blocks_tagged_file_sink</block> <block>blocks_tagged_stream_mux</block> </cat> diff --git a/gr-blocks/grc/blocks_tag_gate.xml b/gr-blocks/grc/blocks_tag_gate.xml new file mode 100644 index 0000000000..5c748f27cf --- /dev/null +++ b/gr-blocks/grc/blocks_tag_gate.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<block> + <name>Tag Gate</name> + <key>blocks_tag_gate</key> + <import>from gnuradio import blocks</import> + <make>blocks.tag_gate($type.size * $vlen, $propagate_tags)</make> + <param> + <name>Item 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>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <param> + <name>Propagate_tags</name> + <key>propagate_tags</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <check>$vlen > 0</check> + <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/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt index 7b74ca7a5d..a877dfc557 100644 --- a/gr-blocks/include/blocks/CMakeLists.txt +++ b/gr-blocks/include/blocks/CMakeLists.txt @@ -203,6 +203,6 @@ install(FILES vector_to_streams.h wavfile_sink.h wavfile_source.h - DESTINATION ${GR_INCLUDE_DIR}/gnuradio/blocks + tag_gate.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/blocks COMPONENT "blocks_devel" ) diff --git a/gr-blocks/include/blocks/tag_gate.h b/gr-blocks/include/blocks/tag_gate.h new file mode 100644 index 0000000000..2c3d20d464 --- /dev/null +++ b/gr-blocks/include/blocks/tag_gate.h @@ -0,0 +1,56 @@ +/* -*- 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_TAG_GATE_H +#define INCLUDED_BLOCKS_TAG_GATE_H + +#include <blocks/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace blocks { + + /*! + * \brief Control tag propagation. + * \ingroup blocks + * + * Use this block to stop tags from propagating. + */ + class BLOCKS_API tag_gate : virtual public gr_sync_block + { + public: + typedef boost::shared_ptr<tag_gate> sptr; + + virtual void set_propagation(bool propagate_tags) = 0; + + /*! + * \param item_size Item size + * \param propagate_tags Set this to true to allow tags to pass through this block. + */ + static sptr make(size_t item_size, bool propagate_tags=false); + }; + + } // namespace blocks +} // namespace gr + +#endif /* INCLUDED_BLOCKS_TAG_GATE_H */ + diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt index eb7af51c0b..57c1cd20df 100644 --- a/gr-blocks/lib/CMakeLists.txt +++ b/gr-blocks/lib/CMakeLists.txt @@ -266,7 +266,8 @@ list(APPEND blocks_libs ${LOG4CPP_LIBRARIES} ) -add_library(gnuradio-blocks SHARED ${gr_blocks_sources}) +add_library(gnuradio-blocks SHARED ${gr_blocks_sources} + tag_gate_impl.cc) add_dependencies(gnuradio-blocks blocks_generated_includes) target_link_libraries(gnuradio-blocks ${blocks_libs}) diff --git a/gr-blocks/lib/tag_gate_impl.cc b/gr-blocks/lib/tag_gate_impl.cc new file mode 100644 index 0000000000..854031bf8b --- /dev/null +++ b/gr-blocks/lib/tag_gate_impl.cc @@ -0,0 +1,79 @@ +/* -*- 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 <gr_io_signature.h> +#include "tag_gate_impl.h" + +namespace gr { + namespace blocks { + + tag_gate::sptr + tag_gate::make(size_t item_size, bool propagate_tags) + { + return gnuradio::get_initial_sptr (new tag_gate_impl(item_size, propagate_tags)); + } + + tag_gate_impl::tag_gate_impl(size_t item_size, bool propagate_tags) + : gr_sync_block("tag_gate", + gr_make_io_signature(1, 1, item_size), + gr_make_io_signature(1, 1, item_size)), + d_item_size(item_size), + d_propagate_tags(propagate_tags) + { + if (!d_propagate_tags) { + set_tag_propagation_policy(TPP_DONT); + } + } + + tag_gate_impl::~tag_gate_impl() + { + } + + void tag_gate_impl::set_propagation(bool propagate_tags) + { + if (propagate_tags) { + set_tag_propagation_policy(TPP_ALL_TO_ALL); + } else { + set_tag_propagation_policy(TPP_DONT); + } + } + + int + tag_gate_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]; + + memcpy((void *) out, (void *) in, d_item_size * noutput_items); + + return noutput_items; + } + + } /* namespace blocks */ +} /* namespace gr */ + diff --git a/gr-blocks/lib/tag_gate_impl.h b/gr-blocks/lib/tag_gate_impl.h new file mode 100644 index 0000000000..4b61b62036 --- /dev/null +++ b/gr-blocks/lib/tag_gate_impl.h @@ -0,0 +1,52 @@ +/* -*- 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_TAG_GATE_IMPL_H +#define INCLUDED_BLOCKS_TAG_GATE_IMPL_H + +#include <blocks/tag_gate.h> + +namespace gr { + namespace blocks { + + class tag_gate_impl : public tag_gate + { + private: + size_t d_item_size; + bool d_propagate_tags; + + public: + tag_gate_impl(size_t item_size, bool propagate_tags); + ~tag_gate_impl(); + + void set_propagation(bool propagate_tags); + + 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_TAG_GATE_IMPL_H */ + diff --git a/gr-blocks/python/qa_tag_gate.py b/gr-blocks/python/qa_tag_gate.py new file mode 100755 index 0000000000..fa3c501fb4 --- /dev/null +++ b/gr-blocks/python/qa_tag_gate.py @@ -0,0 +1,49 @@ +#!/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 +import pmt +import blocks_swig as blocks + + +class qa_tag_gate (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001_t (self): + tag = gr.gr_tag_t() + tag.key = pmt.pmt_string_to_symbol('key') + tag.value = pmt.pmt_from_long(42) + tag.offset = 0 + src = blocks.vector_source_f(range(20), False, 1, (tag,)) + gate = blocks.tag_gate(gr.sizeof_float, False) + sink = blocks.vector_sink_f() + self.tb.run () + self.assertEqual(len(sink.tags()), 0) + +if __name__ == '__main__': + gr_unittest.run(qa_tag_gate, "qa_tag_gate.xml") + diff --git a/gr-blocks/swig/blocks_swig0.i b/gr-blocks/swig/blocks_swig0.i index 1a6e0331d1..912adcfd0c 100644 --- a/gr-blocks/swig/blocks_swig0.i +++ b/gr-blocks/swig/blocks_swig0.i @@ -56,6 +56,7 @@ #include "blocks/streams_to_stream.h" #include "blocks/streams_to_vector.h" #include "blocks/tag_debug.h" +#include "blocks/tag_gate.h" #include "blocks/tagged_file_sink.h" #include "blocks/throttle.h" #include "blocks/vector_map.h" @@ -106,6 +107,7 @@ %include "blocks/streams_to_stream.h" %include "blocks/streams_to_vector.h" %include "blocks/tag_debug.h" +%include "blocks/tag_gate.h" %include "blocks/tagged_file_sink.h" %include "blocks/throttle.h" %include "blocks/vector_map.h" @@ -154,6 +156,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_vector); GR_SWIG_BLOCK_MAGIC2(blocks, streams_to_stream); GR_SWIG_BLOCK_MAGIC2(blocks, streams_to_vector); GR_SWIG_BLOCK_MAGIC2(blocks, tag_debug); +GR_SWIG_BLOCK_MAGIC2(blocks, tag_gate); GR_SWIG_BLOCK_MAGIC2(blocks, tagged_file_sink); GR_SWIG_BLOCK_MAGIC2(blocks, throttle); GR_SWIG_BLOCK_MAGIC2(blocks, vector_map); diff --git a/gr-digital/examples/ofdm/ofdm_loopback.grc b/gr-digital/examples/ofdm/ofdm_loopback.grc new file mode 100644 index 0000000000..45a6ca0869 --- /dev/null +++ b/gr-digital/examples/ofdm/ofdm_loopback.grc @@ -0,0 +1,861 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Tue May 7 15:42:23 2013</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>ofdm_loopback_example</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>OFDM Loopback Example</value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value>Transmit a pre-defined signal (a complex sine) as OFDM packets.</value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(0, -1)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </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>variable</key> + <param> + <key>id</key> + <value>fft_len</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>64</value> + </param> + <param> + <key>_coordinate</key> + <value>(464, 0)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <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>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>(652, 285)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>noise_voltage</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> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</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> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(651, 416)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>import</key> + <param> + <key>id</key> + <value>import_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>(536, -1)</value> + </param> + <param> + <key>_rotation</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>from gnuradio.digital.utils import tagged_streams</value> + </param> + <param> + <key>_coordinate</key> + <value>(633, -1)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>digital_ofdm_tx</key> + <param> + <key>id</key> + <value>digital_ofdm_tx_0</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>packet_len_key</key> + <value>len_tag_key</value> + </param> + <param> + <key>occupied_carriers</key> + <value>()</value> + </param> + <param> + <key>pilot_carriers</key> + <value>()</value> + </param> + <param> + <key>pilot_symbols</key> + <value>()</value> + </param> + <param> + <key>sync_word1</key> + <value>()</value> + </param> + <param> + <key>sync_word2</key> + <value>()</value> + </param> + <param> + <key>header_mod</key> + <value>"BPSK"</value> + </param> + <param> + <key>payload_mod</key> + <value>"BPSK"</value> + </param> + <param> + <key>rolloff</key> + <value>0</value> + </param> + <param> + <key>log</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(390, 78)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_float_to_uchar</key> + <param> + <key>id</key> + <value>blocks_float_to_uchar_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(230, 119)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>tx_signal</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(8*2)]</value> + </param> + <param> + <key>_coordinate</key> + <value>(176, -1)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_vector_source_x</key> + <param> + <key>id</key> + <value>blocks_vector_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>vector</key> + <value>tx_signal</value> + </param> + <param> + <key>tags</key> + <value>tagged_streams.make_lengthtags((8*2*gr.sizeof_float,), (0,), tagname=len_tag_key)</value> + </param> + <param> + <key>repeat</key> + <value>True</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(-1, 101)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_throttle</key> + <param> + <key>id</key> + <value>blocks_throttle_0</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>100e3</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(354, 230)</value> + </param> + <param> + <key>_rotation</key> + <value>180</value> + </param> + </block> + <block> + <key>blocks_tag_gate</key> + <param> + <key>id</key> + <value>blocks_tag_gate_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <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>_coordinate</key> + <value>(539, 230)</value> + </param> + <param> + <key>_rotation</key> + <value>180</value> + </param> + </block> + <block> + <key>wxgui_fftsink2</key> + <param> + <key>id</key> + <value>wxgui_fftsink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>Rx Spectrum</value> + </param> + <param> + <key>samp_rate</key> + <value>100e3</value> + </param> + <param> + <key>baseband_freq</key> + <value>0</value> + </param> + <param> + <key>y_per_div</key> + <value>10</value> + </param> + <param> + <key>y_divs</key> + <value>10</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>ref_scale</key> + <value>2.0</value> + </param> + <param> + <key>fft_size</key> + <value>1024</value> + </param> + <param> + <key>fft_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> + <value>False</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>win</key> + <value>None</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>freqvar</key> + <value>None</value> + </param> + <param> + <key>_coordinate</key> + <value>(92, 463)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>channel_model</key> + <param> + <key>id</key> + <value>chan_model</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>noise_voltage</key> + <value>noise_voltage</value> + </param> + <param> + <key>freq_offset</key> + <value>1.0/fft_len * freq_offset</value> + </param> + <param> + <key>epsilon</key> + <value>1.0</value> + </param> + <param> + <key>taps</key> + <value>1.0</value> + </param> + <param> + <key>seed</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(615, 86)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>digital_ofdm_rx</key> + <param> + <key>id</key> + <value>digital_ofdm_rx_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</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>packet_len_key</key> + <value>"rx_len"</value> + </param> + <param> + <key>occupied_carriers</key> + <value>()</value> + </param> + <param> + <key>pilot_carriers</key> + <value>()</value> + </param> + <param> + <key>pilot_symbols</key> + <value>()</value> + </param> + <param> + <key>sync_word1</key> + <value>()</value> + </param> + <param> + <key>sync_word2</key> + <value>()</value> + </param> + <param> + <key>header_mod</key> + <value>"BPSK"</value> + </param> + <param> + <key>payload_mod</key> + <value>"BPSK"</value> + </param> + <param> + <key>log</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(92, 307)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_uchar_to_float</key> + <param> + <key>id</key> + <value>blocks_uchar_to_float_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> + <key>_coordinate</key> + <value>(332, 340)</value> + </param> + <param> + <key>_rotation</key> + <value>0</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>False</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>_coordinate</key> + <value>(336, 412)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>1.0</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> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</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>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>_coordinate</key> + <value>(504, 314)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>blocks_vector_source_x_0</source_block_id> + <sink_block_id>blocks_float_to_uchar_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>chan_model</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_float_to_uchar_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>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>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_rx_0</source_block_id> + <sink_block_id>blocks_uchar_to_float_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_uchar_to_float_0</source_block_id> + <sink_block_id>wxgui_scopesink2_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_tag_debug_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>chan_model</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>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> +</flow_graph> diff --git a/gr-digital/examples/ofdm/rx_ofdm.grc b/gr-digital/examples/ofdm/rx_ofdm.grc index 766fd9dc2b..470f7ba3bf 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>Thu Feb 14 15:49:35 2013</timestamp> + <timestamp>Tue May 7 15:15:56 2013</timestamp> <block> <key>options</key> <param> @@ -61,22 +61,22 @@ </param> </block> <block> - <key>variable</key> + <key>import</key> <param> <key>id</key> - <value>pilot_symbols_0</value> + <value>import_1</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>((100,),)</value> + <key>import</key> + <value>from gnuradio.digital.utils import tagged_streams</value> </param> <param> <key>_coordinate</key> - <value>(762, 64)</value> + <value>(163, 0)</value> </param> <param> <key>_rotation</key> @@ -87,7 +87,7 @@ <key>variable</key> <param> <key>id</key> - <value>pilot_carriers</value> + <value>fft_len</value> </param> <param> <key>_enabled</key> @@ -95,11 +95,11 @@ </param> <param> <key>value</key> - <value>((0,),)</value> + <value>64</value> </param> <param> <key>_coordinate</key> - <value>(557, 64)</value> + <value>(301, -1)</value> </param> <param> <key>_rotation</key> @@ -110,7 +110,7 @@ <key>variable</key> <param> <key>id</key> - <value>header_formatter</value> + <value>length_tag_name</value> </param> <param> <key>_enabled</key> @@ -118,11 +118,11 @@ </param> <param> <key>value</key> - <value>digital.packet_header_ofdm(occupied_carriers, 1, length_tag_name)</value> + <value>"frame_len"</value> </param> <param> <key>_coordinate</key> - <value>(876, 64)</value> + <value>(367, -1)</value> </param> <param> <key>_rotation</key> @@ -133,7 +133,7 @@ <key>variable</key> <param> <key>id</key> - <value>pilot_symbols</value> + <value>payload_mod</value> </param> <param> <key>_enabled</key> @@ -141,11 +141,11 @@ </param> <param> <key>value</key> - <value>((100,),)</value> + <value>digital.constellation_qpsk()</value> </param> <param> <key>_coordinate</key> - <value>(659, 64)</value> + <value>(648, 0)</value> </param> <param> <key>_rotation</key> @@ -156,7 +156,7 @@ <key>variable</key> <param> <key>id</key> - <value>occupied_carriers</value> + <value>header_mod</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>digital.constellation_bpsk()</value> </param> <param> <key>_coordinate</key> - <value>(404, 64)</value> + <value>(490, 0)</value> </param> <param> <key>_rotation</key> @@ -176,34 +176,45 @@ </param> </block> <block> - <key>analog_noise_source_x</key> + <key>variable</key> <param> <key>id</key> - <value>analog_noise_source_x_0</value> + <value>header_formatter</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> + <key>value</key> + <value>digital.packet_header_ofdm(occupied_carriers, 1, length_tag_name)</value> </param> <param> - <key>noise_type</key> - <value>analog.GR_GAUSSIAN</value> + <key>_coordinate</key> + <value>(811, -1)</value> </param> <param> - <key>amp</key> - <value>1</value> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>occupied_carriers</value> </param> <param> - <key>seed</key> - <value>0</value> + <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> </param> <param> <key>_coordinate</key> - <value>(-1, 185)</value> + <value>(598, 64)</value> </param> <param> <key>_rotation</key> @@ -211,26 +222,45 @@ </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>pilot_carriers</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>fft_len</key> - <value>fft_len</value> + <key>value</key> + <value>((-21, -7, 7, 21,),)</value> </param> <param> - <key>cp_len</key> - <value>fft_len/4</value> + <key>_coordinate</key> + <value>(751, 64)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>pilot_symbols</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>((1, 1, 1, -1,),)</value> </param> <param> <key>_coordinate</key> - <value>(368, 178)</value> + <value>(875, 65)</value> </param> <param> <key>_rotation</key> @@ -238,22 +268,22 @@ </param> </block> <block> - <key>analog_frequency_modulator_fc</key> + <key>variable</key> <param> <key>id</key> - <value>analog_frequency_modulator_fc_0</value> + <value>sync_word2</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>sensitivity</key> - <value>-2.0/fft_len</value> + <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> </param> <param> <key>_coordinate</key> - <value>(692, 175)</value> + <value>(457, 64)</value> </param> <param> <key>_rotation</key> @@ -261,30 +291,45 @@ </param> </block> <block> - <key>blocks_multiply_xx</key> + <key>variable</key> <param> <key>id</key> - <value>blocks_multiply_xx_0</value> + <value>sync_word1</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> + <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> </param> <param> - <key>num_inputs</key> - <value>2</value> + <key>_coordinate</key> + <value>(313, 64)</value> </param> <param> - <key>vlen</key> - <value>1</value> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>3200000</value> </param> <param> <key>_coordinate</key> - <value>(885, 223)</value> + <value>(218, 64)</value> </param> <param> <key>_rotation</key> @@ -292,10 +337,10 @@ </param> </block> <block> - <key>gr_delay</key> + <key>blocks_tag_debug</key> <param> <key>id</key> - <value>gr_delay_0</value> + <value>blocks_tag_debug_0</value> </param> <param> <key>_enabled</key> @@ -303,14 +348,14 @@ </param> <param> <key>type</key> - <value>complex</value> + <value>byte</value> </param> <param> - <key>delay</key> - <value>fft_len+fft_len/4</value> + <key>name</key> + <value>Rx Packets</value> </param> <param> - <key>num_ports</key> + <key>num_inputs</key> <value>1</value> </param> <param> @@ -318,8 +363,12 @@ <value>1</value> </param> <param> + <key>display</key> + <value>True</value> + </param> + <param> <key>_coordinate</key> - <value>(368, 253)</value> + <value>(1101, 791)</value> </param> <param> <key>_rotation</key> @@ -327,22 +376,22 @@ </param> </block> <block> - <key>variable</key> + <key>digital_constellation_decoder_cb</key> <param> <key>id</key> - <value>samp_rate</value> + <value>digital_constellation_decoder_cb_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>3200000</value> + <key>constellation</key> + <value>payload_mod.base()</value> </param> <param> <key>_coordinate</key> - <value>(0, 91)</value> + <value>(879, 799)</value> </param> <param> <key>_rotation</key> @@ -350,22 +399,42 @@ </param> </block> <block> - <key>import</key> + <key>digital_ofdm_serializer_vcc</key> <param> <key>id</key> - <value>import_1</value> + <value>digital_ofdm_serializer_vcc_1</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>import</key> - <value>from gnuradio.digital.utils import tagged_streams</value> + <key>fft_len</key> + <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> + </param> + <param> + <key>packet_len_tag_key</key> + <value>""</value> + </param> + <param> + <key>symbols_skipped</key> + <value>1</value> + </param> + <param> + <key>input_is_shifted</key> + <value>True</value> </param> <param> <key>_coordinate</key> - <value>(163, 0)</value> + <value>(653, 761)</value> </param> <param> <key>_rotation</key> @@ -373,22 +442,42 @@ </param> </block> <block> - <key>variable</key> + <key>fft_vxx</key> <param> <key>id</key> - <value>sync_word</value> + <value>fft_vxx_0_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>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> + </param> + <param> + <key>shift</key> + <value>True</value> + </param> + <param> + <key>nthreads</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(165, 46)</value> + <value>(214, 769)</value> </param> <param> <key>_rotation</key> @@ -396,22 +485,22 @@ </param> </block> <block> - <key>variable</key> + <key>virtual_source</key> <param> <key>id</key> - <value>header_mod</value> + <value>virtual_source_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>digital.constellation_bpsk()</value> + <key>stream_id</key> + <value>Payload Stream</value> </param> <param> <key>_coordinate</key> - <value>(655, 0)</value> + <value>(0, 799)</value> </param> <param> <key>_rotation</key> @@ -419,22 +508,22 @@ </param> </block> <block> - <key>variable</key> + <key>virtual_sink</key> <param> <key>id</key> - <value>payload_mod</value> + <value>virtual_sink_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>digital.constellation_qpsk()</value> + <key>stream_id</key> + <value>Payload Stream</value> </param> <param> <key>_coordinate</key> - <value>(813, 0)</value> + <value>(968, 374)</value> </param> <param> <key>_rotation</key> @@ -442,22 +531,22 @@ </param> </block> <block> - <key>variable</key> + <key>virtual_sink</key> <param> <key>id</key> - <value>n_sync_symbols</value> + <value>virtual_sink_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>1</value> + <key>stream_id</key> + <value>Header Stream</value> </param> <param> <key>_coordinate</key> - <value>(168, 108)</value> + <value>(969, 305)</value> </param> <param> <key>_rotation</key> @@ -465,10 +554,10 @@ </param> </block> <block> - <key>gr_throttle</key> + <key>blocks_multiply_xx</key> <param> <key>id</key> - <value>gr_throttle_0</value> + <value>blocks_multiply_xx_0</value> </param> <param> <key>_enabled</key> @@ -479,8 +568,8 @@ <value>complex</value> </param> <param> - <key>samples_per_second</key> - <value>samp_rate</value> + <key>num_inputs</key> + <value>2</value> </param> <param> <key>vlen</key> @@ -488,7 +577,7 @@ </param> <param> <key>_coordinate</key> - <value>(181, 200)</value> + <value>(798, 137)</value> </param> <param> <key>_rotation</key> @@ -496,22 +585,22 @@ </param> </block> <block> - <key>digital_constellation_decoder_cb</key> + <key>analog_frequency_modulator_fc</key> <param> <key>id</key> - <value>digital_constellation_decoder_cb_0_0</value> + <value>analog_frequency_modulator_fc_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>constellation</key> - <value>header_mod.base()</value> + <key>sensitivity</key> + <value>-2.0/fft_len</value> </param> <param> <key>_coordinate</key> - <value>(854, 343)</value> + <value>(579, 134)</value> </param> <param> <key>_rotation</key> @@ -519,34 +608,34 @@ </param> </block> <block> - <key>digital_ofdm_frame_equalizer_vcvc</key> + <key>gr_delay</key> <param> <key>id</key> - <value>digital_ofdm_frame_equalizer_vcvc_0_0</value> + <value>gr_delay_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>fft_len</key> - <value>fft_len</value> + <key>type</key> + <value>complex</value> </param> <param> - <key>equalizer</key> - <value>digital.ofdm_equalizer_simpledfe(fft_len, header_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols).base()</value> + <key>delay</key> + <value>fft_len+fft_len/4</value> </param> <param> - <key>len_tag_key</key> - <value>length_tag_name</value> + <key>num_ports</key> + <value>1</value> </param> <param> - <key>propagate_channel_state</key> - <value>True</value> + <key>vlen</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(421, 320)</value> + <value>(422, 220)</value> </param> <param> <key>_rotation</key> @@ -554,33 +643,41 @@ </param> </block> <block> - <key>digital_packet_headerparser_b</key> + <key>digital_ofdm_sync_sc_cfb</key> <param> <key>id</key> - <value>digital_packet_headerparser_b_0</value> + <value>digital_ofdm_sync_sc_cfb_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>header_formatter</key> - <value>header_formatter.formatter()</value> + <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> </param> <param> <key>_coordinate</key> - <value>(651, 466)</value> + <value>(244, 137)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>fft_vxx</key> + <key>blocks_throttle</key> <param> <key>id</key> - <value>fft_vxx_0</value> + <value>blocks_throttle_0</value> </param> <param> <key>_enabled</key> @@ -591,51 +688,51 @@ <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> - </param> - <param> - <key>shift</key> - <value>True</value> + <key>samples_per_second</key> + <value>samp_rate</value> </param> <param> - <key>nthreads</key> + <key>vlen</key> <value>1</value> </param> <param> <key>_coordinate</key> - <value>(53, 429)</value> + <value>(186, 235)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>variable</key> + <key>analog_noise_source_x</key> <param> <key>id</key> - <value>fft_len</value> + <value>analog_noise_source_x_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>64</value> + <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> </param> <param> <key>_coordinate</key> - <value>(301, -1)</value> + <value>(0, 220)</value> </param> <param> <key>_rotation</key> @@ -643,72 +740,662 @@ </param> </block> <block> - <key>variable</key> + <key>uhd_usrp_source</key> <param> <key>id</key> - <value>length_tag_name</value> + <value>uhd_usrp_source_0</value> </param> <param> <key>_enabled</key> - <value>True</value> + <value>False</value> </param> <param> - <key>value</key> - <value>"frame_len"</value> + <key>type</key> + <value>fc32</value> </param> <param> - <key>_coordinate</key> - <value>(367, -1)</value> + <key>otw</key> + <value></value> </param> <param> - <key>_rotation</key> + <key>stream_args</key> + <value></value> + </param> + <param> + <key>dev_addr</key> + <value></value> + </param> + <param> + <key>sync</key> + <value></value> + </param> + <param> + <key>clock_rate</key> + <value>0.0</value> + </param> + <param> + <key>num_mboards</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> + </param> + <param> + <key>time_source1</key> + <value></value> + </param> + <param> + <key>sd_spec1</key> + <value></value> + </param> + <param> + <key>clock_source2</key> + <value></value> + </param> + <param> + <key>time_source2</key> + <value></value> + </param> + <param> + <key>sd_spec2</key> + <value></value> + </param> + <param> + <key>clock_source3</key> + <value></value> + </param> + <param> + <key>time_source3</key> + <value></value> + </param> + <param> + <key>sd_spec3</key> + <value></value> + </param> + <param> + <key>clock_source4</key> + <value></value> + </param> + <param> + <key>time_source4</key> + <value></value> + </param> + <param> + <key>sd_spec4</key> + <value></value> + </param> + <param> + <key>clock_source5</key> + <value></value> + </param> + <param> + <key>time_source5</key> + <value></value> + </param> + <param> + <key>sd_spec5</key> + <value></value> + </param> + <param> + <key>clock_source6</key> + <value></value> + </param> + <param> + <key>time_source6</key> + <value></value> + </param> + <param> + <key>sd_spec6</key> + <value></value> + </param> + <param> + <key>clock_source7</key> + <value></value> + </param> + <param> + <key>time_source7</key> + <value></value> + </param> + <param> + <key>sd_spec7</key> + <value></value> + </param> + <param> + <key>nchan</key> + <value>1</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>center_freq0</key> <value>0</value> </param> - </block> - <block> - <key>digital_constellation_decoder_cb</key> <param> - <key>id</key> - <value>digital_constellation_decoder_cb_0</value> + <key>gain0</key> + <value>0</value> </param> <param> - <key>_enabled</key> - <value>True</value> + <key>ant0</key> + <value></value> </param> <param> - <key>constellation</key> - <value>payload_mod.base()</value> + <key>bw0</key> + <value>0</value> </param> <param> - <key>_coordinate</key> - <value>(718, 635)</value> + <key>center_freq1</key> + <value>0</value> </param> <param> - <key>_rotation</key> + <key>gain1</key> <value>0</value> </param> - </block> - <block> - <key>gr_null_sink</key> <param> - <key>id</key> - <value>gr_null_sink_0</value> + <key>ant1</key> + <value></value> </param> <param> - <key>_enabled</key> - <value>True</value> + <key>bw1</key> + <value>0</value> </param> <param> - <key>type</key> - <value>byte</value> + <key>center_freq2</key> + <value>0</value> </param> <param> - <key>vlen</key> - <value>1</value> + <key>gain2</key> + <value>0</value> + </param> + <param> + <key>ant2</key> + <value></value> + </param> + <param> + <key>bw2</key> + <value>0</value> + </param> + <param> + <key>center_freq3</key> + <value>0</value> + </param> + <param> + <key>gain3</key> + <value>0</value> + </param> + <param> + <key>ant3</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> + <value>0</value> + </param> + <param> + <key>ant4</key> + <value></value> + </param> + <param> + <key>bw4</key> + <value>0</value> + </param> + <param> + <key>center_freq5</key> + <value>0</value> + </param> + <param> + <key>gain5</key> + <value>0</value> + </param> + <param> + <key>ant5</key> + <value></value> + </param> + <param> + <key>bw5</key> + <value>0</value> + </param> + <param> + <key>center_freq6</key> + <value>0</value> + </param> + <param> + <key>gain6</key> + <value>0</value> + </param> + <param> + <key>ant6</key> + <value></value> + </param> + <param> + <key>bw6</key> + <value>0</value> + </param> + <param> + <key>center_freq7</key> + <value>0</value> + </param> + <param> + <key>gain7</key> + <value>0</value> + </param> + <param> + <key>ant7</key> + <value></value> + </param> + <param> + <key>bw7</key> + <value>0</value> + </param> + <param> + <key>center_freq8</key> + <value>0</value> + </param> + <param> + <key>gain8</key> + <value>0</value> + </param> + <param> + <key>ant8</key> + <value></value> + </param> + <param> + <key>bw8</key> + <value>0</value> + </param> + <param> + <key>center_freq9</key> + <value>0</value> + </param> + <param> + <key>gain9</key> + <value>0</value> + </param> + <param> + <key>ant9</key> + <value></value> + </param> + <param> + <key>bw9</key> + <value>0</value> + </param> + <param> + <key>center_freq10</key> + <value>0</value> + </param> + <param> + <key>gain10</key> + <value>0</value> + </param> + <param> + <key>ant10</key> + <value></value> + </param> + <param> + <key>bw10</key> + <value>0</value> + </param> + <param> + <key>center_freq11</key> + <value>0</value> + </param> + <param> + <key>gain11</key> + <value>0</value> + </param> + <param> + <key>ant11</key> + <value></value> + </param> + <param> + <key>bw11</key> + <value>0</value> + </param> + <param> + <key>center_freq12</key> + <value>0</value> + </param> + <param> + <key>gain12</key> + <value>0</value> + </param> + <param> + <key>ant12</key> + <value></value> + </param> + <param> + <key>bw12</key> + <value>0</value> + </param> + <param> + <key>center_freq13</key> + <value>0</value> + </param> + <param> + <key>gain13</key> + <value>0</value> + </param> + <param> + <key>ant13</key> + <value></value> + </param> + <param> + <key>bw13</key> + <value>0</value> + </param> + <param> + <key>center_freq14</key> + <value>0</value> + </param> + <param> + <key>gain14</key> + <value>0</value> + </param> + <param> + <key>ant14</key> + <value></value> + </param> + <param> + <key>bw14</key> + <value>0</value> + </param> + <param> + <key>center_freq15</key> + <value>0</value> + </param> + <param> + <key>gain15</key> + <value>0</value> + </param> + <param> + <key>ant15</key> + <value></value> + </param> + <param> + <key>bw15</key> + <value>0</value> + </param> + <param> + <key>center_freq16</key> + <value>0</value> + </param> + <param> + <key>gain16</key> + <value>0</value> + </param> + <param> + <key>ant16</key> + <value></value> + </param> + <param> + <key>bw16</key> + <value>0</value> + </param> + <param> + <key>center_freq17</key> + <value>0</value> + </param> + <param> + <key>gain17</key> + <value>0</value> + </param> + <param> + <key>ant17</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> + <value>0</value> + </param> + <param> + <key>ant18</key> + <value></value> + </param> + <param> + <key>bw18</key> + <value>0</value> + </param> + <param> + <key>center_freq19</key> + <value>0</value> + </param> + <param> + <key>gain19</key> + <value>0</value> + </param> + <param> + <key>ant19</key> + <value></value> + </param> + <param> + <key>bw19</key> + <value>0</value> + </param> + <param> + <key>center_freq20</key> + <value>0</value> + </param> + <param> + <key>gain20</key> + <value>0</value> + </param> + <param> + <key>ant20</key> + <value></value> + </param> + <param> + <key>bw20</key> + <value>0</value> + </param> + <param> + <key>center_freq21</key> + <value>0</value> + </param> + <param> + <key>gain21</key> + <value>0</value> + </param> + <param> + <key>ant21</key> + <value></value> + </param> + <param> + <key>bw21</key> + <value>0</value> + </param> + <param> + <key>center_freq22</key> + <value>0</value> + </param> + <param> + <key>gain22</key> + <value>0</value> + </param> + <param> + <key>ant22</key> + <value></value> + </param> + <param> + <key>bw22</key> + <value>0</value> + </param> + <param> + <key>center_freq23</key> + <value>0</value> + </param> + <param> + <key>gain23</key> + <value>0</value> + </param> + <param> + <key>ant23</key> + <value></value> + </param> + <param> + <key>bw23</key> + <value>0</value> + </param> + <param> + <key>center_freq24</key> + <value>0</value> + </param> + <param> + <key>gain24</key> + <value>0</value> + </param> + <param> + <key>ant24</key> + <value></value> + </param> + <param> + <key>bw24</key> + <value>0</value> + </param> + <param> + <key>center_freq25</key> + <value>0</value> + </param> + <param> + <key>gain25</key> + <value>0</value> + </param> + <param> + <key>ant25</key> + <value></value> + </param> + <param> + <key>bw25</key> + <value>0</value> + </param> + <param> + <key>center_freq26</key> + <value>0</value> + </param> + <param> + <key>gain26</key> + <value>0</value> + </param> + <param> + <key>ant26</key> + <value></value> + </param> + <param> + <key>bw26</key> + <value>0</value> + </param> + <param> + <key>center_freq27</key> + <value>0</value> + </param> + <param> + <key>gain27</key> + <value>0</value> + </param> + <param> + <key>ant27</key> + <value></value> + </param> + <param> + <key>bw27</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> + </param> + <param> + <key>bw28</key> + <value>0</value> + </param> + <param> + <key>center_freq29</key> + <value>0</value> + </param> + <param> + <key>gain29</key> + <value>0</value> + </param> + <param> + <key>ant29</key> + <value></value> + </param> + <param> + <key>bw29</key> + <value>0</value> + </param> + <param> + <key>center_freq30</key> + <value>0</value> + </param> + <param> + <key>gain30</key> + <value>0</value> + </param> + <param> + <key>ant30</key> + <value></value> + </param> + <param> + <key>bw30</key> + <value>0</value> + </param> + <param> + <key>center_freq31</key> + <value>0</value> + </param> + <param> + <key>gain31</key> + <value>0</value> + </param> + <param> + <key>ant31</key> + <value></value> + </param> + <param> + <key>bw31</key> + <value>0</value> </param> <param> <key>_coordinate</key> - <value>(938, 638)</value> + <value>(0, 135)</value> </param> <param> <key>_rotation</key> @@ -731,7 +1418,7 @@ </param> <param> <key>equalizer</key> - <value>digital.ofdm_equalizer_simpledfe(fft_len, header_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols, n_sync_symbols).base()</value> + <value>digital.ofdm_equalizer_simpledfe(fft_len, header_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols, 2).base()</value> </param> <param> <key>len_tag_key</key> @@ -743,7 +1430,7 @@ </param> <param> <key>_coordinate</key> - <value>(265, 612)</value> + <value>(422, 776)</value> </param> <param> <key>_rotation</key> @@ -751,42 +1438,46 @@ </param> </block> <block> - <key>fft_vxx</key> + <key>digital_header_payload_demux</key> <param> <key>id</key> - <value>fft_vxx_0_0</value> + <value>digital_header_payload_demux_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> + <key>header_len</key> + <value>3</value> </param> <param> - <key>fft_size</key> + <key>items_per_symbol</key> <value>fft_len</value> </param> <param> - <key>forward</key> - <value>True</value> + <key>guard_interval</key> + <value>fft_len/4</value> </param> <param> - <key>window</key> - <value></value> + <key>length_tag_key</key> + <value>length_tag_name</value> </param> <param> - <key>shift</key> + <key>trigger_tag_key</key> + <value>""</value> + </param> + <param> + <key>output_symbols</key> <value>True</value> </param> <param> - <key>nthreads</key> - <value>1</value> + <key>type</key> + <value>complex</value> </param> <param> <key>_coordinate</key> - <value>(57, 605)</value> + <value>(678, 298)</value> </param> <param> <key>_rotation</key> @@ -794,6 +1485,29 @@ </param> </block> <block> + <key>digital_packet_headerparser_b</key> + <param> + <key>id</key> + <value>digital_packet_headerparser_b_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>(915, 495)</value> + </param> + <param> + <key>_rotation</key> + <value>90</value> + </param> + </block> + <block> <key>digital_ofdm_serializer_vcc</key> <param> <key>id</key> @@ -829,7 +1543,7 @@ </param> <param> <key>_coordinate</key> - <value>(649, 305)</value> + <value>(245, 643)</value> </param> <param> <key>_rotation</key> @@ -837,42 +1551,88 @@ </param> </block> <block> - <key>digital_ofdm_serializer_vcc</key> + <key>digital_constellation_decoder_cb</key> <param> <key>id</key> - <value>digital_ofdm_serializer_vcc_1</value> + <value>digital_constellation_decoder_cb_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>fft_len</key> - <value>fft_len</value> + <key>constellation</key> + <value>header_mod.base()</value> </param> <param> - <key>occupied_carriers</key> - <value>occupied_carriers</value> + <key>_coordinate</key> + <value>(461, 681)</value> </param> <param> - <key>len_tag_key</key> - <value>length_tag_key</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>virtual_source</key> <param> - <key>packet_len_tag_key</key> - <value>""</value> + <key>id</key> + <value>virtual_source_0</value> </param> <param> - <key>symbols_skipped</key> - <value>1</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>input_is_shifted</key> + <key>stream_id</key> + <value>Header Stream</value> + </param> + <param> + <key>_coordinate</key> + <value>(0, 543)</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>True</value> + </param> + <param> + <key>window</key> + <value></value> + </param> + <param> + <key>shift</key> + <value>True</value> + </param> + <param> + <key>nthreads</key> + <value>1</value> + </param> + <param> <key>_coordinate</key> - <value>(496, 597)</value> + <value>(213, 513)</value> </param> <param> <key>_rotation</key> @@ -891,15 +1651,15 @@ </param> <param> <key>sync_symbol1</key> - <value>sync_word</value> + <value>sync_word1</value> </param> <param> <key>sync_symbol2</key> - <value>()</value> + <value>sync_word2</value> </param> <param> <key>n_data_symbols</key> - <value>n_sync_symbols</value> + <value>2</value> </param> <param> <key>eq_noise_red_len</key> @@ -915,7 +1675,7 @@ </param> <param> <key>_coordinate</key> - <value>(52, 305)</value> + <value>(427, 505)</value> </param> <param> <key>_rotation</key> @@ -923,169 +1683,181 @@ </param> </block> <block> - <key>digital_header_payload_demux</key> + <key>digital_ofdm_frame_equalizer_vcvc</key> <param> <key>id</key> - <value>digital_header_payload_demux_0</value> + <value>digital_ofdm_frame_equalizer_vcvc_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>header_len</key> - <value>2</value> - </param> - <param> - <key>items_per_symbol</key> + <key>fft_len</key> <value>fft_len</value> </param> <param> - <key>guard_interval</key> - <value>fft_len/4</value> + <key>equalizer</key> + <value>digital.ofdm_equalizer_simpledfe(fft_len, header_mod.base(), occupied_carriers, pilot_carriers, pilot_symbols).base()</value> </param> <param> - <key>length_tag_key</key> + <key>len_tag_key</key> <value>length_tag_name</value> </param> <param> - <key>trigger_tag_key</key> - <value>""</value> - </param> - <param> - <key>output_symbols</key> + <key>propagate_channel_state</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> - </param> - <param> <key>_coordinate</key> - <value>(340, 461)</value> + <value>(704, 520)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </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_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_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_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>digital_ofdm_chanest_vcvc_0</source_block_id> + <sink_block_id>digital_ofdm_frame_equalizer_vcvc_0_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>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_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>gr_throttle_0</sink_block_id> + <source_block_id>digital_ofdm_serializer_vcc_0</source_block_id> + <sink_block_id>digital_constellation_decoder_cb_0_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gr_throttle_0</source_block_id> - <sink_block_id>digital_ofdm_sync_sc_cfb_0</sink_block_id> + <source_block_id>digital_constellation_decoder_cb_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>gr_throttle_0</source_block_id> - <sink_block_id>gr_delay_0</sink_block_id> + <source_block_id>fft_vxx_0_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>gr_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_1</sink_block_id> <source_key>0</source_key> - <sink_key>1</sink_key> + <sink_key>0</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>virtual_source_0_0</source_block_id> + <sink_block_id>fft_vxx_0_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>digital_ofdm_serializer_vcc_1</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>digital_ofdm_sync_sc_cfb_0</source_block_id> - <sink_block_id>digital_header_payload_demux_0</sink_block_id> + <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> - <sink_key>1</sink_key> + <sink_key>0</sink_key> </connection> <connection> - <source_block_id>digital_ofdm_chanest_vcvc_0</source_block_id> - <sink_block_id>digital_ofdm_frame_equalizer_vcvc_0_0</sink_block_id> + <source_block_id>digital_header_payload_demux_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_ofdm_frame_equalizer_vcvc_0_0</source_block_id> - <sink_block_id>digital_ofdm_serializer_vcc_0</sink_block_id> + <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> - <source_block_id>digital_packet_headerparser_b_0</source_block_id> - <sink_block_id>digital_header_payload_demux_0</sink_block_id> + <source_block_id>uhd_usrp_source_0</source_block_id> + <sink_block_id>gr_delay_0</sink_block_id> <source_key>0</source_key> - <sink_key>2</sink_key> + <sink_key>0</sink_key> </connection> <connection> - <source_block_id>digital_header_payload_demux_0</source_block_id> - <sink_block_id>fft_vxx_0</sink_block_id> + <source_block_id>uhd_usrp_source_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> - <source_block_id>digital_header_payload_demux_0</source_block_id> - <sink_block_id>fft_vxx_0_0</sink_block_id> - <source_key>1</source_key> + <source_block_id>blocks_throttle_0</source_block_id> + <sink_block_id>gr_delay_0</sink_block_id> + <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>blocks_multiply_xx_0</source_block_id> - <sink_block_id>digital_header_payload_demux_0</sink_block_id> + <source_block_id>analog_noise_source_x_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_constellation_decoder_cb_0</source_block_id> - <sink_block_id>gr_null_sink_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>digital_ofdm_frame_equalizer_vcvc_0</source_block_id> - <sink_block_id>digital_ofdm_serializer_vcc_1</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>digital_ofdm_serializer_vcc_1</source_block_id> - <sink_block_id>digital_constellation_decoder_cb_0</sink_block_id> + <source_block_id>gr_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>fft_vxx_0_0</source_block_id> - <sink_block_id>digital_ofdm_frame_equalizer_vcvc_0</sink_block_id> + <source_block_id>digital_ofdm_sync_sc_cfb_0</source_block_id> + <sink_block_id>digital_header_payload_demux_0</sink_block_id> + <source_key>1</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <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> diff --git a/gr-digital/examples/ofdm/tx_ofdm.grc b/gr-digital/examples/ofdm/tx_ofdm.grc index 62472ebbce..0ac12900f9 100644 --- a/gr-digital/examples/ofdm/tx_ofdm.grc +++ b/gr-digital/examples/ofdm/tx_ofdm.grc @@ -1,59 +1,81 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Tue Feb 5 14:47:32 2013</timestamp> + <timestamp>Tue May 7 15:13:12 2013</timestamp> <block> - <key>options</key> + <key>virtual_source</key> <param> <key>id</key> - <value>tx_ofdm</value> + <value>virtual_source_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>title</key> - <value>OFDM Tx</value> + <key>stream_id</key> + <value>Payload Bits</value> </param> <param> - <key>author</key> - <value></value> + <key>_coordinate</key> + <value>(0, 458)</value> </param> <param> - <key>description</key> - <value>Example of an OFDM Transmitter</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>virtual_sink</key> <param> - <key>window_size</key> - <value>1280, 1024</value> + <key>id</key> + <value>virtual_sink_0_0_0</value> </param> <param> - <key>generate_options</key> - <value>no_gui</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>category</key> - <value>Custom</value> + <key>stream_id</key> + <value>Frame Symbols</value> </param> <param> - <key>run_options</key> - <value>run</value> + <key>_coordinate</key> + <value>(745, 441)</value> </param> <param> - <key>run</key> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_tagged_stream_mux</key> + <param> + <key>id</key> + <value>blocks_tagged_stream_mux_0</value> + </param> + <param> + <key>_enabled</key> <value>True</value> </param> <param> - <key>max_nouts</key> - <value>0</value> + <key>type</key> + <value>complex</value> </param> <param> - <key>realtime_scheduling</key> - <value></value> + <key>ninputs</key> + <value>2</value> + </param> + <param> + <key>lengthtagname</key> + <value>length_tag_name</value> + </param> + <param> + <key>vlen</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(0, -1)</value> + <value>(510, 428)</value> </param> <param> <key>_rotation</key> @@ -61,22 +83,22 @@ </param> </block> <block> - <key>import</key> + <key>virtual_sink</key> <param> <key>id</key> - <value>import_1</value> + <value>virtual_sink_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>import</key> - <value>from gnuradio.digital.utils import tagged_streams</value> + <key>stream_id</key> + <value>Payload Bits</value> </param> <param> <key>_coordinate</key> - <value>(164, 45)</value> + <value>(746, 312)</value> </param> <param> <key>_rotation</key> @@ -84,22 +106,38 @@ </param> </block> <block> - <key>variable</key> + <key>digital_chunks_to_symbols_xx</key> <param> <key>id</key> - <value>length_tag_name</value> + <value>digital_chunks_to_symbols_xx_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>"packet_len"</value> + <key>in_type</key> + <value>byte</value> + </param> + <param> + <key>out_type</key> + <value>complex</value> + </param> + <param> + <key>symbol_table</key> + <value>header_mod.points()</value> + </param> + <param> + <key>dimension</key> + <value>1</value> + </param> + <param> + <key>num_ports</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(399, 0)</value> + <value>(195, 375)</value> </param> <param> <key>_rotation</key> @@ -107,22 +145,38 @@ </param> </block> <block> - <key>variable</key> + <key>digital_chunks_to_symbols_xx</key> <param> <key>id</key> - <value>pilot_symbols_0</value> + <value>digital_chunks_to_symbols_xx_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>((100,),)</value> + <key>in_type</key> + <value>byte</value> + </param> + <param> + <key>out_type</key> + <value>complex</value> + </param> + <param> + <key>symbol_table</key> + <value>payload_mod.points()</value> + </param> + <param> + <key>dimension</key> + <value>1</value> + </param> + <param> + <key>num_ports</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(735, 63)</value> + <value>(195, 450)</value> </param> <param> <key>_rotation</key> @@ -130,22 +184,22 @@ </param> </block> <block> - <key>variable</key> + <key>virtual_source</key> <param> <key>id</key> - <value>occupied_carriers</value> + <value>virtual_source_0</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>stream_id</key> + <value>Header Bits</value> </param> <param> <key>_coordinate</key> - <value>(377, 63)</value> + <value>(0, 384)</value> </param> <param> <key>_rotation</key> @@ -153,22 +207,22 @@ </param> </block> <block> - <key>variable</key> + <key>digital_packet_headergenerator_bb</key> <param> <key>id</key> - <value>pilot_symbols</value> + <value>digital_packet_headergenerator_bb_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>((100,),)</value> + <key>header_formatter</key> + <value>header_formatter.formatter()</value> </param> <param> <key>_coordinate</key> - <value>(632, 63)</value> + <value>(514, 231)</value> </param> <param> <key>_rotation</key> @@ -176,22 +230,34 @@ </param> </block> <block> - <key>variable</key> + <key>blocks_repack_bits_bb</key> <param> <key>id</key> - <value>pilot_carriers</value> + <value>blocks_repack_bits_bb_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>((0,),)</value> + <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> </param> <param> <key>_coordinate</key> - <value>(530, 63)</value> + <value>(522, 289)</value> </param> <param> <key>_rotation</key> @@ -199,22 +265,22 @@ </param> </block> <block> - <key>variable</key> + <key>virtual_sink</key> <param> <key>id</key> - <value>fft_len</value> + <value>header_bits</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>64</value> + <key>stream_id</key> + <value>Header Bits</value> </param> <param> <key>_coordinate</key> - <value>(311, 63)</value> + <value>(748, 231)</value> </param> <param> <key>_rotation</key> @@ -222,22 +288,26 @@ </param> </block> <block> - <key>variable</key> + <key>digital_crc32_bb</key> <param> <key>id</key> - <value>header_mod</value> + <value>digital_crc32_bb_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>digital.constellation_bpsk()</value> + <key>check</key> + <value>False</value> + </param> + <param> + <key>lengthtagname</key> + <value>length_tag_name</value> </param> <param> <key>_coordinate</key> - <value>(620, 0)</value> + <value>(242, 223)</value> </param> <param> <key>_rotation</key> @@ -245,22 +315,38 @@ </param> </block> <block> - <key>variable</key> + <key>blocks_vector_source_x</key> <param> <key>id</key> - <value>payload_mod</value> + <value>blocks_vector_source_x_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>digital.constellation_qpsk()</value> + <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> + </param> + <param> + <key>vlen</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(783, 0)</value> + <value>(0, 216)</value> </param> <param> <key>_rotation</key> @@ -268,30 +354,45 @@ </param> </block> <block> - <key>gr_throttle</key> + <key>variable</key> <param> <key>id</key> - <value>gr_throttle_0</value> + <value>fft_len</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>byte</value> + <key>value</key> + <value>64</value> </param> <param> - <key>samples_per_second</key> - <value>bit_rate/8</value> + <key>_coordinate</key> + <value>(181, -1)</value> </param> <param> - <key>vlen</key> - <value>1</value> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>length_tag_name</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>"packet_len"</value> </param> <param> <key>_coordinate</key> - <value>(234, 167)</value> + <value>(352, 0)</value> </param> <param> <key>_rotation</key> @@ -299,22 +400,22 @@ </param> </block> <block> - <key>import</key> + <key>variable</key> <param> <key>id</key> - <value>import_0</value> + <value>packet_len</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>import</key> - <value>import numpy</value> + <key>value</key> + <value>96</value> </param> <param> <key>_coordinate</key> - <value>(164, 0)</value> + <value>(476, 0)</value> </param> <param> <key>_rotation</key> @@ -322,22 +423,22 @@ </param> </block> <block> - <key>import</key> + <key>variable</key> <param> <key>id</key> - <value>import_0_0</value> + <value>header_mod</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>import</key> - <value>import random</value> + <key>value</key> + <value>digital.constellation_bpsk()</value> </param> <param> <key>_coordinate</key> - <value>(-1, 90)</value> + <value>(567, 0)</value> </param> <param> <key>_rotation</key> @@ -348,7 +449,7 @@ <key>variable</key> <param> <key>id</key> - <value>sync_word</value> + <value>payload_mod</value> </param> <param> <key>_enabled</key> @@ -356,11 +457,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>digital.constellation_qpsk()</value> </param> <param> <key>_coordinate</key> - <value>(95, 90)</value> + <value>(734, 0)</value> </param> <param> <key>_rotation</key> @@ -383,7 +484,7 @@ </param> <param> <key>_coordinate</key> - <value>(234, 91)</value> + <value>(898, -1)</value> </param> <param> <key>_rotation</key> @@ -391,22 +492,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</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>Frame Symbols</value> </param> <param> <key>_coordinate</key> - <value>(849, 63)</value> + <value>(1, 654)</value> </param> <param> <key>_rotation</key> @@ -414,38 +515,38 @@ </param> </block> <block> - <key>gr_vector_source_x</key> + <key>digital_ofdm_carrier_allocator_cvc</key> <param> <key>id</key> - <value>gr_vector_source_x_1</value> + <value>digital_ofdm_carrier_allocator_cvc_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>byte</value> + <key>fft_len</key> + <value>fft_len</value> </param> <param> - <key>vector</key> - <value>range(packet_len)</value> + <key>occupied_carriers</key> + <value>occupied_carriers</value> </param> <param> - <key>tags</key> - <value>tagged_streams.make_lengthtags((packet_len,), (0,), length_tag_name)</value> + <key>pilot_carriers</key> + <value>pilot_carriers</value> </param> <param> - <key>repeat</key> - <value>True</value> + <key>pilot_symbols</key> + <value>pilot_symbols</value> </param> <param> - <key>vlen</key> - <value>1</value> + <key>len_tag_key</key> + <value>length_tag_name</value> </param> <param> <key>_coordinate</key> - <value>(-1, 152)</value> + <value>(205, 624)</value> </param> <param> <key>_rotation</key> @@ -453,22 +554,34 @@ </param> </block> <block> - <key>variable</key> + <key>blocks_tagged_stream_mux</key> <param> <key>id</key> - <value>packet_len</value> + <value>blocks_tagged_stream_mux_1</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>96</value> + <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>fft_len</value> </param> <param> <key>_coordinate</key> - <value>(528, 0)</value> + <value>(445, 600)</value> </param> <param> <key>_rotation</key> @@ -476,22 +589,42 @@ </param> </block> <block> - <key>digital_packet_headergenerator_bb</key> + <key>fft_vxx</key> <param> <key>id</key> - <value>digital_packet_headergenerator_bb_0</value> + <value>fft_vxx_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>header_formatter</key> - <value>header_formatter.formatter()</value> + <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>False</value> + </param> + <param> + <key>nthreads</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(761, 167)</value> + <value>(684, 583)</value> </param> <param> <key>_rotation</key> @@ -502,7 +635,7 @@ <key>variable</key> <param> <key>id</key> - <value>bit_rate</value> + <value>samp_rate</value> </param> <param> <key>_enabled</key> @@ -510,11 +643,11 @@ </param> <param> <key>value</key> - <value>3200000</value> + <value>100000</value> </param> <param> <key>_coordinate</key> - <value>(311, 0)</value> + <value>(255, 0)</value> </param> <param> <key>_rotation</key> @@ -522,123 +655,704 @@ </param> </block> <block> - <key>blocks_repack_bits_bb</key> + <key>uhd_usrp_sink</key> <param> <key>id</key> - <value>blocks_repack_bits_bb_0</value> + <value>uhd_usrp_sink_0</value> </param> <param> <key>_enabled</key> - <value>True</value> + <value>False</value> </param> <param> - <key>k</key> - <value>8</value> + <key>type</key> + <value>fc32</value> </param> <param> - <key>l</key> - <value>payload_mod.bits_per_symbol()</value> + <key>otw</key> + <value></value> </param> <param> - <key>len_tag_key</key> - <value>length_tag_name</value> + <key>stream_args</key> + <value></value> </param> <param> - <key>align_output</key> - <value>False</value> + <key>dev_addr</key> + <value></value> </param> <param> - <key>_coordinate</key> - <value>(516, 228)</value> + <key>sync</key> + <value></value> </param> <param> - <key>_rotation</key> - <value>180</value> + <key>clock_rate</key> + <value>0.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> + <key>num_mboards</key> + <value>1</value> </param> <param> - <key>_enabled</key> - <value>True</value> + <key>clock_source0</key> + <value></value> </param> <param> - <key>in_type</key> - <value>byte</value> + <key>time_source0</key> + <value></value> </param> <param> - <key>out_type</key> - <value>complex</value> + <key>sd_spec0</key> + <value></value> </param> <param> - <key>symbol_table</key> - <value>payload_mod.points()</value> + <key>clock_source1</key> + <value></value> </param> <param> - <key>dimension</key> - <value>1</value> + <key>time_source1</key> + <value></value> </param> <param> - <key>num_ports</key> + <key>sd_spec1</key> + <value></value> + </param> + <param> + <key>clock_source2</key> + <value></value> + </param> + <param> + <key>time_source2</key> + <value></value> + </param> + <param> + <key>sd_spec2</key> + <value></value> + </param> + <param> + <key>clock_source3</key> + <value></value> + </param> + <param> + <key>time_source3</key> + <value></value> + </param> + <param> + <key>sd_spec3</key> + <value></value> + </param> + <param> + <key>clock_source4</key> + <value></value> + </param> + <param> + <key>time_source4</key> + <value></value> + </param> + <param> + <key>sd_spec4</key> + <value></value> + </param> + <param> + <key>clock_source5</key> + <value></value> + </param> + <param> + <key>time_source5</key> + <value></value> + </param> + <param> + <key>sd_spec5</key> + <value></value> + </param> + <param> + <key>clock_source6</key> + <value></value> + </param> + <param> + <key>time_source6</key> + <value></value> + </param> + <param> + <key>sd_spec6</key> + <value></value> + </param> + <param> + <key>clock_source7</key> + <value></value> + </param> + <param> + <key>time_source7</key> + <value></value> + </param> + <param> + <key>sd_spec7</key> + <value></value> + </param> + <param> + <key>nchan</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> + </param> + <param> + <key>ant0</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> + <value>0</value> + </param> + <param> + <key>ant1</key> + <value></value> + </param> + <param> + <key>bw1</key> + <value>0</value> + </param> + <param> + <key>center_freq2</key> + <value>0</value> + </param> + <param> + <key>gain2</key> + <value>0</value> + </param> + <param> + <key>ant2</key> + <value></value> + </param> + <param> + <key>bw2</key> + <value>0</value> + </param> + <param> + <key>center_freq3</key> + <value>0</value> + </param> + <param> + <key>gain3</key> + <value>0</value> + </param> + <param> + <key>ant3</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> + <value>0</value> + </param> + <param> + <key>ant4</key> + <value></value> + </param> + <param> + <key>bw4</key> + <value>0</value> + </param> + <param> + <key>center_freq5</key> + <value>0</value> + </param> + <param> + <key>gain5</key> + <value>0</value> + </param> + <param> + <key>ant5</key> + <value></value> + </param> + <param> + <key>bw5</key> + <value>0</value> + </param> + <param> + <key>center_freq6</key> + <value>0</value> + </param> + <param> + <key>gain6</key> + <value>0</value> + </param> + <param> + <key>ant6</key> + <value></value> + </param> + <param> + <key>bw6</key> + <value>0</value> + </param> + <param> + <key>center_freq7</key> + <value>0</value> + </param> + <param> + <key>gain7</key> + <value>0</value> + </param> + <param> + <key>ant7</key> + <value></value> + </param> + <param> + <key>bw7</key> + <value>0</value> + </param> + <param> + <key>center_freq8</key> + <value>0</value> + </param> + <param> + <key>gain8</key> + <value>0</value> + </param> + <param> + <key>ant8</key> + <value></value> + </param> + <param> + <key>bw8</key> + <value>0</value> + </param> + <param> + <key>center_freq9</key> + <value>0</value> + </param> + <param> + <key>gain9</key> + <value>0</value> + </param> + <param> + <key>ant9</key> + <value></value> + </param> + <param> + <key>bw9</key> + <value>0</value> + </param> + <param> + <key>center_freq10</key> + <value>0</value> + </param> + <param> + <key>gain10</key> + <value>0</value> + </param> + <param> + <key>ant10</key> + <value></value> + </param> + <param> + <key>bw10</key> + <value>0</value> + </param> + <param> + <key>center_freq11</key> + <value>0</value> + </param> + <param> + <key>gain11</key> + <value>0</value> + </param> + <param> + <key>ant11</key> + <value></value> + </param> + <param> + <key>bw11</key> + <value>0</value> + </param> + <param> + <key>center_freq12</key> + <value>0</value> + </param> + <param> + <key>gain12</key> + <value>0</value> + </param> + <param> + <key>ant12</key> + <value></value> + </param> + <param> + <key>bw12</key> + <value>0</value> + </param> + <param> + <key>center_freq13</key> + <value>0</value> + </param> + <param> + <key>gain13</key> + <value>0</value> + </param> + <param> + <key>ant13</key> + <value></value> + </param> + <param> + <key>bw13</key> + <value>0</value> + </param> + <param> + <key>center_freq14</key> + <value>0</value> + </param> + <param> + <key>gain14</key> + <value>0</value> + </param> + <param> + <key>ant14</key> + <value></value> + </param> + <param> + <key>bw14</key> + <value>0</value> + </param> + <param> + <key>center_freq15</key> + <value>0</value> + </param> + <param> + <key>gain15</key> + <value>0</value> + </param> + <param> + <key>ant15</key> + <value></value> + </param> + <param> + <key>bw15</key> + <value>0</value> + </param> + <param> + <key>center_freq16</key> + <value>0</value> + </param> + <param> + <key>gain16</key> + <value>0</value> + </param> + <param> + <key>ant16</key> + <value></value> + </param> + <param> + <key>bw16</key> + <value>0</value> + </param> + <param> + <key>center_freq17</key> + <value>0</value> + </param> + <param> + <key>gain17</key> + <value>0</value> + </param> + <param> + <key>ant17</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> + <value>0</value> + </param> + <param> + <key>ant18</key> + <value></value> + </param> + <param> + <key>bw18</key> + <value>0</value> + </param> + <param> + <key>center_freq19</key> + <value>0</value> + </param> + <param> + <key>gain19</key> + <value>0</value> + </param> + <param> + <key>ant19</key> + <value></value> + </param> + <param> + <key>bw19</key> + <value>0</value> + </param> + <param> + <key>center_freq20</key> + <value>0</value> + </param> + <param> + <key>gain20</key> + <value>0</value> + </param> + <param> + <key>ant20</key> + <value></value> + </param> + <param> + <key>bw20</key> + <value>0</value> + </param> + <param> + <key>center_freq21</key> + <value>0</value> + </param> + <param> + <key>gain21</key> + <value>0</value> + </param> + <param> + <key>ant21</key> + <value></value> + </param> + <param> + <key>bw21</key> + <value>0</value> + </param> + <param> + <key>center_freq22</key> + <value>0</value> + </param> + <param> + <key>gain22</key> + <value>0</value> + </param> + <param> + <key>ant22</key> + <value></value> + </param> + <param> + <key>bw22</key> + <value>0</value> + </param> + <param> + <key>center_freq23</key> + <value>0</value> + </param> + <param> + <key>gain23</key> + <value>0</value> + </param> + <param> + <key>ant23</key> + <value></value> + </param> + <param> + <key>bw23</key> + <value>0</value> + </param> + <param> + <key>center_freq24</key> + <value>0</value> + </param> + <param> + <key>gain24</key> + <value>0</value> + </param> + <param> + <key>ant24</key> + <value></value> + </param> + <param> + <key>bw24</key> + <value>0</value> + </param> + <param> + <key>center_freq25</key> + <value>0</value> + </param> + <param> + <key>gain25</key> + <value>0</value> + </param> + <param> + <key>ant25</key> + <value></value> + </param> + <param> + <key>bw25</key> + <value>0</value> + </param> + <param> + <key>center_freq26</key> + <value>0</value> + </param> + <param> + <key>gain26</key> + <value>0</value> + </param> + <param> + <key>ant26</key> + <value></value> + </param> + <param> + <key>bw26</key> + <value>0</value> + </param> + <param> + <key>center_freq27</key> + <value>0</value> + </param> + <param> + <key>gain27</key> + <value>0</value> + </param> + <param> + <key>ant27</key> + <value></value> + </param> + <param> + <key>bw27</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> + </param> + <param> + <key>bw28</key> + <value>0</value> + </param> + <param> + <key>center_freq29</key> + <value>0</value> + </param> + <param> + <key>gain29</key> + <value>0</value> + </param> + <param> + <key>ant29</key> + <value></value> + </param> + <param> + <key>bw29</key> + <value>0</value> + </param> + <param> + <key>center_freq30</key> + <value>0</value> + </param> + <param> + <key>gain30</key> + <value>0</value> + </param> + <param> + <key>ant30</key> + <value></value> + </param> + <param> + <key>bw30</key> + <value>0</value> + </param> + <param> + <key>center_freq31</key> + <value>0</value> + </param> + <param> + <key>gain31</key> + <value>0</value> + </param> + <param> + <key>ant31</key> + <value></value> + </param> + <param> + <key>bw31</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> - <value>(279, 243)</value> + <value>(578, 746)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>digital_chunks_to_symbols_xx</key> + <key>blocks_throttle</key> <param> <key>id</key> - <value>digital_chunks_to_symbols_xx_0</value> + <value>blocks_throttle_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>in_type</key> - <value>byte</value> - </param> - <param> - <key>out_type</key> + <key>type</key> <value>complex</value> </param> <param> - <key>symbol_table</key> - <value>header_mod.points()</value> - </param> - <param> - <key>dimension</key> - <value>1</value> + <key>samples_per_second</key> + <value>samp_rate</value> </param> <param> - <key>num_ports</key> + <key>vlen</key> <value>1</value> </param> <param> <key>_coordinate</key> - <value>(319, 305)</value> + <value>(579, 823)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>blocks_tagged_stream_mux</key> + <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>blocks_tagged_stream_mux_0</value> + <value>wxgui_scopesink2_0</value> </param> <param> <key>_enabled</key> @@ -649,59 +1363,151 @@ <value>complex</value> </param> <param> - <key>ninputs</key> - <value>2</value> + <key>title</key> + <value>Scope Plot</value> </param> <param> - <key>lengthtagname</key> - <value>length_tag_name</value> + <key>samp_rate</key> + <value>samp_rate</value> </param> <param> - <key>vlen</key> + <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> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> <value>1</value> </param> <param> + <key>win_size</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>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> <key>_coordinate</key> - <value>(44, 254)</value> + <value>(761, 800)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>digital_ofdm_carrier_allocator_cvc</key> + <key>wxgui_fftsink2</key> <param> <key>id</key> - <value>digital_ofdm_carrier_allocator_cvc_0</value> + <value>wxgui_fftsink2_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>fft_len</key> - <value>fft_len</value> + <key>type</key> + <value>complex</value> </param> <param> - <key>occupied_carriers</key> - <value>occupied_carriers</value> + <key>title</key> + <value>FFT Plot</value> </param> <param> - <key>pilot_carriers</key> - <value>pilot_carriers</value> + <key>samp_rate</key> + <value>samp_rate</value> </param> <param> - <key>pilot_symbols</key> - <value>pilot_symbols</value> + <key>baseband_freq</key> + <value>0</value> </param> <param> - <key>len_tag_key</key> - <value>length_tag_name</value> + <key>y_per_div</key> + <value>10</value> + </param> + <param> + <key>y_divs</key> + <value>10</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>ref_scale</key> + <value>2.0</value> + </param> + <param> + <key>fft_size</key> + <value>1024</value> + </param> + <param> + <key>fft_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> + <value>False</value> + </param> + <param> + <key>avg_alpha</key> + <value>0</value> + </param> + <param> + <key>win</key> + <value>None</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>freqvar</key> + <value>None</value> </param> <param> <key>_coordinate</key> - <value>(56, 453)</value> + <value>(579, 867)</value> </param> <param> <key>_rotation</key> @@ -709,10 +1515,10 @@ </param> </block> <block> - <key>gr_vector_source_x</key> + <key>blocks_multiply_const_vxx</key> <param> <key>id</key> - <value>sync_word_source</value> + <value>blocks_multiply_const_vxx_0</value> </param> <param> <key>_enabled</key> @@ -723,24 +1529,16 @@ <value>complex</value> </param> <param> - <key>vector</key> - <value>numpy.array(sync_word) * numpy.sqrt(2)</value> - </param> - <param> - <key>tags</key> - <value>tagged_streams.make_lengthtags((len(sync_word)/fft_len,), (0,), length_tag_name)</value> - </param> - <param> - <key>repeat</key> - <value>True</value> + <key>const</key> + <value>0.05</value> </param> <param> <key>vlen</key> - <value>fft_len</value> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(56, 356)</value> + <value>(386, 823)</value> </param> <param> <key>_rotation</key> @@ -748,10 +1546,10 @@ </param> </block> <block> - <key>blocks_tagged_stream_mux</key> + <key>blocks_vector_source_x</key> <param> <key>id</key> - <value>blocks_tagged_stream_mux_1</value> + <value>blocks_vector_source_x_1</value> </param> <param> <key>_enabled</key> @@ -762,12 +1560,16 @@ <value>complex</value> </param> <param> - <key>ninputs</key> - <value>2</value> + <key>vector</key> + <value>tuple(numpy.array(sync_word1) * numpy.sqrt(2)) + sync_word2</value> </param> <param> - <key>lengthtagname</key> - <value>length_tag_name</value> + <key>tags</key> + <value>tagged_streams.make_lengthtags((2,), (0,), length_tag_name)</value> + </param> + <param> + <key>repeat</key> + <value>True</value> </param> <param> <key>vlen</key> @@ -775,7 +1577,7 @@ </param> <param> <key>_coordinate</key> - <value>(374, 382)</value> + <value>(1, 532)</value> </param> <param> <key>_rotation</key> @@ -783,46 +1585,62 @@ </param> </block> <block> - <key>fft_vxx</key> + <key>options</key> <param> <key>id</key> - <value>fft_vxx_0</value> + <value>tx_ofdm</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> + <key>title</key> + <value>OFDM Tx</value> </param> <param> - <key>fft_size</key> - <value>fft_len</value> + <key>author</key> + <value></value> </param> <param> - <key>forward</key> - <value>False</value> + <key>description</key> + <value>Example of an OFDM Transmitter</value> </param> <param> - <key>window</key> - <value></value> + <key>window_size</key> + <value>1280, 1024</value> </param> <param> - <key>shift</key> - <value>False</value> + <key>generate_options</key> + <value>wx_gui</value> </param> <param> - <key>nthreads</key> - <value>1</value> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>run</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> </param> <param> <key>_coordinate</key> - <value>(765, 498)</value> + <value>(0, -1)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> @@ -853,152 +1671,168 @@ </param> <param> <key>_coordinate</key> - <value>(488, 505)</value> + <value>(86, 800)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>wxgui_fftsink2</key> + <key>variable</key> <param> <key>id</key> - <value>wxgui_fftsink2_0</value> + <value>sync_word2</value> </param> <param> <key>_enabled</key> - <value>False</value> + <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> + <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> </param> <param> - <key>title</key> - <value>FFT Plot</value> + <key>_coordinate</key> + <value>(496, 128)</value> </param> <param> - <key>samp_rate</key> - <value>1.0</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>variable</key> <param> - <key>baseband_freq</key> - <value>0</value> + <key>id</key> + <value>sync_word1</value> </param> <param> - <key>y_per_div</key> - <value>10</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>y_divs</key> - <value>10</value> + <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> </param> <param> - <key>ref_level</key> - <value>50</value> + <key>_coordinate</key> + <value>(352, 128)</value> </param> <param> - <key>ref_scale</key> - <value>2.0</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>variable</key> <param> - <key>fft_size</key> - <value>1024</value> + <key>id</key> + <value>occupied_carriers</value> </param> <param> - <key>fft_rate</key> - <value>15</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>peak_hold</key> - <value>False</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>average</key> - <value>False</value> + <key>_coordinate</key> + <value>(329, 64)</value> </param> <param> - <key>avg_alpha</key> + <key>_rotation</key> <value>0</value> </param> + </block> + <block> + <key>variable</key> <param> - <key>win</key> - <value>None</value> + <key>id</key> + <value>pilot_carriers</value> </param> <param> - <key>win_size</key> - <value></value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>grid_pos</key> - <value></value> + <key>value</key> + <value>((-21, -7, 7, 21,),)</value> </param> <param> - <key>notebook</key> - <value></value> + <key>_coordinate</key> + <value>(480, 64)</value> </param> <param> - <key>freqvar</key> - <value>None</value> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>header_formatter</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> </param> <param> <key>_coordinate</key> - <value>(291, 460)</value> + <value>(708, 64)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>gr_null_sink</key> + <key>variable</key> <param> <key>id</key> - <value>gr_null_sink_0</value> + <value>pilot_symbols</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>vlen</key> - <value>1</value> + <key>value</key> + <value>((1, 1, 1, -1,),)</value> </param> <param> <key>_coordinate</key> - <value>(438, 633)</value> + <value>(601, 64)</value> </param> <param> <key>_rotation</key> - <value>180</value> + <value>0</value> </param> </block> <block> - <key>digital_crc32_bb</key> + <key>import</key> <param> <key>id</key> - <value>digital_crc32_bb_0</value> + <value>import_0</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>import</key> + <value>import numpy</value> </param> <param> <key>_coordinate</key> - <value>(472, 159)</value> + <value>(237, 93)</value> </param> <param> <key>_rotation</key> @@ -1006,38 +1840,45 @@ </param> </block> <block> - <key>gr_tag_debug</key> + <key>import</key> <param> <key>id</key> - <value>gr_tag_debug_0</value> + <value>import_1</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>byte</value> + <key>import</key> + <value>from gnuradio.digital.utils import tagged_streams</value> </param> <param> - <key>name</key> - <value>tdb</value> + <key>_coordinate</key> + <value>(99, 93)</value> </param> <param> - <key>num_inputs</key> - <value>1</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>import</key> <param> - <key>vlen</key> - <value>1</value> + <key>id</key> + <value>import_0_0</value> </param> <param> - <key>display</key> - <value>False</value> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>import</key> + <value>import random</value> </param> <param> <key>_coordinate</key> - <value>(819, 232)</value> + <value>(3, 94)</value> </param> <param> <key>_rotation</key> @@ -1045,56 +1886,50 @@ </param> </block> <connection> - <source_block_id>gr_vector_source_x_1</source_block_id> - <sink_block_id>gr_throttle_0</sink_block_id> + <source_block_id>blocks_tagged_stream_mux_0</source_block_id> + <sink_block_id>virtual_sink_0_0_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gr_throttle_0</source_block_id> - <sink_block_id>digital_crc32_bb_0</sink_block_id> + <source_block_id>virtual_source_0_0</source_block_id> + <sink_block_id>digital_chunks_to_symbols_xx_0_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>digital_packet_headergenerator_bb_0</sink_block_id> + <source_block_id>virtual_source_0</source_block_id> + <sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>blocks_tagged_stream_mux_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>digital_packet_headergenerator_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>blocks_tagged_stream_mux_1</sink_block_id> - <source_key>0</source_key> - <sink_key>1</sink_key> - </connection> - <connection> - <source_block_id>sync_word_source</source_block_id> - <sink_block_id>blocks_tagged_stream_mux_1</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_packet_headergenerator_bb_0</source_block_id> - <sink_block_id>digital_chunks_to_symbols_xx_0</sink_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>blocks_repack_bits_bb_0</source_block_id> - <sink_block_id>digital_chunks_to_symbols_xx_0_0</sink_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_chunks_to_symbols_xx_0</source_block_id> - <sink_block_id>blocks_tagged_stream_mux_0</sink_block_id> + <source_block_id>blocks_vector_source_x_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> @@ -1105,20 +1940,32 @@ <sink_key>1</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>digital_chunks_to_symbols_xx_0</source_block_id> + <sink_block_id>blocks_tagged_stream_mux_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> <connection> - <source_block_id>blocks_tagged_stream_mux_1</source_block_id> - <sink_block_id>fft_vxx_0</sink_block_id> + <source_block_id>blocks_multiply_const_vxx_0</source_block_id> + <sink_block_id>uhd_usrp_sink_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>wxgui_fftsink2_0</sink_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_ofdm_carrier_allocator_cvc_0</source_block_id> + <sink_block_id>blocks_tagged_stream_mux_1</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>blocks_tagged_stream_mux_1</source_block_id> + <sink_block_id>fft_vxx_0</sink_block_id> <source_key>0</source_key> <sink_key>0</sink_key> </connection> @@ -1129,14 +1976,32 @@ <sink_key>0</sink_key> </connection> <connection> - <source_block_id>digital_ofdm_cyclic_prefixer_0</source_block_id> - <sink_block_id>gr_null_sink_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_crc32_bb_0</source_block_id> - <sink_block_id>gr_tag_debug_0</sink_block_id> + <source_block_id>blocks_vector_source_x_1</source_block_id> + <sink_block_id>blocks_tagged_stream_mux_1</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_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>blocks_throttle_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_scopesink2_0</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 46658b7065..32b1fa9427 100644 --- a/gr-digital/grc/digital_block_tree.xml +++ b/gr-digital/grc/digital_block_tree.xml @@ -86,10 +86,12 @@ <block>digital_ofdm_frame_acquisition</block> <block>digital_ofdm_frame_equalizer_vcvc</block> <block>digital_ofdm_insert_preamble</block> + <block>digital_ofdm_rx</block> <block>digital_ofdm_sampler</block> <block>digital_ofdm_serializer_vcc</block> <block>digital_ofdm_sync_pn</block> <block>digital_ofdm_sync_sc_cfb</block> + <block>digital_ofdm_tx</block> </cat> <cat> <name>Symbol Coding</name> diff --git a/gr-digital/grc/digital_header_payload_demux.xml b/gr-digital/grc/digital_header_payload_demux.xml index b29d86435b..f5be5dc6e2 100644 --- a/gr-digital/grc/digital_header_payload_demux.xml +++ b/gr-digital/grc/digital_header_payload_demux.xml @@ -1,5 +1,5 @@ <block> - <name>Header payload demux</name> + <name>Header/Payload Demux</name> <key>digital_header_payload_demux</key> <import>from gnuradio import digital</import> <make>digital.header_payload_demux($header_len, $items_per_symbol, $guard_interval, $length_tag_key, $trigger_tag_key, $output_symbols, $(type.itemsize))</make> diff --git a/gr-digital/grc/digital_ofdm_chanest_vcvc.xml b/gr-digital/grc/digital_ofdm_chanest_vcvc.xml index e8b1571eb6..ea9855fdb6 100644 --- a/gr-digital/grc/digital_ofdm_chanest_vcvc.xml +++ b/gr-digital/grc/digital_ofdm_chanest_vcvc.xml @@ -1,6 +1,6 @@ <?xml version="1.0"?> <block> - <name>OFDM channel & coarse frequency offset estimation</name> + <name>OFDM Channel Estimation</name> <key>digital_ofdm_chanest_vcvc</key> <import>from gnuradio import digital</import> <make>digital.ofdm_chanest_vcvc($sync_symbol1, $sync_symbol2, $n_data_symbols, $eq_noise_red_len, $max_carr_offset, $force_one_symbol)</make> diff --git a/gr-digital/grc/digital_ofdm_rx.xml b/gr-digital/grc/digital_ofdm_rx.xml new file mode 100644 index 0000000000..38222265a7 --- /dev/null +++ b/gr-digital/grc/digital_ofdm_rx.xml @@ -0,0 +1,174 @@ +<?xml version="1.0"?> +<block> + <name>OFDM Receiver</name> + <key>digital_ofdm_rx</key> + <import>from gnuradio import digital</import> + <make>digital.ofdm_rx( + fft_len=$fft_len, cp_len=$cp_len, + frame_length_tag_key='frame_'+$packet_len_key, + packet_length_tag_key=$packet_len_key, + #if $occupied_carriers() + occupied_carriers=$occupied_carriers, + #end if + #if $occupied_carriers() + pilot_carriers=$pilot_carriers, + #end if + #if $occupied_carriers() + pilot_symbols=$pilot_symbols, + #end if + #if $sync_word1() + sync_word1=$sync_word1, + #end if + #if $sync_word2() + sync_word2=$sync_word2, + #end if + bps_header=$header_mod.bps, + bps_payload=$payload_mod.bps, + debug_log=$log + )</make> + <param> + <name>FFT Length</name> + <key>fft_len</key> + <value>64</value> + <type>int</type> + </param> + <param> + <name>Cyclic Prefix Length</name> + <key>cp_len</key> + <value>16</value> + <type>int</type> + </param> + <param> + <name>Packet Length Tag Key</name> + <key>packet_len_key</key> + <value>"length"</value> + <type>string</type> + </param> + <param> + <name>Occupied Carriers</name> + <key>occupied_carriers</key> + <value>()</value> + <type>raw</type> + <hide> + #if $occupied_carriers() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Pilot Carriers</name> + <key>pilot_carriers</key> + <value>()</value> + <type>raw</type> + <hide> + #if $pilot_carriers() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Pilot Symbols</name> + <key>pilot_symbols</key> + <value>()</value> + <type>raw</type> + <hide> + #if $pilot_symbols() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Sync Word 1</name> + <key>sync_word1</key> + <value>()</value> + <type>raw</type> + <hide> + #if $sync_word1() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Sync Word 2</name> + <key>sync_word2</key> + <value>()</value> + <type>raw</type> + <hide> + #if $sync_word2() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Header Modulation</name> + <key>header_mod</key> + <type>enum</type> + <option> + <name>BPSK</name> + <key>"BPSK"</key> + <opt>bps:1</opt> + </option> + <option> + <name>QPSK</name> + <key>"QPSK"</key> + <opt>bps:2</opt> + </option> + </param> + <param> + <name>Payload Modulation</name> + <key>payload_mod</key> + <type>enum</type> + <option> + <name>BPSK</name> + <key>"BPSK"</key> + <opt>bps:1</opt> + </option> + <option> + <name>QPSK</name> + <key>"QPSK"</key> + <opt>bps:2</opt> + </option> + <option> + <name>8-PSK</name> + <key>"8-PSK"</key> + <opt>bps:3</opt> + </option> + </param> + <param> + <name>Log Debug Info</name> + <key>log</key> + <value>False</value> + <type>enum</type> + <hide> #if $log then 'none' else 'part'#</hide> + <option> + <name>No</name> + <key>False</key> + </option> + <option> + <name>Yes</name> + <key>True</key> + </option> + </param> + <check>$fft_len > 0</check> + <check>$cp_len > 0</check> + <check>$cp_len < $fft_len</check> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> + diff --git a/gr-digital/grc/digital_ofdm_sync_sc_cfb.xml b/gr-digital/grc/digital_ofdm_sync_sc_cfb.xml index 7865d248d5..4705c1027a 100644 --- a/gr-digital/grc/digital_ofdm_sync_sc_cfb.xml +++ b/gr-digital/grc/digital_ofdm_sync_sc_cfb.xml @@ -3,7 +3,7 @@ <name>Schmidl & Cox OFDM synchronisation</name> <key>digital_ofdm_sync_sc_cfb</key> <import>from gnuradio import digital</import> - <make>digital.ofdm_sync_sc_cfb($fft_len, $cp_len)</make> + <make>digital.ofdm_sync_sc_cfb($fft_len, $cp_len, $use_even_carriers)</make> <param> <name>FFT length</name> <key>fft_len</key> @@ -14,6 +14,21 @@ <key>cp_len</key> <type>int</type> </param> + <param> + <name>Preamble Carriers</name> + <key>use_even_carriers</key> + <value>False</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>Odd</name> + <key>False</key> + </option> + <option> + <name>Even</name> + <key>True</key> + </option> + </param> <sink> <name>in</name> <type>complex</type> diff --git a/gr-digital/grc/digital_ofdm_tx.xml b/gr-digital/grc/digital_ofdm_tx.xml new file mode 100644 index 0000000000..034d34a2a5 --- /dev/null +++ b/gr-digital/grc/digital_ofdm_tx.xml @@ -0,0 +1,180 @@ +<?xml version="1.0"?> +<block> + <name>OFDM Transmitter</name> + <key>digital_ofdm_tx</key> + <import>from gnuradio import digital</import> + <make>digital.ofdm_tx( + fft_len=$fft_len, cp_len=$cp_len, + packet_length_tag_key=$packet_len_key, + #if $occupied_carriers() + occupied_carriers=$occupied_carriers, + #end if + #if $occupied_carriers() + pilot_carriers=$pilot_carriers, + #end if + #if $occupied_carriers() + pilot_symbols=$pilot_symbols, + #end if + #if $sync_word1() + sync_word1=$sync_word1, + #end if + #if $sync_word2() + sync_word2=$sync_word2, + #end if + bps_header=$header_mod.bps, + bps_payload=$payload_mod.bps, + rolloff=$rolloff, + debug_log=$log + )</make> + <param> + <name>FFT Length</name> + <key>fft_len</key> + <value>64</value> + <type>int</type> + </param> + <param> + <name>Cyclic Prefix Length</name> + <key>cp_len</key> + <value>16</value> + <type>int</type> + </param> + <param> + <name>Length Tag Name</name> + <key>packet_len_key</key> + <value>length</value> + <type>string</type> + </param> + <param> + <name>Occupied Carriers</name> + <key>occupied_carriers</key> + <value>()</value> + <type>raw</type> + <hide> + #if $occupied_carriers() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Pilot Carriers</name> + <key>pilot_carriers</key> + <value>()</value> + <type>raw</type> + <hide> + #if $pilot_carriers() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Pilot Symbols</name> + <key>pilot_symbols</key> + <value>()</value> + <type>raw</type> + <hide> + #if $pilot_symbols() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Sync Word 1</name> + <key>sync_word1</key> + <value>()</value> + <type>raw</type> + <hide> + #if $sync_word1() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Sync Word 2</name> + <key>sync_word2</key> + <value>()</value> + <type>raw</type> + <hide> + #if $sync_word2() + none + #else + part + #end if + </hide> + </param> + <param> + <name>Header Modulation</name> + <key>header_mod</key> + <type>enum</type> + <option> + <name>BPSK</name> + <key>"BPSK"</key> + <opt>bps:1</opt> + </option> + <option> + <name>QPSK</name> + <key>"QPSK"</key> + <opt>bps:2</opt> + </option> + </param> + <param> + <name>Payload Modulation</name> + <key>payload_mod</key> + <type>enum</type> + <option> + <name>BPSK</name> + <key>"BPSK"</key> + <opt>bps:1</opt> + </option> + <option> + <name>QPSK</name> + <key>"QPSK"</key> + <opt>bps:2</opt> + </option> + <option> + <name>8-PSK</name> + <key>"8-PSK"</key> + <opt>bps:3</opt> + </option> + </param> + <param> + <name>Rolloff length (samples)</name> + <key>rolloff</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Log Debug Info</name> + <key>log</key> + <value>False</value> + <type>enum</type> + <hide> #if $log then 'none' else 'part'#</hide> + <option> + <name>No</name> + <key>False</key> + </option> + <option> + <name>Yes</name> + <key>True</key> + </option> + </param> + <check>$fft_len > 0</check> + <check>$cp_len > 0</check> + <check>$cp_len < $fft_len</check> + <check>$rolloff >= 0</check> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h index 262a9b4302..cd1b943f47 100644 --- a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h +++ b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h @@ -34,9 +34,19 @@ namespace gr { * \brief OFDM frame equalizer * \ingroup ofdm_blk * - * Performs equalization in one or two dimensions on a tagged OFDM frame. + * This does two things: + * First, it removes the coarse carrier offset. If a tag is found on the first + * item with the key 'ofdm_sync_carr_offset', this is interpreted as the coarse + * frequency offset in number of carriers. + * Next, it performs equalization in one or two dimensions on a tagged OFDM frame. + * The actual equalization is done by a ofdm_frame_equalizer object, outside of + * the block. + * + * Note that the tag with the coarse carrier offset is not removed. Blocks + * downstream from this block must not attempt to also correct this offset. + * * Input: a tagged series of OFDM symbols. - * Output: The same as the input, but equalized. + * Output: The same as the input, but equalized and frequency-corrected. */ class DIGITAL_API ofdm_frame_equalizer_vcvc : virtual public gr_tagged_stream_block { @@ -45,6 +55,7 @@ namespace gr { /*! * \param equalizer The equalizer object that will do the actual work + * \param cp_len Length of the cyclic prefix in samples (required to correct the frequency offset) * \param len_tag_key Length tag key * \param propagate_channel_state If true, the channel state after the last symbol * will be added to the first symbol as a tag @@ -53,7 +64,8 @@ namespace gr { */ static sptr make( digital_ofdm_equalizer_base_sptr equalizer, - const std::string &len_tag_key = "frame_len", + int cp_len, + const std::string &len_tag_key="frame_len", bool propagate_channel_state=false, int fixed_frame_len=0 ); diff --git a/gr-digital/include/digital/ofdm_serializer_vcc.h b/gr-digital/include/digital/ofdm_serializer_vcc.h index 3893d6674e..fde2458b6b 100644 --- a/gr-digital/include/digital/ofdm_serializer_vcc.h +++ b/gr-digital/include/digital/ofdm_serializer_vcc.h @@ -45,6 +45,9 @@ namespace gr { * output items, and the frame length specifies the exact number of * consumed input items. * + * It is possible to correct a carrier offset in this function by passing + * another tag with said offset. + * * Input: Complex vectors of length \p fft_len * Output: Complex scalars, in the same order as specified in occupied_carriers. */ @@ -59,6 +62,7 @@ namespace gr { * \param len_tag_key The key of the tag identifying the length of the input frame in OFDM symbols. * \param packet_len_tag_key The key of the tag identifying the number of complex symbols in this packet. * \param symbols_skipped If the first symbol is not allocated as in \p occupied_carriers[0], set this + * \param carr_offset_key When this block should correct a carrier offset, specify the tag key of the offset here (not necessary if following an ofdm_frame_equalizer_vcvc) * \param input_is_shifted If the input has the DC carrier on index 0 (i.e. it is not FFT shifted), set this to false */ static sptr make( @@ -67,6 +71,7 @@ namespace gr { const std::string &len_tag_key="frame_len", const std::string &packet_len_tag_key="", int symbols_skipped=0, + const std::string &carr_offset_key="", bool input_is_shifted=true ); @@ -74,12 +79,14 @@ namespace gr { * \param allocator The carrier allocator block of which this shall be the inverse * \param packet_len_tag_key The key of the tag identifying the number of complex symbols in this packet. * \param symbols_skipped If the first symbol is not allocated as in \p occupied_carriers[0], set this + * \param carr_offset_key When this block should correct a carrier offset, specify the tag key of the offset here (not necessary if following an ofdm_frame_equalizer_vcvc) * \param input_is_shifted If the input has the DC carrier on index 0 (i.e. it is not FFT shifted), set this to false */ static sptr make( const digital_ofdm_carrier_allocator_cvc_sptr &allocator, const std::string &packet_len_tag_key="", int symbols_skipped=0, + const std::string &carr_offset_key="", bool input_is_shifted=true ); }; diff --git a/gr-digital/include/digital_ofdm_chanest_vcvc.h b/gr-digital/include/digital_ofdm_chanest_vcvc.h index 73516cd506..afea16994c 100644 --- a/gr-digital/include/digital_ofdm_chanest_vcvc.h +++ b/gr-digital/include/digital_ofdm_chanest_vcvc.h @@ -74,7 +74,9 @@ digital_make_ofdm_chanest_vcvc ( * 'ofdm_sync_carr_offset' (integer), the coarse frequency offset as number of carriers, * and 'ofdm_sync_eq_taps' (complex vector). * Any tags attached to the synchronisation symbols are attached to the first data - * symbol. All other tags are propagated normally. + * symbol. All other tags are propagated as expected. + * + * Note: The vector on ofdm_sync_eq_taps is already frequency-corrected, whereas the rest is not. * * This block assumes the frequency offset is even (i.e. an integer multiple of 2). * diff --git a/gr-digital/include/digital_ofdm_equalizer_base.h b/gr-digital/include/digital_ofdm_equalizer_base.h index a8697835f2..2fc5cf52c3 100644 --- a/gr-digital/include/digital_ofdm_equalizer_base.h +++ b/gr-digital/include/digital_ofdm_equalizer_base.h @@ -42,14 +42,12 @@ class DIGITAL_API digital_ofdm_equalizer_base : public boost::enable_shared_from { protected: int d_fft_len; - int d_carr_offset; public: digital_ofdm_equalizer_base(int fft_len); ~digital_ofdm_equalizer_base(); virtual void reset() = 0; - void set_carrier_offset(int offset) { d_carr_offset = offset; }; virtual void equalize( gr_complex *frame, int n_sym, @@ -71,7 +69,7 @@ class DIGITAL_API digital_ofdm_equalizer_1d_pilots : public digital_ofdm_equaliz //! If \p d_occupied_carriers[k][l] is true, symbol k, carrier l is carrying data. // (this is a different format than occupied_carriers!) std::vector<bool> d_occupied_carriers; - //! If \p d_pilot_carriers[k][l] is true, symbol k, carrier l is carrying data. + //! If \p d_pilot_carriers[k][l] is true, symbol k, carrier l is carrying a pilot symbol. // (this is a different format than pilot_carriers!) std::vector<std::vector<bool> > d_pilot_carriers; //! If \p d_pilot_carriers[k][l] is true, d_pilot_symbols[k][l] is its tx'd value. diff --git a/gr-digital/include/digital_ofdm_equalizer_static.h b/gr-digital/include/digital_ofdm_equalizer_static.h index 03ffd441e5..dd8d48aadb 100644 --- a/gr-digital/include/digital_ofdm_equalizer_static.h +++ b/gr-digital/include/digital_ofdm_equalizer_static.h @@ -70,11 +70,11 @@ class DIGITAL_API digital_ofdm_equalizer_static : public digital_ofdm_equalizer_ public: digital_ofdm_equalizer_static( int fft_len, - const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), - const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), - int symbols_skipped = 0, - bool input_is_shifted = true); + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + bool input_is_shifted); ~digital_ofdm_equalizer_static(); /*! \brief Divide the input signal with the current channel state. diff --git a/gr-digital/include/digital_ofdm_sync_sc_cfb.h b/gr-digital/include/digital_ofdm_sync_sc_cfb.h index f58be3df59..26cf5b3de5 100644 --- a/gr-digital/include/digital_ofdm_sync_sc_cfb.h +++ b/gr-digital/include/digital_ofdm_sync_sc_cfb.h @@ -30,9 +30,12 @@ typedef boost::shared_ptr<digital_ofdm_sync_sc_cfb> digital_ofdm_sync_sc_cfb_spt /*! \param fft_len FFT length * \param cp_len Length of the guard interval (cyclic prefix) in samples + * \param use_even_carriers If true, the carriers in the sync preamble are occupied such + * that the even carriers are used (0, 2, 4, ...). If you use all + * carriers, that would include the DC carrier, so be careful. */ DIGITAL_API digital_ofdm_sync_sc_cfb_sptr -digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len); +digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len, bool use_even_carriers=false); /*! * \brief Schmidl & Cox synchronisation for OFDM @@ -68,8 +71,8 @@ digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len); class DIGITAL_API digital_ofdm_sync_sc_cfb : public gr_hier_block2 { private: - friend DIGITAL_API digital_ofdm_sync_sc_cfb_sptr digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len); - digital_ofdm_sync_sc_cfb(int fft_len, int cp_len); + friend DIGITAL_API digital_ofdm_sync_sc_cfb_sptr digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len, bool use_even_carriers); + digital_ofdm_sync_sc_cfb(int fft_len, int cp_len, bool use_even_carriers); public: ~digital_ofdm_sync_sc_cfb(); diff --git a/gr-digital/lib/digital_ofdm_chanest_vcvc.cc b/gr-digital/lib/digital_ofdm_chanest_vcvc.cc index f38017e00b..1e3adbb67f 100644 --- a/gr-digital/lib/digital_ofdm_chanest_vcvc.cc +++ b/gr-digital/lib/digital_ofdm_chanest_vcvc.cc @@ -1,5 +1,4 @@ /* -*- c++ -*- */ -// vim: set sw=2: /* Copyright 2012 Free Software Foundation, Inc. * * This file is part of GNU Radio @@ -36,8 +35,16 @@ digital_make_ofdm_chanest_vcvc ( int max_carr_offset, bool force_one_sync_symbol) { - return gnuradio::get_initial_sptr (new digital_ofdm_chanest_vcvc( - sync_symbol1, sync_symbol2, n_data_symbols, eq_noise_red_len, max_carr_offset, force_one_sync_symbol)); + return gnuradio::get_initial_sptr ( + new digital_ofdm_chanest_vcvc( + sync_symbol1, + sync_symbol2, + n_data_symbols, + eq_noise_red_len, + max_carr_offset, + force_one_sync_symbol + ) + ); } @@ -50,7 +57,7 @@ digital_ofdm_chanest_vcvc::digital_ofdm_chanest_vcvc ( bool force_one_sync_symbol) : gr_block ("ofdm_chanest_vcvc", gr_make_io_signature(1, 1, sizeof (gr_complex) * sync_symbol1.size()), - gr_make_io_signature(1, 1, sizeof (gr_complex) * sync_symbol1.size())), + gr_make_io_signature(1, 2, sizeof (gr_complex) * sync_symbol1.size())), d_fft_len(sync_symbol1.size()), d_n_data_syms(n_data_symbols), d_n_sync_syms(1), @@ -201,13 +208,14 @@ digital_ofdm_chanest_vcvc::get_chan_taps( } for (int i = loop_start; i < loop_end; i++) { if ((d_ref_sym[i-carr_offset] != gr_complex(0, 0))) { - taps[i] = sym[i] / d_ref_sym[i-carr_offset]; + taps[i-carr_offset] = sym[i] / d_ref_sym[i-carr_offset]; } } if (d_interpolate) { + // FIXME check this out re offset + update docs for (int i = d_first_active_carrier + 1; i < d_last_active_carrier; i += 2) { - taps[i] = (taps[i-1] + taps[i+1]) / gr_complex(2.0, 0); + taps[i] = taps[i-1]; } taps[d_last_active_carrier] = taps[d_last_active_carrier-1]; } @@ -246,6 +254,12 @@ digital_ofdm_chanest_vcvc::general_work (int noutput_items, std::vector<gr_complex> chan_taps(d_fft_len, 0); get_chan_taps(in, in+d_fft_len, carr_offset, chan_taps); + if (output_items.size() == 2) { + gr_complex *out_chantaps = ((gr_complex *) output_items[1]) + i * d_fft_len; + memcpy((void *) out_chantaps, (void *) &chan_taps[0], sizeof(gr_complex) * d_fft_len); + produce(1, 1); + } + memcpy((void *) out, (void *) &in[d_n_sync_syms * d_fft_len], sizeof(gr_complex) * d_fft_len * d_n_data_syms); @@ -253,29 +267,30 @@ digital_ofdm_chanest_vcvc::general_work (int noutput_items, out += d_n_data_syms * d_fft_len; std::vector<gr_tag_t> tags; - this->get_tags_in_range(tags, 0, - this->nitems_read(0)+i*framesize, - this->nitems_read(0)+(i+1)*framesize); + get_tags_in_range(tags, 0, + nitems_read(0)+i*framesize, + nitems_read(0)+(i+1)*framesize); for (unsigned t = 0; t < tags.size(); t++) { - int offset = tags[t].offset - (this->nitems_read(0) + i*framesize); + int offset = tags[t].offset - (nitems_read(0) + i*framesize); if (offset < d_n_sync_syms) { offset = 0; } else { offset -= d_n_sync_syms; } - tags[t].offset = offset + this->nitems_written(0) + i*d_n_data_syms; - this->add_item_tag(0, tags[t]); + tags[t].offset = offset + nitems_written(0) + i*d_n_data_syms; + add_item_tag(0, tags[t]); } - this->add_item_tag(0, this->nitems_written(0) + i*d_n_data_syms, + add_item_tag(0, nitems_written(0) + i*d_n_data_syms, pmt::pmt_string_to_symbol("ofdm_sync_carr_offset"), pmt::pmt_from_long(carr_offset)); - this->add_item_tag(0, this->nitems_written(0) + i*d_n_data_syms, + add_item_tag(0, nitems_written(0) + i*d_n_data_syms, pmt::pmt_string_to_symbol("ofdm_sync_chan_taps"), pmt::pmt_init_c32vector(d_fft_len, chan_taps)); } - + produce(0, n_frames * d_n_data_syms); consume_each(n_frames * framesize); - return n_frames * d_n_data_syms; + + return WORK_CALLED_PRODUCE; } diff --git a/gr-digital/lib/digital_ofdm_equalizer_base.cc b/gr-digital/lib/digital_ofdm_equalizer_base.cc index b4fa5df87e..29f23910b9 100644 --- a/gr-digital/lib/digital_ofdm_equalizer_base.cc +++ b/gr-digital/lib/digital_ofdm_equalizer_base.cc @@ -27,8 +27,7 @@ // *** Base class **************************************************** digital_ofdm_equalizer_base::digital_ofdm_equalizer_base(int fft_len) : - d_fft_len(fft_len), - d_carr_offset(0) + d_fft_len(fft_len) { } @@ -51,7 +50,7 @@ digital_ofdm_equalizer_1d_pilots::digital_ofdm_equalizer_1d_pilots( d_pilot_carriers(pilot_carriers.size(), std::vector<bool>(fft_len, false)), d_pilot_symbols(pilot_symbols.size(), std::vector<gr_complex>(fft_len, gr_complex(0, 0))), d_symbols_skipped(symbols_skipped), - d_pilot_carr_set(symbols_skipped), + d_pilot_carr_set(pilot_carriers.empty() ? 0 : symbols_skipped % pilot_carriers.size()), d_channel_state(fft_len, gr_complex(1, 0)) { int fft_shift_width = 0; @@ -104,7 +103,7 @@ void digital_ofdm_equalizer_1d_pilots::reset() { std::fill(d_channel_state.begin(), d_channel_state.end(), gr_complex(1, 0)); - d_pilot_carr_set = d_symbols_skipped; + d_pilot_carr_set = d_pilot_carriers.empty() ? 0 : d_symbols_skipped % d_pilot_carriers.size(); } @@ -113,4 +112,3 @@ void digital_ofdm_equalizer_1d_pilots::get_channel_state(std::vector<gr_complex> taps = d_channel_state; } - diff --git a/gr-digital/lib/digital_ofdm_equalizer_simpledfe.cc b/gr-digital/lib/digital_ofdm_equalizer_simpledfe.cc index 9abab8c1dd..6e771446b0 100644 --- a/gr-digital/lib/digital_ofdm_equalizer_simpledfe.cc +++ b/gr-digital/lib/digital_ofdm_equalizer_simpledfe.cc @@ -84,10 +84,10 @@ digital_ofdm_equalizer_simpledfe::equalize(gr_complex *frame, if (!d_occupied_carriers[k]) { continue; } - if (d_pilot_carriers.size() && d_pilot_carriers[d_pilot_carr_set][k-d_carr_offset]) { + if (!d_pilot_carriers.empty() && d_pilot_carriers[d_pilot_carr_set][k]) { d_channel_state[k] = d_alpha * d_channel_state[k] - + (1-d_alpha) * frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; - frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; + + (1-d_alpha) * frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k]; + frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k]; } else { sym_eq = frame[i*d_fft_len+k] / d_channel_state[k]; d_constellation->map_to_points(d_constellation->decision_maker(&sym_eq), &sym_est); @@ -95,7 +95,9 @@ digital_ofdm_equalizer_simpledfe::equalize(gr_complex *frame, frame[i*d_fft_len+k] = sym_est; } } - d_pilot_carr_set = (d_pilot_carr_set + 1) % d_pilot_carriers.size(); + if (!d_pilot_carriers.empty()) { + d_pilot_carr_set = (d_pilot_carr_set + 1) % d_pilot_carriers.size(); + } } } diff --git a/gr-digital/lib/digital_ofdm_equalizer_static.cc b/gr-digital/lib/digital_ofdm_equalizer_static.cc index 66903fa90a..e4ae325dd8 100644 --- a/gr-digital/lib/digital_ofdm_equalizer_static.cc +++ b/gr-digital/lib/digital_ofdm_equalizer_static.cc @@ -25,8 +25,6 @@ #include "digital_ofdm_equalizer_static.h" -#include <iostream> - digital_ofdm_equalizer_static_sptr digital_make_ofdm_equalizer_static( int fft_len, @@ -75,9 +73,9 @@ digital_ofdm_equalizer_static::equalize(gr_complex *frame, if (!d_occupied_carriers[k]) { continue; } - if (d_pilot_carriers.size() && d_pilot_carriers[d_pilot_carr_set][k-d_carr_offset]) { - d_channel_state[k] = frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; - frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k-d_carr_offset]; + if (!d_pilot_carriers.empty() && d_pilot_carriers[d_pilot_carr_set][k]) { + d_channel_state[k] = frame[i*d_fft_len + k] / d_pilot_symbols[d_pilot_carr_set][k]; + frame[i*d_fft_len+k] = d_pilot_symbols[d_pilot_carr_set][k]; } else { frame[i*d_fft_len+k] /= d_channel_state[k]; } diff --git a/gr-digital/lib/digital_ofdm_sync_sc_cfb.cc b/gr-digital/lib/digital_ofdm_sync_sc_cfb.cc index 1085662e1f..23c3712707 100644 --- a/gr-digital/lib/digital_ofdm_sync_sc_cfb.cc +++ b/gr-digital/lib/digital_ofdm_sync_sc_cfb.cc @@ -42,13 +42,13 @@ //#define SYNC_ADD_DEBUG_OUTPUT digital_ofdm_sync_sc_cfb_sptr -digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len) +digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len, bool use_even_carriers) { - return gnuradio::get_initial_sptr (new digital_ofdm_sync_sc_cfb(fft_len, cp_len)); + return gnuradio::get_initial_sptr (new digital_ofdm_sync_sc_cfb(fft_len, cp_len, use_even_carriers)); } -digital_ofdm_sync_sc_cfb::digital_ofdm_sync_sc_cfb (int fft_len, int cp_len) +digital_ofdm_sync_sc_cfb::digital_ofdm_sync_sc_cfb (int fft_len, int cp_len, bool use_even_carriers) : gr_hier_block2 ("ofdm_sync_sc_cfb", gr_make_io_signature(1, 1, sizeof (gr_complex)), #ifndef SYNC_ADD_DEBUG_OUTPUT @@ -61,7 +61,7 @@ digital_ofdm_sync_sc_cfb::digital_ofdm_sync_sc_cfb (int fft_len, int cp_len) gr_delay_sptr delay(gr_make_delay(sizeof(gr_complex), fft_len/2)); gr::blocks::conjugate_cc::sptr delay_conjugate(gr::blocks::conjugate_cc::make()); gr::blocks::multiply_cc::sptr delay_corr(gr::blocks::multiply_cc::make()); - gr::filter::fir_filter_ccf::sptr delay_ma(gr::filter::fir_filter_ccf::make(1, std::vector<float>(fft_len/2, 1.0))); + gr::filter::fir_filter_ccf::sptr delay_ma(gr::filter::fir_filter_ccf::make(1, std::vector<float>(fft_len/2, use_even_carriers ? 1.0 : -1.0))); gr::blocks::complex_to_mag_squared::sptr delay_magsquare(gr::blocks::complex_to_mag_squared::make()); gr::blocks::divide_ff::sptr delay_normalize(gr::blocks::divide_ff::make()); diff --git a/gr-digital/lib/header_payload_demux_impl.cc b/gr-digital/lib/header_payload_demux_impl.cc index f79678e903..0c3adf701e 100644 --- a/gr-digital/lib/header_payload_demux_impl.cc +++ b/gr-digital/lib/header_payload_demux_impl.cc @@ -123,7 +123,8 @@ namespace gr { int produced_hdr = 0; int produced_payload = 0; - while (nread < noutput_items && !exit_loop) { + // FIXME ninput_items[1] does not have to be defined O_o + while (nread < noutput_items && nread < ninput_items[0] && nread < ninput_items[1] && !exit_loop) { switch (d_state) { case STATE_IDLE: // 1) Search for a trigger signal on input 1 (if present) @@ -154,6 +155,7 @@ namespace gr { // 4) fall through to next state d_remaining_symbols = -1; if (!parse_header_data_msg()) { + d_state = STATE_IDLE; exit_loop = true; break; } @@ -241,6 +243,8 @@ namespace gr { } } else if (pmt::pmt_is_null(msg)) { // Blocking call was interrupted return false; + } else if (msg == pmt::PMT_F) { // Header was invalid + return false; } else { throw std::runtime_error("Received illegal header data"); } diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc index 168a04cf75..f881a6e6dd 100644 --- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc +++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc @@ -23,15 +23,19 @@ #include "config.h" #endif +#include <gr_expj.h> #include <gr_io_signature.h> #include "ofdm_frame_equalizer_vcvc_impl.h" +#define M_TWOPI (2*M_PI) + namespace gr { namespace digital { ofdm_frame_equalizer_vcvc::sptr ofdm_frame_equalizer_vcvc::make( digital_ofdm_equalizer_base_sptr equalizer, + int cp_len, const std::string &len_tag_key, bool propagate_channel_state, int fixed_frame_len @@ -39,13 +43,14 @@ namespace gr { { return gnuradio::get_initial_sptr ( new ofdm_frame_equalizer_vcvc_impl( - equalizer, len_tag_key, propagate_channel_state, fixed_frame_len + equalizer, cp_len, len_tag_key, propagate_channel_state, fixed_frame_len ) ); } ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl( digital_ofdm_equalizer_base_sptr equalizer, + int cp_len, const std::string &len_tag_key, bool propagate_channel_state, int fixed_frame_len @@ -54,26 +59,50 @@ namespace gr { gr_make_io_signature(1, 1, sizeof (gr_complex) * equalizer->fft_len()), len_tag_key), d_fft_len(equalizer->fft_len()), + d_cp_len(cp_len), d_eq(equalizer), d_propagate_channel_state(propagate_channel_state), - d_fixed_frame_len(len_tag_key.empty() ? fixed_frame_len : 0), + d_fixed_frame_len(fixed_frame_len), d_channel_state(equalizer->fft_len(), gr_complex(1, 0)) { + if (len_tag_key.empty() && fixed_frame_len == 0) { + throw std::invalid_argument("Either specify a length tag or a frame length!"); + } + if (d_fixed_frame_len < 0) { + throw std::invalid_argument("Invalid frame length!"); + } if (d_fixed_frame_len) { set_output_multiple(d_fixed_frame_len); } + set_relative_rate(1.0); } ofdm_frame_equalizer_vcvc_impl::~ofdm_frame_equalizer_vcvc_impl() { } + void + ofdm_frame_equalizer_vcvc_impl::parse_length_tags( + const std::vector<std::vector<gr_tag_t> > &tags, + gr_vector_int &n_input_items_reqd + ){ + if (d_fixed_frame_len) { + n_input_items_reqd[0] = d_fixed_frame_len; + } else { + for (unsigned k = 0; k < tags[0].size(); k++) { + if (tags[0][k].key == pmt::pmt_string_to_symbol(d_length_tag_key_str)) { + n_input_items_reqd[0] = pmt::pmt_to_long(tags[0][k].value); + remove_item_tag(0, tags[0][k]); + } + } + } + } + +#include <iostream> int ofdm_frame_equalizer_vcvc_impl::work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { const gr_complex *in = (const gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; @@ -92,23 +121,55 @@ namespace gr { d_channel_state = pmt::pmt_c32vector_elements(tags[i].value); remove_item_tag(0, tags[i]); } + if (pmt::pmt_symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") { + carrier_offset = pmt::pmt_to_long(tags[i].value); + } + } + + // Copy the frame and the channel state vector such that the symbols are shifted to the correct position + if (carrier_offset < 0) { + memset((void *) out, 0x00, sizeof(gr_complex) * (-carrier_offset)); + memcpy( + (void *) &out[-carrier_offset], (void *) in, + sizeof(gr_complex) * (d_fft_len * frame_len + carrier_offset) + ); + } else { + memset((void *) (out + d_fft_len * frame_len - carrier_offset), 0x00, sizeof(gr_complex) * carrier_offset); + memcpy( + (void *) out, (void *) (in+carrier_offset), + sizeof(gr_complex) * (d_fft_len * frame_len - carrier_offset) + ); + } + + // Correct the frequency shift on the symbols + gr_complex phase_correction; + for (int i = 0; i < frame_len; i++) { + phase_correction = gr_expj(-M_TWOPI * carrier_offset * d_cp_len / d_fft_len * (i+1)); + for (int k = 0; k < d_fft_len; k++) { + out[i*d_fft_len+k] *= phase_correction; + } } - memcpy((void *) out, (void *) in, sizeof(gr_complex) * d_fft_len * frame_len); + // Do the equalizing d_eq->reset(); - d_eq->set_carrier_offset(carrier_offset); d_eq->equalize(out, frame_len, d_channel_state); d_eq->get_channel_state(d_channel_state); + + // Update the channel state regarding the frequency offset + phase_correction = gr_expj(M_TWOPI * carrier_offset * d_cp_len / d_fft_len * frame_len); + for (int k = 0; k < d_fft_len; k++) { + d_channel_state[k] *= phase_correction; + } + + // Housekeeping if (d_propagate_channel_state) { add_item_tag(0, nitems_written(0), pmt::pmt_string_to_symbol("ofdm_sync_chan_taps"), pmt::pmt_init_c32vector(d_fft_len, d_channel_state)); } - - if (d_fixed_frame_len) { + if (d_fixed_frame_len && d_length_tag_key_str.empty()) { consume_each(frame_len); } - return frame_len; } diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h index 89e59db053..c855b46f7d 100644 --- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h +++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.h @@ -31,19 +31,22 @@ namespace gr { { private: const int d_fft_len; + const int d_cp_len; digital_ofdm_equalizer_base_sptr d_eq; bool d_propagate_channel_state; const int d_fixed_frame_len; std::vector<gr_complex> d_channel_state; protected: - // These aren't really necessary, so let's override them with nuthin' - void remove_length_tags(const std::vector<std::vector<gr_tag_t> > &tags) {}; - void update_length_tags(int n_produced, int n_ports) {}; + void parse_length_tags( + const std::vector<std::vector<gr_tag_t> > &tags, + gr_vector_int &n_input_items_reqd + ); public: ofdm_frame_equalizer_vcvc_impl( digital_ofdm_equalizer_base_sptr equalizer, + int cp_len, const std::string &len_tag_key, bool propagate_channel_state, int fixed_frame_len diff --git a/gr-digital/lib/ofdm_serializer_vcc_impl.cc b/gr-digital/lib/ofdm_serializer_vcc_impl.cc index 2fdb9bd0e8..2d6d68f758 100644 --- a/gr-digital/lib/ofdm_serializer_vcc_impl.cc +++ b/gr-digital/lib/ofdm_serializer_vcc_impl.cc @@ -36,6 +36,7 @@ namespace gr { const std::string &len_tag_key, const std::string &packet_len_tag_key, int symbols_skipped, + const std::string &carr_offset_key, bool input_is_shifted ) { @@ -43,7 +44,9 @@ namespace gr { new ofdm_serializer_vcc_impl( fft_len, occupied_carriers, len_tag_key, packet_len_tag_key, - symbols_skipped, input_is_shifted + symbols_skipped, + carr_offset_key, + input_is_shifted ) ); } @@ -53,6 +56,7 @@ namespace gr { const digital_ofdm_carrier_allocator_cvc_sptr &allocator, const std::string &packet_len_tag_key, int symbols_skipped, + const std::string &carr_offset_key, bool input_is_shifted ) { @@ -63,6 +67,7 @@ namespace gr { allocator->len_tag_key(), packet_len_tag_key, symbols_skipped, + carr_offset_key, input_is_shifted ) ); @@ -74,6 +79,7 @@ namespace gr { const std::string &len_tag_key, const std::string &packet_len_tag_key, int symbols_skipped, + const std::string &carr_offset_key, bool input_is_shifted) : gr_tagged_stream_block ("ofdm_serializer_vcc", gr_make_io_signature(1, 1, sizeof (gr_complex) * fft_len), @@ -84,6 +90,7 @@ namespace gr { d_packet_len_tag_key(pmt::pmt_string_to_symbol(packet_len_tag_key)), d_out_len_tag_key(pmt::pmt_string_to_symbol((packet_len_tag_key.empty() ? len_tag_key : packet_len_tag_key))), d_symbols_skipped(symbols_skipped % occupied_carriers.size()), + d_carr_offset_key(pmt::pmt_string_to_symbol(carr_offset_key)), d_curr_set(symbols_skipped % occupied_carriers.size()), d_symbols_per_set(0) { @@ -96,7 +103,7 @@ namespace gr { throw std::invalid_argument("ofdm_serializer_vcc: trying to occupy a carrier outside the fft length."); } if (input_is_shifted) { - d_occupied_carriers[i][k] = (d_occupied_carriers[i][k] + fft_len) % fft_len; + d_occupied_carriers[i][k] = (d_occupied_carriers[i][k] + fft_len/2) % fft_len; } } } @@ -148,7 +155,7 @@ namespace gr { if (!d_length_tag_key_str.empty()) { get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1); for (unsigned i = 0; i < tags.size(); i++) { - if (pmt::pmt_symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") { + if (tags[i].key == d_carr_offset_key) { carr_offset = pmt::pmt_to_long(tags[i].value); } if (tags[i].key == d_packet_len_tag_key) { @@ -176,8 +183,8 @@ namespace gr { ); for (unsigned t = 0; t < tags.size(); t++) { add_item_tag(0, nitems_written(0)+n_out_symbols, - tags[i].key, - tags[i].value + tags[t].key, + tags[t].value ); } for (unsigned k = 0; k < d_occupied_carriers[d_curr_set].size(); k++) { diff --git a/gr-digital/lib/ofdm_serializer_vcc_impl.h b/gr-digital/lib/ofdm_serializer_vcc_impl.h index 4f750eac71..b6fbfdb146 100644 --- a/gr-digital/lib/ofdm_serializer_vcc_impl.h +++ b/gr-digital/lib/ofdm_serializer_vcc_impl.h @@ -35,6 +35,7 @@ namespace gr { pmt::pmt_t d_packet_len_tag_key; //!< Key of the length tag pmt::pmt_t d_out_len_tag_key; //!< Key of the length tag const int d_symbols_skipped; //!< Start position in d_occupied_carriers + pmt::pmt_t d_carr_offset_key; //!< Key of the carrier offset tag int d_curr_set; //!< Current position in d_occupied_carriers int d_symbols_per_set; @@ -53,6 +54,7 @@ namespace gr { const std::string &len_tag_key, const std::string &packet_len_tag_key, int symbols_skipped, + const std::string &carr_offset_key, bool input_is_shifted ); ~ofdm_serializer_vcc_impl(); diff --git a/gr-digital/lib/packet_header_default.cc b/gr-digital/lib/packet_header_default.cc index 2bcbf59957..573114bc51 100644 --- a/gr-digital/lib/packet_header_default.cc +++ b/gr-digital/lib/packet_header_default.cc @@ -47,7 +47,7 @@ namespace gr { int bits_per_byte) : d_header_len(header_len), d_len_tag_key(pmt::pmt_string_to_symbol(len_tag_key)), - d_num_tag_key(pmt::pmt_string_to_symbol(num_tag_key)), + d_num_tag_key(num_tag_key.empty() ? pmt::PMT_NIL : pmt::pmt_string_to_symbol(num_tag_key)), d_bits_per_byte(bits_per_byte), d_header_number(0) { @@ -65,7 +65,7 @@ namespace gr { long packet_len, unsigned char *out, const std::vector<gr_tag_t> &tags - ) + ) { packet_len &= 0x0FFF; @@ -107,12 +107,16 @@ namespace gr { if (k >= d_header_len) { return true; } - for (int i = 0; i < 16 && k < d_header_len; i += d_bits_per_byte, k++) { - header_num |= (((int) in[k]) & d_mask) << i; + if (d_num_tag_key == pmt::PMT_NIL) { + k += 16; + } else { + for (int i = 0; i < 16 && 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::pmt_from_long(header_num); + tags.push_back(tag); } - tag.key = d_num_tag_key; - tag.value = pmt::pmt_from_long(header_num); - tags.push_back(tag); if (k >= d_header_len) { return true; } diff --git a/gr-digital/lib/packet_header_ofdm.cc b/gr-digital/lib/packet_header_ofdm.cc index 6d40fcfffa..9758ee696a 100644 --- a/gr-digital/lib/packet_header_ofdm.cc +++ b/gr-digital/lib/packet_header_ofdm.cc @@ -90,15 +90,18 @@ namespace gr { if (!packet_header_default::header_parser(in, tags)) { return false; } - int packet_len = 0; // # of bytes in this frame + int packet_len = 0; // # of symbols in this frame for (unsigned i = 0; i < tags.size(); i++) { if (pmt::pmt_equal(tags[i].key, d_len_tag_key)) { - packet_len = pmt::pmt_to_long(tags[i].value); + // Convert bytes to complex symbols: + packet_len = pmt::pmt_to_long(tags[i].value) * 8 / d_bits_per_payload_sym; + if (pmt::pmt_to_long(tags[i].value) * 8 % d_bits_per_payload_sym) { + packet_len++; + } + tags[i].value = pmt::pmt_from_long(packet_len); break; } } - // Convert bytes to complex symbols: - packet_len = packet_len * 8 / d_bits_per_payload_sym; // frame_len == # of OFDM symbols in this frame int frame_len = packet_len / d_syms_per_set; diff --git a/gr-digital/lib/packet_headerparser_b_impl.cc b/gr-digital/lib/packet_headerparser_b_impl.cc index e7e949e387..fa24564d48 100644 --- a/gr-digital/lib/packet_headerparser_b_impl.cc +++ b/gr-digital/lib/packet_headerparser_b_impl.cc @@ -73,6 +73,11 @@ namespace gr { } std::vector<gr_tag_t> tags; + get_tags_in_range( + tags, 0, + nitems_read(0), + nitems_read(0)+d_header_formatter->header_len() + ); if (!d_header_formatter->header_parser(in, tags)) { GR_LOG_INFO(d_logger, boost::format("Detected an invalid packet at item %1%") % nitems_read(0)); message_port_pub(msg_port_id, pmt::PMT_F); diff --git a/gr-digital/python/ofdm_txrx.py b/gr-digital/python/ofdm_txrx.py index de9811a646..ea5f682edd 100644 --- a/gr-digital/python/ofdm_txrx.py +++ b/gr-digital/python/ofdm_txrx.py @@ -1,5 +1,5 @@ # -# Copyright 2005,2006,2007 Free Software Foundation, Inc. +# Copyright 2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -44,20 +44,63 @@ except ImportError: _def_fft_len = 64 _def_cp_len = 16 _def_frame_length_tag_key = "frame_length" -_def_packet_length_tag_key = "frame_length" -_def_packet_num_tag_key = "" -_def_occupied_carriers=(range(1, 27) + range(38, 64),) -_def_pilot_carriers=((0,),) -_def_pilot_symbols=((100,),) +_def_packet_length_tag_key = "packet_length" +_def_packet_num_tag_key = "packet_num" +# Data and pilot carriers are same as in 802.11a +_def_occupied_carriers = (range(-26, -21) + range(-20, -7) + range(-6, 0) + range(1, 7) + range(8, 21) + range(22, 27),) +_def_pilot_carriers=((-21, -7, 7, 21,),) +_pilot_sym_scramble_seq = ( + 1,1,1,1, -1,-1,-1,1, -1,-1,-1,-1, 1,1,-1,1, -1,-1,1,1, -1,1,1,-1, 1,1,1,1, 1,1,-1,1, + 1,1,-1,1, 1,-1,-1,1, 1,1,-1,1, -1,-1,-1,1, -1,1,-1,-1, 1,-1,-1,1, 1,1,1,1, -1,-1,1,1, + -1,-1,1,-1, 1,-1,1,1, -1,-1,-1,1, 1,-1,-1,-1, -1,1,-1,-1, 1,-1,1,1, 1,1,-1,1, -1,1,-1,1, + -1,-1,-1,-1, -1,1,-1,1, 1,-1,1,-1, 1,1,1,-1, -1,1,-1,-1, -1,1,1,1, -1,-1,-1,-1, -1,-1,-1 +) +_def_pilot_symbols= tuple([(x, x, x, -x) for x in _pilot_sym_scramble_seq]) _seq_seed = 42 -def _make_sync_word(fft_len, occupied_carriers, constellation): - """ Makes a random sync sequence """ - occupied_carriers = list(occupied_carriers[0]) - occupied_carriers = [occupied_carriers[x] + fft_len if occupied_carriers[x] < 0 else occupied_carriers[x] for x in range(len(occupied_carriers))] + +def _get_active_carriers(fft_len, occupied_carriers, pilot_carriers): + active_carriers = list() + for carrier in list(occupied_carriers[0]) + list(pilot_carriers[0]): + if carrier < 0: + carrier += fft_len + active_carriers.append(carrier) + return active_carriers + +def _make_sync_word1(fft_len, occupied_carriers, pilot_carriers): + """ Creates a random sync sequence for fine frequency offset and timing + estimation. This is the first of typically two sync preamble symbols + for the Schmidl & Cox sync algorithm. + The relevant feature of this symbols is that every second sub-carrier + is zero. In the time domain, this results in two identical halves of + the OFDM symbols. + Symbols are always BPSK symbols. Carriers are scaled by sqrt(2) to keep + total energy constant. + Carrier 0 (DC carrier) is always zero. If used, carrier 1 is non-zero. + This means the sync algorithm has to check on odd carriers! + """ + active_carriers = _get_active_carriers(fft_len, occupied_carriers, pilot_carriers) + numpy.random.seed(_seq_seed) + bpsk = {0: numpy.sqrt(2), 1: -numpy.sqrt(2)} + return [bpsk[numpy.random.randint(2)] if x in active_carriers and x % 2 else 0 for x in range(fft_len)] + +def _make_sync_word2(fft_len, occupied_carriers, pilot_carriers): + """ Creates a random sync sequence for coarse frequency offset and channel + estimation. This is the second of typically two sync preamble symbols + for the Schmidl & Cox sync algorithm. + Symbols are always BPSK symbols. + """ + active_carriers = _get_active_carriers(fft_len, occupied_carriers, pilot_carriers) numpy.random.seed(_seq_seed) - sync_sequence = [constellation.map_to_points_v(numpy.random.randint(constellation.arity()))[0] * numpy.sqrt(2) if x in occupied_carriers and x % 3 else 0 for x in range(fft_len)] - return sync_sequence + bpsk = {0: 1, 1: -1} + sw2 = [bpsk[numpy.random.randint(2)] if x in active_carriers else 0 for x in range(fft_len)] + sw2[0] = 0j + return sw2 + +SW2 = ( + 0+0j, 1, -1, 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, + 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 +) def _get_constellation(bps): """ Returns a modulator block for a given number of bits per symbol """ @@ -73,22 +116,28 @@ def _get_constellation(bps): exit(1) class ofdm_tx(gr.hier_block2): - """ - Hierarchical block for OFDM modulation. + """ Hierarchical block for OFDM modulation. The input is a byte stream (unsigned char) and the output is the complex modulated signal at baseband. Args: fft_len: The length of FFT (integer). - cp_len: The length of cyclic prefix (integer). - occupied_carriers: ?? - pilot_carriers: ?? - pilot_symbols: ?? - length_tag_key: The name of the tag giving packet length. + cp_len: The length of cyclic prefix in total samples (integer). + packet_length_tag_key: The name of the tag giving packet length at the input. + occupied_carriers: A vector of vectors describing which OFDM carriers are occupied. + pilot_carriers: A vector of vectors describing which OFDM carriers are occupied with pilot symbols. + pilot_symbols: The pilot symbols. + bps_header: Bits per symbol (header). + bps_payload: Bits per symbol (payload). + sync_word1: The first sync preamble symbol. This has to be with zeros on alternating carriers. + Used for fine and coarse frequency offset and timing estimation. + 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. """ def __init__(self, fft_len=_def_fft_len, cp_len=_def_cp_len, - frame_length_tag_key=_def_frame_length_tag_key, + packet_length_tag_key=_def_packet_length_tag_key, occupied_carriers=_def_occupied_carriers, pilot_carriers=_def_pilot_carriers, pilot_symbols=_def_pilot_symbols, @@ -96,91 +145,120 @@ class ofdm_tx(gr.hier_block2): bps_payload=1, sync_word1=None, sync_word2=None, - rolloff=0 + rolloff=0, + debug_log=False ): gr.hier_block2.__init__(self, "ofdm_tx", gr.io_signature(1, 1, gr.sizeof_char), gr.io_signature(1, 1, gr.sizeof_gr_complex)) + ### Param init / sanity check ######################################## self.fft_len = fft_len self.cp_len = cp_len - self.frame_length_tag_key = frame_length_tag_key + self.packet_length_tag_key = packet_length_tag_key self.occupied_carriers = occupied_carriers self.pilot_carriers = pilot_carriers self.pilot_symbols = pilot_symbols self.bps_header = bps_header self.bps_payload = bps_payload n_sync_words = 1 - header_constellation = _get_constellation(bps_header) - header_mod = digital.chunks_to_symbols_bc(header_constellation.points()) self.sync_word1 = sync_word1 if sync_word1 is None: - self.sync_word1 = _make_sync_word(fft_len, occupied_carriers, header_constellation) + self.sync_word1 = _make_sync_word1(fft_len, occupied_carriers, pilot_carriers) else: if len(sync_word1) != self.fft_len: raise ValueError("Length of sync sequence(s) must be FFT length.") total_sync_word = self.sync_word1 + self.sync_words = [self.sync_word1,] self.sync_word2 = () - if sync_word2 is not None: - if len(sync_word2) != fft_len: + if sync_word2 is None: + self.sync_word2 = _make_sync_word2(fft_len, occupied_carriers, pilot_carriers) + 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 = sync_word2 + self.sync_word2 = list(self.sync_word2) + total_sync_word = self.sync_word1 + self.sync_word2 n_sync_words = 2 - total_sync_word = sync_word1 + sync_word2 - crc = digital.crc32_bb(False, self.frame_length_tag_key) + ### Header modulation ################################################ + crc = digital.crc32_bb(False, self.packet_length_tag_key) + header_constellation = _get_constellation(bps_header) + header_mod = digital.chunks_to_symbols_bc(header_constellation.points()) formatter_object = digital.packet_header_ofdm( occupied_carriers=occupied_carriers, n_syms=1, - bits_per_sym=self.bps_header + bits_per_header_sym=self.bps_header, + bits_per_payload_sym=self.bps_payload ) - header_gen = digital.packet_headergenerator_bb(formatter_object.base(), self.frame_length_tag_key) - header_payload_mux = blocks.tagged_stream_mux(gr.sizeof_gr_complex*1, self.frame_length_tag_key) + 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)) + ### Payload modulation ############################################### payload_constellation = _get_constellation(bps_payload) payload_mod = digital.chunks_to_symbols_bc(payload_constellation.points()) self.connect( crc, - blocks.repack_bits_bb(8, bps_payload, frame_length_tag_key), + blocks.repack_bits_bb( + 8, # Unpack 8 bits per byte + bps_payload, + self.packet_length_tag_key + ), payload_mod, (header_payload_mux, 1) ) - self.connect(payload_mod, gr.tag_debug(gr.sizeof_gr_complex, "pmod")) + ### Sync word prepending ############################################# sync_word_gen = gr.vector_source_c( total_sync_word, True, self.fft_len, - tagged_streams.make_lengthtags((n_sync_words,), (0,), self.frame_length_tag_key) + tagged_streams.make_lengthtags((n_sync_words,), (0,), self.packet_length_tag_key) ) + syncword_data_mux = blocks.tagged_stream_mux(gr.sizeof_gr_complex*self.fft_len, self.packet_length_tag_key) + self.connect(sync_word_gen, (syncword_data_mux, 0)) + ### Create OFDM frame ################################################ allocator = digital.ofdm_carrier_allocator_cvc( self.fft_len, - occupied_carriers=self.occupied_carriers, - pilot_carriers=self.pilot_carriers, - pilot_symbols=self.pilot_symbols, - len_tag_key=self.frame_length_tag_key + self.occupied_carriers, + self.pilot_carriers, + self.pilot_symbols, + #self.sync_words, + self.packet_length_tag_key + ) + ffter = fft.fft_vcc( + self.fft_len, + False, # Inverse FFT + (), # No window + False # No shifting ) - syncword_data_mux = blocks.tagged_stream_mux(gr.sizeof_gr_complex*self.fft_len, self.frame_length_tag_key) - self.connect(sync_word_gen, (syncword_data_mux, 0)) - self.connect(header_payload_mux, allocator, (syncword_data_mux, 1)) - ffter = fft.fft_vcc(self.fft_len, False, (), False) cyclic_prefixer = digital.ofdm_cyclic_prefixer( self.fft_len, self.fft_len+self.cp_len, rolloff, - self.frame_length_tag_key + self.packet_length_tag_key ) + self.connect(header_payload_mux, allocator, (syncword_data_mux, 1)) self.connect(syncword_data_mux, ffter, cyclic_prefixer, self) + if debug_log: + self.connect(allocator, blocks.file_sink(8*64, 'tx-post-allocator.dat')) + self.connect(syncword_data_mux, blocks.file_sink(8*64, 'post-sync-mux.dat')) + self.connect(cyclic_prefixer, blocks.file_sink(8, 'tx-signal.dat')) class ofdm_rx(gr.hier_block2): - """ - Hierarchical block for OFDM demodulation. + """ Hierarchical block for OFDM demodulation. - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. + The input is a complex baseband signal (e.g. from a UHD source). + The detected packets are output as a stream of packed bits on the output. Args: fft_len: The length of FFT (integer). - cp_len: The length of cyclic prefix (integer). - occupied_carriers: ?? - pilot_carriers: ?? - pilot_symbols: ?? - length_tag_key: The name of the tag giving packet length. + cp_len: The length of cyclic prefix in total samples (integer). + frame_length_tag_key: Used internally to tag the length of the OFDM frame. + packet_length_tag_key: The name of the tag giving packet length at the input. + occupied_carriers: A vector of vectors describing which OFDM carriers are occupied. + pilot_carriers: A vector of vectors describing which OFDM carriers are occupied with pilot symbols. + pilot_symbols: The pilot symbols. + bps_header: Bits per symbol (header). + bps_payload: Bits per symbol (payload). + sync_word1: The first sync preamble symbol. This has to be with zeros on alternating carriers. + Used for fine and coarse frequency offset and timing estimation. + sync_word2: The second sync preamble symbol. This has to be filled entirely. Also used for + coarse frequency offset and channel estimation. """ def __init__(self, fft_len=_def_fft_len, cp_len=_def_cp_len, frame_length_tag_key=_def_frame_length_tag_key, @@ -192,11 +270,13 @@ class ofdm_rx(gr.hier_block2): bps_header=1, bps_payload=1, sync_word1=None, - sync_word2=None + sync_word2=None, + debug_log=False ): gr.hier_block2.__init__(self, "ofdm_rx", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_char)) + ### Param init / sanity check ######################################## self.fft_len = fft_len self.cp_len = cp_len self.frame_length_tag_key = frame_length_tag_key @@ -205,44 +285,60 @@ class ofdm_rx(gr.hier_block2): self.bps_header = bps_header self.bps_payload = bps_payload n_sync_words = 1 - header_constellation = _get_constellation(bps_header) if sync_word1 is None: - self.sync_word1 = _make_sync_word(fft_len, occupied_carriers, header_constellation) + self.sync_word1 = _make_sync_word1(fft_len, occupied_carriers, pilot_carriers) else: if len(sync_word1) != self.fft_len: raise ValueError("Length of sync sequence(s) must be FFT length.") self.sync_word1 = sync_word1 self.sync_word2 = () - if sync_word2 is not None: + if sync_word2 is None: + self.sync_word2 = _make_sync_word2(fft_len, occupied_carriers, pilot_carriers) + n_sync_words = 2 + elif len(sync_word2): if len(sync_word2) != fft_len: raise ValueError("Length of sync sequence(s) must be FFT length.") self.sync_word2 = sync_word2 n_sync_words = 2 - else: - sync_word2 = () - # Receiver path + ### Sync ############################################################ sync_detect = digital.ofdm_sync_sc_cfb(fft_len, cp_len) + delay = blocks.delay(gr.sizeof_gr_complex, fft_len+cp_len) oscillator = analog.frequency_modulator_fc(-2.0 / fft_len) - delay = gr.delay(gr.sizeof_gr_complex, fft_len+cp_len) mixer = gr.multiply_cc() - hpd = digital.header_payload_demux(n_sync_words, fft_len, cp_len, - frame_length_tag_key, "", True) + hpd = digital.header_payload_demux( + n_sync_words+1, # Number of OFDM symbols before payload (sync + 1 sym header) + fft_len, cp_len, # FFT length, guard interval + frame_length_tag_key, # Frame length tag key + "", # We're not using trigger tags + True # One output item is one OFDM symbol (False would output complex scalars) + ) self.connect(self, sync_detect) - self.connect((sync_detect, 0), oscillator, (mixer, 0)) - self.connect(self, delay, (mixer, 1)) - self.connect(mixer, (hpd, 0)) + self.connect(self, delay, (mixer, 0), (hpd, 0)) + self.connect((sync_detect, 0), oscillator, (mixer, 1)) self.connect((sync_detect, 1), (hpd, 1)) - # Header demodulation - header_fft = fft.fft_vcc(self.fft_len, True, (), True) - chanest = digital.ofdm_chanest_vcvc(self.sync_word1, self.sync_word2, 1) - header_equalizer = digital.ofdm_equalizer_simpledfe( - fft_len, header_constellation.base(), - occupied_carriers, pilot_carriers, pilot_symbols - ) - header_eq = digital.ofdm_frame_equalizer_vcvc(header_equalizer.base(), frame_length_tag_key, True) - header_serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers) + if debug_log: + self.connect((sync_detect, 0), blocks.file_sink(gr.sizeof_float, 'freq-offset.dat')) + self.connect((sync_detect, 1), blocks.file_sink(gr.sizeof_char, 'sync-detect.dat')) + ### Header demodulation ############################################## + header_fft = fft.fft_vcc(self.fft_len, True, (), True) + chanest = digital.ofdm_chanest_vcvc(self.sync_word1, numpy.fft.fftshift(self.sync_word2), 1) header_constellation = _get_constellation(bps_header) - header_demod = digital.constellation_decoder_cb(header_constellation.base()) + header_equalizer = digital.ofdm_equalizer_simpledfe( + fft_len, header_constellation.base(), + occupied_carriers, pilot_carriers, pilot_symbols, 0, 0 + ) + header_eq = digital.ofdm_frame_equalizer_vcvc( + header_equalizer.base(), + cp_len, + self.frame_length_tag_key, + True, + 1 # Header is 1 symbol long + ) + header_serializer = digital.ofdm_serializer_vcc( + fft_len, occupied_carriers, + self.frame_length_tag_key + ) + header_demod = digital.constellation_decoder_cb(header_constellation.base()) header_formatter = digital.packet_header_ofdm( occupied_carriers, 1, packet_length_tag_key, @@ -253,16 +349,45 @@ class ofdm_rx(gr.hier_block2): 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.msg_connect(header_parser, "header_data", hpd, "header_data") - # Payload demodulation + if debug_log: + self.connect((chanest, 1), blocks.file_sink(512, 'channel-estimate.dat')) + self.connect((chanest, 0), blocks.file_sink(512, 'post-hdr-chanest.dat')) + self.connect(header_eq, blocks.file_sink(512, 'post-hdr-eq.dat')) + self.connect(header_serializer, blocks.file_sink(8, 'post-hdr-serializer.dat')) + self.connect(header_demod, 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, header_constellation.base(), - occupied_carriers, pilot_carriers, pilot_symbols, 1 + fft_len, payload_constellation.base(), + occupied_carriers, + pilot_carriers, + pilot_symbols, + 1 # Skip 1 symbol (that was already in the header) + ) + payload_eq = digital.ofdm_frame_equalizer_vcvc( + payload_equalizer.base(), + cp_len, + self.frame_length_tag_key + ) + payload_serializer = digital.ofdm_serializer_vcc( + fft_len, occupied_carriers, + self.frame_length_tag_key, + self.packet_length_tag_key, + 1 # Skip 1 symbol (that was already in the header) ) - payload_eq = digital.ofdm_frame_equalizer_vcvc(payload_equalizer.base(), frame_length_tag_key) - payload_serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers) - payload_constellation = _get_constellation(bps_payload) payload_demod = digital.constellation_decoder_cb(payload_constellation.base()) - bit_packer = blocks.repack_bits_bb(bps_payload, 8, packet_length_tag_key, True) - self.connect((hpd, 1), payload_fft, payload_eq, payload_serializer, payload_demod, bit_packer, self) + 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) + if debug_log: + self.connect((hpd, 1), blocks.tag_debug(8*64, 'post-hpd')); + self.connect(payload_fft, blocks.file_sink(8*64, 'post-payload-fft.dat')) + self.connect(payload_eq, blocks.file_sink(8*64, 'post-payload-eq.dat')) + self.connect(payload_serializer, blocks.file_sink(8, 'post-payload-serializer.dat')) + self.connect(payload_demod, blocks.file_sink(1, 'post-payload-demod.dat')) + self.connect(repack, blocks.file_sink(1, 'post-payload-repack.dat')) + self.connect(crc, blocks.file_sink(1, 'post-payload-crc.dat')) + self.connect(crc, blocks.tag_debug(1, 'post-payload-crc')) + diff --git a/gr-digital/python/qa_ofdm_chanest_vcvc.py b/gr-digital/python/qa_ofdm_chanest_vcvc.py index c78f8fccfc..3b1ca15a05 100755 --- a/gr-digital/python/qa_ofdm_chanest_vcvc.py +++ b/gr-digital/python/qa_ofdm_chanest_vcvc.py @@ -19,13 +19,15 @@ # Boston, MA 02110-1301, USA. # +import sys +import numpy +import random from gnuradio import gr, gr_unittest try: import pmt except: from gruel import pmt import digital_swig as digital -import sys -import numpy -import random +import blocks_swig as blocks +from ofdm_txrx import ofdm_tx def shift_tuple(vec, N): """ Shifts a vector by N elements. Fills up with zeros. """ @@ -128,7 +130,9 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): chan = gr.multiply_const_vcc(channel) chanest = digital.ofdm_chanest_vcvc(sync_symbol1, sync_symbol2, 1) sink = gr.vector_sink_c(fft_len) + sink_chanest = gr.vector_sink_c(fft_len) self.tb.connect(src, chan, chanest, sink) + self.tb.connect((chanest, 1), sink_chanest) self.tb.run() tags = sink.tags() self.assertEqual(shift_tuple(sink.data(), -carr_offset), tuple(numpy.multiply(data_symbol, channel))) @@ -137,6 +141,7 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): self.assertEqual(pmt.pmt_to_long(tag.value), carr_offset) if pmt.pmt_symbol_to_string(tag.key) == 'ofdm_sync_chan_taps': self.assertEqual(pmt.pmt_c32vector_elements(tag.value), channel) + self.assertEqual(sink_chanest.data(), channel) def test_004_channel_no_carroffset_1sym (self): """ Add a channel, check if it's correctly estimated. @@ -146,13 +151,17 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): sync_symbol = (0, 0, 0, 1, 0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 0) data_symbol = (0, 0, 0, 1, -1, 1, -1, 1, 0, 1, -1, -1, -1, 1, 0, 0) tx_data = sync_symbol + data_symbol - channel = (0, 0, 0, 2, 2, 2, 2.5, 3, 2.5, 2, 2.5, 3, 2, 1, 1, 0) - src = gr.vector_source_c(tx_data, False, fft_len) - chan = gr.multiply_const_vcc(channel) + channel = (0, 0, 0, 2, 2, 2, 2, 3, 3, 2.5, 2.5, -3, -3, 1j, 1j, 0) + #channel = (0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) + src = blocks.vector_source_c(tx_data, False, fft_len) + chan = blocks.multiply_const_vcc(channel) chanest = digital.ofdm_chanest_vcvc(sync_symbol, (), 1) - sink = gr.vector_sink_c(fft_len) + sink = blocks.vector_sink_c(fft_len) + sink_chanest = blocks.vector_sink_c(fft_len) self.tb.connect(src, chan, chanest, sink) + self.tb.connect((chanest, 1), sink_chanest) self.tb.run() + self.assertEqual(sink_chanest.data(), channel) tags = sink.tags() for tag in tags: if pmt.pmt_symbol_to_string(tag.key) == 'ofdm_sync_carr_offset': @@ -193,6 +202,7 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): data_symbol = (0, 0, 0, 1, -1, 1, -1, 1, 0, 1, -1, -1, -1, 1, 0, 0) # Channel 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # Shifted (0, 0, 0, 0, 0, 1j, -1, 1, -1j, 1j, 0, 1, -1j, -1, -1j, 1) + chanest_exp = (0, 0, 0, 5, 6, 7, 8, 9, 0, 11, 12, 13, 14, 15, 0, 0) tx_data = shift_tuple(sync_symbol1, carr_offset) + \ shift_tuple(sync_symbol2, carr_offset) + \ shift_tuple(data_symbol, carr_offset) @@ -210,9 +220,7 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): self.assertEqual(pmt.pmt_to_long(tag.value), carr_offset) if pmt.pmt_symbol_to_string(tag.key) == 'ofdm_sync_chan_taps': chan_est = pmt.pmt_c32vector_elements(tag.value) - for i in range(fft_len): - if shift_tuple(sync_symbol2, carr_offset)[i]: # Only here the channel can be estimated - self.assertEqual(chan_est[i], channel[i]) + self.assertEqual(chan_est, chanest_exp) self.assertEqual(sink.data(), tuple(numpy.multiply(shift_tuple(data_symbol, carr_offset), channel))) @@ -226,7 +234,7 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): wgn_amplitude = 0.05 min_chan_ampl = 0.1 max_chan_ampl = 5 - n_iter = 100 + n_iter = 20 # The more the accurater def run_flow_graph(sync_sym1, sync_sym2, data_sym): top_block = gr.top_block() carr_offset = random.randint(-max_offset/2, max_offset/2) * 2 @@ -235,7 +243,7 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): shift_tuple(data_sym, carr_offset) channel = [rand_range(min_chan_ampl, max_chan_ampl) * numpy.exp(1j * rand_range(0, 2 * numpy.pi)) for x in range(fft_len)] src = gr.vector_source_c(tx_data, False, fft_len) - chan = gr.multiply_const_vcc(channel) + chan= gr.multiply_const_vcc(channel) noise = gr.noise_source_c(gr.GR_GAUSSIAN, wgn_amplitude) add = gr.add_cc(fft_len) chanest = digital.ofdm_chanest_vcvc(sync_sym1, sync_sym2, 1) @@ -252,7 +260,7 @@ class qa_ofdm_sync_eqinit_vcvc (gr_unittest.TestCase): carr_offset_hat = pmt.pmt_to_long(tag.value) self.assertEqual(carr_offset, carr_offset_hat) if pmt.pmt_symbol_to_string(tag.key) == 'ofdm_sync_chan_taps': - channel_est = pmt.pmt_c32vector_elements(tag.value) + channel_est = shift_tuple(pmt.pmt_c32vector_elements(tag.value), carr_offset) shifted_carrier_mask = shift_tuple(carrier_mask, carr_offset) for i in range(fft_len): if shifted_carrier_mask[i] and channel_est[i]: diff --git a/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py b/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py index cc369fafb5..36ae9af29e 100755 --- a/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py +++ b/gr-digital/python/qa_ofdm_frame_equalizer_vcvc.py @@ -24,6 +24,7 @@ from gnuradio import gr, gr_unittest try: import pmt except: from gruel import pmt import digital_swig as digital +import blocks_swig as blocks class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): @@ -34,7 +35,14 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): self.tb = None def test_001_simple (self): - """ Very simple functionality testing """ + """ Very simple functionality testing: + - static equalizer + - init channel state with all ones + - transmit all ones + - make sure we rx all ones + - Tag check: put in frame length tag and one other random tag, + make sure they're propagated + """ fft_len = 8 equalizer = digital.ofdm_equalizer_static(fft_len) n_syms = 3 @@ -48,18 +56,135 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): chan_tag.offset = 0 chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") chan_tag.value = pmt.pmt_init_c32vector(fft_len, (1,) * fft_len) - src = gr.vector_source_c(tx_data, False, fft_len, (len_tag, chan_tag)) - eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), len_tag_key) + random_tag = gr.gr_tag_t() + random_tag.offset = 1 + random_tag.key = pmt.pmt_string_to_symbol("foo") + random_tag.value = pmt.pmt_from_long(42) + src = gr.vector_source_c(tx_data, False, fft_len, (len_tag, chan_tag, random_tag)) + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () # Check data self.assertEqual(tx_data, sink.data()) + # Check tags + tag_dict = dict() for tag in sink.tags(): - self.assertEqual(pmt.pmt_symbol_to_string(tag.key), len_tag_key) - self.assertEqual(pmt.pmt_to_long(tag.value), n_syms) + ptag = gr.tag_to_python(tag) + tag_dict[ptag.key] = ptag.value + expected_dict = { + 'frame_len': n_syms, + 'foo': 42 + } + self.assertEqual(tag_dict, expected_dict) + + def test_001b_simple_skip_nothing (self): + """ + Same as before, but put a skip-header in there + """ + fft_len = 8 + equalizer = digital.ofdm_equalizer_static(fft_len, symbols_skipped=1) + n_syms = 3 + len_tag_key = "frame_len" + tx_data = (1,) * fft_len * n_syms + len_tag = gr.gr_tag_t() + len_tag.offset = 0 + len_tag.key = pmt.pmt_string_to_symbol(len_tag_key) + len_tag.value = pmt.pmt_from_long(n_syms) + chan_tag = gr.gr_tag_t() + chan_tag.offset = 0 + chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") + chan_tag.value = pmt.pmt_init_c32vector(fft_len, (1,) * fft_len) + src = gr.vector_source_c(tx_data, False, fft_len, (len_tag, chan_tag)) + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key) + sink = gr.vector_sink_c(fft_len) + self.tb.connect(src, eq, sink) + self.tb.run () + # Check data + self.assertEqual(tx_data, sink.data()) + + def test_001c_carrier_offset_no_cp (self): + """ + Same as before, but put a carrier offset in there + """ + fft_len = 8 + cp_len = 0 + n_syms = 1 + carr_offset = 1 + occupied_carriers = ((-2, -1, 1, 2),) + tx_data = ( + 0, 0, 0, -1j, -1j, 0, -1j, -1j, + ) + # The rx'd signal is shifted + rx_expected = (0, 0, 1, 1, 0, 1, 1, 0) * n_syms + equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers) + len_tag_key = "frame_len" + len_tag = gr.gr_tag_t() + len_tag.offset = 0 + len_tag.key = pmt.pmt_string_to_symbol(len_tag_key) + len_tag.value = pmt.pmt_from_long(n_syms) + chan_tag = gr.gr_tag_t() + chan_tag.offset = 0 + chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") + # Note: this is shifted to the correct position! + chan_tag.value = pmt.pmt_init_c32vector(fft_len, (0, 0, -1j, -1j, 0, -1j, -1j, 0)) + offset_tag = gr.gr_tag_t() + offset_tag.offset = 0 + offset_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_carr_offset") + offset_tag.value = pmt.pmt_from_long(carr_offset) + src = gr.vector_source_c(tx_data, False, fft_len, (len_tag, chan_tag, offset_tag)) + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), cp_len, len_tag_key) + sink = gr.vector_sink_c(fft_len) + self.tb.connect(src, eq, sink) + self.tb.run () + # Check data + self.assertComplexTuplesAlmostEqual(rx_expected, sink.data(), places=4) + + def test_001c_carrier_offset_cp (self): + """ + Same as before, but put a carrier offset in there and a CP + """ + fft_len = 8 + cp_len = 2 + n_syms = 3 + # cp_len/fft_len == 1/4, therefore, the phase is rotated by + # carr_offset * \pi/2 in every symbol + occupied_carriers = ((-2, -1, 1, 2),) + carr_offset = -1 + tx_data = ( + 0,-1j,-1j, 0,-1j,-1j, 0, 0, + 0, -1, -1, 0, -1, -1, 0, 0, + 0, 1j, 1j, 0, 1j, 1j, 0, 0, + ) + # Rx'd signal is corrected + rx_expected = (0, 0, 1, 1, 0, 1, 1, 0) * n_syms + equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers) + len_tag_key = "frame_len" + len_tag = gr.gr_tag_t() + len_tag.offset = 0 + len_tag.key = pmt.pmt_string_to_symbol(len_tag_key) + len_tag.value = pmt.pmt_from_long(n_syms) + chan_tag = gr.gr_tag_t() + chan_tag.offset = 0 + chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") + chan_tag.value = pmt.pmt_init_c32vector(fft_len, (0, 0, 1, 1, 0, 1, 1, 0)) + offset_tag = gr.gr_tag_t() + offset_tag.offset = 0 + offset_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_carr_offset") + offset_tag.value = pmt.pmt_from_long(carr_offset) + src = gr.vector_source_c(tx_data, False, fft_len, (len_tag, chan_tag, offset_tag)) + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), cp_len, len_tag_key) + sink = gr.vector_sink_c(fft_len) + self.tb.connect(src, eq, sink) + self.tb.run () + # Check data + self.assertComplexTuplesAlmostEqual(rx_expected, sink.data(), places=4) def test_002_static (self): + """ + - Add a simple channel + - Make symbols QPSK + """ fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 @@ -76,14 +201,18 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly... + 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (but less than \pi/2) 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! - 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. + 0, 0, 1j, 1j, 0, 1j, 1j, 0 + ] + channel = [ + 0, 0, 1, 1, 0, 1, 1, 0, + 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (but less than \pi/2) + 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! + 0, 0, 1j, 1j, 0, 1j, 1j, 0 ] for idx in range(fft_len, 2*fft_len): channel[idx] = channel[idx-fft_len] * numpy.exp(1j * .1 * numpy.pi * (numpy.random.rand()-.5)) - idx2 = idx+2*fft_len - channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) len_tag_key = "frame_len" len_tag = gr.gr_tag_t() len_tag.offset = 0 @@ -94,20 +223,36 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") chan_tag.value = pmt.pmt_init_c32vector(fft_len, channel[:fft_len]) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len, (len_tag, chan_tag)) - eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), len_tag_key, True) + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key, True) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] + # Check data self.assertEqual(tx_data, rx_data) + # Check tags + tag_dict = dict() for tag in sink.tags(): - if pmt.pmt_symbol_to_string(tag.key) == len_tag_key: - self.assertEqual(pmt.pmt_to_long(tag.value), 4) - if pmt.pmt_symbol_to_string(tag.key) == "ofdm_sync_chan_taps": - self.assertEqual(list(pmt.pmt_c32vector_elements(tag.value)), channel[-fft_len:]) + ptag = gr.tag_to_python(tag) + tag_dict[ptag.key] = ptag.value + if ptag.key == 'ofdm_sync_chan_taps': + tag_dict[ptag.key] = list(pmt.pmt_c32vector_elements(tag.value)) + else: + tag_dict[ptag.key] = pmt.to_python(tag.value) + expected_dict = { + 'frame_len': 4, + 'ofdm_sync_chan_taps': channel[-fft_len:] + } + self.assertEqual(tag_dict, expected_dict) def test_002_static_wo_tags (self): + """ Same as before, but the input stream has no tag. + We specify the frame size in the constructor. + We also specify a tag key, so the output stream *should* have + a length tag. + """ fft_len = 8 + n_syms = 4 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 -1, -1, 0, 2, -1, 2, 0, -1, # 8 @@ -123,7 +268,7 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): equalizer = digital.ofdm_equalizer_static(fft_len, occupied_carriers, pilot_carriers, pilot_symbols) channel = [ 0, 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly... + 0, 0, 1, 1, 0, 1, 1, 0, # These coefficients will be rotated slightly (below)... 0, 0, 1j, 1j, 0, 1j, 1j, 0, # Go crazy here! 0, 0, 1j, 1j, 0, 1j, 1j, 0 # ...and again here. ] @@ -132,14 +277,24 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): idx2 = idx+2*fft_len channel[idx2] = channel[idx2] * numpy.exp(1j * 0 * numpy.pi * (numpy.random.rand()-.5)) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len) - eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), "", False, 4) + # We do specify a length tag, it should then appear at the output + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, "frame_len", False, n_syms) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () rx_data = [cnst.decision_maker_v((x,)) if x != 0 else -1 for x in sink.data()] self.assertEqual(tx_data, rx_data) + # Check len tag + tags = sink.tags() + len_tag = dict() + for tag in tags: + ptag = gr.tag_to_python(tag) + if ptag.key == 'frame_len': + len_tag[ptag.key] = ptag.value + self.assertEqual(len_tag, {'frame_len': 4}) def test_002_simpledfe (self): + """ Use the simple DFE equalizer. """ fft_len = 8 # 4 5 6 7 0 1 2 3 tx_data = [-1, -1, 1, 2, -1, 3, 0, -1, # 0 @@ -176,7 +331,7 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase): chan_tag.key = pmt.pmt_string_to_symbol("ofdm_sync_chan_taps") chan_tag.value = pmt.pmt_init_c32vector(fft_len, channel[:fft_len]) src = gr.vector_source_c(numpy.multiply(tx_signal, channel), False, fft_len, (len_tag, chan_tag)) - eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), len_tag_key, True) + eq = digital.ofdm_frame_equalizer_vcvc(equalizer.base(), 0, len_tag_key, True) sink = gr.vector_sink_c(fft_len) self.tb.connect(src, eq, sink) self.tb.run () diff --git a/gr-digital/python/qa_ofdm_serializer_vcc.py b/gr-digital/python/qa_ofdm_serializer_vcc.py index 5914df9a56..1c7b4c23b1 100755 --- a/gr-digital/python/qa_ofdm_serializer_vcc.py +++ b/gr-digital/python/qa_ofdm_serializer_vcc.py @@ -23,6 +23,7 @@ from gnuradio import gr, gr_unittest import fft_swig as fft import digital_swig as digital +import blocks_swig as blocks try: import pmt except: from gruel import pmt import numpy @@ -38,7 +39,6 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): def test_001_simple (self): """ Standard test """ fft_len = 16 - tx_symbols = range(1, 16); tx_symbols = (0, 1, 1j, 2, 3, 0, 0, 0, 0, 0, 0, 4, 5, 2j, 6, 0, 0, 7, 8, 3j, 9, 0, 0, 0, 0, 0, 0, 10, 4j, 11, 12, 0, 0, 13, 1j, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 2j, 0, 0) @@ -51,7 +51,34 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): tag.key = pmt.pmt_string_to_symbol(tag_name) tag.value = pmt.pmt_from_long(n_syms) src = gr.vector_source_c(tx_symbols, False, fft_len, (tag,)) - serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers, tag_name, "", 0, False) + serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers, tag_name, "", 0, "", False) + sink = gr.vector_sink_c() + self.tb.connect(src, serializer, sink) + self.tb.run () + self.assertEqual(sink.data(), expected_result) + self.assertEqual(len(sink.tags()), 1) + result_tag = sink.tags()[0] + self.assertEqual(pmt.pmt_symbol_to_string(result_tag.key), tag_name) + self.assertEqual(pmt.pmt_to_long(result_tag.value), n_syms * len(occupied_carriers[0])) + + def test_001b_shifted (self): + """ Same as before, but shifted, because that's the normal mode in OFDM Rx """ + fft_len = 16 + tx_symbols = ( + 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 4, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 1j, 7, 8, 0, 9, 10, 1j, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 13, 14, 0, 15, 16, 17, 0, 0, 0, 0, + ) + expected_result = tuple(range(18)) + occupied_carriers = ((13, 14, 15, 1, 2, 3), (-4, -2, -1, 1, 2, 4),) + n_syms = len(tx_symbols)/fft_len + tag_name = "len" + tag = gr.gr_tag_t() + tag.offset = 0 + tag.key = pmt.pmt_string_to_symbol(tag_name) + tag.value = pmt.pmt_from_long(n_syms) + src = gr.vector_source_c(tx_symbols, False, fft_len, (tag,)) + serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers, tag_name) sink = gr.vector_sink_c() self.tb.connect(src, serializer, sink) self.tb.run () @@ -82,7 +109,14 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): offsettag.key = pmt.pmt_string_to_symbol("ofdm_sync_carr_offset") offsettag.value = pmt.pmt_from_long(carr_offset) src = gr.vector_source_c(tx_symbols, False, fft_len, (tag, offsettag)) - serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers, tag_name, "", 0, False) + serializer = digital.ofdm_serializer_vcc( + fft_len, + occupied_carriers, + tag_name, + "", 0, + "ofdm_sync_carr_offset", + False + ) sink = gr.vector_sink_c() self.tb.connect(src, serializer, sink) self.tb.run () @@ -112,7 +146,7 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): pilot_carriers, pilot_symbols, tag_name) - serializer = digital.ofdm_serializer_vcc(alloc) + serializer = digital.ofdm_serializer_vcc(alloc, "", 0, "", False) sink = gr.vector_sink_c() self.tb.connect(src, alloc, serializer, sink) self.tb.run () @@ -127,14 +161,13 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): - Frequency offset is -2 carriers """ fft_len = 8 - n_syms = 2 + n_syms = 1 carr_offset = -2 - freq_offset = 2 * numpy.pi * carr_offset / fft_len # If the sampling rate == 1 - occupied_carriers = ((1, 2, -2, -1),) + freq_offset = 1.0 / fft_len * carr_offset # Normalized frequency + occupied_carriers = ((-2, -1, 1, 2),) pilot_carriers = ((3,),(5,)) pilot_symbols = ((1j,),(-1j,)) - tx_data = tuple([numpy.random.randint(0, 10) for x in range(4 * n_syms)]) - #tx_data = (1,) * occupied_carriers[0] * n_syms + tx_data = (1, 1, 1, 1) tag_name = "len" tag = gr.gr_tag_t() tag.offset = 0 @@ -150,11 +183,13 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): pilot_carriers, pilot_symbols, tag_name) - tx_ifft = fft.fft_vcc(fft_len, False, ()) - offset_sig = gr.sig_source_c(1.0, gr.GR_COS_WAVE, freq_offset, 1.0) + tx_ifft = fft.fft_vcc(fft_len, False, (1.0/fft_len,)*fft_len) + oscillator = gr.sig_source_c(1.0, gr.GR_COS_WAVE, freq_offset, 1.0/fft_len) mixer = gr.multiply_cc() rx_fft = fft.fft_vcc(fft_len, True, (), True) - serializer = digital.ofdm_serializer_vcc(alloc) + serializer = digital.ofdm_serializer_vcc( + alloc, "", 0, "ofdm_sync_carr_offset" + ) sink = gr.vector_sink_c() self.tb.connect( src, alloc, tx_ifft, @@ -163,10 +198,9 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): gr.stream_to_vector(gr.sizeof_gr_complex, fft_len), rx_fft, serializer, sink ) - self.tb.connect(offset_sig, (mixer, 1)) + self.tb.connect(oscillator, (mixer, 1)) self.tb.run () - # FIXME check this - #self.assertEqual(sink.data(), tx_data) + self.assertComplexTuplesAlmostEqual(sink.data(), tx_data, places=5) def test_005_packet_len_tag (self): """ Standard test """ @@ -188,7 +222,7 @@ class qa_ofdm_serializer_vcc (gr_unittest.TestCase): tag2.key = pmt.pmt_string_to_symbol("packet_len") tag2.value = pmt.pmt_from_long(len(expected_result)) src = gr.vector_source_c(tx_symbols, False, fft_len, (tag, tag2)) - serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers, tag_name, "packet_len", 0, False) + serializer = digital.ofdm_serializer_vcc(fft_len, occupied_carriers, tag_name, "packet_len", 0, "", False) sink = gr.vector_sink_c() self.tb.connect(src, serializer, sink) self.tb.run () diff --git a/gr-digital/python/qa_ofdm_sync_sc_cfb.py b/gr-digital/python/qa_ofdm_sync_sc_cfb.py index f6ae001ea3..b6feee79cd 100755 --- a/gr-digital/python/qa_ofdm_sync_sc_cfb.py +++ b/gr-digital/python/qa_ofdm_sync_sc_cfb.py @@ -62,7 +62,7 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase): sink_freq = gr.vector_sink_f() sink_detect = gr.vector_sink_b() self.tb.connect(gr.vector_source_c(tx_signal), (add, 0)) - self.tb.connect(gr.noise_source_c(gr.GR_GAUSSIAN, .01), (add, 1)) + self.tb.connect(gr.noise_source_c(gr.GR_GAUSSIAN, .005), (add, 1)) self.tb.connect(add, sync) self.tb.connect((sync, 0), sink_freq) self.tb.connect((sync, 1), sink_detect) @@ -74,12 +74,13 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase): self.assertEqual(numpy.sum(sig1_detect), 1) self.assertEqual(numpy.sum(sig2_detect), 1) - def test_002_freq (self): """ Add a fine frequency offset and see if that get's detected properly """ fft_len = 32 cp_len = 4 - freq_offset = 0.1 # Must stay < 2*pi/fft_len = 0.196 (otherwise, it's coarse) + # This frequency offset is normalized to rads, i.e. \pi == f_s/2 + max_freq_offset = 2*numpy.pi/fft_len # Otherwise, it's coarse + freq_offset = ((2 * random.random()) - 1) * max_freq_offset sig_len = (fft_len + cp_len) * 10 sync_symbol = [(random.randint(0, 1)*2)-1 for x in range(fft_len/2)] * 2 tx_signal = sync_symbol[-cp_len:] + \ @@ -87,13 +88,11 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase): [(random.randint(0, 1)*2)-1 for x in range(sig_len)] mult = gr.multiply_cc() add = gr.add_cc() - sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len) + sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len, True) + channel = gr.channel_model(0.005, freq_offset / 2.0 / numpy.pi) sink_freq = gr.vector_sink_f() sink_detect = gr.vector_sink_b() - self.tb.connect(gr.vector_source_c(tx_signal), (mult, 0), (add, 0)) - self.tb.connect(gr.sig_source_c(2 * numpy.pi, gr.GR_SIN_WAVE, freq_offset, 1.0), (mult, 1)) - self.tb.connect(gr.noise_source_c(gr.GR_GAUSSIAN, .01), (add, 1)) - self.tb.connect(add, sync) + self.tb.connect(gr.vector_source_c(tx_signal), channel, sync) self.tb.connect((sync, 0), sink_freq) self.tb.connect((sync, 1), sink_detect) self.tb.run() @@ -101,7 +100,6 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase): est_freq_offset = 2 * phi_hat / fft_len self.assertAlmostEqual(est_freq_offset, freq_offset, places=2) - def test_003_multiburst (self): """ Send several bursts, see if the number of detects is correct. Burst lengths and content are random. @@ -120,75 +118,55 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase): sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len) sink_freq = gr.vector_sink_f() sink_detect = gr.vector_sink_b() - self.tb.connect(gr.vector_source_c(tx_signal), (add, 0)) - self.tb.connect(gr.noise_source_c(gr.GR_GAUSSIAN, .005), (add, 1)) - self.tb.connect(add, sync) + channel = gr.channel_model(0.005) + self.tb.connect(gr.vector_source_c(tx_signal), channel, sync) self.tb.connect((sync, 0), sink_freq) self.tb.connect((sync, 1), sink_detect) self.tb.run() - self.assertEqual(numpy.sum(sink_detect.data()), n_bursts, + n_bursts_detected = numpy.sum(sink_detect.data()) + # We allow for one false alarm or missed burst + self.assertTrue(abs(n_bursts_detected - n_bursts) <= 1, msg="""Because of statistics, it is possible (though unlikely) that the number of detected bursts differs slightly. If the number of detects is off by one or two, run the test again and see what happen. Detection error was: %d """ % (numpy.sum(sink_detect.data()) - n_bursts) ) - # FIXME ofdm_mod is currently not working - #def test_004_ofdm_packets (self): - #""" - #Send several bursts, see if the number of detects is correct. - #Burst lengths and content are random. - #""" - #n_bursts = 42 - #fft_len = 64 - #cp_len = 12 - #tx_signal = [] - #packets = [] - #tagname = "length" - #min_packet_length = 100 - #max_packet_length = 100 - #sync_sequence = [random.randint(0, 1)*2-1 for x in range(fft_len/2)] - #for i in xrange(n_bursts): - #packet_length = random.randint(min_packet_length, - #max_packet_length+1) - #packet = [random.randint(0, 255) for i in range(packet_length)] - #packets.append(packet) - #data, tags = tagged_streams.packets_to_vectors( - #packets, tagname, vlen=1) - #total_length = len(data) - - #src = gr.vector_source_b(data, False, 1, tags) - #mod = ofdm_tx( - #fft_len=fft_len, - #cp_len=cp_len, - #length_tag_name=tagname, - #occupied_carriers=(range(1, 27) + range(38, 64),), - #pilot_carriers=((0,),), - #pilot_symbols=((100,),), - #) - #rate_in = 16000 - #rate_out = 48000 - #ratio = float(rate_out) / rate_in - #throttle1 = gr.throttle(gr.sizeof_gr_complex, rate_in) - #sink_countbursts = gr.vector_sink_c() - #head = gr.head(gr.sizeof_gr_complex, int(total_length * ratio*2)) - #add = gr.add_cc() - #sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len) - #sink_freq = gr.vector_sink_f() - #sink_detect = gr.vector_sink_b() - #noise_level = 0.01 - #noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_level) - #self.tb.connect(src, mod, gr.null_sink(gr.sizeof_gr_complex)) - #self.tb.connect(insert_zeros, sink_countbursts) - #self.tb.connect(noise, (add, 1)) - #self.tb.connect(add, sync) - #self.tb.connect((sync, 0), sink_freq) - #self.tb.connect((sync, 1), sink_detect) - #self.tb.run() - #count_data = sink_countbursts.data() - #count_tags = sink_countbursts.tags() - #burstcount = tagged_streams.count_bursts(count_data, count_tags, tagname) - #self.assertEqual(numpy.sum(sink_detect.data()), burstcount) + def test_004_ofdm_packets (self): + """ + Send several bursts using ofdm_tx, see if the number of detects is correct. + Burst lengths and content are random. + """ + n_bursts = 42 + fft_len = 64 + cp_len = 16 + # Here, coarse freq offset is allowed + max_freq_offset = 2*numpy.pi/fft_len * 4 + freq_offset = ((2 * random.random()) - 1) * max_freq_offset + tx_signal = [] + packets = [] + tagname = "packet_length" + min_packet_length = 10 + max_packet_length = 50 + sync_sequence = [random.randint(0, 1)*2-1 for x in range(fft_len/2)] + for i in xrange(n_bursts): + packet_length = random.randint(min_packet_length, + max_packet_length+1) + packet = [random.randint(0, 255) for i in range(packet_length)] + packets.append(packet) + data, tags = tagged_streams.packets_to_vectors(packets, tagname, vlen=1) + total_length = len(data) + src = gr.vector_source_b(data, False, 1, tags) + mod = ofdm_tx(packet_length_tag_key=tagname) + sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len) + sink_freq = gr.vector_sink_f() + sink_detect = gr.vector_sink_b() + noise_level = 0.005 + channel = gr.channel_model(noise_level, freq_offset / 2 / numpy.pi) + self.tb.connect(src, mod, channel, sync, sink_freq) + self.tb.connect((sync, 1), sink_detect) + self.tb.run() + self.assertEqual(numpy.sum(sink_detect.data()), n_bursts) if __name__ == '__main__': diff --git a/gr-digital/python/qa_ofdm_txrx.py b/gr-digital/python/qa_ofdm_txrx.py index ad5a996b2c..ca85c776d4 100755 --- a/gr-digital/python/qa_ofdm_txrx.py +++ b/gr-digital/python/qa_ofdm_txrx.py @@ -21,12 +21,46 @@ # import numpy +import scipy import random from gnuradio import gr, gr_unittest +import blocks_swig as blocks import digital_swig as digital from ofdm_txrx import ofdm_tx, ofdm_rx from utils import tagged_streams +# Set this to true if you need to write out data +LOG_DEBUG_INFO=False + +class ofdm_tx_fg (gr.top_block): + def __init__(self, data, len_tag_key): + 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.sink = blocks.vector_sink_c() + self.connect(src, self.tx, self.sink) + + def get_tx_samples(self): + return self.sink.data() + +class ofdm_rx_fg (gr.top_block): + def __init__(self, samples, len_tag_key, channel=None, prepend_zeros=100): + 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) + if channel is not None: + self.connect(src, channel, self.rx) + else: + self.connect(src, self.rx) + self.sink = blocks.vector_sink_b() + self.connect(self.rx, self.sink) + + def get_rx_bytes(self): + return self.sink.data() + class test_ofdm_txrx (gr_unittest.TestCase): def setUp (self): @@ -35,26 +69,73 @@ class test_ofdm_txrx (gr_unittest.TestCase): def tearDown (self): self.tb = None - def test_001 (self): - pass - #len_tag_key = 'frame_len' - #n_bytes = 100 - #test_data = [random.randint(0, 255) for x in range(n_bytes)] - #tx_data, tags = tagged_streams.packets_to_vectors((test_data,), len_tag_key) - #src = gr.vector_source_b(test_data, False, 1, tags) - #tx = ofdm_tx(frame_length_tag_key=len_tag_key) - #rx = ofdm_rx(frame_length_tag_key=len_tag_key) - #self.assertEqual(tx.sync_word1, rx.sync_word1) - #self.assertEqual(tx.sync_word2, rx.sync_word2) - #delay = gr.delay(gr.sizeof_gr_complex, 100) - #noise = gr.noise_source_c(gr.GR_GAUSSIAN, 0.05) - #add = gr.add_cc() - #sink = gr.vector_sink_b() - ##self.tb.connect(src, tx, add, rx, sink) - ##self.tb.connect(noise, (add, 1)) - #self.tb.connect(src, tx, gr.null_sink(gr.sizeof_gr_complex)) - #self.tb.run() + def test_001_tx (self): + """ Just make sure the Tx works in general """ + len_tag_key = 'frame_len' + n_bytes = 52 + n_samples_expected = (numpy.ceil(1.0 * (n_bytes + 4) / 6) + 3) * 80 + test_data = [random.randint(0, 255) for x in range(n_bytes)] + tx_data, tags = tagged_streams.packets_to_vectors((test_data,), len_tag_key) + src = gr.vector_source_b(test_data, False, 1, tags) + tx = ofdm_tx(packet_length_tag_key=len_tag_key) + tx_fg = ofdm_tx_fg(test_data, len_tag_key) + tx_fg.run() + self.assertEqual(len(tx_fg.get_tx_samples()), n_samples_expected) + + def test_002_rx_only_noise(self): + """ Run the RX with only noise, check it doesn't crash + or return a burst. """ + len_tag_key = 'frame_len' + samples = (0,) * 1000 + channel = gr.channel_model(0.1) + rx_fg = ofdm_rx_fg(samples, len_tag_key, channel) + rx_fg.run() + self.assertEqual(len(rx_fg.get_rx_bytes()), 0) + + def test_003_tx1packet(self): + """ Transmit one packet, with slight AWGN and slight frequency + timing offset. + Check packet is received and no bit errors have occurred. """ + 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 = gr.channel_model(0.01, freq_offset) + # Tx + tx_fg = ofdm_tx_fg(test_data, len_tag_key) + 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) + rx_fg.run() + rx_data = rx_fg.get_rx_bytes() + self.assertEqual(tx_fg.tx.sync_word1, 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. """ + fft_len = 64 + len_tag_key = 'frame_len' + n_bytes = 21 + #test_data = tuple([random.randint(0, 255) for x in range(n_bytes)]) + test_data = tuple([255 for x in range(n_bytes)]) + # 1.0/fft_len is one sub-carrier + frequency_offset = 1.0 / fft_len * 2.5 + channel = gr.channel_model(0.00001, frequency_offset) + # Tx + tx_fg = ofdm_tx_fg(test_data, len_tag_key) + 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) + rx_fg.run() + rx_data = rx_fg.get_rx_bytes() + self.assertEqual(tx_fg.tx.sync_word1, 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) if __name__ == '__main__': gr_unittest.run(test_ofdm_txrx, "test_ofdm_txrx.xml") diff --git a/gr-digital/python/qa_packet_headerparser_b.py b/gr-digital/python/qa_packet_headerparser_b.py index fd6fdd2b68..3b8b8b3ee9 100755 --- a/gr-digital/python/qa_packet_headerparser_b.py +++ b/gr-digital/python/qa_packet_headerparser_b.py @@ -49,7 +49,11 @@ class qa_packet_headerparser_b (gr_unittest.TestCase): ) packet_len_tagname = "packet_len" - src = gr.vector_source_b(encoded_headers) + random_tag = gr.gr_tag_t() + random_tag.offset = 5 + random_tag.key = pmt.pmt_string_to_symbol("foo") + random_tag.value = pmt.pmt_from_long(42) + src = gr.vector_source_b(encoded_headers, tags=(random_tag,)) parser = digital.packet_headerparser_b(32, packet_len_tagname) sink = gr.message_debug() self.tb.connect(src, parser) @@ -62,7 +66,7 @@ class qa_packet_headerparser_b (gr_unittest.TestCase): msg1 = pmt.to_python(sink.get_message(0)) msg2 = pmt.to_python(sink.get_message(1)) msg3 = pmt.to_python(sink.get_message(2)) - self.assertEqual(msg1, {'packet_len': 4, 'packet_num': 0}) + self.assertEqual(msg1, {'packet_len': 4, 'packet_num': 0, 'foo': 42}) self.assertEqual(msg2, {'packet_len': 2, 'packet_num': 1}) self.assertEqual(msg3, False) @@ -124,8 +128,10 @@ class qa_packet_headerparser_b (gr_unittest.TestCase): self.assertEqual(sink.num_messages(), 2) msg1 = pmt.to_python(sink.get_message(0)) msg2 = pmt.to_python(sink.get_message(1)) - self.assertEqual(msg1, {'packet_len': 193, 'frame_len': 25, 'packet_num': 0}) - self.assertEqual(msg2, {'packet_len': 8, 'frame_len': 1, 'packet_num': 1}) + 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}) if __name__ == '__main__': gr_unittest.run(qa_packet_headerparser_b, "qa_packet_headerparser_b.xml") + + diff --git a/gr-digital/swig/digital_ofdm_equalizer_base.i b/gr-digital/swig/digital_ofdm_equalizer_base.i index c862fed09d..9de293f358 100644 --- a/gr-digital/swig/digital_ofdm_equalizer_base.i +++ b/gr-digital/swig/digital_ofdm_equalizer_base.i @@ -37,7 +37,6 @@ class digital_ofdm_equalizer_base digital_ofdm_equalizer_base(int fft_len); virtual void reset() = 0; - void set_carrier_offset(int offset) { d_carr_offset = offset; }; virtual void equalize( gr_complex *frame, int n_sym, diff --git a/gr-digital/swig/digital_ofdm_sync_sc_cfb.i b/gr-digital/swig/digital_ofdm_sync_sc_cfb.i index 6a863ca3f9..e0298f8b8d 100644 --- a/gr-digital/swig/digital_ofdm_sync_sc_cfb.i +++ b/gr-digital/swig/digital_ofdm_sync_sc_cfb.i @@ -23,11 +23,11 @@ GR_SWIG_BLOCK_MAGIC(digital, ofdm_sync_sc_cfb) digital_ofdm_sync_sc_cfb_sptr -digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len); +digital_make_ofdm_sync_sc_cfb (int fft_len, int cp_len, bool use_even_carriers=false); class digital_ofdm_sync_sc_cfb : public gr_hier_block2 { private: - digital_ofdm_sync_sc_cfb(int fft_len, int cp_len); + digital_ofdm_sync_sc_cfb(int fft_len, int cp_len, bool use_even_carriers); }; |