diff options
author | Tom Rondeau <tom@trondeau.com> | 2013-10-23 16:38:14 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2013-10-29 12:10:55 -0400 |
commit | ecfac74f2a7117da540eb39ac46b903431598fed (patch) | |
tree | b22c94091879eb6919a1a86f6342a13ede7de130 | |
parent | 1cbeec5083bbfdd281b30271e874f0849b0a9be0 (diff) |
blocks: adding message ports to repack_bits for setting input and output values with messages.
-rw-r--r-- | gr-blocks/lib/repack_bits_bb_impl.cc | 90 | ||||
-rw-r--r-- | gr-blocks/lib/repack_bits_bb_impl.h | 8 | ||||
-rwxr-xr-x | gr-blocks/python/blocks/qa_repack_bits_bb.py | 53 |
3 files changed, 119 insertions, 32 deletions
diff --git a/gr-blocks/lib/repack_bits_bb_impl.cc b/gr-blocks/lib/repack_bits_bb_impl.cc index af83187e92..2b5d82ef8b 100644 --- a/gr-blocks/lib/repack_bits_bb_impl.cc +++ b/gr-blocks/lib/repack_bits_bb_impl.cc @@ -47,8 +47,18 @@ namespace gr { d_align_output(align_output) { if (d_k > 8 || d_k < 1 || d_l > 8 || d_l < 1) { - throw std::invalid_argument("k and l must be in [1, 8]"); + throw std::invalid_argument("k and l must be in [1, 8]"); } + message_port_register_in(pmt::mp("set_n_input_bits")); + set_msg_handler( + pmt::mp("set_n_input_bits"), + boost::bind(&repack_bits_bb_impl::handle_set_n_input_bits, + this, _1)); + message_port_register_in(pmt::mp("set_n_output_bits")); + set_msg_handler( + pmt::mp("set_n_output_bits"), + boost::bind(&repack_bits_bb_impl::handle_set_n_output_bits, + this, _1)); set_relative_rate((double) d_k / d_l); } @@ -62,12 +72,32 @@ namespace gr { { int n_out_bytes_required = (ninput_items[0] * d_k) / d_l; if ((ninput_items[0] * d_k) % d_l && (!d_packet_mode || (d_packet_mode && !d_align_output))) { - n_out_bytes_required++; + n_out_bytes_required++; } return n_out_bytes_required; } + void + repack_bits_bb_impl::handle_set_n_input_bits (pmt::pmt_t k_pmt) { + set_n_input_bits((unsigned int)pmt::to_long(k_pmt)); + } + + void + repack_bits_bb_impl::handle_set_n_output_bits (pmt::pmt_t l_pmt) { + set_n_output_bits((unsigned int)pmt::to_long(l_pmt)); + } + + void + repack_bits_bb_impl::set_n_input_bits (unsigned int k) { + d_k = k; + } + + void + repack_bits_bb_impl::set_n_output_bits (unsigned int l) { + d_l = l; + } + int repack_bits_bb_impl::work (int noutput_items, gr_vector_int &ninput_items, @@ -79,45 +109,45 @@ namespace gr { int bytes_to_write = noutput_items; if (d_packet_mode) { // noutput_items could be larger than necessary - int bytes_to_read = ninput_items[0]; - bytes_to_write = bytes_to_read * d_k / d_l; - if (!d_align_output && (((bytes_to_read * d_k) % d_l) != 0)) { - bytes_to_write++; - } + int bytes_to_read = ninput_items[0]; + bytes_to_write = bytes_to_read * d_k / d_l; + if (!d_align_output && (((bytes_to_read * d_k) % d_l) != 0)) { + bytes_to_write++; + } } int n_read = 0; int n_written = 0; while(n_written < bytes_to_write && n_read < ninput_items[0]) { - if (d_out_index == 0) { // Starting a fresh byte - out[n_written] = 0; - } - out[n_written] |= ((in[n_read] >> d_in_index) & 0x01) << d_out_index; - - d_in_index = (d_in_index + 1) % d_k; - d_out_index = (d_out_index + 1) % d_l; - if (d_in_index == 0) { - n_read++; - d_in_index = 0; - } - if (d_out_index == 0) { - n_written++; - d_out_index = 0; - } + if (d_out_index == 0) { // Starting a fresh byte + out[n_written] = 0; + } + out[n_written] |= ((in[n_read] >> d_in_index) & 0x01) << d_out_index; + + d_in_index = (d_in_index + 1) % d_k; + d_out_index = (d_out_index + 1) % d_l; + if (d_in_index == 0) { + n_read++; + d_in_index = 0; + } + if (d_out_index == 0) { + n_written++; + d_out_index = 0; + } } - + if (d_packet_mode) { - if (d_out_index) { - n_written++; - d_out_index = 0; - } + if (d_out_index) { + n_written++; + d_out_index = 0; + } } else { - consume_each(n_read); + consume_each(n_read); } - + return n_written; } - + } /* namespace blocks */ } /* namespace gr */ diff --git a/gr-blocks/lib/repack_bits_bb_impl.h b/gr-blocks/lib/repack_bits_bb_impl.h index ffb8349d35..e6edb579a1 100644 --- a/gr-blocks/lib/repack_bits_bb_impl.h +++ b/gr-blocks/lib/repack_bits_bb_impl.h @@ -31,12 +31,16 @@ namespace gr { class repack_bits_bb_impl : public repack_bits_bb { private: - const int d_k; //! Bits on input stream - const int d_l; //! Bits on output stream + int d_k; //! Bits on input stream + int d_l; //! Bits on output stream const bool d_packet_mode; int d_in_index; // Current bit of input byte int d_out_index; // Current bit of output byte bool d_align_output; //! true if the output shall be aligned, false if the input shall be aligned + void handle_set_n_input_bits (pmt::pmt_t k_pmt); + void handle_set_n_output_bits (pmt::pmt_t l_pmt); + void set_n_input_bits (unsigned int k); + void set_n_output_bits (unsigned int l); protected: int calculate_output_stream_length(const gr_vector_int &ninput_items); diff --git a/gr-blocks/python/blocks/qa_repack_bits_bb.py b/gr-blocks/python/blocks/qa_repack_bits_bb.py index d9bbfe4fac..539d576039 100755 --- a/gr-blocks/python/blocks/qa_repack_bits_bb.py +++ b/gr-blocks/python/blocks/qa_repack_bits_bb.py @@ -121,6 +121,59 @@ class qa_repack_bits_bb (gr_unittest.TestCase): self.assertEqual(pmt.symbol_to_string(out_tag.key), tag_name) self.assertEqual(pmt.to_long(out_tag.value), len(expected_data)) + def test_switch_k_with_tag (self): + """ + A: 3 -> 8 (3*9=27 -> 8*3+3) It throws away extra bits. + B: 5 -> 8 (5*3=15 -> 8*1+7) + """ + src_dataA = (0b101,) + (0b111,) * 7 + (0b001,) + src_dataB = (0b10101,) + (0b11111,) + (0b00110,) + expected_dataA = (0b11111101, 0b11111111, 0b11111111, ) + expected_dataB = (0b11110101, ) + kA = 3 + kB = 5 + l = 8 + tag_name = "len" + len_tagA = gr.tag_t() + len_tagA.offset = 0 + len_tagA.key = pmt.string_to_symbol(tag_name) + len_tagA.value = pmt.from_long(len(src_dataA)) + + k_tagA = gr.tag_t() + k_tagA.offset = 0 + k_tagA.key = pmt.string_to_symbol("set_n_input_bits") + k_tagA.value = pmt.from_long(kA) + len_tagB = gr.tag_t() + len_tagB.offset = len(src_dataA) + len_tagB.key = pmt.string_to_symbol(tag_name) + len_tagB.value = pmt.from_long(len(src_dataB)) + k_tagB = gr.tag_t() + k_tagB.offset = len(src_dataA) + k_tagB.key = pmt.string_to_symbol("set_n_input_bits") + k_tagB.value = pmt.from_long(kB) + src = blocks.vector_source_b(src_dataA+src_dataB, False, 1, + (len_tagA, k_tagA, len_tagB, k_tagB)) + repack = blocks.repack_bits_bb(kA, l, tag_name, True) + sink = blocks.vector_sink_b() + self.tb.connect(src, repack, sink) + self.tb.run () + self.assertEqual(sink.data(), expected_dataA+expected_dataB) + # The output should contains 4 tags. + # Two these should be length tags. + length_tags = [] + for tag in sink.tags(): + if pmt.symbol_to_string(tag.key) == tag_name: + length_tags.append(tag) + self.assertEqual(len(length_tags), 2) + out_tagA = length_tags[0] + out_tagB = length_tags[1] + self.assertEqual(out_tagA.offset, 0) + self.assertEqual(out_tagB.offset, len(expected_dataA)) + self.assertEqual(pmt.symbol_to_string(out_tagA.key), tag_name) + self.assertEqual(pmt.symbol_to_string(out_tagB.key), tag_name) + self.assertEqual(pmt.to_long(out_tagA.value), len(expected_dataA)) + self.assertEqual(pmt.to_long(out_tagB.value), len(expected_dataB)) + if __name__ == '__main__': gr_unittest.run(qa_repack_bits_bb, "qa_repack_bits_bb.xml") |