|Subject:||Re: [Discuss-gnuradio] How to analyse chunks of data in GNU Radio|
|Date:||Sun, 4 Oct 2015 12:09:39 +0200|
|User-agent:||Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0|
don't worry, that's a very valid (and valuable) question, so welcome to the mailing list!
So, having read the GNU Radio guided tutorials (I presume you've read , but there's others, older ones, floating around the net), you're probably aware of the general_work() function of each block.
Now, the idea behind GNU Radio generally is that the scheduler calls your block's work with as many items (in your case, samples) as it can. Assuming the file source reads as many samples at once as fit in half its output buffer, roughly the following happens:
1. GNU Radio calls the source's work method. That work method writes the first 4096 samples from the file to its output buffer, and returns the number 4096, telling the runtime that it has produce 4096 items.
2. GNU Radio now calls your block's "forecast" method and asks it "to produce <size of your block's output buffer/2> items, how many items would you need?". Your block would then answer something like "10000"; since that is more than what is available, GNU Radio asks again: "to produce <size of output buf/4>...", your block still wants 10000, and so on. That's kind of a bad thing, because it makes the flow graph stall -- there's no way to produce 10000 input samples (the input buffer isn't even large enough), and your block can't work with less, so your block's general_work() is never called.
There's now two fundamental ways to go about this:
1. changing how GNU Radio sizes the buffers, and
2. changing your implementation to be able to adapt to smaller item "chunks".
Generally, 2. seems advisable -- it keeps the samples flowing more "constantly", and hence minimizes latency and maximizes parallelization. However, not every algorithm lends itself to that, so here's an approach to do 1.:
You could either use the file source's "set_min_output_buffer(20000)" of the file source (if you're in the GNU Radio companion, look at the "advanced" tab), to instruct GNU Radio to reserve at least twice as much buffer as you'll need, or you could specify the input item size to be 10000*complex (assuming your input samples are complexes), and let the file source produce vectors of the same length. Both aren't really "nice" to the scheduler, but should work.
Now, I usually recommend a different approach to finding packets; that approach stems from the fact that your preamble is probably much shorter than 10000 samples, and until you find it, you can just throw away all input samples that you're sure don't contain a preamble. You can be sure of that for all but the (preamble length - 1) last samples, after correlation. GNU Radio has a feature called "history", which allows you to safe the last N items from last call to general_work as "prefix" to the new items. What I hence propose is a finite state machine that simply has the two states "looking for preamble", and "passing through input to output".
In the "looking" state, forecast always returns "to produce N items, I'll need at least (N + preamble length) items", whereas in the passing state, it returns "to produce N, I'll need N". Your general_work method would act based up on the current state, and consume() every item unless it finds the preamble, and then sets an internal counter "items_passed_through" (or similar) to as many items as it then can savely pass through to the output, copy those to the output buffer, change the state variable to "passing through", and return the number of passed items (to let GNU Radio know that it produced output).
In the "passing through" state, your block would just copy as many input items to the output as it can -- the upper limit either being the available items on input, or the remaining items to be passed through (hence the internal counter above). After that, it would just consume() all passed on items, return the items copied, update the counter, and if the number of items that should be passed have been passed, changes the state to "looking".
I hope this gave you some kind of architecture to consider;
On 04.10.2015 00:42, Chris Dandy wrote:
|[Prev in Thread]||Current Thread||[Next in Thread]|