Rothy
Rothy

Reputation: 21

How do GNU Radio input and output buffers work?

I'm new to GNU Radio and having problems with understanding how input and output buffers work.

I wish to make a block with 1 input and 2 output ports. Furthermore, I want to divide a fixed size input into 2 output streams that have the same number of items.

At the very beginning, I made a block that has 1 input and 1 output port. It receives 4 elements and should put every other on the output port, i.e. for input values 1, 2, 3 and 4, it should output 1 and 3. I've overridden the forecast and general work method in the following way (adding the printf functions for easier debuging):

void test_block_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
    {
      printf("Forcast, number of noutput_items %d\n", noutput_items);
      ninput_items_required[0] = noutput_items * 2;
      printf("Forcast, required input items %d\n", ninput_items_required[0]);
    }


int test_block_impl::general_work (int noutput_items,
                       gr_vector_int &ninput_items,
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
    {
      const float *in = (const float *) input_items[0];
      float *out = (float *) output_items[0];
      int num_inputitems = ninput_items[0];

      printf("General work, number of input items %d, number of output items %d\n", num_inputitems, noutput_items);
      for (int i = 0; i < num_inputitems ; i++)
      {
        if (i % 2 == 0)
        {
          out[ i/2 ] = in[i];
          printf("out %f, in %f\n", out[i/2], in[i]);
        }
      }
      consume_each (noutput_items*2); // or should I put num_inputitems

      // Tell runtime system how many output items we produced.
      return noutput_items*2;
    }

I also called set_max_noutput_items(2) in the constructor. I was hoping that the forecast function will tell the block that it needs an input of size 4 and than after that the general work function will process those items and output only every second one.

Unfortunately, after writing a Python test, I got a lot of unexpected results so I figured I didn't understand correctly the concept of buffers. For the test:

    src_data = array ( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0])

    expected_result1 = (1.0, 3.0, 5.0)

    src = blocks.vector_source_f(src_data)
    dmx = tutorial.test_block(number)
    dst1 = blocks.vector_sink_f()

    self.tb.connect(src, dmx)
    self.tb.connect(dmx, dst1)
    self.tb.run (4)

I've recieved:

4: Forcast, number of noutput_items 2
4: Forcast, required input items 4
4: Forcast, number of noutput_items 1
4: Forcast, required input items 2
4: Forcast, number of noutput_items 2
4: Forcast, required input items 4
4: General work, number of input items 6, number of output items 2
4: out 1.000000, in 1.000000
4: out 3.000000, in 3.000000
4: out 5.000000, in 5.000000
4: Forcast, number of noutput_items 2
4: Forcast, required input items 4
4: Forcast, number of noutput_items 1
4: Forcast, required input items 2
4: General work, number of input items 2, number of output items 1
4: out 5.000000, in 5.000000
4: Forcast, number of noutput_items 2
4: Forcast, required input items 4
4: Forcast, number of noutput_items 1
4: Forcast, required input items 2
4: (1.0, 3.0, 5.0, 0.0, 5.0, 0.0)

If somebody can help me understand from where did GNU Radio get those zeros and why does it call the forecast method in that order? :)

Upvotes: 2

Views: 2122

Answers (1)

Rothy
Rothy

Reputation: 21

I've realized that general_work should return the number of output produced in this method call and consume should receive the number or input elements it will process. So in my case for getting the expected result, I should call consume_each with ninput_items (consume_each(ninput_items)) and return ninput_items/2

Upvotes: 0

Related Questions