summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rondeau <tom@trondeau.com>2013-10-23 16:38:14 -0400
committerTom Rondeau <tom@trondeau.com>2013-10-29 12:10:55 -0400
commitecfac74f2a7117da540eb39ac46b903431598fed (patch)
treeb22c94091879eb6919a1a86f6342a13ede7de130
parent1cbeec5083bbfdd281b30271e874f0849b0a9be0 (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.cc90
-rw-r--r--gr-blocks/lib/repack_bits_bb_impl.h8
-rwxr-xr-xgr-blocks/python/blocks/qa_repack_bits_bb.py53
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")