Friday, October 12, 2012

Understanding a Singal Processing Block in GNU Radio : gr_block.h

A signal processing flow is constructed by creating a tree of hierarchical blocks, which at any level may also contain terminal nodes that actually implement signal processing functions. gr_block.h is the base class for all such leaf nodes.

You can find it at /usr/local/include/gnuradio/gr_block.h

Blocks have a set of input streams and output streams.

The input_signature and output_signature define the number of input streams and output streams respectively, and the type of the data items in each stream.

Although blocks may consume data on each input stream at a different rate, all outputs streams(of the same block) must produce data at the same rate.  That rate may be different from any of the input rates.

All the signal processing blocks are derived from the gr_block.h

User derived blocks override two methods, forecast and general_work, to implement their signal processing behavior.

forecast is called by the system scheduler to determine how many items are required on each input stream in order to produce a given number of output

general_work is called to perform the signal processing in the block. It reads the input items and writes the output items.

As you can see in the definition, gr_block is itself a (public)derived class of the base class of gr_basic_block

Lets see the important fields and those which are inherited from the gr_basic_block and redefined in the gr_block

gr_basic_block.h has following protected variables :

std::string                       d_name;
gr_io_signature_sptr      d_input_signature;
gr_io_signature_sptr      d_output_signature;
long                                d_unique_id;

gr_block.h has following private variables :

int                                   d_output_multiple;                                     double                            d_relative_rate;    // approx output_rate / input_rate
gr_block_detail_sptr      d_detail;        // implementation details

d_name and d_unique_id (text and numeral respectively )are unique identifiers for the block and can be used for debugging

d_output_multiple and d_relative_rate informs the scheduler of the block about block's rate of data consumption and generation

d_input_signature, d_output_signature, d_detail are all boost smart pointers.

d_input_signature, d_output_signature pointing towards gr_io_signature type objects

d_detail pointing towards gr_block_detail type objects

Lets look at some important functions in gr_block.h

void  set_history (unsigned history) { d_history = history; }

virtual void forecast (int noutput_items,
             gr_vector_int &ninput_items_required);

virtual int general_work (int noutput_items,
                gr_vector_int &ninput_items,
                gr_vector_const_void_star &input_items,
                gr_vector_void_star &output_items) = 0;

void consume (int which_input, int how_many_items);

A block tell the scheduler how much processing has been done so far and how much more input the block needs to produce more output.
It is done so that the scheduler knows what data it no longer needs to store, how much buffer memory to allocate, when to schedule the block to execute next etc.

This in turn, determines when the scheduler will invoke the next of the block and with how much input.

Reference :

No comments:

Post a Comment