Search code examples
c++gnuradio

Change the number of output items dynamically


Is possible in the work() function of a gr block, to change dynamically the number of the output items leaving the same number of input items?

In my case I need 2 cases based on a condition: 1) 4096 IN : 0 OUT 2) 4096 IN : 4096 OUT

Thank you


Solution

  • Yes, you'll want your block to inherit from gr::block (as opposed to the more common sync_block, etc) and use general_work to process the samples.

    In general_work, you can call this->consume() to report the number of samples you want to drop from the input buffer, and return [int] will tell the scheduler dynamically how many samples you're passing to the next block this time.

    https://gnuradio.org/redmine/projects/gnuradio/wiki/BlocksCodingGuide#Basic-Block

    Here's their code example from the wiki, though note the coding style of this example doesn't exactly match up with how gnuradio blocks are currently coded, but it gives you the idea of how to use general_work. For an up-to-date example, I recommend cloing the gnuradio source and grepping for general_work:

    #include <gr_block.h>
    
    class my_basic_block : public gr_block
    {
    public:
      my_basic_adder_block(...):
        gr_block("another adder block",
                 in_sig,
                 out_sig)
      {
        //constructor stuff
      }
    
      int general_work(int noutput_items,
                       gr_vector_int &ninput_items,
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
      {
        //cast buffers
        const float* in0 = reinterpret_cast<const float *>(input_items[0]);
        const float* in1 = reinterpret_cast<const float *>(input_items[1]);
        float* out = reinterpret_cast<float *>(output_items[0]);
    
        //process data
        for(size_t i = 0; i < noutput_items; i++) {
          out[i] = in0[i] + in1[i];
        }
    
        //consume the inputs
        this->consume(0, noutput_items); //consume port 0 input
        this->consume(1, noutput_items); //consume port 1 input
        //this->consume_each(noutput_items); //or shortcut to consume on all inputs
    
        //return produced
        return noutput_items;
      }
    };