diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-09-23 18:00:41 -0400 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2014-09-24 15:48:58 -0700 |
commit | 71299bf848d3185af73e36bcee0de7a649398b91 (patch) | |
tree | d518e60dea7e546a6fe2c3b4af1333840e117075 /gr-blocks/lib | |
parent | 881c41c75b414b1769a7b44478806430f36b10be (diff) |
blocks: deinterleaver will process more than one block at a time for significant speed improvements.
Diffstat (limited to 'gr-blocks/lib')
-rw-r--r-- | gr-blocks/lib/deinterleave_impl.cc | 36 | ||||
-rw-r--r-- | gr-blocks/lib/deinterleave_impl.h | 3 |
2 files changed, 33 insertions, 6 deletions
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, |