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]
<mailto:[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
<http://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]> 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 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] <mailto:[email protected]>
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio
_______________________________________________
Discuss-gnuradio mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio