Hi Patric,
since your goal is to produce a variable number of output items, your
`general_work` approach seems to be the correct one.
I mean "variable number of output items" in the sense that there is no
fixed relation between the number of input items to the number of output
items. Just for reference.
`WORK_CALLED_PRODUCE` is one of those "magic values" that are defined
somewhere in the system. I've never personally used it in any block.
It is documented here:
https://www.gnuradio.org/doc/doxygen/classgr_1_1block.html
The function is found here:
https://www.gnuradio.org/doc/doxygen/classgr_1_1block.html#aa5581727d057bdd8113f8b2a3fc5bd66
I use `bpython3` to explore Python methods etc. In your case, I expect
that `self.WORK_CALLED_PRODUCE` should be available.
BUT: Don't use `produce`! In your case use:
`return self.buffer_len`
Why? Because the all the buffer pointer updates will be handled after
you return from `general_work`. The `produce` method exists for cases
where you have multiple output buffers and want to produce different
numbers of output items. e.g 5 samples on `output_items[0]` and 25
samples on `output_items[1]`.
In your case, you `return 0` which tells the scheduler that you did not
produce any items.
More generally, try to minimize calls to `consume`/`produce`. Keep track
of the number of samples your `general_work` consumes and how many
samples you've written to your output buffer. At the end of
`general_work` report these values to the system:
- consumed items via `consume_each`
- produced items via `return integer_with_number_of_consumed_items`.
The `forecast` method expects estimates. The scheduler will call
`general_work` anyways at some point, if the system is unable to fulfill
your forecast requirement. `set_output_multiple` is much more strict.
In your case I'd start with:
`ninput_items_required[0] = noutput_items`
which might be inefficient. But you can update it with better forecasts
later. Talking about efficiency: I'd only worry about efficiency in C++
blocks. Python blocks incur quite a penalty.
Cheers
Johannes
On 21.01.22 15:14, Patric Müller wrote:
Hello everyone,
I am currently trying to create a basic block similar to this issue:
https://stackoverflow.com/questions/68289222/gnu-radio-buffer-size
Some software and hardware info:
GNU Radio version: 3.9.3.0
Python version: 3.9.7
OS: Ubuntu 20.04
I always want to work on the same number of items, say 1024. Now I would
like to use up all of the items, but I want to produce something between
say 500 - 1500 items.
For now, I would like to create a simple block with one input and one
output, which consumes a set number of items and outputs only a fraction
of those incoming items in order to understand it better.
Therefore I started with a general block and wanted to change
ninput_items_required[0].
However, ninput_items_required is an integer. Trying to directly change
this integer values results in:
Unable to cast Python instance to C++ type (compile in debug mode for
details)
My second question is about the produce() function. If it is used,
general_work() should return
WORK_CALLED_PRODUCE
but how exactly? After calling produce() and telling the scheduler how
many items are produced, can I then change output_items[0]?
My attempt at the forecast() function and general_work() is provided
below. General suggestions/hints or a basic example would be helpful and
immensely appreciated.
If additional background is required, let me know and I will gladly
provide more information.
def forecast(self, noutput_items, ninput_items_required):
# Estimate, that we will always need self.buffer_len items on
input port [0]
ninput_items_required[0] = self.buffer_len
def general_work(self, input_items, output_items):
# Firstly check, if input_items has a sufficient amount of items
if len(input_items[0]) >= self.buffer_len:
# Then consume exactly self.buffer_len items on input_port[0]
self.consume(0, self.buffer_len)
# Now I would like to only output a fraction of the input
items
# say the first self.out_items, on output port[0]
self.produce(0, self.out_items)
# Do I set my output_items[0] here?
# Now I only need to return WORK_CALLED_PRODUCE, but how exactly?
return 0
Kind regards,
Patric Müller