Last active
August 29, 2015 14:06
-
-
Save trondeau/7d5d06ea2f0586f0e9e4 to your computer and use it in GitHub Desktop.
patch for gr::blocks::deinterleave to handle multiple blocks of data at once
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/gr-blocks/lib/deinterleave_impl.cc b/gr-blocks/lib/deinterleave_impl.cc | |
index c9d0e9a..9e18c35 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 247ee3a..71a551a 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, |
Updated from what mbr0wn suggested.We had to properly set forecast for this to work, too.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm wondering if this is actually the most optimal solution: Your loop exit condition is
yet you increase count in every loop. Isn't noutput_items the number available in every output buffer? I.e. shouldn't you increase count every time skip is incremented?