# Block with N inputs and M outputs (M>=N)

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

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.”
[email protected] 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.
[email protected]

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

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?

[email protected] 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: [email protected]
URL: http://www-personal.engin.umich.edu/~anastas/

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 …

+++
// 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

I would take a look at gr_rational_resampler. The forecasting and all
of the control stuff should be useful for you.

Matt

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.