Forum: GNU Radio Block with N inputs and M outputs (M>=N)

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.
Achilleas A. (Guest)
on 2006-04-10 17:41
(Received via mailing list)
I am trying to write a block that takes N inputs at a time
and produces M outputs at a time.
Since M>=N this is an interpolator.
However, M/N is not neccesarily an integer.

Is there an elegant way to force the work() function to
process a multiple number of N input samples every time it is called?


Thanks
Achilleas
Michael D. (Guest)
on 2006-04-10 19:13
(Received via mailing list)
Let's assume you're working with 1 input and output stream.

If the interpolator block doesn't do it for you (I think it does, so try
to inherit from that code), use "set_output_multiple(M)", then make sure
your "forecast()" function sets the input stream's required items
correctly (to a multiple of N).  "forecast()" will always be called with
"noutput" being a multiple of "M", which makes finding the required
items simple (#in = #out * M / N).  You should do an "assert(M % N ==
0)" before before the divide just to be sure it's OK.

Hope this helps! - MLD

On Mon, 10 Apr 2006 09:36:51 -0400, "Achilleas A."
<removed_email_address@domain.invalid> said:
> I am trying to write a block that takes N inputs at a time
> and produces M outputs at a time.
> Since M>=N this is an interpolator.
> However, M/N is not neccesarily an integer.
>
> Is there an elegant way to force the work() function to
> process a multiple number of N input samples every time it is called?
--
  Michael D.
  removed_email_address@domain.invalid
Michael D. (Guest)
on 2006-04-10 21:41
(Received via mailing list)
Just a quick additive note, all from my testing of
"set_output_multiple()":

"set_output_multiple (M)" will work so long as M isn't too big.
Anything up to 100 or so seems to work OK; even 1000 or so usually
works.  5000 or higher generally doesn't work, though I'm sure there
are specific values which would work (e.g. powers of 2 are more likely
than prime numbers).  Unless your M and N are "small enough", then
you'll likely need to inherit from "gr_block" directory and use
"general_work()".  Using a finite-state machine (FSM; e.g. the GMSK
packet sink), if your task can be broken down into parts as well as
picked up from available "history", would allow for a much more robust
implementation - taking in whatever input data is available, not just a
given multiple of some number, and producing whatever it can from that
data.  The trade-off is that "forecast()"ing the number of input items
required for a given number of output items is potentially more
challenging ... could depend on the amount of accumulated history, what
state the FSM is in, etc.. - MLD
Achilleas A. (Guest)
on 2006-04-10 23:56
(Received via mailing list)
Michael,

Thanks for the info.
Indeed I am looking into small numbers of M,N (order of 10)
so this should work.

Can I ask for a clarification here:

> If the interpolator block doesn't do it for you (I think it does, so try
> to inherit from that code),

Since my overall interpolator block is an M/N-interpolator, even if I
inherit from interpolator, it does not force output_multiple to M,
but rather multiples of (M/N), which is not what I want.
I guess I have to inherit from block and do that manually using
set_output_multiple(M), as you suggested.

am I right?

> <removed_email_address@domain.invalid> said:
>
>>I am trying to write a block that takes N inputs at a time
>>and produces M outputs at a time.
>>Since M>=N this is an interpolator.
>>However, M/N is not neccesarily an integer.
>>
>>Is there an elegant way to force the work() function to
>>process a multiple number of N input samples every time it is called?

--
_______________________________________________________
Achilleas A.
Associate Professor
EECS Department               Voice : (734)615-4024
UNIVERSITY OF MICHIGAN        Fax   : (734)763-8041
Ann Arbor, MI 48109-2122      E-mail: removed_email_address@domain.invalid
URL: http://www-personal.engin.umich.edu/~anastas/
_______________________________________________________
Matt E. (Guest)
on 2006-04-11 01:52
(Received via mailing list)
I would take a look at gr_rational_resampler.  The forecasting and all
of the control stuff should be useful for you.

Matt
Michael D. (Guest)
on 2006-04-11 05:11
(Received via mailing list)
Achilleas - I did not have the gr_sync_interpolator code in front of
me when I wrote originally, so it was a guess ... which was not
entirely correct (the interpolation must be an -integer- value, while
yours is not guaranteed to be so).  Thus, yes, you will need to
inherit from "gr_block" and, since M and N are reasonably small, you
can use "set_output_multiple(M)" to guarantee a multiple of N input
items when you use write "forecast()" to handle this.  For example,
if "d_M" and "d_N" are the values of M and N at instantiation, then ...

1) In your instantiator, include:
+++
// Set the approximate output rate / input rate
   set_relative_rate (1.0 * d_M / ((double) d_N));
// Set the output multiple to guarantee a multiple of M
   set_output_multiple (d_M);
+++
2) In forecast (), include:
+++
// Check that the number of requested output items is a multiple of M
   assert (noutput_items % d_M == 0);
// find the number of input items required to
// generate the requested number of output items
   int ninput_items =  d_N * noutput_items / d_M;
// set all streams' input requirements
   unsigned ninputs = ninput_items_required.size ();
   for (unsigned i = 0; i < ninputs; i++)
     ninput_items_required[i] = ninput_items;
+++
3) In general_work (), include:
+++
// Check that the number of requested output items is a multiple of M
   assert (noutput_items % d_M == 0);
// find the number of input items required to
// generate the requested number of output items
   int ninput_items = d_N * noutput_items / d_M;
+++
to get the number of input items as make sure it really is a multiple
of N (via that the # of output items is a multiple of M).  You can,
of course, choose other means for doing this which are more in your
coding style.  And the asserts can be dropped (I use #if's) once
you're happy that it's all working as you want.  Hope this is clear!
- MLD
This topic is locked and can not be replied to.