[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Having trouble with C++ OOT block in restricting output to those inp

From: Martin Luelf
Subject: Re: Having trouble with C++ OOT block in restricting output to those input values I wish to pass
Date: Thu, 10 Sep 2020 08:05:23 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0

Dear George,

this also caused me a lot of headache when I started with GNURadio, so here is what I learned about it.

Let's start with the forecast method. This tells GNURadio how many input samples you need on each input stream to generate the requested number of output items. Usually GNURadio will run your forecast function a couple of times with different output numbers to find a good data chunk size to give to the general work function. Keep in mind that the number of required input items you give here is a minimum number and GNURadio might decide to give you more input data than you requested. It is also important to know that the number of samples you request here is just an estimate. You are not forced to actually process that much data.

Now to the general_work function. noutput_items tells you how many samples GNURadio would like you to produce (this is a maximum number you may produce less). It also tells you how much memory is allocated in every array in the output_items vector. If you have only one output and you used the default <out type> *out = (<out type> *) output_items[0]; definition this tells you how many items you can place (at most) into the out array.

The ninput_items[] array tells you how many input items are available in the input arrays. Again if you just have one input and you use const <in type> *in = (const <in type> *) input_items[0]; ninput_items[0] is the number of inputs available in the in array. You may not read more items than that from the array.

Within the given input symbols you can start looking for your sync pattern. If you generate output you have to write (in your case copy) it to the out array. At the end of general_work you call consume(0, K) with the number of input items K that you have consumed on input 0. That is how many of the input items you have used and do not need to see again. If you consume 0 symbols the next call to general_work will show you the exact same input samples again. If you consume ninput_items[0] you will see completely new input samples on the first input the next time general_work is called. And then you return the number of samples you generated (i.e. how much samples you put into the out array). This number must be smaller or equal noutput_items, because otherwise you would have written out of the allocated memory which might result in a segfault/core dump. Note that you don't have to call consume at the very end of work and there is also another way of telling GNURadio how many samples you have produced, but let's leave that for another day.

So a very easy (but not the most efficient) setup for your problem could be:
Add a boolean flag to your _impl class that both forecast and general_work can read/write to. This flag will indicate whether or not you have found the sync pattern or not. You initialize this flag with false. Assume you have a sync pattern of length L and a message with M data symbols afterwards.

In forecast if the flag is set (meaning you have found the sync pattern) you need L+M symbols of input. If the flag is not set you need L input samples, regardless of how many output samples GNURadio wants you to generate.

In general work if the flag is false you search the input for the sync pattern. If you found it at position i (counting from 0) you set the flag to true, consume i samples (i.e. everything before the sync marker). If the sync marker is not found you keep the flag to false and consume the inputs that you have searched so far. In both cases you return 0 since you have not generated any output yet.

If the flag is true you copy the first L+M samples from the input to the output, you set the flag to false (because after the data you have to start searching for the sync marker again) you consume L+M samples and return L+M samples.

Note: This is a very easy to understand scheme, but unfortunately not very efficient. You only process a single block of either unwanted spurious symbols, or one sync marker and data at a time. So once you have a good understanding of how this works you should tweak that block to be able to process multiple blocks of spurious symbols and sync patterns/data within once call to general_work. It uses the same kind of logic, but requires more housekeeping of counters and indices.

If your input is symbols rather than bits/bytes you should also look at the paper from J. Massey "Optimum Frame Synchronization" from 1972 on how to perform optimum sync marker detection, which performs better than the intuitive correlation search.

Hope that gets you started.


On 10.09.20 04:34, George Edwards wrote:

I am writing an OOT block in C++ that receives a sequence of numbers and searches through for a sync pattern and passes to its output the sync pattern and the  bytes of data which follows it. The QA test shows the block recognizes the pattern and will pass the pattern along with the data that follow it, but there is a problem. The block does not know a priori the number of spurious bytes preceding the sync pattern of bytes, so I cannot set up the true relationship between the ninput_items and noutput_items. However, the block can count the number of bytes that came in before the pattern. This is my problem:

1) In the OOT general_work method: If I set noutput_items = ninput_items[0], then in addition to passing the correct data to the output, it passes trailing zeros equal to the number of spurious bytes that entered before the pattern.

2) If I set the return noutput_items = ninput_items - cnt (where cnt is the number of spurious bytes before the pattern) depending on where I put noutput_items in the code, it either throws a core dump or cuts off the number of true data.

Also, within the forecast method, I simply use a _for_ loop and set

I will appreciate any help to point me in the right direction in dealing with this non-regular output/ inputs relationship.

Thank you!


reply via email to

[Prev in Thread] Current Thread [Next in Thread]