On 05/29/2015 01:46 PM, Jeon wrote:
I am trying to remove `preamble` and `start frame
delimiter` from a frame and only the payload will be passed to
the next block.
While in debugging, `ninput_items` is 7742, and
`noutput_items` is 4096, for instance. An offset where the
frame starts is 790.
Simple calculation gives me that 7742 - 790 = 6952 samples
should be passed to the next block. But output space given is
only 4096. Thus, I can only pass 4096 samples and 6952 - 4096
= 2856 samples will be discarded. But, I need them to be
There's no reason not to pass through your payload in parts, if you
implement a state machine with a counter for remaining items to pass
through in your block.
However, there's an advantage to waiting for the whole payload to be
on your input at once, which I'll explain further down.
Does your payload always have the same length? In that case, your
forecast should always demand payload_length input items to produce
any amount of output items -- that way, you can make sure that at
*one point*, you get the whole payload into your input buffer.
No matter what you really do, you will need to use a state machine
of some kind.
In your case, that's comparatively easy: Just check, at the
beginning of each general_work call, whether you're in pass-through
mode, or in "search preamble mode", etc, and let your work act based
upon that. For example, assume you're in search preamble mode, you
find a preamble, so you consume all items up to the end of that
preamble, and set your state to "pass through", and then return from
general_work. Before GNU Radio calls you next time, it will ask
forecast() how many input items you need. Forecast always says it
needs payload_length items, so at the point where work is actually
called in "pass through" mode, you *should* have at least
payload_length input items; let your block consume and produce these
items, switch to "search preamble mode", and return.
Even worse, a stream of samples are coming continuously
from a previous block.
Lucky you! You have GNU Radio, which makes sure there's only one
instance of your general_work being run at once, and presenting you
with all the items you did not consume in the previous general_work
Will it be helpful if I have some very long buffer in a
block? I don't think it works since `noutput_items` is always
smaller than `ninput_items` every time the block runs
That's not generally the case. It might be the case here, but that
simply means that the downstream block isn't consuming the whole
buffer, or your upstream items are larger, or your upstream block is
just much faster at producing items than you and your downstream
blocks are at consuming them.
If you just try to rely on GNU Radio's buffers, you would be safe
from something like buffer overflows happening -- GNU Radio will
only call the upstream's general_work function if there is enough
space in its output buffer (which is your input buffer).
Personally, I think what you're doing is a complicated task, so I
have a lot of respect for the effort you're putting into this.
I'd try to avoid the complexity by not
doing this in one
block -- use a preamble correlator to mark the beginning of your
frame with a stream tag. Then, use a state-machine block to only
copy the payload_length items after such a tag (a whole payload at a
time), adding a tag on the first item containing the length of the
payload as long:
I mentioned above there's an advantage to passing the whole payload
at once; what you have when you have a length tag on the first item
of contigous packet items is a tagged stream. Tagged stream blocks
are a GNU Radio concept dedicated to processing packeted data, in
which work() methods are always called with the whole packet at once
Discuss-gnuradio mailing list