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

on 2006-04-10 15:41

on 2006-04-10 17:13

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 Anastasopoulos" <anastas@umich.edu> 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 Dickens mlk@alum.mit.edu

on 2006-04-10 19:41

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

on 2006-04-10 21:56

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? > <anastas@umich.edu> 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 Anastasopoulos Associate Professor EECS Department Voice : (734)615-4024 UNIVERSITY OF MICHIGAN Fax : (734)763-8041 Ann Arbor, MI 48109-2122 E-mail: anastas@umich.edu URL: http://www-personal.engin.umich.edu/~anastas/ _______________________________________________________

on 2006-04-10 23:52

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

on 2006-04-11 03:11

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