diff options
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r-- | gnuradio-core/src/lib/general/gr_delay.cc | 84 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_delay.h | 18 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_delay.i | 2 |
3 files changed, 85 insertions, 19 deletions
diff --git a/gnuradio-core/src/lib/general/gr_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc index b06346f59..cf868b37b 100644 --- a/gnuradio-core/src/lib/general/gr_delay.cc +++ b/gnuradio-core/src/lib/general/gr_delay.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2010 Free Software Foundation, Inc. + * Copyright 2007,2010,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -35,30 +35,90 @@ gr_make_delay (size_t itemsize, int delay) } gr_delay::gr_delay (size_t itemsize, int delay) - : gr_sync_block ("delay", - gr_make_io_signature (1, -1, itemsize), - gr_make_io_signature (1, -1, itemsize)), + : gr_block ("delay", + gr_make_io_signature (1, -1, itemsize), + gr_make_io_signature (1, -1, itemsize)), d_itemsize(itemsize) { set_delay(delay); + d_delta = 0; +} + +void +gr_delay::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + // make sure all inputs have noutput_items available + unsigned ninputs = ninput_items_required.size (); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = noutput_items; +} + +void +gr_delay::set_delay (int d) +{ + gruel::scoped_lock l(d_mutex_delay); + int old = delay(); + set_history(d+1); + d_delta = delay() - old; } int -gr_delay::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +gr_delay::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + gruel::scoped_lock l(d_mutex_delay); assert(input_items.size() == output_items.size()); const char *iptr; char *optr; + int cons, ret; - for(size_t i = 0; i < input_items.size(); i++) { - iptr = (const char *) input_items[i]; - optr = (char *) output_items[i]; + // No change in delay; just memcpy ins to outs + if(d_delta == 0) { + for(size_t i = 0; i < input_items.size(); i++) { + iptr = (const char *) input_items[i]; + optr = (char *) output_items[i]; + std::memcpy(optr, iptr, noutput_items*d_itemsize); + } + cons = noutput_items; + ret = noutput_items; + } - memcpy(optr, iptr, noutput_items*d_itemsize); + // Skip over d_delta items on the input + else if(d_delta < 0) { + int n_to_copy, n_adj; + int delta = -d_delta; + n_to_copy = std::max(0, noutput_items-delta); + n_adj = std::min(delta, noutput_items); + for(size_t i = 0; i < input_items.size(); i++) { + iptr = (const char *) input_items[i]; + optr = (char *) output_items[i]; + std::memcpy(optr, iptr+delta*d_itemsize, n_to_copy*d_itemsize); + } + cons = noutput_items; + ret = n_to_copy; + delta -= n_adj; + d_delta = -delta; } - return noutput_items; + //produce but not consume (inserts zeros) + else { // d_delta > 0 + int n_from_input, n_padding; + n_from_input = std::max(0, noutput_items-d_delta); + n_padding = std::min(d_delta, noutput_items); + for(size_t i = 0; i < input_items.size(); i++) { + iptr = (const char *) input_items[i]; + optr = (char *) output_items[i]; + std::memset(optr, 0, n_padding*d_itemsize); + std::memcpy(optr, iptr, n_from_input*d_itemsize); + } + cons = n_from_input; + ret = noutput_items; + d_delta -= n_padding; + } + + consume_each(cons); + return ret; } diff --git a/gnuradio-core/src/lib/general/gr_delay.h b/gnuradio-core/src/lib/general/gr_delay.h index 14de9af1f..4ba06cf1c 100644 --- a/gnuradio-core/src/lib/general/gr_delay.h +++ b/gnuradio-core/src/lib/general/gr_delay.h @@ -24,7 +24,8 @@ #define INCLUDED_GR_DELAY_H #include <gr_core_api.h> -#include <gr_sync_block.h> +#include <gr_block.h> +#include <gruel/thread.h> class gr_delay; typedef boost::shared_ptr<gr_delay> gr_delay_sptr; @@ -35,21 +36,26 @@ GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay); * \brief delay the input by a certain number of samples * \ingroup misc_blk */ -class GR_CORE_API gr_delay : public gr_sync_block +class GR_CORE_API gr_delay : public gr_block { friend GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay); gr_delay (size_t itemsize, int delay); + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + size_t d_itemsize; + int d_delta; + gruel::mutex d_mutex_delay; public: int delay () const { return history()-1; } - void set_delay (int delay) { set_history(delay+1); } + void set_delay (int delay); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; #endif diff --git a/gnuradio-core/src/lib/general/gr_delay.i b/gnuradio-core/src/lib/general/gr_delay.i index a527d008f..2e62a222f 100644 --- a/gnuradio-core/src/lib/general/gr_delay.i +++ b/gnuradio-core/src/lib/general/gr_delay.i @@ -24,7 +24,7 @@ GR_SWIG_BLOCK_MAGIC(gr,delay) gr_delay_sptr gr_make_delay (size_t itemsize, int delay); -class gr_delay : public gr_sync_block +class gr_delay : public gr_block { private: gr_delay (size_t itemsize, int delay); |