summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--docs/doxygen/Doxyfile.in27
-rw-r--r--docs/doxygen/other/stream_tags.dox5
-rw-r--r--gnuradio-runtime/include/gnuradio/block.h6
-rw-r--r--gnuradio-runtime/include/gnuradio/buffer.h10
-rw-r--r--gnuradio-runtime/include/pmt/pmt.h10
-rw-r--r--gnuradio-runtime/lib/buffer.cc58
-rw-r--r--gnuradio-runtime/lib/pmt/pmt.cc12
-rw-r--r--gnuradio-runtime/lib/pmt/qa_pmt_prims.cc9
-rw-r--r--gnuradio-runtime/python/gnuradio/gr/tag_utils.py17
-rwxr-xr-xgnuradio-runtime/python/pmt/qa_pmt.py2
-rw-r--r--gnuradio-runtime/swig/pmt_swig.i2
-rw-r--r--gr-blocks/examples/CMakeLists.txt8
-rw-r--r--gr-blocks/examples/vector_source_with_tags.grc698
-rw-r--r--gr-blocks/grc/blocks_abs_xx.xml19
-rw-r--r--gr-blocks/grc/blocks_tagged_stream_to_pdu.xml1
-rw-r--r--gr-blocks/include/gnuradio/blocks/abs_XX.h.t2
-rw-r--r--gr-blocks/lib/abs_XX_impl.cc.t13
-rw-r--r--gr-blocks/lib/abs_XX_impl.h.t5
-rw-r--r--gr-blocks/lib/deinterleave_impl.cc36
-rw-r--r--gr-blocks/lib/deinterleave_impl.h3
-rw-r--r--gr-blocks/lib/message_strobe_impl.cc8
-rw-r--r--gr-blocks/lib/message_strobe_impl.h2
-rw-r--r--gr-blocks/lib/message_strobe_random_impl.cc4
-rw-r--r--gr-blocks/lib/message_strobe_random_impl.h2
-rw-r--r--gr-blocks/lib/qa_block_tags.cc198
-rw-r--r--gr-blocks/lib/throttle_impl.cc8
-rw-r--r--gr-blocks/lib/throttle_impl.h3
-rw-r--r--gr-blocks/lib/vector_source_X_impl.cc.t2
-rw-r--r--gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h17
-rw-r--r--gr-digital/lib/header_payload_demux_impl.cc71
-rw-r--r--gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc66
-rw-r--r--gr-digital/lib/ofdm_serializer_vcc_impl.cc80
-rwxr-xr-xgr-digital/python/digital/qa_header_payload_demux.py80
-rwxr-xr-xgr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py2
-rw-r--r--gr-fec/lib/decoder_impl.cc8
-rw-r--r--gr-fec/lib/encoder_impl.cc12
-rw-r--r--gr-uhd/lib/usrp_sink_impl.cc15
-rw-r--r--gr-uhd/lib/usrp_source_impl.cc15
-rw-r--r--grc/base/FlowGraph.py20
-rw-r--r--grc/blocks/options.xml10
-rw-r--r--grc/gui/ActionHandler.py15
-rw-r--r--grc/gui/Block.py10
-rw-r--r--grc/gui/Constants.py7
-rw-r--r--grc/gui/Messages.py8
-rw-r--r--grc/gui/Param.py5
-rw-r--r--grc/gui/Port.py8
-rw-r--r--volk/apps/volk_profile.cc62
-rw-r--r--volk/kernels/volk/volk_32f_tanh_32f.h296
-rw-r--r--volk/lib/CMakeLists.txt15
-rw-r--r--volk/lib/qa_utils.cc32
-rw-r--r--volk/lib/qa_utils.h43
-rw-r--r--volk/lib/testqa.cc1
53 files changed, 1696 insertions, 376 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8846513a07..858a7d6a2f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,8 +46,8 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
# Set the version information here
set(VERSION_INFO_MAJOR_VERSION 3)
set(VERSION_INFO_API_COMPAT 7)
-set(VERSION_INFO_MINOR_VERSION 5)
-set(VERSION_INFO_MAINT_VERSION 0)
+set(VERSION_INFO_MINOR_VERSION 6)
+set(VERSION_INFO_MAINT_VERSION git)
include(GrVersion) #setup version info
# Append -O2 optimization flag for Debug builds
diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in
index 3b82e2c40c..3f558526e7 100644
--- a/docs/doxygen/Doxyfile.in
+++ b/docs/doxygen/Doxyfile.in
@@ -142,26 +142,51 @@ STRIP_FROM_PATH =
# are normally passed to the compiler using the -I flag.
STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/gnuradio-runtime/include \
+ @CMAKE_BINARY_DIR@/gnuradio-runtime/include \
@CMAKE_SOURCE_DIR@/gr-analog/include \
+ @CMAKE_BINARY_DIR@/gr-analog/include \
@CMAKE_SOURCE_DIR@/gr-atsc/include \
+ @CMAKE_BINARY_DIR@/gr-atsc/include \
@CMAKE_SOURCE_DIR@/gr-audio/include \
+ @CMAKE_BINARY_DIR@/gr-audio/include \
@CMAKE_SOURCE_DIR@/gr-blocks/include \
+ @CMAKE_BINARY_DIR@/gr-blocks/include \
@CMAKE_SOURCE_DIR@/gr-channels/include \
+ @CMAKE_BINARY_DIR@/gr-channels/include \
@CMAKE_SOURCE_DIR@/gr-comedi/include \
+ @CMAKE_BINARY_DIR@/gr-comedi/include \
@CMAKE_SOURCE_DIR@/gr-digital/include \
+ @CMAKE_BINARY_DIR@/gr-digital/include \
+ @CMAKE_SOURCE_DIR@/gr-dtv/include \
+ @CMAKE_BINARY_DIR@/gr-dtv/include \
@CMAKE_SOURCE_DIR@/gr-fcd/include \
+ @CMAKE_BINARY_DIR@/gr-fcd/include \
@CMAKE_SOURCE_DIR@/gr-fec/include \
+ @CMAKE_BINARY_DIR@/gr-fec/include \
@CMAKE_SOURCE_DIR@/gr-fft/include \
+ @CMAKE_BINARY_DIR@/gr-fft/include \
@CMAKE_SOURCE_DIR@/gr-filter/include \
+ @CMAKE_BINARY_DIR@/gr-filter/include \
@CMAKE_SOURCE_DIR@/gr-noaa/include \
+ @CMAKE_BINARY_DIR@/gr-noaa/include \
@CMAKE_SOURCE_DIR@/gr-pager/include \
+ @CMAKE_BINARY_DIR@/gr-pager/include \
@CMAKE_SOURCE_DIR@/gr-qtgui/include \
+ @CMAKE_BINARY_DIR@/gr-qtgui/include \
@CMAKE_SOURCE_DIR@/gr-trellis/include \
+ @CMAKE_BINARY_DIR@/gr-trellis/include \
@CMAKE_SOURCE_DIR@/gr-uhd/include \
+ @CMAKE_BINARY_DIR@/gr-uhd/include \
@CMAKE_SOURCE_DIR@/gr-video-sdl/include \
+ @CMAKE_BINARY_DIR@/gr-video-sdl/include \
@CMAKE_SOURCE_DIR@/gr-vocoder/include \
+ @CMAKE_BINARY_DIR@/gr-vocoder/include \
+ @CMAKE_SOURCE_DIR@/gr-wavelet/include \
+ @CMAKE_BINARY_DIR@/gr-wavelet/include \
@CMAKE_SOURCE_DIR@/gr-wxgui/include \
- @CMAKE_SOURCE_DIR@/volk/include
+ @CMAKE_BINARY_DIR@/gr-wxgui/include \
+ @CMAKE_SOURCE_DIR@/volk/include \
+ @CMAKE_BINARY_DIR@/volk/include
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful if your file system
diff --git a/docs/doxygen/other/stream_tags.dox b/docs/doxygen/other/stream_tags.dox
index 851740984e..d48ec1ddee 100644
--- a/docs/doxygen/other/stream_tags.dox
+++ b/docs/doxygen/other/stream_tags.dox
@@ -61,7 +61,10 @@ at <em>nitems_written(0)+i</em> for the 0th output port.
\section stream_tags_api Stream Tags API
The stream tags API consists of four functions, two to add and two to
-get the stream tags. These functions are:
+get the stream tags. These functions are only meant to be accessed
+within a call to general_work/work. While they can be called elsewhere
+in time by a block, the behavior outside of work is undefined without
+exact knowledge of the item counts in the buffers.
\li gr::block::add_item_tag: Adds an item tag to a particular output port using a
gr::tag_t data type.
diff --git a/gnuradio-runtime/include/gnuradio/block.h b/gnuradio-runtime/include/gnuradio/block.h
index a033e0ac27..43fc50c54b 100644
--- a/gnuradio-runtime/include/gnuradio/block.h
+++ b/gnuradio-runtime/include/gnuradio/block.h
@@ -636,7 +636,7 @@ namespace gr {
void add_item_tag(unsigned int which_output, const tag_t &tag);
/*!
- * \brief Removes a tag from the given input buffer.
+ * \brief DEPRECATED. Will be removed in 3.8.
*
* \param which_input an integer of which input stream to remove the tag from
* \param abs_offset a uint64 number of the absolute item number
@@ -662,9 +662,7 @@ namespace gr {
}
/*!
- * \brief Removes a tag from the given input buffer.
- *
- * If no such tag is found, does nothing.
+ * \brief DEPRECATED. Will be removed in 3.8.
*
* \param which_input an integer of which input stream to remove the tag from
* \param tag the tag object to remove
diff --git a/gnuradio-runtime/include/gnuradio/buffer.h b/gnuradio-runtime/include/gnuradio/buffer.h
index e2d5760e59..c0c9f3d39d 100644
--- a/gnuradio-runtime/include/gnuradio/buffer.h
+++ b/gnuradio-runtime/include/gnuradio/buffer.h
@@ -28,7 +28,7 @@
#include <gnuradio/tags.h>
#include <boost/weak_ptr.hpp>
#include <gnuradio/thread/thread.h>
-#include <deque>
+#include <map>
namespace gr {
@@ -125,8 +125,10 @@ namespace gr {
*/
void prune_tags(uint64_t max_time);
- std::deque<tag_t>::iterator get_tags_begin() { return d_item_tags.begin(); }
- std::deque<tag_t>::iterator get_tags_end() { return d_item_tags.end(); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_begin() { return d_item_tags.begin(); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_end() { return d_item_tags.end(); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_lower_bound(uint64_t x) { return d_item_tags.lower_bound(x); }
+ std::multimap<uint64_t,tag_t>::iterator get_tags_upper_bound(uint64_t x) { return d_item_tags.upper_bound(x); }
// -------------------------------------------------------------------------
@@ -157,7 +159,7 @@ namespace gr {
unsigned int d_write_index; // in items [0,d_bufsize)
uint64_t d_abs_write_offset; // num items written since the start
bool d_done;
- std::deque<tag_t> d_item_tags;
+ std::multimap<uint64_t,tag_t> d_item_tags;
uint64_t d_last_min_items_read;
unsigned index_add(unsigned a, unsigned b)
diff --git a/gnuradio-runtime/include/pmt/pmt.h b/gnuradio-runtime/include/pmt/pmt.h
index 3e17571b23..cb6fdf44d5 100644
--- a/gnuradio-runtime/include/pmt/pmt.h
+++ b/gnuradio-runtime/include/pmt/pmt.h
@@ -201,6 +201,7 @@ PMT_API bool is_real(pmt_t obj);
//! Return the pmt value that represents double \p x.
PMT_API pmt_t from_double(double x);
+PMT_API pmt_t from_float(float x);
/*!
* \brief Convert pmt to double if possible.
@@ -211,6 +212,15 @@ PMT_API pmt_t from_double(double x);
*/
PMT_API double to_double(pmt_t x);
+/*!
+ * \brief Convert pmt to float if possible.
+ *
+ * This basically is to_double() with a type-cast; the PMT stores
+ * the value as a double in any case. Use this when strict typing
+ * is required.
+ */
+PMT_API float to_float(pmt_t x);
+
/*
* ------------------------------------------------------------------------
* Complex
diff --git a/gnuradio-runtime/lib/buffer.cc b/gnuradio-runtime/lib/buffer.cc
index 162324e590..f00e9a04bf 100644
--- a/gnuradio-runtime/lib/buffer.cc
+++ b/gnuradio-runtime/lib/buffer.cc
@@ -23,7 +23,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-
+#include <algorithm>
#include <gnuradio/buffer.h>
#include <gnuradio/math.h>
#include "vmcircbuf.h"
@@ -225,16 +225,16 @@ namespace gr {
buffer::add_item_tag(const tag_t &tag)
{
gr::thread::scoped_lock guard(*mutex());
- d_item_tags.push_back(tag);
+ d_item_tags.insert(std::pair<uint64_t,tag_t>(tag.offset,tag));
}
void
buffer::remove_item_tag(const tag_t &tag, long id)
{
gr::thread::scoped_lock guard(*mutex());
- for(std::deque<tag_t>::iterator it = d_item_tags.begin(); it != d_item_tags.end(); ++it) {
- if(*it == tag) {
- (*it).marked_deleted.push_back(id);
+ for(std::multimap<uint64_t,tag_t>::iterator it = d_item_tags.lower_bound(tag.offset); it != d_item_tags.upper_bound(tag.offset); ++it) {
+ if((*it).second == tag) {
+ (*it).second.marked_deleted.push_back(id);
}
}
}
@@ -250,25 +250,9 @@ namespace gr {
If this function is used elsewhere, remember to lock the
buffer's mutex al la the scoped_lock line below.
*/
- //gr::thread::scoped_lock guard(*mutex());
- std::deque<tag_t>::iterator itr = d_item_tags.begin();
-
- uint64_t item_time;
-
- // Since tags are not guarenteed to be in any particular order, we
- // need to erase here instead of pop_front. An erase in the middle
- // invalidates all iterators; so this resets the iterator to find
- // more. Mostly, we wil be erasing from the front and
- // therefore lose little time this way.
- while(itr != d_item_tags.end()) {
- item_time = (*itr).offset;
- if(item_time+d_max_reader_delay + bufsize() < max_time) {
- d_item_tags.erase(itr);
- itr = d_item_tags.begin();
- }
- else
- itr++;
- }
+ std::multimap<uint64_t, tag_t>::iterator end_itr = d_item_tags.lower_bound(max_time);
+ std::multimap<uint64_t, tag_t>::iterator begin_itr = d_item_tags.begin();
+ d_item_tags.erase(begin_itr, end_itr);
}
long
@@ -333,30 +317,28 @@ namespace gr {
buffer_reader::get_tags_in_range(std::vector<tag_t> &v,
uint64_t abs_start,
uint64_t abs_end,
- long id)
+ long id)
{
gr::thread::scoped_lock guard(*mutex());
v.resize(0);
- std::deque<tag_t>::iterator itr = d_buffer->get_tags_begin();
+ std::multimap<uint64_t,tag_t>::iterator itr = d_buffer->get_tags_lower_bound(abs_start);
+ std::multimap<uint64_t,tag_t>::iterator itr_end = d_buffer->get_tags_upper_bound(abs_end);
uint64_t item_time;
- while(itr != d_buffer->get_tags_end()) {
- item_time = (*itr).offset + d_attr_delay;
-
+ while(itr != itr_end) {
+ item_time = (*itr).second.offset + d_attr_delay;
if((item_time >= abs_start) && (item_time < abs_end)) {
- std::vector<long>::iterator id_itr;
- id_itr = std::find(itr->marked_deleted.begin(), itr->marked_deleted.end(), id);
-
+ std::vector<long>::iterator id_itr;
+ id_itr = std::find(itr->second.marked_deleted.begin(), itr->second.marked_deleted.end(), id);
// If id is not in the vector of marked blocks
- if(id_itr == itr->marked_deleted.end()) {
- tag_t t = *itr;
+ if(id_itr == itr->second.marked_deleted.end()) {
+ tag_t t = (*itr).second;
t.offset += d_attr_delay;
- v.push_back(t);
- v.back().marked_deleted.clear();
- }
+ v.push_back(t);
+ v.back().marked_deleted.clear();
+ }
}
-
itr++;
}
}
diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc
index 082b98a80d..da830e1aed 100644
--- a/gnuradio-runtime/lib/pmt/pmt.cc
+++ b/gnuradio-runtime/lib/pmt/pmt.cc
@@ -368,6 +368,12 @@ from_double(double x)
return pmt_t(new pmt_real(x));
}
+pmt_t
+from_float(float x)
+{
+ return pmt_t(new pmt_real(x));
+}
+
double
to_double(pmt_t x)
{
@@ -379,6 +385,12 @@ to_double(pmt_t x)
throw wrong_type("pmt_to_double", x);
}
+float
+to_float(pmt_t x)
+{
+ return float(to_double(x));
+}
+
////////////////////////////////////////////////////////////////////////////
// Complex
////////////////////////////////////////////////////////////////////////////
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc b/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
index 2f46b014db..2b3ca32293 100644
--- a/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
+++ b/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
@@ -125,6 +125,15 @@ qa_pmt_prims::test_reals()
CPPUNIT_ASSERT_EQUAL(-1.0, pmt::to_double(m1));
CPPUNIT_ASSERT_EQUAL(1.0, pmt::to_double(p1));
CPPUNIT_ASSERT_EQUAL(1.0, pmt::to_double(pmt::from_long(1)));
+
+ pmt::pmt_t p2 = pmt::from_float(1);
+ pmt::pmt_t m2 = pmt::from_float(-1);
+ CPPUNIT_ASSERT(pmt::is_real(p2));
+ CPPUNIT_ASSERT(pmt::is_real(m2));
+ CPPUNIT_ASSERT_THROW(pmt::to_float(pmt::PMT_T), pmt::wrong_type);
+ CPPUNIT_ASSERT_EQUAL(float(-1.0), pmt::to_float(m2));
+ CPPUNIT_ASSERT_EQUAL(float(1.0), pmt::to_float(p2));
+ CPPUNIT_ASSERT_EQUAL(float(1.0), pmt::to_float(pmt::from_long(1)));
}
void
diff --git a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
index cbca9d44ae..ba46e3f4d9 100644
--- a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
+++ b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py
@@ -89,9 +89,22 @@ def python_to_tag(tag_struct):
tag.srcid = tag_struct[3]
good = True
+ elif(len(tag_struct) == 3):
+ if(isinstance(tag_struct[0], (int,long))):
+ tag.offset = tag_struct[0]
+ good = True
+
+ if(isinstance(tag_struct[1], pmt.pmt_swig.swig_int_ptr)):
+ tag.key = tag_struct[1]
+ good = True
+
+ if(isinstance(tag_struct[2], pmt.pmt_swig.swig_int_ptr)):
+ tag.value = tag_struct[2]
+ good = True
+
+ tag.srcid = pmt.PMT_F
+
if(good):
return tag
else:
return None
-
-
diff --git a/gnuradio-runtime/python/pmt/qa_pmt.py b/gnuradio-runtime/python/pmt/qa_pmt.py
index 5c1af2c00e..32cff62f44 100755
--- a/gnuradio-runtime/python/pmt/qa_pmt.py
+++ b/gnuradio-runtime/python/pmt/qa_pmt.py
@@ -36,7 +36,9 @@ class test_pmt(unittest.TestCase):
const = 123765
x_pmt = pmt.from_double(const)
x_int = pmt.to_double(x_pmt)
+ x_float = pmt.to_float(x_pmt)
self.assertEqual(x_int, const)
+ self.assertEqual(x_float, const)
def test03(self):
v = pmt.init_f32vector(3, [11, -22, 33])
diff --git a/gnuradio-runtime/swig/pmt_swig.i b/gnuradio-runtime/swig/pmt_swig.i
index e54b544977..c4b678222d 100644
--- a/gnuradio-runtime/swig/pmt_swig.i
+++ b/gnuradio-runtime/swig/pmt_swig.i
@@ -111,6 +111,8 @@ namespace pmt{
bool is_real(pmt_t obj);
pmt_t from_double(double x);
double to_double(pmt_t x);
+ pmt_t from_float(double x);
+ double to_float(pmt_t x);
bool is_complex(pmt_t obj);
pmt_t make_rectangular(double re, double im);
diff --git a/gr-blocks/examples/CMakeLists.txt b/gr-blocks/examples/CMakeLists.txt
index c9829661b6..bb07cdc2b5 100644
--- a/gr-blocks/examples/CMakeLists.txt
+++ b/gr-blocks/examples/CMakeLists.txt
@@ -17,6 +17,14 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
+install(
+ FILES
+ matrix_multiplexer.grc
+ vector_source_with_tags.grc
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/blocks
+ COMPONENT "runtime_python"
+)
+
add_subdirectory(metadata)
add_subdirectory(tags)
diff --git a/gr-blocks/examples/vector_source_with_tags.grc b/gr-blocks/examples/vector_source_with_tags.grc
new file mode 100644
index 0000000000..e266b91f85
--- /dev/null
+++ b/gr-blocks/examples/vector_source_with_tags.grc
@@ -0,0 +1,698 @@
+<?xml version='1.0' encoding='ASCII'?>
+<?grc format='1' created='3.7.6'?>
+<flow_graph>
+ <timestamp>Mon Sep 22 11:59:58 2014</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>vector_source_with_tags</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value>Shows how to use tags in a vector_source</value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>qt_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>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>tag1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>gr.tag_utils.python_to_tag((1, pmt.intern('mark'), pmt.PMT_T))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 267)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>tag0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>gr.tag_utils.python_to_tag((0, pmt.intern('mark'), pmt.PMT_T, pmt.intern("src")))</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 203)</value>
+ </param>
+ <param>
+ <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>32000</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(184, 11)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_pmt</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import pmt</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(280, 11)</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>float</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ignoretag</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(272, 123)</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>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value></value>
+ </param>
+ <param>
+ <key>filter</key>
+ <value>""</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>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(456, 195)</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>(-0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 0.0)</value>
+ </param>
+ <param>
+ <key>tags</key>
+ <value>[tag0, tag1]</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(16, 107)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_time_sink_x</key>
+ <param>
+ <key>id</key>
+ <value>qtgui_time_sink_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>ylabel</key>
+ <value>Amplitude</value>
+ </param>
+ <param>
+ <key>yunit</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>60</value>
+ </param>
+ <param>
+ <key>srate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>autoscale</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>entags</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value></value>
+ </param>
+ <param>
+ <key>tr_mode</key>
+ <value>qtgui.TRIG_MODE_TAG</value>
+ </param>
+ <param>
+ <key>tr_slope</key>
+ <value>qtgui.TRIG_SLOPE_POS</value>
+ </param>
+ <param>
+ <key>tr_level</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>tr_delay</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_chan</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>tr_tag</key>
+ <value>mark</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>style1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>style2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker2</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"green"</value>
+ </param>
+ <param>
+ <key>style3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker3</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"black"</value>
+ </param>
+ <param>
+ <key>style4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker4</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"cyan"</value>
+ </param>
+ <param>
+ <key>style5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker5</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"magenta"</value>
+ </param>
+ <param>
+ <key>style6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker6</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"yellow"</value>
+ </param>
+ <param>
+ <key>style7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker7</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"dark red"</value>
+ </param>
+ <param>
+ <key>style8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker8</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"dark green"</value>
+ </param>
+ <param>
+ <key>style9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker9</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>style10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>marker10</key>
+ <value>-1</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(456, 107)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_vector_source_x_0</source_block_id>
+ <sink_block_id>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>blocks_tag_debug_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-blocks/grc/blocks_abs_xx.xml b/gr-blocks/grc/blocks_abs_xx.xml
index 65ef97ddff..77298716c8 100644
--- a/gr-blocks/grc/blocks_abs_xx.xml
+++ b/gr-blocks/grc/blocks_abs_xx.xml
@@ -8,7 +8,13 @@
<name>Abs</name>
<key>blocks_abs_xx</key>
<import>from gnuradio import blocks</import>
- <make>blocks.abs_$(type.fcn)()</make>
+ <make>blocks.abs_$(type.fcn)($vlen)</make>
+ <param>
+ <name>Vec Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
<param>
<name>IO Type</name>
<key>type</key>
@@ -29,21 +35,14 @@
<opt>fcn:ff</opt>
</option>
</param>
- <param>
- <name>Num Inputs</name>
- <key>num_inputs</key>
- <value>1</value>
- <type>int</type>
- </param>
- <check>$num_inputs &gt;= 1</check>
<sink>
<name>in</name>
<type>$type</type>
- <nports>$num_inputs</nports>
+ <vlen>$vlen</vlen>
</sink>
<source>
<name>out</name>
<type>$type</type>
- <nports>$num_inputs</nports>
+ <vlen>$vlen</vlen>
</source>
</block>
diff --git a/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml b/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml
index f85b47fb19..ae8ad3b6c5 100644
--- a/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml
+++ b/gr-blocks/grc/blocks_tagged_stream_to_pdu.xml
@@ -42,5 +42,6 @@
<source>
<name>pdus</name>
<type>message</type>
+ <optional>1</optional>
</source>
</block>
diff --git a/gr-blocks/include/gnuradio/blocks/abs_XX.h.t b/gr-blocks/include/gnuradio/blocks/abs_XX.h.t
index f8688edcd3..541716296f 100644
--- a/gr-blocks/include/gnuradio/blocks/abs_XX.h.t
+++ b/gr-blocks/include/gnuradio/blocks/abs_XX.h.t
@@ -49,7 +49,7 @@ namespace gr {
/*!
* \brief Create an instance of @NAME@
*/
- static sptr make();
+ static sptr make(size_t vlen=1);
};
} /* namespace blocks */
diff --git a/gr-blocks/lib/abs_XX_impl.cc.t b/gr-blocks/lib/abs_XX_impl.cc.t
index 6bb9f149fd..195d8dff3d 100644
--- a/gr-blocks/lib/abs_XX_impl.cc.t
+++ b/gr-blocks/lib/abs_XX_impl.cc.t
@@ -32,15 +32,16 @@
namespace gr {
namespace blocks {
- @NAME@::sptr @NAME@::make()
+ @NAME@::sptr @NAME@::make(size_t vlen)
{
- return gnuradio::get_initial_sptr(new @NAME_IMPL@());
+ return gnuradio::get_initial_sptr(new @NAME_IMPL@(vlen));
}
- @NAME_IMPL@::@NAME_IMPL@()
+ @NAME_IMPL@::@NAME_IMPL@(size_t vlen)
: sync_block ("@NAME@",
- io_signature::make (1, 1, sizeof (@I_TYPE@)),
- io_signature::make (1, 1, sizeof (@O_TYPE@)))
+ io_signature::make (1, 1, sizeof (@I_TYPE@)*vlen),
+ io_signature::make (1, 1, sizeof (@O_TYPE@)*vlen)),
+ d_vlen(vlen)
{
}
@@ -52,7 +53,7 @@ namespace gr {
@I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
@O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
- for(int i=0; i<noutput_items; i++) {
+ for(size_t i=0; i<noutput_items*d_vlen; i++) {
@I_TYPE@ val = iptr[i];
optr[i] = ((val < ((@I_TYPE@)0)) ? -val : val);
}
diff --git a/gr-blocks/lib/abs_XX_impl.h.t b/gr-blocks/lib/abs_XX_impl.h.t
index b31ef5fb31..fa96c84073 100644
--- a/gr-blocks/lib/abs_XX_impl.h.t
+++ b/gr-blocks/lib/abs_XX_impl.h.t
@@ -32,8 +32,11 @@ namespace gr {
class BLOCKS_API @NAME_IMPL@ : public @NAME@
{
+ private:
+ size_t d_vlen;
+
public:
- @NAME_IMPL@();
+ @NAME_IMPL@(size_t vlen);
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-blocks/lib/deinterleave_impl.cc b/gr-blocks/lib/deinterleave_impl.cc
index c9d0e9aeda..9e18c35e58 100644
--- a/gr-blocks/lib/deinterleave_impl.cc
+++ b/gr-blocks/lib/deinterleave_impl.cc
@@ -41,13 +41,20 @@ namespace gr {
io_signature::make (1, io_signature::IO_INFINITE, itemsize)),
d_itemsize(itemsize), d_blocksize(blocksize), d_current_output(0)
{
+ d_size_bytes = d_itemsize * d_blocksize;
set_output_multiple(blocksize);
}
+ void
+ deinterleave_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+ {
+ ninput_items_required[0] = noutput_items * d_noutputs;
+ }
+
bool
deinterleave_impl::check_topology(int ninputs, int noutputs)
{
- set_relative_rate((double)noutputs);
+ set_relative_rate(1.0/(double)noutputs);
d_noutputs = noutputs;
return true;
}
@@ -61,10 +68,29 @@ namespace gr {
const char *in = (const char*)input_items[0];
char **out = (char**)&output_items[0];
- memcpy(out[d_current_output], in, d_itemsize * d_blocksize);
- consume_each(d_blocksize);
- produce(d_current_output, d_blocksize);
- d_current_output = (d_current_output + 1) % d_noutputs;
+ int count = 0, totalcount = noutput_items*d_noutputs;
+ unsigned int skip = 0;
+ unsigned int acc = 0;
+ while(count < totalcount) {
+ memcpy(out[d_current_output]+skip*d_size_bytes, in, d_size_bytes);
+ in += d_size_bytes;
+ produce(d_current_output, d_blocksize);
+ d_current_output = (d_current_output + 1) % d_noutputs;
+
+ // accumulate times through the loop; increment skip after a
+ // full pass over the output streams.
+ // This is separate than d_current_output since we could be in
+ // the middle of a loop when we exit.
+ acc++;
+ if(acc >= d_noutputs) {
+ skip++;
+ acc = 0;
+ }
+
+ // Keep track of our loop counter
+ count+=d_blocksize;
+ }
+ consume_each(totalcount);
return WORK_CALLED_PRODUCE;
}
diff --git a/gr-blocks/lib/deinterleave_impl.h b/gr-blocks/lib/deinterleave_impl.h
index 247ee3a018..71a551a69c 100644
--- a/gr-blocks/lib/deinterleave_impl.h
+++ b/gr-blocks/lib/deinterleave_impl.h
@@ -35,11 +35,12 @@ namespace gr {
unsigned int d_blocksize;
unsigned int d_current_output;
unsigned int d_noutputs;
-
+ unsigned int d_size_bytes; // block size in bytes
public:
deinterleave_impl(size_t itemsize, unsigned int blocksize);
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
bool check_topology(int ninputs, int noutputs);
int general_work(int noutput_items,
diff --git a/gr-blocks/lib/message_strobe_impl.cc b/gr-blocks/lib/message_strobe_impl.cc
index bd0ad80142..b3f1782229 100644
--- a/gr-blocks/lib/message_strobe_impl.cc
+++ b/gr-blocks/lib/message_strobe_impl.cc
@@ -47,15 +47,15 @@ namespace gr {
message_strobe_impl::message_strobe_impl(pmt::pmt_t msg, float period_ms)
: block("message_strobe",
- io_signature::make(0, 0, 0),
- io_signature::make(0, 0, 0)),
+ io_signature::make(0, 0, 0),
+ io_signature::make(0, 0, 0)),
d_finished(false),
d_period_ms(period_ms),
d_msg(msg)
{
message_port_register_out(pmt::mp("strobe"));
- d_thread = boost::shared_ptr<boost::thread>
- (new boost::thread(boost::bind(&message_strobe_impl::run, this)));
+ d_thread = boost::shared_ptr<gr::thread::thread>
+ (new gr::thread::thread(boost::bind(&message_strobe_impl::run, this)));
message_port_register_in(pmt::mp("set_msg"));
set_msg_handler(pmt::mp("set_msg"),
diff --git a/gr-blocks/lib/message_strobe_impl.h b/gr-blocks/lib/message_strobe_impl.h
index 7a54680286..0f37cd2e0e 100644
--- a/gr-blocks/lib/message_strobe_impl.h
+++ b/gr-blocks/lib/message_strobe_impl.h
@@ -31,7 +31,7 @@ namespace gr {
class BLOCKS_API message_strobe_impl : public message_strobe
{
private:
- boost::shared_ptr<boost::thread> d_thread;
+ boost::shared_ptr<gr::thread::thread> d_thread;
bool d_finished;
float d_period_ms;
pmt::pmt_t d_msg;
diff --git a/gr-blocks/lib/message_strobe_random_impl.cc b/gr-blocks/lib/message_strobe_random_impl.cc
index 80819fc2fc..c62aad1c7a 100644
--- a/gr-blocks/lib/message_strobe_random_impl.cc
+++ b/gr-blocks/lib/message_strobe_random_impl.cc
@@ -61,8 +61,8 @@ namespace gr {
// set up ports
message_port_register_out(pmt::mp("strobe"));
- d_thread = boost::shared_ptr<boost::thread>
- (new boost::thread(boost::bind(&message_strobe_random_impl::run, this)));
+ d_thread = boost::shared_ptr<gr::thread::thread>
+ (new gr::thread::thread(boost::bind(&message_strobe_random_impl::run, this)));
message_port_register_in(pmt::mp("set_msg"));
set_msg_handler(pmt::mp("set_msg"),
diff --git a/gr-blocks/lib/message_strobe_random_impl.h b/gr-blocks/lib/message_strobe_random_impl.h
index 32eddb592c..2dcaa7effa 100644
--- a/gr-blocks/lib/message_strobe_random_impl.h
+++ b/gr-blocks/lib/message_strobe_random_impl.h
@@ -36,7 +36,7 @@ namespace gr {
class BLOCKS_API message_strobe_random_impl : public message_strobe_random
{
private:
- boost::shared_ptr<boost::thread> d_thread;
+ boost::shared_ptr<gr::thread::thread> d_thread;
bool d_finished;
float d_mean_ms;
float d_std_ms;
diff --git a/gr-blocks/lib/qa_block_tags.cc b/gr-blocks/lib/qa_block_tags.cc
index c554425f8e..d794f8edfe 100644
--- a/gr-blocks/lib/qa_block_tags.cc
+++ b/gr-blocks/lib/qa_block_tags.cc
@@ -33,20 +33,32 @@
#include <gnuradio/blocks/annotator_alltoall.h>
#include <gnuradio/blocks/annotator_1to1.h>
#include <gnuradio/blocks/keep_one_in_n.h>
-#include <gnuradio/tags.h>
// ----------------------------------------------------------------
// set to 1 to turn on debug output
// The debug output fully checks that the tags seen are what are expected. While
-// this behavior currently works with our implementation, there is no guarentee
+// this behavior currently works with our implementation, there is no guarantee
// that the tags will be coming in this specific order, so it's dangerous to
// rely on this as a test of the tag system working. We would really want to
// tags we know we should see and then test that they all occur once, but in no
// particular order.
#define QA_TAGS_DEBUG 0
+gr::tag_t make_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t value, pmt::pmt_t srcid) {
+ gr::tag_t result;
+ result.offset = offset;
+ result.key = key;
+ result.value = value;
+ result.srcid = srcid;
+ return result;
+}
+
+std::ostream&
+operator << (std::ostream& os, const gr::tag_t &t) {
+ return os;
+}
void
qa_block_tags::t0()
{
@@ -59,8 +71,6 @@ qa_block_tags::t0()
tb->connect(src, 0, head, 0);
tb->connect(head, 0, snk, 0);
- //CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::runtime_error);
- //CPPUNIT_ASSERT_THROW(src->nitems_written(0), std::runtime_error);
CPPUNIT_ASSERT_EQUAL(src->nitems_read(0), (uint64_t)0);
CPPUNIT_ASSERT_EQUAL(src->nitems_written(0), (uint64_t)0);
@@ -117,39 +127,39 @@ qa_block_tags::t1()
str1 << ann1->name() << ann1->unique_id();
str2 << ann2->name() << ann2->unique_id();
- pmt::pmt_t expected_tags3[8];
- expected_tags3[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags3[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags3[2] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
- expected_tags3[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags3[4] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
- expected_tags3[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags3[6] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags3[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
-
- pmt::pmt_t expected_tags4[8];
- expected_tags4[0] = mp(pmt::from_uint64(0), mp(str2.str()), mp("seq"), mp(0));
- expected_tags4[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags4[2] = mp(pmt::from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
- expected_tags4[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags4[4] = mp(pmt::from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
- expected_tags4[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags4[6] = mp(pmt::from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
- expected_tags4[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+ gr::tag_t expected_tags3[8];
+ expected_tags3[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[2] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags3[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[4] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags3[6] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags3[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+
+ gr::tag_t expected_tags4[8];
+ expected_tags4[0] = make_tag(0, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags4[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[2] = make_tag(10000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[4] = make_tag(20000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[6] = make_tag(30000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
std::cout << std::endl << "qa_block_tags::t1" << std::endl;
// For annotator 3, we know it gets tags from ann0 and ann1, test this
for(size_t i = 0; i < tags3.size(); i++) {
std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags3[i]), pmt::write_string(expected_tags3[i]));
+ CPPUNIT_ASSERT_EQUAL(tags3[i], expected_tags3[i]);
}
// For annotator 4, we know it gets tags from ann0 and ann2, test this
std::cout << std::endl;
for(size_t i = 0; i < tags4.size(); i++) {
std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags4[i]), pmt::write_string(expected_tags4[i]));
+ CPPUNIT_ASSERT_EQUAL(tags4[i], expected_tags4[i]);
}
#endif
}
@@ -207,33 +217,33 @@ qa_block_tags::t2 ()
str0 << ann0->name() << ann0->unique_id();
str1 << ann1->name() << ann1->unique_id();
- pmt::pmt_t expected_tags2[12];
- expected_tags2[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags2[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags2[2] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags2[3] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags2[4] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags2[5] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags2[6] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(6));
- expected_tags2[7] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags2[8] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags2[9] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(9));
- expected_tags2[10] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
- expected_tags2[11] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
-
- pmt::pmt_t expected_tags4[12];
- expected_tags4[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(2));
- expected_tags4[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags4[2] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags4[3] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(5));
- expected_tags4[4] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags4[5] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags4[6] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(8));
- expected_tags4[7] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags4[8] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags4[9] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(11));
- expected_tags4[10] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
- expected_tags4[11] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+ gr::tag_t expected_tags2[12];
+ expected_tags2[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[2] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags2[3] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[4] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags2[5] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[6] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(6));
+ expected_tags2[7] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags2[8] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags2[9] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(9));
+ expected_tags2[10] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+ expected_tags2[11] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
+
+ gr::tag_t expected_tags4[12];
+ expected_tags4[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags4[2] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[3] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[4] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[5] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[6] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(8));
+ expected_tags4[7] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags4[8] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[9] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(11));
+ expected_tags4[10] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+ expected_tags4[11] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
std::cout << std::endl << "qa_block_tags::t2" << std::endl;
@@ -243,13 +253,13 @@ qa_block_tags::t2 ()
// inconceivable for ann3 to have it wrong.
for(size_t i = 0; i < tags2.size(); i++) {
std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags2[i]), pmt::write_string(expected_tags2[i]));
+ CPPUNIT_ASSERT_EQUAL(tags2[i], expected_tags2[i]);
}
std::cout << std::endl;
for(size_t i = 0; i < tags4.size(); i++) {
std::cout << "tags2[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags4[i]), pmt::write_string(expected_tags4[i]));
+ CPPUNIT_ASSERT_EQUAL(tags4[i], expected_tags4[i]);
}
#endif
}
@@ -301,39 +311,39 @@ qa_block_tags::t3()
str1 << ann1->name() << ann1->unique_id();
str2 << ann2->name() << ann2->unique_id();
- pmt::pmt_t expected_tags3[8];
- expected_tags3[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags3[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags3[2] = mp(pmt::from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
- expected_tags3[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags3[4] = mp(pmt::from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
- expected_tags3[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
- expected_tags3[6] = mp(pmt::from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags3[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
-
- pmt::pmt_t expected_tags4[8];
- expected_tags4[0] = mp(pmt::from_uint64(0), mp(str2.str()), mp("seq"), mp(0));
- expected_tags4[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
- expected_tags4[2] = mp(pmt::from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
- expected_tags4[3] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags4[4] = mp(pmt::from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
- expected_tags4[5] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
- expected_tags4[6] = mp(pmt::from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
- expected_tags4[7] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+ gr::tag_t expected_tags3[8];
+ expected_tags3[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags3[2] = make_tag(10000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags3[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[4] = make_tag(20000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags3[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags3[6] = make_tag(30000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags3[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(6));
+
+ gr::tag_t expected_tags4[8];
+ expected_tags4[0] = make_tag(0, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags4[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[2] = make_tag(10000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags4[3] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[4] = make_tag(20000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags4[5] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(5));
+ expected_tags4[6] = make_tag(30000, pmt::mp(str2.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags4[7] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(7));
std::cout << std::endl << "qa_block_tags::t3" << std::endl;
// For annotator 3, we know it gets tags from ann0 and ann1, test this
for(size_t i = 0; i < tags3.size(); i++) {
std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags3[i]), pmt::write_string(expected_tags3[i]));
+ CPPUNIT_ASSERT_EQUAL(tags3[i], expected_tags3[i]);
}
// For annotator 4, we know it gets tags from ann0 and ann2, test this
std::cout << std::endl;
for(size_t i = 0; i < tags4.size(); i++) {
std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags4[i]), pmt::write_string(expected_tags4[i]));
+ CPPUNIT_ASSERT_EQUAL(tags4[i], expected_tags4[i]);
}
#endif
}
@@ -409,23 +419,23 @@ qa_block_tags::t5()
str1 << ann1->name() << ann1->unique_id();
str2 << ann2->name() << ann2->unique_id();
- pmt_t expected_tags1[5];
- expected_tags1[0] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags1[1] = mp(pmt::from_uint64(10000), mp(str0.str()), mp("seq"), mp(1));
- expected_tags1[2] = mp(pmt::from_uint64(20000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags1[3] = mp(pmt::from_uint64(30000), mp(str0.str()), mp("seq"), mp(3));
-
- pmt_t expected_tags2[10];
- expected_tags2[0] = mp(pmt::from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
- expected_tags2[1] = mp(pmt::from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
- expected_tags2[2] = mp(pmt::from_uint64(1000), mp(str1.str()), mp("seq"), mp(1));
- expected_tags2[3] = mp(pmt::from_uint64(1000), mp(str0.str()), mp("seq"), mp(1));
- expected_tags2[4] = mp(pmt::from_uint64(2000), mp(str1.str()), mp("seq"), mp(2));
- expected_tags2[5] = mp(pmt::from_uint64(2000), mp(str0.str()), mp("seq"), mp(2));
- expected_tags2[6] = mp(pmt::from_uint64(3000), mp(str1.str()), mp("seq"), mp(3));
- expected_tags2[7] = mp(pmt::from_uint64(3000), mp(str0.str()), mp("seq"), mp(3));
- expected_tags2[8] = mp(pmt::from_uint64(4000), mp(str1.str()), mp("seq"), mp(4));
- expected_tags2[9] = mp(pmt::from_uint64(4000), mp(str0.str()), mp("seq"), mp(4));
+ gr::tag_t expected_tags1[5];
+ expected_tags1[0] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags1[1] = make_tag(10000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags1[2] = make_tag(20000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags1[3] = make_tag(30000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+
+ gr::tag_t expected_tags2[10];
+ expected_tags2[0] = make_tag(0, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[1] = make_tag(0, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(0));
+ expected_tags2[2] = make_tag(1000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags2[3] = make_tag(1000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(1));
+ expected_tags2[4] = make_tag(2000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags2[5] = make_tag(2000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(2));
+ expected_tags2[6] = make_tag(3000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[7] = make_tag(3000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(3));
+ expected_tags2[8] = make_tag(4000, pmt::mp(str1.str()), pmt::mp("seq"), pmt::mp(4));
+ expected_tags2[9] = make_tag(4000, pmt::mp(str0.str()), pmt::mp("seq"), pmt::mp(4));
std::cout << std::endl << "qa_block_tags::t5" << std::endl;
@@ -433,7 +443,7 @@ qa_block_tags::t5()
std::cout << "tags1.size(): " << tags1.size() << std::endl;
for(size_t i = 0; i < tags1.size(); i++) {
std::cout << "tags1[" << i << "] = " << tags1[i] << "\t\t" << expected_tags1[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags1[i]), pmt::write_string(expected_tags1[i]));
+ CPPUNIT_ASSERT_EQUAL(tags1[i], expected_tags1[i]);
}
// annotator 2 gets tags from annotators 0 and 1
@@ -441,7 +451,7 @@ qa_block_tags::t5()
std::cout << "tags2.size(): " << tags2.size() << std::endl;
for(size_t i = 0; i < tags2.size(); i++) {
std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
- CPPUNIT_ASSERT_EQUAL(pmt::write_string(tags2[i]), pmt::write_string(expected_tags2[i]));
+ CPPUNIT_ASSERT_EQUAL(tags2[i], expected_tags2[i]);
}
#endif
}
diff --git a/gr-blocks/lib/throttle_impl.cc b/gr-blocks/lib/throttle_impl.cc
index f46decee11..7c24f80ae1 100644
--- a/gr-blocks/lib/throttle_impl.cc
+++ b/gr-blocks/lib/throttle_impl.cc
@@ -57,6 +57,14 @@ namespace gr {
{
}
+ bool
+ throttle_impl::start()
+ {
+ d_start = boost::get_system_time();
+ d_total_samples = 0;
+ return block::start();
+ }
+
void
throttle_impl::set_sample_rate(double rate)
{
diff --git a/gr-blocks/lib/throttle_impl.h b/gr-blocks/lib/throttle_impl.h
index c5e43d7564..6afacbba5d 100644
--- a/gr-blocks/lib/throttle_impl.h
+++ b/gr-blocks/lib/throttle_impl.h
@@ -41,6 +41,9 @@ namespace gr {
throttle_impl(size_t itemsize, double samples_per_sec, bool ignore_tags=true);
~throttle_impl();
+ // Overloading gr::block::start to reset timer
+ bool start();
+
void setup_rpc();
void set_sample_rate(double rate);
diff --git a/gr-blocks/lib/vector_source_X_impl.cc.t b/gr-blocks/lib/vector_source_X_impl.cc.t
index 93f672bfb9..cb17c70d63 100644
--- a/gr-blocks/lib/vector_source_X_impl.cc.t
+++ b/gr-blocks/lib/vector_source_X_impl.cc.t
@@ -106,7 +106,7 @@ namespace gr {
optr += size;
for(unsigned t = 0; t < d_tags.size(); t++) {
add_item_tag(0, nitems_written(0)+i+d_tags[t].offset,
- d_tags[t].key, d_tags[t].value);
+ d_tags[t].key, d_tags[t].value, d_tags[t].srcid);
}
}
}
diff --git a/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h
index 2715316a93..be38b6f8ae 100644
--- a/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h
+++ b/gr-digital/include/gnuradio/digital/ofdm_frame_equalizer_vcvc.h
@@ -58,18 +58,19 @@ 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 tsb_key TSB key
* \param propagate_channel_state If true, the channel state after the last symbol
* will be added to the first symbol as a tag
- * \param fixed_frame_len Set if the frame length is fixed throughout,
- * helps with book keeping.
+ * \param fixed_frame_len Set if the frame length is fixed. When this value is given,
+ * the TSB tag key can be left empty, but it is useful even
+ * when using tagged streams at the input.
*/
static sptr make(
- ofdm_equalizer_base::sptr equalizer,
- int cp_len,
- const std::string &len_tag_key = "frame_len",
- bool propagate_channel_state=false,
- int fixed_frame_len=0
+ ofdm_equalizer_base::sptr equalizer,
+ int cp_len,
+ const std::string &tsb_key="frame_len",
+ bool propagate_channel_state=false,
+ int fixed_frame_len=0
);
};
diff --git a/gr-digital/lib/header_payload_demux_impl.cc b/gr-digital/lib/header_payload_demux_impl.cc
index 15308c0be1..160f54036d 100644
--- a/gr-digital/lib/header_payload_demux_impl.cc
+++ b/gr-digital/lib/header_payload_demux_impl.cc
@@ -1,5 +1,5 @@
/* -*- c++ -*- */
-/* Copyright 2012,2013 Free Software Foundation, Inc.
+/* Copyright 2012-2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -300,20 +300,19 @@ namespace gr {
}
}
if (d_uses_trigger_tag) {
- std::vector<tag_t> tags;
- get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_trigger_tag_key);
- uint64_t min_offset = ULLONG_MAX;
- int tag_index = -1;
- for (unsigned i = 0; i < tags.size(); i++) {
- if (tags[i].offset < min_offset) {
- tag_index = (int) i;
- min_offset = tags[i].offset;
- }
- }
- if (tag_index != -1) {
- remove_item_tag(0, tags[tag_index]);
- return min_offset - nitems_read(0);
- }
+ std::vector<tag_t> tags;
+ get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_trigger_tag_key);
+ uint64_t min_offset = ULLONG_MAX;
+ int tag_index = -1;
+ for (unsigned i = 0; i < tags.size(); i++) {
+ if (tags[i].offset < min_offset) {
+ tag_index = (int) i;
+ min_offset = tags[i].offset;
+ }
+ }
+ if (tag_index != -1) {
+ return min_offset - nitems_read(0);
+ }
}
return -1;
} /* find_trigger_signal() */
@@ -388,26 +387,30 @@ namespace gr {
// Copy tags
std::vector<tag_t> tags;
get_tags_in_range(
- tags, 0,
- nitems_read(0),
- nitems_read(0) + n_symbols * (d_items_per_symbol + d_gi)
+ tags, 0,
+ nitems_read(0),
+ nitems_read(0) + n_symbols * (d_items_per_symbol + d_gi)
);
- for (unsigned t = 0; t < tags.size(); t++) {
- int new_offset = tags[t].offset - nitems_read(0);
- if (d_output_symbols) {
- new_offset /= (d_items_per_symbol + d_gi);
- } else if (d_gi) {
- int pos_on_symbol = (new_offset % (d_items_per_symbol + d_gi)) - d_gi;
- if (pos_on_symbol < 0) {
- pos_on_symbol = 0;
- }
- new_offset = (new_offset / (d_items_per_symbol + d_gi)) + pos_on_symbol;
- }
- add_item_tag(port,
- nitems_written(port) + new_offset,
- tags[t].key,
- tags[t].value
- );
+ for (size_t t = 0; t < tags.size(); t++) {
+ // The trigger tag is *not* propagated
+ if (tags[t].key == d_trigger_tag_key) {
+ continue;
+ }
+ int new_offset = tags[t].offset - nitems_read(0);
+ if (d_output_symbols) {
+ new_offset /= (d_items_per_symbol + d_gi);
+ } else if (d_gi) {
+ int pos_on_symbol = (new_offset % (d_items_per_symbol + d_gi)) - d_gi;
+ if (pos_on_symbol < 0) {
+ pos_on_symbol = 0;
+ }
+ new_offset = (new_offset / (d_items_per_symbol + d_gi)) + pos_on_symbol;
+ }
+ add_item_tag(port,
+ nitems_written(port) + new_offset,
+ tags[t].key,
+ tags[t].value
+ );
}
} /* copy_n_symbols() */
diff --git a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc
index 4446306a8b..70e840d778 100644
--- a/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc
+++ b/gr-digital/lib/ofdm_frame_equalizer_vcvc_impl.cc
@@ -29,6 +29,9 @@
#define M_TWOPI (2*M_PI)
+static const pmt::pmt_t CARR_OFFSET_KEY = pmt::mp("ofdm_sync_carr_offset");
+static const pmt::pmt_t CHAN_TAPS_KEY = pmt::mp("ofdm_sync_chan_taps");
+
namespace gr {
namespace digital {
@@ -36,14 +39,14 @@ namespace gr {
ofdm_frame_equalizer_vcvc::make(
ofdm_equalizer_base::sptr equalizer,
int cp_len,
- const std::string &len_tag_key,
+ const std::string &tsb_key,
bool propagate_channel_state,
int fixed_frame_len
)
{
return gnuradio::get_initial_sptr (
new ofdm_frame_equalizer_vcvc_impl(
- equalizer, cp_len, len_tag_key, propagate_channel_state, fixed_frame_len
+ equalizer, cp_len, tsb_key, propagate_channel_state, fixed_frame_len
)
);
}
@@ -51,13 +54,13 @@ namespace gr {
ofdm_frame_equalizer_vcvc_impl::ofdm_frame_equalizer_vcvc_impl(
ofdm_equalizer_base::sptr equalizer,
int cp_len,
- const std::string &len_tag_key,
+ const std::string &tsb_key,
bool propagate_channel_state,
int fixed_frame_len
) : tagged_stream_block("ofdm_frame_equalizer_vcvc",
io_signature::make(1, 1, sizeof (gr_complex) * equalizer->fft_len()),
io_signature::make(1, 1, sizeof (gr_complex) * equalizer->fft_len()),
- len_tag_key),
+ tsb_key),
d_fft_len(equalizer->fft_len()),
d_cp_len(cp_len),
d_eq(equalizer),
@@ -65,16 +68,18 @@ namespace gr {
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 (tsb_key.empty() && fixed_frame_len == 0) {
+ throw std::invalid_argument("Either specify a TSB tag or a fixed frame length!");
}
if (d_fixed_frame_len < 0) {
- throw std::invalid_argument("Invalid frame length!");
+ throw std::invalid_argument("Invalid frame length!");
}
if (d_fixed_frame_len) {
- set_output_multiple(d_fixed_frame_len);
+ set_output_multiple(d_fixed_frame_len);
}
set_relative_rate(1.0);
+ // Really, we have TPP_ONE_TO_ONE, but the channel state is not propagated
+ set_tag_propagation_policy(TPP_DONT);
}
ofdm_frame_equalizer_vcvc_impl::~ofdm_frame_equalizer_vcvc_impl()
@@ -83,18 +88,17 @@ namespace gr {
void
ofdm_frame_equalizer_vcvc_impl::parse_length_tags(
- const std::vector<std::vector<tag_t> > &tags,
- gr_vector_int &n_input_items_reqd
- ){
+ const std::vector<std::vector<tag_t> > &tags,
+ gr_vector_int &n_input_items_reqd
+ ) {
if (d_fixed_frame_len) {
- n_input_items_reqd[0] = 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::string_to_symbol(d_length_tag_key_str)) {
- n_input_items_reqd[0] = pmt::to_long(tags[0][k].value);
- remove_item_tag(0, tags[0][k]);
- }
- }
+ for (unsigned k = 0; k < tags[0].size(); k++) {
+ if (tags[0][k].key == pmt::string_to_symbol(d_length_tag_key_str)) {
+ n_input_items_reqd[0] = pmt::to_long(tags[0][k].value);
+ }
+ }
}
}
@@ -114,15 +118,14 @@ namespace gr {
}
std::vector<tag_t> tags;
- get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1);
+ get_tags_in_window(tags, 0, 0, 1);
for (unsigned i = 0; i < tags.size(); i++) {
- if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_chan_taps") {
- d_channel_state = pmt::c32vector_elements(tags[i].value);
- remove_item_tag(0, tags[i]);
- }
- if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") {
- carrier_offset = pmt::to_long(tags[i].value);
- }
+ if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_chan_taps") {
+ d_channel_state = pmt::c32vector_elements(tags[i].value);
+ }
+ if (pmt::symbol_to_string(tags[i].key) == "ofdm_sync_carr_offset") {
+ carrier_offset = pmt::to_long(tags[i].value);
+ }
}
// Copy the frame and the channel state vector such that the symbols are shifted to the correct position
@@ -157,7 +160,16 @@ namespace gr {
// 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;
+ d_channel_state[k] *= phase_correction;
+ }
+
+ // Propagate tags (except for the channel state and the TSB tag)
+ get_tags_in_window(tags, 0, 0, frame_len);
+ for (size_t i = 0; i < tags.size(); i++) {
+ if (tags[i].key != CHAN_TAPS_KEY
+ and tags[i].key != pmt::mp(d_length_tag_key_str)) {
+ add_item_tag(0, tags[i]);
+ }
}
// Housekeeping
diff --git a/gr-digital/lib/ofdm_serializer_vcc_impl.cc b/gr-digital/lib/ofdm_serializer_vcc_impl.cc
index f6c796d3c5..1398dcd2a1 100644
--- a/gr-digital/lib/ofdm_serializer_vcc_impl.cc
+++ b/gr-digital/lib/ofdm_serializer_vcc_impl.cc
@@ -1,5 +1,5 @@
/* -*- c++ -*- */
-/* Copyright 2012 Free Software Foundation, Inc.
+/* Copyright 2012,2014 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -157,55 +157,57 @@ namespace gr {
std::vector<tag_t> tags;
// Packet mode
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 (tags[i].key == d_carr_offset_key) {
- carr_offset = pmt::to_long(tags[i].value);
- }
- if (tags[i].key == d_packet_len_tag_key) {
- packet_length = pmt::to_long(tags[i].value);
- remove_item_tag(0, tags[i]);
- }
- }
+ get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+1);
+ for (unsigned i = 0; i < tags.size(); i++) {
+ if (tags[i].key == d_carr_offset_key) {
+ carr_offset = pmt::to_long(tags[i].value);
+ }
+ if (tags[i].key == d_packet_len_tag_key) {
+ packet_length = pmt::to_long(tags[i].value);
+ }
+ }
} else {
- // recalc frame length from noutput_items
- frame_length = 0;
- int sym_per_frame = 0;
- while ((sym_per_frame + d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size()) < (size_t)noutput_items) {
- frame_length++;
- sym_per_frame += d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size();
- }
+ // recalc frame length from noutput_items
+ frame_length = 0;
+ int sym_per_frame = 0;
+ while ((sym_per_frame + d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size()) < (size_t)noutput_items) {
+ frame_length++;
+ sym_per_frame += d_occupied_carriers[(frame_length + 1) % d_occupied_carriers.size()].size();
+ }
}
// Copy symbols
int n_out_symbols = 0;
for (int i = 0; i < frame_length; i++) {
- // Copy all tags associated with this input OFDM symbol onto the first output symbol
- get_tags_in_range(tags, 0,
- nitems_read(0)+i,
- nitems_read(0)+i+1
- );
- for (unsigned t = 0; t < tags.size(); t++) {
- add_item_tag(0, nitems_written(0)+n_out_symbols,
- tags[t].key,
- tags[t].value
- );
- }
- for (unsigned k = 0; k < d_occupied_carriers[d_curr_set].size(); k++) {
- out[n_out_symbols++] = in[i * d_fft_len + d_occupied_carriers[d_curr_set][k] + carr_offset];
- }
- if (packet_length && n_out_symbols > packet_length) {
- n_out_symbols = packet_length;
- break;
- }
- d_curr_set = (d_curr_set + 1) % d_occupied_carriers.size();
+ // Copy all tags associated with this input OFDM symbol onto the first output symbol
+ get_tags_in_range(tags, 0,
+ nitems_read(0)+i,
+ nitems_read(0)+i+1
+ );
+ for (size_t t = 0; t < tags.size(); t++) {
+ // The packet length tag is not propagated
+ if (tags[t].key != d_packet_len_tag_key) {
+ add_item_tag(0, nitems_written(0)+n_out_symbols,
+ tags[t].key,
+ tags[t].value
+ );
+ }
+ }
+ for (unsigned k = 0; k < d_occupied_carriers[d_curr_set].size(); k++) {
+ out[n_out_symbols++] = in[i * d_fft_len + d_occupied_carriers[d_curr_set][k] + carr_offset];
+ }
+ if (packet_length && n_out_symbols > packet_length) {
+ n_out_symbols = packet_length;
+ break;
+ }
+ d_curr_set = (d_curr_set + 1) % d_occupied_carriers.size();
}
// Housekeeping
if (d_length_tag_key_str.empty()) {
- consume_each(frame_length);
+ consume_each(frame_length);
} else {
- d_curr_set = d_symbols_skipped;
+ d_curr_set = d_symbols_skipped;
}
return n_out_symbols;
diff --git a/gr-digital/python/digital/qa_header_payload_demux.py b/gr-digital/python/digital/qa_header_payload_demux.py
index 0b754fe248..8006d4442e 100755
--- a/gr-digital/python/digital/qa_header_payload_demux.py
+++ b/gr-digital/python/digital/qa_header_payload_demux.py
@@ -113,6 +113,86 @@ class qa_header_payload_demux (gr_unittest.TestCase):
]
self.assertEqual(expected_tags_payload, ptags_payload)
+ def test_001_t_tags (self):
+ """ Like the previous test, but use a trigger tag instead of
+ a trigger signal.
+ """
+ n_zeros = 1
+ header = (1, 2, 3)
+ payload = tuple(range(5, 20))
+ data_signal = (0,) * n_zeros + header + payload
+ # Trigger tag
+ trigger_tag = gr.tag_t()
+ trigger_tag.offset = n_zeros
+ trigger_tag.key = pmt.string_to_symbol('detect')
+ trigger_tag.value = pmt.PMT_T
+ # This is dropped:
+ testtag1 = gr.tag_t()
+ testtag1.offset = 0
+ testtag1.key = pmt.string_to_symbol('tag1')
+ testtag1.value = pmt.from_long(0)
+ # This goes on output 0, item 0:
+ testtag2 = gr.tag_t()
+ testtag2.offset = n_zeros
+ testtag2.key = pmt.string_to_symbol('tag2')
+ testtag2.value = pmt.from_long(23)
+ # This goes on output 0, item 2:
+ testtag3 = gr.tag_t()
+ testtag3.offset = n_zeros + len(header) - 1
+ testtag3.key = pmt.string_to_symbol('tag3')
+ testtag3.value = pmt.from_long(42)
+ # This goes on output 1, item 3:
+ testtag4 = gr.tag_t()
+ testtag4.offset = n_zeros + len(header) + 3
+ testtag4.key = pmt.string_to_symbol('tag4')
+ testtag4.value = pmt.from_long(314)
+ data_src = blocks.vector_source_f(
+ data_signal,
+ False,
+ tags=(trigger_tag, testtag1, testtag2, testtag3, testtag4)
+ )
+ hpd = digital.header_payload_demux(
+ len(header), 1, 0, "frame_len", "detect", False, gr.sizeof_float
+ )
+ self.assertEqual(pmt.length(hpd.message_ports_in()), 2) #extra system port defined for you
+ header_sink = blocks.vector_sink_f()
+ payload_sink = blocks.vector_sink_f()
+
+ self.tb.connect(data_src, (hpd, 0))
+ self.tb.connect((hpd, 0), header_sink)
+ self.tb.connect((hpd, 1), payload_sink)
+ self.tb.start()
+ time.sleep(.2) # Need this, otherwise, the next message is ignored
+ hpd.to_basic_block()._post(
+ pmt.intern('header_data'),
+ pmt.from_long(len(payload))
+ )
+ while len(payload_sink.data()) < len(payload):
+ time.sleep(.2)
+ self.tb.stop()
+ self.tb.wait()
+
+ self.assertEqual(header_sink.data(), header)
+ self.assertEqual(payload_sink.data(), payload)
+ ptags_header = []
+ for tag in header_sink.tags():
+ ptag = gr.tag_to_python(tag)
+ ptags_header.append({'key': ptag.key, 'offset': ptag.offset})
+ expected_tags_header = [
+ {'key': 'tag2', 'offset': 0},
+ {'key': 'tag3', 'offset': 2},
+ ]
+ self.assertEqual(expected_tags_header, ptags_header)
+ ptags_payload = []
+ for tag in payload_sink.tags():
+ ptag = gr.tag_to_python(tag)
+ ptags_payload.append({'key': ptag.key, 'offset': ptag.offset})
+ expected_tags_payload = [
+ {'key': 'frame_len', 'offset': 0},
+ {'key': 'tag4', 'offset': 3},
+ ]
+ self.assertEqual(expected_tags_payload, ptags_payload)
+
def test_002_symbols (self):
"""
Same as before, but operate on symbols
diff --git a/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py b/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py
index c42fb2b907..1b3ffb7738 100755
--- a/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py
+++ b/gr-digital/python/digital/qa_ofdm_frame_equalizer_vcvc.py
@@ -72,7 +72,7 @@ class qa_ofdm_frame_equalizer_vcvc (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
tag_dict[ptag.key] = ptag.value
expected_dict = {
- 'foo': 42
+ 'foo': 42
}
self.assertEqual(tag_dict, expected_dict)
diff --git a/gr-fec/lib/decoder_impl.cc b/gr-fec/lib/decoder_impl.cc
index ba8a7d000e..62c301d501 100644
--- a/gr-fec/lib/decoder_impl.cc
+++ b/gr-fec/lib/decoder_impl.cc
@@ -95,8 +95,8 @@ namespace gr {
noutput_items/(output_multiple() - d_decoder->get_history()) :
innum;
- GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
- % outnum % ninput_items[0] % items);
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
+ // % outnum % ninput_items[0] % items);
for(int i = 0; i < items; ++i) {
d_decoder->generic_work((void*)(in+(i*d_decoder->get_input_size()*d_input_item_size)),
@@ -109,8 +109,8 @@ namespace gr {
int consumed = static_cast<int>(items/relative_rate()*(output_multiple() - d_decoder->get_history()) + 0.5);
int returned = items*(output_multiple() - d_decoder->get_history());
- GR_LOG_DEBUG(d_debug_logger, boost::format("consumed %1%") % consumed);
- GR_LOG_DEBUG(d_debug_logger, boost::format("returned %1%") % returned);
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("consumed %1%") % consumed);
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("returned %1%") % returned);
consume_each(consumed);
return returned;
diff --git a/gr-fec/lib/encoder_impl.cc b/gr-fec/lib/encoder_impl.cc
index 399bcc41cf..af72f31133 100644
--- a/gr-fec/lib/encoder_impl.cc
+++ b/gr-fec/lib/encoder_impl.cc
@@ -91,8 +91,8 @@ namespace gr {
char *inbuffer = (char*)input_items[0];
char *outbuffer = (char*)output_items[0];
- GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
- % noutput_items % ninput_items[0] % (noutput_items/output_multiple()));
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("%1%, %2%, %3%") \
+ // % noutput_items % ninput_items[0] % (noutput_items/output_multiple()));
for(int i = 0; i < noutput_items/output_multiple(); i++) {
@@ -100,10 +100,10 @@ namespace gr {
(void*)(outbuffer+(i*d_output_size)));
}
- GR_LOG_DEBUG(d_debug_logger, boost::format("consuming: %1%") \
- % (fixed_rate_noutput_to_ninput(noutput_items)));
- GR_LOG_DEBUG(d_debug_logger, boost::format("returning: %1%") \
- % (noutput_items));
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("consuming: %1%") \
+ // % (fixed_rate_noutput_to_ninput(noutput_items)));
+ //GR_LOG_DEBUG(d_debug_logger, boost::format("returning: %1%") \
+ // % (noutput_items));
consume_each(fixed_rate_noutput_to_ninput(noutput_items));
return noutput_items;
diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc
index 1a17e87775..c184f0a406 100644
--- a/gr-uhd/lib/usrp_sink_impl.cc
+++ b/gr-uhd/lib/usrp_sink_impl.cc
@@ -88,7 +88,7 @@ namespace gr {
{
bool clocks_locked = true;
- // 1) Check ref lock for all mboards
+ // Check ref lock for all mboards
for (size_t mboard_index = 0; mboard_index < _dev->get_num_mboards(); mboard_index++) {
std::string sensor_name = "ref_locked";
if (_dev->get_clock_source(mboard_index) == "internal") {
@@ -107,19 +107,6 @@ namespace gr {
}
}
- // 2) Check LO for all channels
- for (size_t i = 0; i < _nchan; i++) {
- size_t chan_index = _stream_args.channels[i];
- if (not _wait_for_locked_sensor(
- get_sensor_names(chan_index),
- "lo_locked",
- boost::bind(&usrp_sink_impl::get_sensor, this, _1, chan_index)
- )) {
- GR_LOG_WARN(d_logger, boost::format("Sensor 'lo_locked' failed to lock within timeout on channel %d.") % chan_index);
- clocks_locked = false;
- }
- }
-
return clocks_locked;
}
diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc
index 6be0bac9ca..3142627952 100644
--- a/gr-uhd/lib/usrp_source_impl.cc
+++ b/gr-uhd/lib/usrp_source_impl.cc
@@ -87,7 +87,7 @@ namespace gr {
{
bool clocks_locked = true;
- // 1) Check ref lock for all mboards
+ // Check ref lock for all mboards
for (size_t mboard_index = 0; mboard_index < _dev->get_num_mboards(); mboard_index++) {
std::string sensor_name = "ref_locked";
if (_dev->get_clock_source(mboard_index) == "internal") {
@@ -106,19 +106,6 @@ namespace gr {
}
}
- // 2) Check LO for all channels
- for (size_t i = 0; i < _nchan; i++) {
- size_t chan_index = _stream_args.channels[i];
- if (not _wait_for_locked_sensor(
- get_sensor_names(chan_index),
- "lo_locked",
- boost::bind(&usrp_source_impl::get_sensor, this, _1, chan_index)
- )) {
- GR_LOG_WARN(d_logger, boost::format("Sensor 'lo_locked' failed to lock within timeout on channel %d.") % chan_index);
- clocks_locked = false;
- }
- }
-
return clocks_locked;
}
diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py
index 02d1b112c4..fb25b46821 100644
--- a/grc/base/FlowGraph.py
+++ b/grc/base/FlowGraph.py
@@ -17,11 +17,13 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
+import time
from . import odict
from Element import Element
from .. gui import Messages
from . Constants import FLOW_GRAPH_FILE_FORMAT_VERSION
+
class FlowGraph(Element):
def __init__(self, platform):
@@ -36,6 +38,8 @@ class FlowGraph(Element):
"""
#initialize
Element.__init__(self, platform)
+ self._elements = []
+ self._timestamp = time.ctime()
#inital blank import
self.import_data()
@@ -51,12 +55,14 @@ class FlowGraph(Element):
"""
index = 0
while True:
- id = '%s_%d'%(base_id, index)
- index = index + 1
+ id = '%s_%d' % (base_id, index)
+ index += 1
#make sure that the id is not used by another block
if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
- def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
+ def __str__(self):
+ return 'FlowGraph - %s(%s)' % (self.get_option('title'), self.get_option('id'))
+
def rewrite(self):
def refactor_bus_structure():
@@ -242,9 +248,8 @@ class FlowGraph(Element):
Returns:
a nested data odict
"""
- import time
n = odict()
- n['timestamp'] = time.ctime()
+ n['timestamp'] = self._timestamp
n['block'] = [block.export_data() for block in self.get_blocks()]
n['connection'] = [connection.export_data() for connection in self.get_connections()]
instructions = odict({
@@ -273,6 +278,7 @@ class FlowGraph(Element):
file_format = 0
#use blank data if none provided
fg_n = n and n.find('flow_graph') or odict()
+ self._timestamp = fg_n.find('timestamp') or time.ctime()
blocks_n = fg_n.findall('block')
connections_n = fg_n.findall('connection')
#create option block
@@ -384,7 +390,7 @@ def _initialize_dummy_block(block, block_n):
"""
block._key = block_n.find('key')
block.is_dummy_block = lambda: True
- block.is_valid = lambda: False
+ block.is_valid = lambda: False
block.get_enabled = lambda: False
for param_n in block_n.findall('param'):
if param_n['key'] not in block.get_param_keys():
@@ -393,7 +399,7 @@ def _initialize_dummy_block(block, block_n):
def _dummy_block_add_port(block, key, dir):
- """This is so ugly... Add a port to a dummy-fied block"""
+ """This is so ugly... Add a port to a dummy-field block"""
port_n = odict({'name': '?', 'key': key, 'type': ''})
port = block.get_parent().get_parent().Port(block=block, n=port_n, dir=dir)
if port.is_source():
diff --git a/grc/blocks/options.xml b/grc/blocks/options.xml
index 0c3a804fd7..c1c94e4e24 100644
--- a/grc/blocks/options.xml
+++ b/grc/blocks/options.xml
@@ -58,17 +58,17 @@ else: self.stop(); self.wait()</callback>
<param>
<name>Generate Options</name>
<key>generate_options</key>
- <value>wx_gui</value>
+ <value>qt_gui</value>
<type>enum</type>
<option>
- <name>WX GUI</name>
- <key>wx_gui</key>
- </option>
- <option>
<name>QT GUI</name>
<key>qt_gui</key>
</option>
<option>
+ <name>WX GUI</name>
+ <key>wx_gui</key>
+ </option>
+ <option>
<name>No GUI</name>
<key>no_gui</key>
</option>
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index f8963fa472..6c56a94e9c 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -495,9 +495,11 @@ class ActionHandler:
ExecFlowGraphThread(self)
elif action == Actions.FLOW_GRAPH_KILL:
if self.get_page().get_proc():
- try: self.get_page().get_proc().kill()
- except: print "could not kill process: %d"%self.get_page().get_proc().pid
- elif action == Actions.PAGE_CHANGE: #pass and run the global actions
+ try:
+ self.get_page().get_proc().kill()
+ except:
+ print "could not kill process: %d" % self.get_page().get_proc().pid
+ elif action == Actions.PAGE_CHANGE: # pass and run the global actions
pass
elif action == Actions.RELOAD_BLOCKS:
self.platform.load_blocks()
@@ -583,7 +585,7 @@ class ActionHandler:
sensitive = self.get_flow_graph().is_valid() and not self.get_page().get_proc()
Actions.FLOW_GRAPH_GEN.set_sensitive(sensitive)
Actions.FLOW_GRAPH_EXEC.set_sensitive(sensitive)
- Actions.FLOW_GRAPH_KILL.set_sensitive(self.get_page().get_proc() != None)
+ Actions.FLOW_GRAPH_KILL.set_sensitive(self.get_page().get_proc() is not None)
class ExecFlowGraphThread(Thread):
"""Execute the flow graph as a new process and wait on it to finish."""
@@ -619,13 +621,14 @@ class ExecFlowGraphThread(Thread):
"""
#handle completion
r = "\n"
- while(r):
+ while r:
gobject.idle_add(Messages.send_verbose_exec, r)
r = os.read(self.p.stdout.fileno(), 1024)
+ self.p.poll()
gobject.idle_add(self.done)
def done(self):
"""Perform end of execution tasks."""
- Messages.send_end_exec()
+ Messages.send_end_exec(self.p.returncode)
self.page.set_proc(None)
self.update_exec_stop()
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 1a32f6c2ba..9b8d3b1b56 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -25,7 +25,7 @@ from Constants import BORDER_PROXIMITY_SENSITIVITY
from Constants import \
BLOCK_LABEL_PADDING, \
PORT_SEPARATION, LABEL_SEPARATION, \
- PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS
+ PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS, BLOCK_FONT, PARAM_FONT
import Actions
import pygtk
pygtk.require('2.0')
@@ -34,7 +34,7 @@ import pango
BLOCK_MARKUP_TMPL="""\
#set $foreground = $block.is_valid() and 'black' or 'red'
-<span foreground="$foreground" font_desc="Sans 8"><b>$encode($block.get_name())</b></span>"""
+<span foreground="$foreground" font_desc="$font"><b>$encode($block.get_name())</b></span>"""
class Block(Element):
"""The graphical signal block."""
@@ -146,11 +146,13 @@ class Block(Element):
#create the main layout
layout = gtk.DrawingArea().create_pango_layout('')
layouts.append(layout)
- layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self))
+ layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self, font=BLOCK_FONT))
self.label_width, self.label_height = layout.get_pixel_size()
#display the params
if self.is_dummy_block():
- markups = ['<span foreground="black" font_desc="Sans 7.5"><b>key: </b>{}</span>'.format(self._key)]
+ markups = [
+ '<span foreground="black" font_desc="$font"><b>key: </b>{key}</span>'.format(font=PARAM_FONT, key=self._key)
+ ]
else:
markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')]
if markups:
diff --git a/grc/gui/Constants.py b/grc/gui/Constants.py
index 7db291df99..0dc6279fd2 100644
--- a/grc/gui/Constants.py
+++ b/grc/gui/Constants.py
@@ -41,6 +41,13 @@ MIN_DIALOG_HEIGHT = 500
##default sizes
DEFAULT_BLOCKS_WINDOW_WIDTH = 100
DEFAULT_REPORTS_WINDOW_WIDTH = 100
+## flow-graph canvas fonts
+FONT_FAMILY = "Sans"
+FONT_SIZE = 8
+BLOCK_FONT = "%s %f" % (FONT_FAMILY, FONT_SIZE)
+PORT_FONT = BLOCK_FONT
+PARAM_FONT = "%s %f" % (FONT_FAMILY, FONT_SIZE - 0.5)
+
##The size of the state saving cache in the flow graph (for undo/redo functionality)
STATE_CACHE_SIZE = 42
diff --git a/grc/gui/Messages.py b/grc/gui/Messages.py
index f220b6dd06..90f508d770 100644
--- a/grc/gui/Messages.py
+++ b/grc/gui/Messages.py
@@ -24,15 +24,17 @@ import os
## A list of functions that can receive a message.
MESSENGERS_LIST = list()
+
def register_messenger(messenger):
"""
Append the given messenger to the list of messengers.
Args:
- messenger: a method thats takes a string
+ messenger: a method that takes a string
"""
MESSENGERS_LIST.append(messenger)
+
def send(message):
"""
Give the message to each of the messengers.
@@ -102,8 +104,8 @@ def send_start_exec(file_path):
def send_verbose_exec(verbose):
send(verbose)
-def send_end_exec():
- send('\n>>> Done\n')
+def send_end_exec(returncode=0):
+ send('\n>>> Done%s\n' % (" (return code %s)" % returncode if returncode else ""))
################# functions for saving flow graphs ########################################
def send_fail_save(file_path):
diff --git a/grc/gui/Param.py b/grc/gui/Param.py
index 499af2e2ed..76dafdf3cc 100644
--- a/grc/gui/Param.py
+++ b/grc/gui/Param.py
@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
import Utils
from Element import Element
+from . Constants import PARAM_FONT
import pygtk
pygtk.require('2.0')
import gtk
@@ -184,7 +185,7 @@ class FileParam(EntryParam):
PARAM_MARKUP_TMPL="""\
#set $foreground = $param.is_valid() and 'black' or 'red'
-<span foreground="$foreground" font_desc="Sans 7.5"><b>$encode($param.get_name()): </b>$encode(repr($param))</span>"""
+<span foreground="$foreground" font_desc="$font"><b>$encode($param.get_name()): </b>$encode(repr($param))</span>"""
PARAM_LABEL_MARKUP_TMPL="""\
#set $foreground = $modified and 'blue' or $param.is_valid() and 'black' or 'red'
@@ -249,4 +250,4 @@ class Param(Element):
Returns:
a pango markup string
"""
- return Utils.parse_template(PARAM_MARKUP_TMPL, param=self)
+ return Utils.parse_template(PARAM_MARKUP_TMPL, param=self, font=PARAM_FONT)
diff --git a/grc/gui/Port.py b/grc/gui/Port.py
index 364ca6a5b9..2a87573911 100644
--- a/grc/gui/Port.py
+++ b/grc/gui/Port.py
@@ -21,7 +21,7 @@ from Element import Element
from Constants import \
PORT_SEPARATION, CONNECTOR_EXTENSION_MINIMAL, \
CONNECTOR_EXTENSION_INCREMENT, \
- PORT_LABEL_PADDING, PORT_MIN_WIDTH, PORT_LABEL_HIDDEN_WIDTH
+ PORT_LABEL_PADDING, PORT_MIN_WIDTH, PORT_LABEL_HIDDEN_WIDTH, PORT_FONT
import Utils
import Actions
import Colors
@@ -29,10 +29,8 @@ import pygtk
pygtk.require('2.0')
import gtk
-PORT_HIDDEN_MARKUP_TMPL="""\
-<span foreground="black" font_desc="Sans 7.5"> </span>"""
PORT_MARKUP_TMPL="""\
-<span foreground="black" font_desc="Sans 7.5">$encode($port.get_name())</span>"""
+<span foreground="black" font_desc="$font">$encode($port.get_name())</span>"""
class Port(Element):
@@ -115,7 +113,7 @@ class Port(Element):
self._bg_color = Colors.get_color(self.get_color())
#create the layout
layout = gtk.DrawingArea().create_pango_layout('')
- layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self))
+ layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self, font=PORT_FONT))
self.w, self.h = layout.get_pixel_size()
self.W, self.H = 2*PORT_LABEL_PADDING + self.w, 2*PORT_LABEL_PADDING+self.h
self.H = self.modify_height(self.H)
diff --git a/volk/apps/volk_profile.cc b/volk/apps/volk_profile.cc
index 074d1e7be4..416884734d 100644
--- a/volk/apps/volk_profile.cc
+++ b/volk/apps/volk_profile.cc
@@ -37,6 +37,49 @@
namespace fs = boost::filesystem;
+void write_json(std::ofstream &json_file, std::vector<volk_test_results_t> results) {
+ json_file << "{" << std::endl;
+ json_file << " \"volk_tests\": [" << std::endl;
+ size_t len = results.size();
+ size_t i = 0;
+ BOOST_FOREACH(volk_test_results_t &result, results) {
+ json_file << " {" << std::endl;
+ json_file << " \"name\": \"" << result.name << "\"," << std::endl;
+ json_file << " \"vlen\": " << result.vlen << "," << std::endl;
+ json_file << " \"iter\": " << result.iter << "," << std::endl;
+ json_file << " \"best_arch_a\": \"" << result.best_arch_a
+ << "\"," << std::endl;
+ json_file << " \"best_arch_u\": \"" << result.best_arch_u
+ << "\"," << std::endl;
+ json_file << " \"results\": {" << std::endl;
+ size_t results_len = result.results.size();
+ size_t ri = 0;
+ typedef std::pair<std::string, volk_test_time_t> tpair;
+ BOOST_FOREACH(tpair pair, result.results) {
+ volk_test_time_t time = pair.second;
+ json_file << " \"" << time.name << "\": {" << std::endl;
+ json_file << " \"name\": \"" << time.name << "\"," << std::endl;
+ json_file << " \"time\": " << time.time << "," << std::endl;
+ json_file << " \"units\": \"" << time.units << "\"" << std::endl;
+ json_file << " }" ;
+ if(ri+1 != results_len) {
+ json_file << ",";
+ }
+ json_file << std::endl;
+ ri++;
+ }
+ json_file << " }" << std::endl;
+ json_file << " }";
+ if(i+1 != len) {
+ json_file << ",";
+ }
+ json_file << std::endl;
+ i++;
+ }
+ json_file << " ]" << std::endl;
+ json_file << "}" << std::endl;
+}
+
int main(int argc, char *argv[]) {
// Adding program options
boost::program_options::options_description desc("Options");
@@ -49,6 +92,9 @@ int main(int argc, char *argv[]) {
("tests-regex,R",
boost::program_options::value<std::string>(),
"Run tests matching regular expression.")
+ ("json,j",
+ boost::program_options::value<std::string>(),
+ "JSON output file")
;
// Handle the options that were given
@@ -56,6 +102,8 @@ int main(int argc, char *argv[]) {
bool benchmark_mode;
std::string kernel_regex;
bool store_results = true;
+ std::ofstream json_file;
+
try {
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
boost::program_options::notify(vm);
@@ -83,9 +131,14 @@ int main(int argc, char *argv[]) {
return 0;
}
+ if ( vm.count("json") )
+ {
+ json_file.open( vm["json"].as<std::string>().c_str() );
+ }
+
// Run tests
- std::vector<std::string> results;
+ std::vector<volk_test_results_t> results;
//VOLK_PROFILE(volk_16i_x5_add_quad_16i_x4, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
//VOLK_PROFILE(volk_16i_branch_4_state_8, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
@@ -178,6 +231,7 @@ int main(int argc, char *argv[]) {
VOLK_PROFILE(volk_32f_s32f_multiply_32f, 1e-4, 1.0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32f_binary_slicer_32i, 0, 1.0, 204602, 10000, &results, benchmark_mode, kernel_regex);
VOLK_PROFILE(volk_32f_binary_slicer_8i, 0, 1.0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_32f_tanh_32f, 1e-6, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
// Until we can update the config on a kernel by kernel basis
// do not overwrite volk_config when using a regex.
@@ -204,8 +258,10 @@ int main(int argc, char *argv[]) {
#the function name is followed by the preferred architecture.\n\
";
- BOOST_FOREACH(std::string result, results) {
- config << result << std::endl;
+ BOOST_FOREACH(volk_test_results_t result, results) {
+ config << result.config_name << " "
+ << result.best_arch_a << " "
+ << result.best_arch_u << std::endl;
}
config.close();
}
diff --git a/volk/kernels/volk/volk_32f_tanh_32f.h b/volk/kernels/volk/volk_32f_tanh_32f.h
new file mode 100644
index 0000000000..3f407d4656
--- /dev/null
+++ b/volk/kernels/volk/volk_32f_tanh_32f.h
@@ -0,0 +1,296 @@
+#ifndef INCLUDED_volk_32f_tanh_32f_a_H
+#define INCLUDED_volk_32f_tanh_32f_a_H
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef LV_HAVE_GENERIC
+/*!
+\brief Calculates tanh(x)
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_generic(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ for(; number < num_points; number++) {
+ *cPtr++ = tanh(*aPtr++);
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+
+#ifdef LV_HAVE_GENERIC
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_series(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ for(; number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+
+
+#ifdef LV_HAVE_SSE
+#include <xmmintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_a_sse(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m128 aVal, cVal, x2, a, b;
+ __m128 const1, const2, const3, const4, const5, const6;
+ const1 = _mm_set_ps1(135135.0f);
+ const2 = _mm_set_ps1(17325.0f);
+ const3 = _mm_set_ps1(378.0f);
+ const4 = _mm_set_ps1(62370.0f);
+ const5 = _mm_set_ps1(3150.0f);
+ const6 = _mm_set_ps1(28.0f);
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_load_ps(aPtr);
+ x2 = _mm_mul_ps(aVal, aVal);
+ a = _mm_mul_ps(aVal, _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const2, _mm_mul_ps(x2, _mm_add_ps(const3, x2))))));
+ b = _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const4, _mm_mul_ps(x2, _mm_add_ps(const5, _mm_mul_ps(x2, const6))))));
+
+ cVal = _mm_div_ps(a, b);
+
+ _mm_store_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_a_avx(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m256 aVal, cVal, x2, a, b;
+ __m256 const1, const2, const3, const4, const5, const6;
+ const1 = _mm256_set1_ps(135135.0f);
+ const2 = _mm256_set1_ps(17325.0f);
+ const3 = _mm256_set1_ps(378.0f);
+ const4 = _mm256_set1_ps(62370.0f);
+ const5 = _mm256_set1_ps(3150.0f);
+ const6 = _mm256_set1_ps(28.0f);
+ for(;number < eighthPoints; number++){
+
+ aVal = _mm256_load_ps(aPtr);
+ x2 = _mm256_mul_ps(aVal, aVal);
+ a = _mm256_mul_ps(aVal, _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const2, _mm256_mul_ps(x2, _mm256_add_ps(const3, x2))))));
+ b = _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const4, _mm256_mul_ps(x2, _mm256_add_ps(const5, _mm256_mul_ps(x2, const6))))));
+
+ cVal = _mm256_div_ps(a, b);
+
+ _mm256_store_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 8;
+ cPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_AVX */
+
+
+
+
+#ifdef LV_HAVE_SSE
+#include <xmmintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_u_sse(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m128 aVal, cVal, x2, a, b;
+ __m128 const1, const2, const3, const4, const5, const6;
+ const1 = _mm_set_ps1(135135.0f);
+ const2 = _mm_set_ps1(17325.0f);
+ const3 = _mm_set_ps1(378.0f);
+ const4 = _mm_set_ps1(62370.0f);
+ const5 = _mm_set_ps1(3150.0f);
+ const6 = _mm_set_ps1(28.0f);
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_loadu_ps(aPtr);
+ x2 = _mm_mul_ps(aVal, aVal);
+ a = _mm_mul_ps(aVal, _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const2, _mm_mul_ps(x2, _mm_add_ps(const3, x2))))));
+ b = _mm_add_ps(const1, _mm_mul_ps(x2, _mm_add_ps(const4, _mm_mul_ps(x2, _mm_add_ps(const5, _mm_mul_ps(x2, const6))))));
+
+ cVal = _mm_div_ps(a, b);
+
+ _mm_storeu_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+
+
+#ifdef LV_HAVE_AVX
+#include <immintrin.h>
+/*!
+\brief Calculates tanh(x) using a series approximation, good to within 1e-6 of the actual tanh.
+\param cVector The vector where the results will be stored
+\param aVector Input vector
+\param num_points The number of values to calulate
+*/
+static inline void volk_32f_tanh_32f_u_avx(float* cVector, const float* aVector,
+ unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+
+ __m256 aVal, cVal, x2, a, b;
+ __m256 const1, const2, const3, const4, const5, const6;
+ const1 = _mm256_set1_ps(135135.0f);
+ const2 = _mm256_set1_ps(17325.0f);
+ const3 = _mm256_set1_ps(378.0f);
+ const4 = _mm256_set1_ps(62370.0f);
+ const5 = _mm256_set1_ps(3150.0f);
+ const6 = _mm256_set1_ps(28.0f);
+ for(;number < eighthPoints; number++){
+
+ aVal = _mm256_loadu_ps(aPtr);
+ x2 = _mm256_mul_ps(aVal, aVal);
+ a = _mm256_mul_ps(aVal, _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const2, _mm256_mul_ps(x2, _mm256_add_ps(const3, x2))))));
+ b = _mm256_add_ps(const1, _mm256_mul_ps(x2, _mm256_add_ps(const4, _mm256_mul_ps(x2, _mm256_add_ps(const5, _mm256_mul_ps(x2, const6))))));
+
+ cVal = _mm256_div_ps(a, b);
+
+ _mm256_storeu_ps(cPtr, cVal); // Store the results back into the C container
+
+ aPtr += 8;
+ cPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(;number < num_points; number++) {
+ if(*aPtr > 4.97)
+ *cPtr++ = 1;
+ else if(*aPtr <= -4.97)
+ *cPtr++ = -1;
+ else {
+ float x2 = (*aPtr) * (*aPtr);
+ float a = (*aPtr) * (135135.0f + x2 * (17325.0f + x2 * (378.0f + x2)));
+ float b = 135135.0f + x2 * (62370.0f + x2 * (3150.0f + x2 * 28.0f));
+ *cPtr++ = a / b;
+ aPtr++;
+ }
+ }
+}
+#endif /* LV_HAVE_AVX */
+
+#endif /* INCLUDED_volk_32f_tanh_32f_a_H */
diff --git a/volk/lib/CMakeLists.txt b/volk/lib/CMakeLists.txt
index 6cc4504cfa..37915e5552 100644
--- a/volk/lib/CMakeLists.txt
+++ b/volk/lib/CMakeLists.txt
@@ -406,10 +406,8 @@ if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
# if we find one that matches our current system architecture
# set up the assembler flags and include the source files
foreach(ARCH ${ASM_ARCHS_AVAILABLE})
- message(STATUS "--==>> -CFLAGS1: ${FULL_C_FLAGS}")
string(REGEX MATCH "${ARCH}" ASM_ARCH "${FULL_C_FLAGS}")
if( ASM_ARCH STREQUAL "armv7" )
- set(ASM-ATT $ENV{ASM})
message(STATUS "---- Adding ASM files") # we always use ATT syntax
message(STATUS "-- Detected armv7 architecture; enabling ASM")
# setup architecture specific assembler flags
@@ -422,13 +420,20 @@ if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
message(STATUS "Adding source file: ${asm_file}")
endforeach(asm_file)
endif()
- set(CMAKE_ASM-ATT_FLAGS_INIT ${ARCH_ASM_FLAGS})
- enable_language(ASM-ATT) # this must be after flags_init
- message(STATUS "asm flags: ${CMAKE_ASM-ATT_FLAGS}")
+ enable_language(ASM)
+ set(CMAKE_ASM_FLAGS ${ARCH_ASM_FLAGS})
+ message(STATUS "c flags: ${FULL_C_FLAGS}")
+ message(STATUS "asm flags: ${CMAKE_ASM_FLAGS}")
endforeach(ARCH)
else(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
message(STATUS "Not enabling ASM support. CMake >= 2.8.10 required.")
+ foreach(machine_name ${available_machines})
+ string(REGEX MATCH "neon" NEON_MACHINE ${machine_name})
+ if( NEON_MACHINE STREQUAL "neon")
+ message(FATAL_ERROR "CMake >= 2.8.10 is required for ARM NEON support")
+ endif()
+ endforeach()
endif(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
########################################################################
diff --git a/volk/lib/qa_utils.cc b/volk/lib/qa_utils.cc
index f30f0097ae..3ab4a9970c 100644
--- a/volk/lib/qa_utils.cc
+++ b/volk/lib/qa_utils.cc
@@ -5,7 +5,9 @@
#include <boost/tokenizer.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <iostream>
+#include <fstream>
#include <vector>
+#include <map>
#include <list>
#include <ctime>
#include <cmath>
@@ -328,9 +330,9 @@ bool run_volk_tests(volk_func_desc_t desc,
lv_32fc_t scalar,
int vlen,
int iter,
- std::vector<std::string> *best_arch_vector = 0,
- std::string puppet_master_name = "NULL",
- bool benchmark_mode,
+ std::vector<volk_test_results_t> *results,
+ std::string puppet_master_name,
+ bool benchmark_mode,
std::string kernel_regex
) {
boost::xpressive::sregex kernel_expression = boost::xpressive::sregex::compile(kernel_regex);
@@ -338,6 +340,12 @@ bool run_volk_tests(volk_func_desc_t desc,
// in this case we have a regex and are only looking to test one kernel
return false;
}
+ if(results) {
+ results->push_back(volk_test_results_t());
+ results->back().name = name;
+ results->back().vlen = vlen;
+ results->back().iter = iter;
+ }
std::cout << "RUN_VOLK_TESTS: " << name << "(" << vlen << "," << iter << ")" << std::endl;
// The multiply and lv_force_cast_hf are work arounds for GNU Radio bugs 582 and 583
@@ -453,6 +461,13 @@ bool run_volk_tests(volk_func_desc_t desc,
end = clock();
double arch_time = 1000.0 * (double)(end-start)/(double)CLOCKS_PER_SEC;
std::cout << arch_list[i] << " completed in " << arch_time << "ms" << std::endl;
+ if(results) {
+ volk_test_time_t result;
+ result.name = arch_list[i];
+ result.time = arch_time;
+ result.units = "ms";
+ results->back().results[result.name] = result;
+ }
profile_times.push_back(arch_time);
}
@@ -553,13 +568,14 @@ bool run_volk_tests(volk_func_desc_t desc,
std::cout << "Best aligned arch: " << best_arch_a << std::endl;
std::cout << "Best unaligned arch: " << best_arch_u << std::endl;
- if(best_arch_vector) {
+ if(results) {
if(puppet_master_name == "NULL") {
- best_arch_vector->push_back(name + " " + best_arch_a + " " + best_arch_u);
- }
- else {
- best_arch_vector->push_back(puppet_master_name + " " + best_arch_a + " " + best_arch_u);
+ results->back().config_name = name;
+ } else {
+ results->back().config_name = puppet_master_name;
}
+ results->back().best_arch_a = best_arch_a;
+ results->back().best_arch_u = best_arch_u;
}
return fail_global;
diff --git a/volk/lib/qa_utils.h b/volk/lib/qa_utils.h
index fc1a0239eb..7ca8b8d1e8 100644
--- a/volk/lib/qa_utils.h
+++ b/volk/lib/qa_utils.h
@@ -3,7 +3,10 @@
#include <cstdlib>
#include <string>
+#include <iostream>
+#include <fstream>
#include <vector>
+#include <map>
#include <volk/volk.h>
#include <volk/volk_common.h>
@@ -21,10 +24,46 @@ volk_type_t volk_type_from_string(std::string);
float uniform(void);
void random_floats(float *buf, unsigned n);
-bool run_volk_tests(volk_func_desc_t, void(*)(), std::string, float, lv_32fc_t, int, int, std::vector<std::string> *, std::string, bool benchmark_mode=false, std::string kernel_regex="");
+class volk_test_time_t {
+ public:
+ std::string name;
+ double time;
+ std::string units;
+};
+
+class volk_test_results_t {
+ public:
+ std::string name;
+ std::string config_name;
+ int vlen;
+ int iter;
+ std::map<std::string, volk_test_time_t> results;
+ std::string best_arch_a;
+ std::string best_arch_u;
+};
+
+bool run_volk_tests(
+ volk_func_desc_t,
+ void(*)(),
+ std::string,
+ float,
+ lv_32fc_t,
+ int,
+ int,
+ std::vector<volk_test_results_t> *results = NULL,
+ std::string puppet_master_name = "NULL",
+ bool benchmark_mode=false,
+ std::string kernel_regex=""
+ );
-#define VOLK_RUN_TESTS(func, tol, scalar, len, iter) BOOST_AUTO_TEST_CASE(func##_test) { BOOST_CHECK_EQUAL(run_volk_tests(func##_get_func_desc(), (void (*)())func##_manual, std::string(#func), tol, scalar, len, iter, 0, "NULL"), 0); }
+#define VOLK_RUN_TESTS(func, tol, scalar, len, iter) \
+ BOOST_AUTO_TEST_CASE(func##_test) { \
+ BOOST_CHECK_EQUAL(run_volk_tests( \
+ func##_get_func_desc(), (void (*)())func##_manual, \
+ std::string(#func), tol, scalar, len, iter, 0, "NULL"), \
+ 0); \
+ }
#define VOLK_PROFILE(func, tol, scalar, len, iter, results, bnmode, kernel_regex) run_volk_tests(func##_get_func_desc(), (void (*)())func##_manual, std::string(#func), tol, scalar, len, iter, results, "NULL", bnmode, kernel_regex)
#define VOLK_PUPPET_PROFILE(func, puppet_master_func, tol, scalar, len, iter, results, bnmode, kernel_regex) run_volk_tests(func##_get_func_desc(), (void (*)())func##_manual, std::string(#func), tol, scalar, len, iter, results, std::string(#puppet_master_func), bnmode, kernel_regex)
typedef void (*volk_fn_1arg)(void *, unsigned int, const char*); //one input, operate in place
diff --git a/volk/lib/testqa.cc b/volk/lib/testqa.cc
index bc97ad16e5..9d837517f1 100644
--- a/volk/lib/testqa.cc
+++ b/volk/lib/testqa.cc
@@ -114,3 +114,4 @@ VOLK_RUN_TESTS(volk_8u_conv_k7_r2puppet_8u, 0, 0, 2060, 1);
VOLK_RUN_TESTS(volk_32f_invsqrt_32f, 1e-2, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32f_binary_slicer_32i, 0, 0, 20462, 1);
VOLK_RUN_TESTS(volk_32f_binary_slicer_8i, 0, 0, 20462, 1);
+VOLK_RUN_TESTS(volk_32f_tanh_32f, 1e-6, 0, 20462, 1);