Forum: GNU Radio How to check if more input is available on an input stream

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mir A. (Guest)
on 2009-01-07 12:46
(Received via mailing list)
Hi,
I have a simple question. I have a block that has 2 input streams and
the
inputs are consumed at different rates. For each 1 input consumed on the
first input stream N inputs are consumed in the second stream.

The forecast function and set_multiple call of this block are as shown
below,

my_new_block::forecast(int noutput_items,gr_vector_int
&ninput_items_required){
    assert(noutput_items % N==0); # the


    int items_on_first_input_stream = noutput_items;
    int items_on_second_input_stream = noutput_items/(8*N);
    ninput_items_required[0]=items_on_first_input_stream;
    ninput_items_required[1]=items_on_data_input_stream;
    }


 {
           set_output_multiple(8*N); # the output items are a multiple
of
8*N.

}
For each (8*N) inputs consumed on second stream 1 input is consumed on
first
stream.
If the first stream has uninterrupted supply but the second one doesn't
then
how should I check if input is available on the second stream. Will the
input_vector contain NULL values when nothing is in it? If it is true
should
i just do

if(second_stream[next_item]==null){
.......
}

Please clarify.

Thanks
Ali
Eric B. (Guest)
on 2009-01-07 20:40
(Received via mailing list)
On Wed, Jan 07, 2009 at 04:44:39AM -0600, Mir A. wrote:
>     assert(noutput_items % N==0); # the
>            set_output_multiple(8*N); # the output items are a multiple of 8*N.
> }

>
> Please clarify.
>
> Thanks
> Ali

You should be deriving your class from gr_block (you may already be
doing this).
There is no need to call set_output_multiple.

If I understand you correctly, to produce a single output item, you
need a single item on the first input stream, and N (== 8) items on the
second stream.

Assuming I'm understanding you correctly, then your forecast routine
should be:


static const int N = 8;

void
my_new_block::forecast(int noutput_items, gr_vector_int
&ninput_items_required)
{
  ninput_items_required[0] = noutput_items;
  ninput_items_required[1] = noutput_items * N;
}

You then need to override general_work, not work:

(I'm assuming that your input and output types are float.  Change as
required)


float f(const float *a, const float *b)
{
  // Produce a single float value by using a[0] and b[0] through
b[N-1]...

  return XXX;
}

int
my_new_block::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 *in0 = (const float *)input_items[0];
  const float *in1 = (const float *)input_items[1];
  float *out = (float *)output_items[0];

  for (int i = 0; i < noutput_items; i++){

    out[i] = f(&in0[i], &in1[i * N]);

  }

  consume(0, noutput_items);
  consume(1, noutput_items * N);

  return noutput_items;
}


Eric
Mir A. (Guest)
on 2009-01-07 22:39
(Received via mailing list)
Hi Eric,

I actually forgot to mention one more thing.

I use N items of first stream and one item on second stream to produce N
items on output stream.
I am actually spreading data. If the spreading code is N-character bytes
long, then each bit of data input byte (i.e. a total of 8 bits on input
byte
on second stream) will produce 8*N output items.

The input to the spreading stream is uninterrupted from a sequence
generator
block. But the input to the data stream i.e. the second input stream can
be
from a file which will exhaust when file is read completely. So i want
to
check if any data is available on the second stream(i.e. the data
stream) in
the work function each time i am done with the previous data byte.

I hope i make myself clear. Sorry for the confusion earlier.

Thanks
Ali
Eric B. (Guest)
on 2009-01-07 23:39
(Received via mailing list)
On Wed, Jan 07, 2009 at 02:38:34PM -0600, Mir A. wrote:
> The input to the spreading stream is uninterrupted from a sequence generator
> block. But the input to the data stream i.e. the second input stream can be
> from a file which will exhaust when file is read completely. So i want to
> check if any data is available on the second stream(i.e. the data stream) in
> the work function each time i am done with the previous data byte.
>
> I hope i make myself clear. Sorry for the confusion earlier.
>
> Thanks
> Ali


OK, no problem.  Try this:



static const int N = 8;


my_new_block::my_new_block() : ...
{
  ...
  set_output_multiple(N);
  ...
}


void
my_new_block::forecast(int noutput_items, gr_vector_int
&ninput_items_required)
{
  ninput_items_required[0] = noutput_items;
  ninput_items_required[1] = noutput_items / N;
}

void f(float *out, const float *a, const float *b)
{
 // write out[0] through out[N-1] using using inputs a[0] through a[N-1]
and b[0]
 ...
}

int
my_new_block::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 *in0 = (const float *)input_items[0];
 const float *in1 = (const float *)input_items[1];
 float *out = (float *)output_items[0];

 assert(noutput_items % N == 0);

 for (int i = 0; i < noutput_items; i += N){

   f(&out[i], &in0[i], &in1[i/N]);

 }

 consume(0, noutput_items);
 consume(1, noutput_items / N);

 return noutput_items;
}


Note that there's no need to "check for input".  That's what forecast
does for you.  general_work won't be called until everything is OK.
You will have enough input to compute noutput_items.

Eric
This topic is locked and can not be replied to.