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
