Kevin: remember that the parameters available for changing during runtime
are underlined in the block settings window.

2015-07-27 13:45 GMT-03:00 Marcus Müller <[email protected]>:

>  Hi Kevin,
>
> On 27.07.2015 17:53, mcquiggi wrote:
>
> Hi Marcus:
>
>  I’m just following up on my Repeat block question.  I figured that I
> would take this off-list but if you think it appropriate for all then feel
> free to cc it back on-list.
>
> I'll do that :)
>
>
>  Thanks for the assistance, let me know if I am wasting your time.
>
> Far from it, actually! I think discussions like these are immensely
> valuable for the community -- people with different backgrounds
> contributing is one of the strengths of the GNU Radio project, and you are
> freely investing your time in this; in fact, I think what you're addressing
> below will be of interest to a lot of mailing list archive readers later on!
>
>
>  I had a look at various source code modules yesterday.  I looked at
> 'repeat_impl.cc' and ‘repeat_impl.h’  What I understand so far is that the
> new version of the Repeat block may have to move to the “General” type of
> block from that of an “interpolator” block, as it will now be in the M:N
> samples realm, rather than 1:N.
>
> That's halfway true; if I understand your intention correctly, the block
> would stay 1:N -- but that N would be subject to change over the lifetime
> of the block. As far as I know, the normal sync_interpolator mother class
> can deal with that.
>
>
>  I also think I see that there is a value ‘noutput_items’ that gets
> computed once, when the block/object is created.
>
> oh, no, that's the amount of items that the scheduler allows you to
> produce, so it's different each time work() is called!
>
>   What I need is for this value to be variable and re-calculated by a
> change in the parameter in the GRC block.
>
> It's a parameter, not a result of your work -- what you in fact need to
> re-calculate is the ratio between number of items you consume and number of
> items a call to work() produced.
> In fact, sync_interpolator just overrides general_work like you would in a
> general block, and calls work(..) from within there -- based on the items
> work produced (usually, that's just the number work() returns), it
> calculates the items consumed (by a simple division).
>
>  As the work function (which is fairly simple) is just a for loop 1 to
> noutput_items, then this seems correct.
>
> So what you need to do when changing the number of repititions is just
> a) change the value of d_interp, so that repeat's work() does the "right
> thing" and
> b) call the set_interpolation method [1] to change the factor that is used
> behind the scenes to keep the amount of samples flowing in and out correct.
>
>
>  I see repeat_impl and work functions.  I gather that the repeat_impl
> routine allocates a block of storage or a buffer or something based on the
> static value of noutput_items which has been pre-computed in a higher level
> block.  This (I think) is where the code has to change.
>
> repeat_impl is a subclass of repeat (which itself is a subclass of
> sync_interpolator, which is a sync_block subclass, which is a block
> subclass, which is a basic_block subclass; C++ inheritance :) ).
>
> This is now a bit of a oversimplification of C++, but I think you can deal
> with this: here, think of these C++ classes as C structs, that inherit all
> the elements from their mother structs. Methods are basically function
> pointers in these structs, and when invoked they automatically (and
> hiddenly) set a parameter "this" to be a pointer to the indidual struct
> object. That way, you can work with methods that really only operate on a
> single object's state, and don't have to always carry around a handle to
> the object to modify (which is a very C thing to do). So, work is such a
> function, and d_interp is a member of the struct that automatically relates
> to the "this" parameter, ie. you could also use this->d_interp (which
> really is a valid alias for d_interp).
>
> What happens is that C++ makes sure that when the GNU Radio scheduler
> calls the general_work of any block, the respective block's
> implementation's general_work is called (in this case, sync_interpolator
> has that implementation of general_work). In the case of sync_interpolator,
> that general_work computes the right in- and output item numbers, and calls
> its work(), which is overridden by repeat_impl::work.
>
> Now that's more software design theory than the average GNU Radio user
> has. What you need to know is: you implement a work() method; GNU Radio
> calls that when there's new data available or when there's still data on
> the input but new output space has become available.
>
> There's one caveat that we'll have to address later: GNU Radio is
> multithreaded, and heavily so. Imagine the segfaults that would happen if
> you were to change d_interp from 1 to 10^9 in the middle of the for loop in
> work() running, but there was only output space for input_items[0]*1! C++,
> boost and GNU Radio have methods of dealing with that problem, and I'll
> gladly help with it.
>
>
>  Would re-calculation of noutput_items imply that the object created for
> the delay block has to be destroyed and get re-created?  I do not know
> anything about the internal structure of gnuradio so I am obviously in the
> dark.  I was unsuccessful in locating the place where noutput_items is
> calculated, I am guessing that it is in a higher-level block.
>
>  I’ve grabbed the source code and am building gnuradio (via the
> build-gnuradio script), so once I have all the source locally it will be
> easier to locate stuff.  I will look for where noutput_items is initially
> calculated.
>
> It's calculated again, again and again, every time before calling your
> work() method.
> The idea is that every block has it's (general_)work method, and GNU radio
> calls them, whenever the circumstances make that sensible, ie. when there
> is opportunity to generate/process items:
> Assume you connect block A, B, C:
> A->B->C
> when the work method of B returns, the consumed input samples in its input
> buffer can be overwritten (GNU Radio implements circular buffers), since
> they already have been processed. Hence, in a different thread A's work()
> is called, with the info that noutput_items is now larger by exactly that
> amount of samples.
> The same happens for C: B::work() returns, and GNU Radio calls C's work()
> with the info that there's new input available. When C::work() returns, B
> is notified again that there's output space available, and everything keeps
> flowing.
>
>
>  It may be a matter of you telling me how wrong I am, but otherwise I
> would ask if I am anywhere near the correct track?
>
> You're pretty close to the real thing! The C coder is speaking through
> your questions, but that's absolutely not a bad thing; young "C++ folks" (I
> might consider myself that) often struggle with things like dealing with
> memory, pointer casting etc, where that's bread and butter techniques and
> patterns for C devs.
> Have I pointed you to the guided tutorials?
> https://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorials
> Especially chapter 4 will be of interest to you. It does assume that
> you're somewhat proficient with C++, but 4.3.2.4 / Interpolation
>
> <https://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorial_GNU_Radio_in_C++#4324-Rate-changing-blocks-Interpolators-and-Decimators>illustrates
> what we're dealing with pretty nicely, I think.
>
> Best regards,
> Marcus
>
> [1]
> https://gnuradio.org/doc/doxygen/classgr_1_1sync__interpolator.html#ae4daef83760cfe1951c9cf8a83520352
>
>
>
>  On Jul 26, 2015, at 2:54 AM, Marcus Müller <[email protected]>
> wrote:
>
>  Hi Kevin,
>
> this is everything but a dumb newbie question! In fact, it explains quite
> well what you want to do, you illustrate with a screenshot of the relevant
> things, and you describe what happens instead. That makes this a
> well-researched, well-presented and thought through question.
>
> So the point is that the GRC repeat block is but a graphical alias for the
> gr::blocks::repeat block[1]. As the docs show, that doesn't allow dynamic
> setting of the interpolation.
>
> So, this email thread could now address different things:
>
> (0. You kind of reported a bug. Or at least a feature request. If you want
> to do this the right way, open a issue on gnuradio.org's issue tracker.)
> 1. Do you really need repeat functionality, or are you in fact trying to
> adjustably interpolate a band-limited signal, in which case interpolation
> with a filter might be the right thing to do? There's a block that just
> wraps that nicely (fractional interpolator).
> 2. Do you want us to help you add that functionality to the repeat block?
> I had a look, it's not that hard, and it could get you on the contributor's
> list by helping an awesome free software project :) ; I haven't added that
> functionality yet, so there might be some surprises while doing this, but
> it should work.
>
> Best regards,
> Marcus
>
> [1]https://gnuradio.org/doc/doxygen/classgr_1_1blocks_1_1repeat.html
>
> On 26.07.2015 06:07, Kevin McQuiggin wrote:
>
> I should have added that I am running gnuradio version 3.7.7.1 under OSX 
> 10.10.4.
>
>
>  On Jul 25, 2015, at 8:26 PM, Kevin McQuiggin <[email protected]> 
> <[email protected]> wrote:
>
> Hi All:
>
> I would like to use a repeat block to stretch the duration of vectored input 
> dynamically.  For example, (0,1,0,1,…) input should become 
> (0,0,0,1,1,1,0,0,0,…), the repeat count under control of a variable.  In this 
> example the Interpolation parameter would be 3.
>
> I observe that the “Interpolation” value in the Repeat block appears to be 
> set initially, but does not respond to dynamic changes.  Here is a minimalist 
> flowgraph that shows this behaviour:
>
> <PastedGraphic-2.png>
>
> I would like to be able to use the QT GUI Chooser to select other vales for 
> variable “test1” and have this dynamically adjust the Repeat block 
> “Interpolation” value.  This doesn’t work.  In the example flowgraph, 
> “Interpolation” is initialized and remains at 2, despite selecting other 
> values for “test1” when the flowgraph is run.
>
> It is likely a dumb, newbie question, but how can I achieve the desired 
> behaviour?  I have scoured the Wiki, docs, Google, etc, and having not found 
> an answer, I thought I’d make my first post and ask.
>
> Thanks in advance,
>
> Kevin
>
>
>
> _______________________________________________
> Discuss-gnuradio mailing 
> [email protected]https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>
>
>
> _______________________________________________
> Discuss-gnuradio mailing 
> [email protected]https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>
>
>  _______________________________________________
> Discuss-gnuradio mailing list
> [email protected]
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>
>
>
>
> _______________________________________________
> Discuss-gnuradio mailing list
> [email protected]
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>
>
_______________________________________________
Discuss-gnuradio mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to