GNU Radio 3.6.3 C++ API
gr_block.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2004,2007,2009,2010 Free Software Foundation, Inc.
00004  *
00005  * This file is part of GNU Radio
00006  *
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  *
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #ifndef INCLUDED_GR_BLOCK_H
00024 #define INCLUDED_GR_BLOCK_H
00025 
00026 #include <gr_core_api.h>
00027 #include <gr_basic_block.h>
00028 #include <gr_tags.h>
00029 
00030 /*!
00031  * \brief The abstract base class for all 'terminal' processing blocks.
00032  * \ingroup base_blk
00033  *
00034  * A signal processing flow is constructed by creating a tree of
00035  * hierarchical blocks, which at any level may also contain terminal nodes
00036  * that actually implement signal processing functions. This is the base
00037  * class for all such leaf nodes.
00038 
00039  * Blocks have a set of input streams and output streams.  The
00040  * input_signature and output_signature define the number of input
00041  * streams and output streams respectively, and the type of the data
00042  * items in each stream.
00043  *
00044  * Although blocks may consume data on each input stream at a
00045  * different rate, all outputs streams must produce data at the same
00046  * rate.  That rate may be different from any of the input rates.
00047  *
00048  * User derived blocks override two methods, forecast and general_work,
00049  * to implement their signal processing behavior. forecast is called
00050  * by the system scheduler to determine how many items are required on
00051  * each input stream in order to produce a given number of output
00052  * items.
00053  *
00054  * general_work is called to perform the signal processing in the block.
00055  * It reads the input items and writes the output items.
00056  */
00057 
00058 class GR_CORE_API gr_block : public gr_basic_block {
00059 
00060  public:
00061 
00062   //! Magic return values from general_work
00063   enum {
00064     WORK_CALLED_PRODUCE = -2,
00065     WORK_DONE = -1
00066   };
00067 
00068   enum tag_propagation_policy_t {
00069     TPP_DONT = 0,
00070     TPP_ALL_TO_ALL = 1,
00071     TPP_ONE_TO_ONE = 2
00072   };
00073 
00074   virtual ~gr_block ();
00075 
00076   /*!
00077    * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
00078    * History is the number of x_i's that are examined to produce one y_i.
00079    * This comes in handy for FIR filters, where we use history to
00080    * ensure that our input contains the appropriate "history" for the
00081    * filter.   History should be equal to the number of filter taps.
00082    */
00083   unsigned history () const { return d_history; }
00084   void  set_history (unsigned history) { d_history = history; }
00085 
00086   /*!
00087    * \brief Return true if this block has a fixed input to output rate.
00088    *
00089    * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called.
00090    */
00091   bool fixed_rate() const { return d_fixed_rate; }
00092 
00093   // ----------------------------------------------------------------
00094   //            override these to define your behavior
00095   // ----------------------------------------------------------------
00096 
00097   /*!
00098    * \brief  Estimate input requirements given output request
00099    *
00100    * \param noutput_items           number of output items to produce
00101    * \param ninput_items_required   number of input items required on each input stream
00102    *
00103    * Given a request to product \p noutput_items, estimate the number of
00104    * data items required on each input stream.  The estimate doesn't have
00105    * to be exact, but should be close.
00106    */
00107   virtual void forecast (int noutput_items,
00108                          gr_vector_int &ninput_items_required);
00109 
00110   /*!
00111    * \brief compute output items from input items
00112    *
00113    * \param noutput_items       number of output items to write on each output stream
00114    * \param ninput_items        number of input items available on each input stream
00115    * \param input_items         vector of pointers to the input items, one entry per input stream
00116    * \param output_items        vector of pointers to the output items, one entry per output stream
00117    *
00118    * \returns number of items actually written to each output stream, or -1 on EOF.
00119    * It is OK to return a value less than noutput_items.  -1 <= return value <= noutput_items
00120    *
00121    * general_work must call consume or consume_each to indicate how many items
00122    * were consumed on each input stream.
00123    */
00124   virtual int general_work (int noutput_items,
00125                             gr_vector_int &ninput_items,
00126                             gr_vector_const_void_star &input_items,
00127                             gr_vector_void_star &output_items);
00128 
00129   /*!
00130    * \brief Called to enable drivers, etc for i/o devices.
00131    *
00132    * This allows a block to enable an associated driver to begin
00133    * transfering data just before we start to execute the scheduler.
00134    * The end result is that this reduces latency in the pipeline when
00135    * dealing with audio devices, usrps, etc.
00136    */
00137   virtual bool start();
00138 
00139   /*!
00140    * \brief Called to disable drivers, etc for i/o devices.
00141    */
00142   virtual bool stop();
00143 
00144   // ----------------------------------------------------------------
00145 
00146   /*!
00147    * \brief Constrain the noutput_items argument passed to forecast and general_work
00148    *
00149    * set_output_multiple causes the scheduler to ensure that the noutput_items
00150    * argument passed to forecast and general_work will be an integer multiple
00151    * of \param multiple  The default value of output multiple is 1.
00152    */
00153   void set_output_multiple (int multiple);
00154   int  output_multiple () const { return d_output_multiple; }
00155   bool  output_multiple_set () const { return d_output_multiple_set; }
00156 
00157   /*!
00158    * \brief Constrains buffers to work on a set item alignment (for SIMD)
00159    *
00160    * set_alignment_multiple causes the scheduler to ensure that the noutput_items
00161    * argument passed to forecast and general_work will be an integer multiple
00162    * of \param multiple  The default value is 1.
00163    *
00164    * This control is similar to the output_multiple setting, except
00165    * that if the number of items passed to the block is less than the
00166    * output_multiple, this value is ignored and the block can produce
00167    * like normal. The d_unaligned value is set to the number of items
00168    * the block is off by. In the next call to general_work, the
00169    * noutput_items is set to d_unaligned or less until
00170    * d_unaligned==0. The buffers are now aligned again and the aligned
00171    * calls can be performed again.
00172    */
00173   void set_alignment (int multiple);
00174   int  alignment () const { return d_output_multiple; }
00175 
00176   void set_unaligned (int na);
00177   int unaligned () const { return d_unaligned; }
00178   void set_is_unaligned (bool u);
00179   bool is_unaligned () const { return d_is_unaligned; }
00180 
00181   /*!
00182    * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed.
00183    */
00184   void consume (int which_input, int how_many_items);
00185 
00186   /*!
00187    * \brief Tell the scheduler \p how_many_items were consumed on each input stream.
00188    */
00189   void consume_each (int how_many_items);
00190 
00191   /*!
00192    * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output.
00193    *
00194    * If the block's general_work method calls produce, \p general_work must return WORK_CALLED_PRODUCE.
00195    */
00196   void produce (int which_output, int how_many_items);
00197 
00198   /*!
00199    * \brief Set the approximate output rate / input rate
00200    *
00201    * Provide a hint to the buffer allocator and scheduler.
00202    * The default relative_rate is 1.0
00203    *
00204    * decimators have relative_rates < 1.0
00205    * interpolators have relative_rates > 1.0
00206    */
00207   void  set_relative_rate (double relative_rate);
00208 
00209   /*!
00210    * \brief return the approximate output rate / input rate
00211    */
00212   double relative_rate () const { return d_relative_rate; }
00213 
00214   /*
00215    * The following two methods provide special case info to the
00216    * scheduler in the event that a block has a fixed input to output
00217    * ratio.  gr_sync_block, gr_sync_decimator and gr_sync_interpolator
00218    * override these.  If you're fixed rate, subclass one of those.
00219    */
00220   /*!
00221    * \brief Given ninput samples, return number of output samples that will be produced.
00222    * N.B. this is only defined if fixed_rate returns true.
00223    * Generally speaking, you don't need to override this.
00224    */
00225   virtual int fixed_rate_ninput_to_noutput(int ninput);
00226 
00227   /*!
00228    * \brief Given noutput samples, return number of input samples required to produce noutput.
00229    * N.B. this is only defined if fixed_rate returns true.
00230    * Generally speaking, you don't need to override this.
00231    */
00232   virtual int fixed_rate_noutput_to_ninput(int noutput);
00233 
00234   /*!
00235    * \brief Return the number of items read on input stream which_input
00236    */
00237   uint64_t nitems_read(unsigned int which_input);
00238 
00239   /*!
00240    * \brief  Return the number of items written on output stream which_output
00241    */
00242   uint64_t nitems_written(unsigned int which_output);
00243 
00244   /*!
00245    * \brief Asks for the policy used by the scheduler to moved tags downstream.
00246    */
00247   tag_propagation_policy_t tag_propagation_policy();
00248 
00249   /*!
00250    * \brief Set the policy by the scheduler to determine how tags are moved downstream.
00251    */
00252   void set_tag_propagation_policy(tag_propagation_policy_t p);
00253 
00254   /*!
00255    * \brief Return the maximum number of output items this block will
00256    * handle during a call to work.
00257    */
00258   int max_noutput_items();
00259 
00260   /*!
00261    * \brief Set the maximum number of ouput items htis block will
00262    * handle during a call to work.
00263    *
00264    * \param m the maximum noutput_items this block will handle.
00265    */
00266   void set_max_noutput_items(int m);
00267 
00268   /*!
00269    * \brief Clear the switch for using the max_noutput_items value of this block.
00270    *
00271    * When is_set_max_noutput_items() returns 'true', the scheduler
00272    * will use the value returned by max_noutput_items() to limit the
00273    * size of the number of items possible for this block's work
00274    * function. If is_set_max_notput_items() returns 'false', then the
00275    * scheduler ignores the internal value and uses the value set
00276    * globally in the top_block.
00277    *
00278    * Use this value to clear the 'is_set' flag so the scheduler will
00279    * ignore this. Use the set_max_noutput_items(m) call to both set a
00280    * new value for max_noutput_items and to reenable its use in the
00281    * scheduler.
00282    */
00283   void unset_max_noutput_items();
00284 
00285   /*!
00286    * \brief Ask the block if the flag is or is not set to use the
00287    * internal value of max_noutput_items during a call to work.
00288    */
00289   bool is_set_max_noutput_items();
00290 
00291   /*
00292    * Used to expand the vectors that hold the min/max buffer sizes.
00293    *
00294    * Specifically, when -1 is used, the vectors are just initialized
00295    * with 1 value; this is used by the flat_flowgraph to expand when
00296    * required to add a new value for new ports on these blocks.
00297    */
00298   void expand_minmax_buffer(int port) {
00299     if((size_t)port >= d_max_output_buffer.size())
00300       set_max_output_buffer(port, -1);
00301     if((size_t)port >= d_min_output_buffer.size())
00302       set_min_output_buffer(port, -1);
00303   }
00304 
00305   /*!
00306    * \brief Returns max buffer size on output port \p i.
00307    */
00308   long max_output_buffer(size_t i) {
00309     if(i >= d_max_output_buffer.size())
00310       throw std::invalid_argument("gr_basic_block::max_output_buffer: port out of range.");
00311     return d_max_output_buffer[i];
00312   }
00313 
00314   /*!
00315    * \brief Sets max buffer size on all output ports.
00316    */
00317   void set_max_output_buffer(long max_output_buffer) { 
00318     for(int i = 0; i < output_signature()->max_streams(); i++) {
00319       set_max_output_buffer(i, max_output_buffer);
00320     }
00321   }
00322 
00323   /*!
00324    * \brief Sets max buffer size on output port \p port.
00325    */
00326   void set_max_output_buffer(int port, long max_output_buffer) {
00327     if((size_t)port >= d_max_output_buffer.size())
00328       d_max_output_buffer.push_back(max_output_buffer);
00329     else
00330       d_max_output_buffer[port] = max_output_buffer; 
00331   }
00332 
00333   /*!
00334    * \brief Returns min buffer size on output port \p i.
00335    */
00336   long min_output_buffer(size_t i) {
00337     if(i >= d_min_output_buffer.size())
00338       throw std::invalid_argument("gr_basic_block::min_output_buffer: port out of range.");
00339     return d_min_output_buffer[i];
00340   }
00341 
00342   /*!
00343    * \brief Sets min buffer size on all output ports.
00344    */
00345   void set_min_output_buffer(long min_output_buffer) {
00346     for(int i=0; i<output_signature()->max_streams(); i++) {
00347       set_min_output_buffer(i, min_output_buffer);
00348     }
00349   }
00350 
00351   /*!
00352    * \brief Sets min buffer size on output port \p port.
00353    */
00354   void set_min_output_buffer(int port, long min_output_buffer) {
00355     if((size_t)port >= d_min_output_buffer.size())
00356       d_min_output_buffer.push_back(min_output_buffer);
00357     else
00358       d_min_output_buffer[port] = min_output_buffer; 
00359   }
00360 
00361   // ----------------------------------------------------------------------------
00362 
00363  private:
00364 
00365   int                   d_output_multiple;
00366   bool                  d_output_multiple_set;
00367   int                   d_unaligned;
00368   bool                  d_is_unaligned;
00369   double                d_relative_rate;        // approx output_rate / input_rate
00370   gr_block_detail_sptr  d_detail;               // implementation details
00371   unsigned              d_history;
00372   bool                  d_fixed_rate;
00373   bool                  d_max_noutput_items_set;     // if d_max_noutput_items is valid
00374   int                   d_max_noutput_items;         // value of max_noutput_items for this block
00375   tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream
00376 
00377  protected:
00378   gr_block (void){} //allows pure virtual interface sub-classes
00379   gr_block (const std::string &name,
00380             gr_io_signature_sptr input_signature,
00381             gr_io_signature_sptr output_signature);
00382 
00383   void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; }
00384 
00385 
00386   /*!
00387    * \brief  Adds a new tag onto the given output buffer.
00388    *
00389    * \param which_output an integer of which output stream to attach the tag
00390    * \param abs_offset   a uint64 number of the absolute item number
00391    *                     assicated with the tag. Can get from nitems_written.
00392    * \param key          the tag key as a PMT symbol
00393    * \param value        any PMT holding any value for the given key
00394    * \param srcid        optional source ID specifier; defaults to PMT_F
00395    */
00396   inline void add_item_tag(unsigned int which_output,
00397                     uint64_t abs_offset,
00398                     const pmt::pmt_t &key,
00399                     const pmt::pmt_t &value,
00400                     const pmt::pmt_t &srcid=pmt::PMT_F)
00401     {
00402         gr_tag_t tag;
00403         tag.offset = abs_offset;
00404         tag.key = key;
00405         tag.value = value;
00406         tag.srcid = srcid;
00407         this->add_item_tag(which_output, tag);
00408     }
00409 
00410  /*!
00411    * \brief  Adds a new tag onto the given output buffer.
00412    *
00413    * \param which_output an integer of which output stream to attach the tag
00414    * \param tag the tag object to add
00415    */
00416   void add_item_tag(unsigned int which_output, const gr_tag_t &tag);
00417 
00418   /*!
00419    * \brief Given a [start,end), returns a vector of all tags in the range.
00420    *
00421    * Range of counts is from start to end-1.
00422    *
00423    * Tags are tuples of:
00424    *      (item count, source id, key, value)
00425    *
00426    * \param v            a vector reference to return tags into
00427    * \param which_input  an integer of which input stream to pull from
00428    * \param abs_start    a uint64 count of the start of the range of interest
00429    * \param abs_end      a uint64 count of the end of the range of interest
00430    */
00431   void get_tags_in_range(std::vector<gr_tag_t> &v,
00432                          unsigned int which_input,
00433                          uint64_t abs_start,
00434                          uint64_t abs_end);
00435 
00436   /*!
00437    * \brief Given a [start,end), returns a vector of all tags in the range
00438    * with a given key.
00439    *
00440    * Range of counts is from start to end-1.
00441    *
00442    * Tags are tuples of:
00443    *      (item count, source id, key, value)
00444    *
00445    * \param v            a vector reference to return tags into
00446    * \param which_input  an integer of which input stream to pull from
00447    * \param abs_start    a uint64 count of the start of the range of interest
00448    * \param abs_end      a uint64 count of the end of the range of interest
00449    * \param key          a PMT symbol key to filter only tags of this key
00450    */
00451   void get_tags_in_range(std::vector<gr_tag_t> &v,
00452                          unsigned int which_input,
00453                          uint64_t abs_start,
00454                          uint64_t abs_end,
00455                          const pmt::pmt_t &key);
00456 
00457   std::vector<long>    d_max_output_buffer;
00458   std::vector<long>    d_min_output_buffer;
00459 
00460 
00461   // These are really only for internal use, but leaving them public avoids
00462   // having to work up an ever-varying list of friend GR_CORE_APIs
00463 
00464  public:
00465   gr_block_detail_sptr detail () const { return d_detail; }
00466   void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
00467 };
00468 
00469 typedef std::vector<gr_block_sptr> gr_block_vector_t;
00470 typedef std::vector<gr_block_sptr>::iterator gr_block_viter_t;
00471 
00472 inline gr_block_sptr cast_to_block_sptr(gr_basic_block_sptr p)
00473 {
00474   return boost::dynamic_pointer_cast<gr_block, gr_basic_block>(p);
00475 }
00476 
00477 
00478 std::ostream&
00479 operator << (std::ostream& os, const gr_block *m);
00480 
00481 #endif /* INCLUDED_GR_BLOCK_H */