diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2017-04-25 17:36:56 +0000 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2017-04-26 19:44:21 +0000 |
commit | f2f09be209ee4394d041b422e5d7375354ca0af3 (patch) | |
tree | 4e46c9124c53d415c3d3c853e9c09e688bb52584 | |
parent | 082711cc3f7d910e50609695224e7a3c994a4c73 (diff) |
blocks: tag_gate (improvements)
- Make it possible to specify a single tag key
to look for instead of all tags.
- Extended unit test for new functionality
- Actually fix a bug which made the unit test do nothing earlier
-rw-r--r-- | gr-blocks/grc/blocks_tag_gate.xml | 12 | ||||
-rw-r--r-- | gr-blocks/include/gnuradio/blocks/tag_gate.h | 15 | ||||
-rw-r--r-- | gr-blocks/lib/tag_gate_impl.cc | 41 | ||||
-rw-r--r-- | gr-blocks/lib/tag_gate_impl.h | 6 | ||||
-rwxr-xr-x | gr-blocks/python/blocks/qa_tag_gate.py | 75 |
5 files changed, 145 insertions, 4 deletions
diff --git a/gr-blocks/grc/blocks_tag_gate.xml b/gr-blocks/grc/blocks_tag_gate.xml index 5c748f27cf..bf38a8f850 100644 --- a/gr-blocks/grc/blocks_tag_gate.xml +++ b/gr-blocks/grc/blocks_tag_gate.xml @@ -3,7 +3,10 @@ <name>Tag Gate</name> <key>blocks_tag_gate</key> <import>from gnuradio import blocks</import> - <make>blocks.tag_gate($type.size * $vlen, $propagate_tags)</make> + <make>blocks.tag_gate($type.size * $vlen, $propagate_tags) +self.$(id).set_single_key($single_key))</make> + <callback>self.$(id).set_single_key($single_key)</callback> + <param> <name>Item Type</name> <key>type</key> @@ -54,6 +57,13 @@ <key>False</key> </option> </param> + + <param> + <name>Single key</name> + <key>single_key</key> + <value>""</value> + <type>string</type> + </param> <check>$vlen > 0</check> <sink> <name>in</name> diff --git a/gr-blocks/include/gnuradio/blocks/tag_gate.h b/gr-blocks/include/gnuradio/blocks/tag_gate.h index 5363301192..644b5cf75a 100644 --- a/gr-blocks/include/gnuradio/blocks/tag_gate.h +++ b/gr-blocks/include/gnuradio/blocks/tag_gate.h @@ -47,6 +47,21 @@ namespace gr { * \param propagate_tags Set this to true to allow tags to pass through this block. */ static sptr make(size_t item_size, bool propagate_tags=false); + + /*! + * \brief Only gate stream tags with one specific key instead of all keys + * + * \details + * If set to "", all tags will be affected by the gate. + * If set to "foo", all tags with key different from "foo" will pass + * through. + */ + virtual void set_single_key(const std::string &single_key)=0; + + /*! + * \brief Get the current single key. + */ + virtual std::string single_key() const = 0; }; } // namespace blocks diff --git a/gr-blocks/lib/tag_gate_impl.cc b/gr-blocks/lib/tag_gate_impl.cc index 643ec6748f..ad55c8af9a 100644 --- a/gr-blocks/lib/tag_gate_impl.cc +++ b/gr-blocks/lib/tag_gate_impl.cc @@ -41,11 +41,13 @@ namespace gr { gr::io_signature::make(1, 1, item_size), gr::io_signature::make(1, 1, item_size)), d_item_size(item_size), - d_propagate_tags(propagate_tags) + d_propagate_tags(propagate_tags), + d_single_key_set(false) { if (!d_propagate_tags) { set_tag_propagation_policy(TPP_DONT); } + d_single_key = pmt::PMT_NIL; } tag_gate_impl::~tag_gate_impl() @@ -54,10 +56,34 @@ namespace gr { void tag_gate_impl::set_propagation(bool propagate_tags) { + d_propagate_tags = propagate_tags; + if (propagate_tags) { - set_tag_propagation_policy(TPP_ALL_TO_ALL); + set_tag_propagation_policy(TPP_ALL_TO_ALL); } else { - set_tag_propagation_policy(TPP_DONT); + set_tag_propagation_policy(TPP_DONT); + } + } + + void tag_gate_impl::set_single_key(const std::string &single_key) + { + if(single_key == "") { + d_single_key = pmt::PMT_NIL; + d_single_key_set = false; + } + else { + d_single_key = pmt::intern(single_key); + d_single_key_set = true; + } + } + + std::string tag_gate_impl::single_key() const + { + if(pmt::equal(d_single_key, pmt::PMT_NIL)) { + return ""; + } + else { + return pmt::symbol_to_string(d_single_key); } } @@ -68,9 +94,18 @@ namespace gr { { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; + std::vector<tag_t> tags; memcpy((void *) out, (void *) in, d_item_size * noutput_items); + if (d_single_key_set && (!d_propagate_tags)) { + get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0) + noutput_items); + for (unsigned int i=0; i < tags.size(); i++) { + if (!pmt::equal(tags[i].key, d_single_key)) + add_item_tag(0, tags[i].offset, tags[i].key, tags[i].value, tags[i].srcid); + } + } + return noutput_items; } diff --git a/gr-blocks/lib/tag_gate_impl.h b/gr-blocks/lib/tag_gate_impl.h index 4983ba10b4..129fb78cb8 100644 --- a/gr-blocks/lib/tag_gate_impl.h +++ b/gr-blocks/lib/tag_gate_impl.h @@ -33,6 +33,9 @@ namespace gr { private: size_t d_item_size; bool d_propagate_tags; + bool d_single_key_set; + + pmt::pmt_t d_single_key; public: tag_gate_impl(size_t item_size, bool propagate_tags); @@ -43,6 +46,9 @@ namespace gr { int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + + void set_single_key(const std::string &single_key); + std::string single_key() const; }; } // namespace blocks diff --git a/gr-blocks/python/blocks/qa_tag_gate.py b/gr-blocks/python/blocks/qa_tag_gate.py index acb2c68a82..7ae676562e 100755 --- a/gr-blocks/python/blocks/qa_tag_gate.py +++ b/gr-blocks/python/blocks/qa_tag_gate.py @@ -40,9 +40,84 @@ class qa_tag_gate (gr_unittest.TestCase): src = blocks.vector_source_f(range(20), False, 1, (tag,)) gate = blocks.tag_gate(gr.sizeof_float, False) sink = blocks.vector_sink_f() + self.tb.connect(src, gate, sink) self.tb.run () self.assertEqual(len(sink.tags()), 0) + def test_002_t (self): + tags = [] + tags.append(gr.tag_t()) + tags[0].key = pmt.string_to_symbol('key') + tags[0].value = pmt.from_long(42) + tags[0].offset = 0 + tags.append(gr.tag_t()) + tags[1].key = pmt.string_to_symbol('key') + tags[1].value = pmt.from_long(42) + tags[1].offset = 5 + tags.append(gr.tag_t()) + tags[2].key = pmt.string_to_symbol('secondkey') + tags[2].value = pmt.from_long(42) + tags[2].offset = 6 + src = blocks.vector_source_f(range(20), False, 1, tags) + gate = blocks.tag_gate(gr.sizeof_float, False) + gate.set_single_key("key") + self.assertEqual(gate.single_key(),"key") + sink = blocks.vector_sink_f() + self.tb.connect(src, gate, sink) + self.tb.run () + self.assertEqual(len(sink.tags()), 1) + + def test_003_t (self): + tags = [] + tags.append(gr.tag_t()) + tags[0].key = pmt.string_to_symbol('key') + tags[0].value = pmt.from_long(42) + tags[0].offset = 0 + tags.append(gr.tag_t()) + tags[1].key = pmt.string_to_symbol('key') + tags[1].value = pmt.from_long(42) + tags[1].offset = 5 + tags.append(gr.tag_t()) + tags[2].key = pmt.string_to_symbol('secondkey') + tags[2].value = pmt.from_long(42) + tags[2].offset = 6 + src = blocks.vector_source_f(range(20), False, 1, tags) + gate = blocks.tag_gate(gr.sizeof_float, True) + gate.set_single_key("key") + sink = blocks.vector_sink_f() + self.tb.connect(src, gate, sink) + self.tb.run () + self.assertEqual(len(sink.tags()), 3) + + def test_004_t (self): + tags = [] + tags.append(gr.tag_t()) + tags[0].key = pmt.string_to_symbol('key') + tags[0].value = pmt.from_long(42) + tags[0].offset = 0 + tags.append(gr.tag_t()) + tags[1].key = pmt.string_to_symbol('key') + tags[1].value = pmt.from_long(42) + tags[1].offset = 5 + tags.append(gr.tag_t()) + tags[2].key = pmt.string_to_symbol('secondkey') + tags[2].value = pmt.from_long(42) + tags[2].offset = 6 + src = blocks.vector_source_f(range(20), False, 1, tags) + gate = blocks.tag_gate(gr.sizeof_float, True) + sink = blocks.vector_sink_f() + self.tb.connect(src, gate, sink) + self.tb.run () + self.assertEqual(len(sink.tags()), 3) + + def test_005_t (self): + gate = blocks.tag_gate(gr.sizeof_float, True) + self.assertEqual(gate.single_key(), "") + gate.set_single_key("the_key") + self.assertEqual(gate.single_key(), "the_key") + gate.set_single_key("") + self.assertEqual(gate.single_key(), "") + if __name__ == '__main__': gr_unittest.run(qa_tag_gate, "qa_tag_gate.xml") |