diff options
Diffstat (limited to 'gnuradio-runtime/lib/runtime_block_gateway.cc')
-rw-r--r-- | gnuradio-runtime/lib/runtime_block_gateway.cc | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/gnuradio-runtime/lib/runtime_block_gateway.cc b/gnuradio-runtime/lib/runtime_block_gateway.cc new file mode 100644 index 0000000000..11d16af41e --- /dev/null +++ b/gnuradio-runtime/lib/runtime_block_gateway.cc @@ -0,0 +1,185 @@ +/* + * Copyright 2011-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <runtime_block_gateway.h> +#include <gr_io_signature.h> +#include <iostream> +#include <boost/bind.hpp> + +/*********************************************************************** + * Helper routines + **********************************************************************/ +template <typename OutType, typename InType> +void copy_pointers(OutType &out, const InType &in){ + out.resize(in.size()); + for (size_t i = 0; i < in.size(); i++){ + out[i] = (void *)(in[i]); + } +} + +/*********************************************************************** + * The gr_block gateway implementation class + **********************************************************************/ +class runtime_block_gateway_impl : public runtime_block_gateway{ +public: + runtime_block_gateway_impl( + gr_feval_ll *handler, + const std::string &name, + gr_io_signature_sptr in_sig, + gr_io_signature_sptr out_sig, + const gr_block_gw_work_type work_type, + const unsigned factor + ): + gr_block(name, in_sig, out_sig), + _handler(handler), + _work_type(work_type) + { + switch(_work_type){ + case GR_BLOCK_GW_WORK_GENERAL: + _decim = 1; //not relevant, but set anyway + _interp = 1; //not relevant, but set anyway + break; + + case GR_BLOCK_GW_WORK_SYNC: + _decim = 1; + _interp = 1; + this->set_fixed_rate(true); + break; + + case GR_BLOCK_GW_WORK_DECIM: + _decim = factor; + _interp = 1; + break; + + case GR_BLOCK_GW_WORK_INTERP: + _decim = 1; + _interp = factor; + this->set_output_multiple(_interp); + break; + } + } + + /******************************************************************* + * Overloads for various scheduler-called functions + ******************************************************************/ + void forecast( + int noutput_items, + gr_vector_int &ninput_items_required + ){ + switch(_work_type){ + case GR_BLOCK_GW_WORK_GENERAL: + _message.action = gr_block_gw_message_type::ACTION_FORECAST; + _message.forecast_args_noutput_items = noutput_items; + _message.forecast_args_ninput_items_required = ninput_items_required; + _handler->calleval(0); + ninput_items_required = _message.forecast_args_ninput_items_required; + return; + + default: + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items); + return; + } + } + + int general_work( + int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + switch(_work_type){ + case GR_BLOCK_GW_WORK_GENERAL: + _message.action = gr_block_gw_message_type::ACTION_GENERAL_WORK; + _message.general_work_args_noutput_items = noutput_items; + _message.general_work_args_ninput_items = ninput_items; + copy_pointers(_message.general_work_args_input_items, input_items); + _message.general_work_args_output_items = output_items; + _handler->calleval(0); + return _message.general_work_args_return_value; + + default: + int r = work (noutput_items, input_items, output_items); + if (r > 0) consume_each(r*_decim/_interp); + return r; + } + } + + int work( + int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + _message.action = gr_block_gw_message_type::ACTION_WORK; + _message.work_args_ninput_items = fixed_rate_noutput_to_ninput(noutput_items); + if (_message.work_args_ninput_items == 0) return -1; + _message.work_args_noutput_items = noutput_items; + copy_pointers(_message.work_args_input_items, input_items); + _message.work_args_output_items = output_items; + _handler->calleval(0); + return _message.work_args_return_value; + } + + int fixed_rate_noutput_to_ninput(int noutput_items){ + return (noutput_items*_decim/_interp) + history() - 1; + } + + int fixed_rate_ninput_to_noutput(int ninput_items){ + return std::max(0, ninput_items - (int)history() + 1)*_interp/_decim; + } + + bool start(void){ + _message.action = gr_block_gw_message_type::ACTION_START; + _handler->calleval(0); + return _message.start_args_return_value; + } + + bool stop(void){ + _message.action = gr_block_gw_message_type::ACTION_STOP; + _handler->calleval(0); + return _message.stop_args_return_value; + } + + gr_block_gw_message_type &gr_block_message(void){ + return _message; + } + +private: + gr_feval_ll *_handler; + gr_block_gw_message_type _message; + const gr_block_gw_work_type _work_type; + unsigned _decim, _interp; +}; + +boost::shared_ptr<runtime_block_gateway> runtime_make_block_gateway( + gr_feval_ll *handler, + const std::string &name, + gr_io_signature_sptr in_sig, + gr_io_signature_sptr out_sig, + const gr_block_gw_work_type work_type, + const unsigned factor +){ + return boost::shared_ptr<runtime_block_gateway>( + new runtime_block_gateway_impl(handler, name, in_sig, out_sig, + work_type, factor) + ); +} |