-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RSPduo "Dual Tuner (diversity receiption)" Large Data Set Coherent Processing #51
Comments
After hours of trial and error I finally got the point:
To make the two buffers and their indexes static they are implemented in the init() function:
The essential input processing in the general_work() function is:
Followed by my block's signal processing and output and ending in:
You may close this issue or even delete it. Or you may leave it for others having the same problem. In any case it is not an issue of your gr-sdrplay3 driver but rather an issue of understanding how GNU Radio wants stream to vector processing to be implemented. |
@gozillah - I am glad to hear you figured it out. A good resource for questions related to GNU Radio is their discussion mailing list: https://wiki.gnuradio.org/index.php/MailingLists - there are a lot of experts there. Franco |
Thanks for the link. I may register there and migrate my observations to the discussion forum. I am somewhat worried about losing samples when the GNU Radio scheduler or Windows are running the thread of my block in intervals so large that the RSPduo's sampling output will overfill a buffer in your gr-sdrplay3 driver or somewhere in GNU Radio between your gr-sdrplay3 driver and my block. Taking statistics about the "stream chunks" delivered to my block's "Stream to Vector" processing I am observing the following behavior:
The maximum chunk size seems to be 8191 samples. A current stream chunk size of 8191 samples raises the suspicion that samples may have been lost due to buffer overrun, spoiling the coherence of my vector data. Is this limit of approximately 8k (= 2^13) a limitation in your gr-sdrplay3 driver or possibly in GNU Radio? |
Note: The above list contains only newly occurring chunks sizes, i.e. a listet chunk size may occur many times. |
@gozillah - you may want to enable 'Sample gaps check' in the RSPduo source block under 'Other Options'. If you see those messages with your GNU Radio Companion flowgraph, it means that the Franco |
My processing cycle is as follows:
When activating the 'Sample gaps check' I see a lot of missed samples warnings, but I am unable to specifically attribute them to either my sampling or my processing phase. So for the time being I cannot tell whether I am actually losing samples during my sampling phase. My processing output does not look bad, but my observation is that correllation S/N is varying from cycle to cycle by up to about +/- 5dB. I do not know whether this is due to loss of samples or antenna signal variations. Decimation would greatly reduce processing quality. Translating all of my blocks from Python to C++ would improve downstream processing speed by maybe a factor of two at the cost of a lot of work (I do most of the maths with numpy, so the gain may be even less than two). According to my Windows' Task manager, gr-sdrplay3 and the blocks of my application are running in a single process as separate threads. Running the workload of my blocks in separate processes on several CPUs may speed them up (I could start these processes from within the block's thread and communicate with them via shared memory), but this seems complex and I have no practical experience in this. Assuming that gr-sdrplay3 has a mechanism warranting not to miss any samples from the RSPduo, and futher assuming that GNU Radio warrants that a vector output reliaby transfers the entire vector to the next block irrespective of GNU Radio or Windows scheduling, then the following concept may assure that no samples are lost during my sampling phase:
But as I said above, I am not sure whether I am regularly losing samples during my sampling period. Uff, this has now been TL;DR ;-). |
@gozillah - thanks for the detailed and interesting explanation. A couple of things you can try to make sure this RSPduo source block doesn't drop samples under normal conditions:
Then, little by little, you can add other blocks downstream (one by one so you can see the differences) to see how it goes in terms of dropped samples. Some of the questions you are asking me require an in-depth knowledge of how GNU Radio and its scheduler work, and I honestly don't have that level of expertise. If I were you, I would post a message with what you are trying to do to the GNU Radio discuss mailing list to see what they suggest. Franco |
Just to repeat it once in a while: I very much appreciate your responsiveness and help! I created that RSPduo+Nothingelse+Nullsink graph, and yes, under Windows it initially drops samples:
But then the scheduler kicks the Null sink in, consuming them all. I also inserted my first block converting the streams into vectors and doing initial processing of my chain. This block still is consuming all samples. But as I add futher blocks the dropouts take off. I haven't found a comprehensive documentation of GNU Radio's scheduler. Most sources just say that it is complex, and please do not change anything unless you know what you are doing. And I know nothing ;-). There seems to be a project called GNU Radio 4.0 comprising a total redesign of the scheduler. As the scheduler is very close to the OS kernel, I hope that it will be available with all its new goodies for Windows as well. Under Windows the 3.x scheduler is lacking some kernel-related functionality as e.g. thread priority link . By analyzing the gaps between gap warnings I found out that (due to processing chain overload) I actually lose samples in my stream to vector conversion, so the assumed problem is existing indeed. I initially rejected your proposal to decimate the streams because decimation would degrade processing quality as a side-effect. However skipping whole vectors would be acceptable, because I do need no-gaps sampling only within a vector. At that time I was assuming that this could only be achieved by doing the stream to vector conversion in your gr-sdrplay3, see my comment of August 15 above. But then I discovered the "Stream to Vec Decim" block which seems to have been designed for exactly this purpose. And indeed, my processing results have improved! Problem solved! |
@gozillah - glad to hear you got it working with decimation! A couple of comments:
Franco |
Thanks for the links. There is also a good scheduler presentation from Marcus Muller at link. GNU Radio 4 will be exciting indeed.
Well, sort of. It is now about ten times better than before I applied the stream to vector decimator. But I am still losing some samples. My setup is as follows: What happens is that at the decimator's output I am receiving bursts of gaps followed by series of flawless vector data. It looks like so (I am printing the dynamic range of my processing after each vector); ... Taking this gap as an example: I have no idea whether the gaps are occurring in the stream data for the vectors I am actually receiving from the decimator or in the decimated data disposed off by the decimator. The gaps explode whenever I am increasing the decimation rate beyond about 0.4 . Reducing the decimation on the fly via QT GUI Range back to 0.4 or below will not recover the situation. I will have to restart the flowgraph. On the other hand the processing results of my application are not looking really bad as long as I am limiting decimation to about 0.4 . I read in other GNU Radio posts in the Internet that other people are having problems with sample gaps as well. I suspect that the GNU Radio buffering and the single task / multiple threads concept of the scheduler are simply overstrained by my large vectors of between one and four megasamples. I can parallelize parts of my code with Numba but not the crucial buffering and scheduling. Is there any possibility to increase the GNU Radio buffer sizes? |
@gozillah 38+33 means 38*252 + 33, where 252 is the size of the SDRplay API RX callback vectors xi and xq. Regarding the GNU Radio buffer sizes, I think you should ask that question to the GNU Radio discuss mailing list (https://www.gnuradio.org/community/) to see what those more familiar with GNU radio internals think about it. Also thanks for the link to the presentation by Mark Muller on YouTube; I'll watch it tonight after work. Franco |
Are these samples being lost between the SDRduo and your gr-sdrplay3 source block or between your source block and the first non-source block? I unsuccessfully tried to find your code implementing the gap analysis. |
@gozillah - the code that checks for gaps in the sample streams is here: https://github.com/fventuri/gr-sdrplay3/blob/main/lib/rsp_impl.cc#L1057-L1074 and it is invoked by the two RX callback functions here: https://github.com/fventuri/gr-sdrplay3/blob/main/lib/rsp_impl.cc#L709-L710 and here: https://github.com/fventuri/gr-sdrplay3/blob/main/lib/rsp_impl.cc#L730-L731 The samples being "lost" is simply because the GNU Radio scheduler doesn't call the Franco |
In rsp_impl.cc's work() function is a line If ring_buffer.tail is larger than ring_buffer.head (because ring_buffer.head has wrapped around the ring_buffer's linear top), then nsamples becomes negative, with the consequence that at Then new_tail at This does not happen very often as RingBufferSize is large compared to GNU Radio's usual noutput_items in the work() function's call parameters. But I will happen from time to time. Or did I overlook something? |
Maybe I overlooked this part preceeding above code: |
@gozillah - I am out of town these days, so I won't be able to take a look at the issue with negative values for Regarding the use of that condition variable ( Franco |
Ok thanks, take your time. I will study the link. I am trying to modify your code for my own purposes while still struggling with refreshing and rounding my C++ knowledge. For this it is of course essential for me to grasp what your code is doing. I succeeded compiling and installing your code with small test modifications in my Radioconda / Windows environment. My objective is to make your code output large vectors (instead of streams) containing contiguous samples without gaps while maintaining coherence between the two cannels of SDRplay duo. It is ok if the downstream processing chain is losing samples between verctors due to ithe chain's inability to process the samples as fast as SDRplay is delivering them. But the vectors polled by the downsteam processing chain must be without gaps inside the vectors. As a beneficial side-effect this will reduce latency by sidestepping downstream "stream to vector" blocks. My understanding of your code is that the SRDplay API is pushing samples into the ring buffers via the callback rsp_impl::event_callback().
On the other side of the ring buffers rsp_impl::work() is invoked by the GNU Radio scheduler and is transfering samples from the ring buffers to this source block's outputs. rsp_impl::work() will miss the samples overwritten by rsp_impl::event_callback() when the ring buffers become full (as detailed above).
My approach is as follows:
I will have to modify rsp_impl::work():
Question 3: Is there anything probelmatic in my approach? |
Franco |
I am reading data from gr-sdrplay3 RSPduo in "Dual Tuner (diversity receiption)" mode for large data set correlation processing (typically 2^20 samples per batch or even more). To maintain both processing batch size as well as correlation my processing needs vector input (vector size 2^20 samples or even more). So far I have been using two GRC "Stream to Vector" blocks to convert RSPduo's stream outputs into my processing's vector inputs. This is working quite well with a correlation S/N of rougly 30 dB at 2^20 samples per batch (or less dB with lower batch sizes), measured while feeding both tuners from the same antenna.
Collecting and processing 2^20 samples is creating several seconds of latency down my processing chain. In order to reduce latency introduced by the GRC "Stream to Vector" blocks I integrated the "Stream to Vector" conversion into the first block of my GRC processing chain (written in Python, sorry), but so far without success. Since doing this I have completely lost correlation. My (unsuccessful) approach is as follows:
I suspect that I am loosing coherence in the abovementioned while-loop. Could it be that my Python implementation is so slow that it misses some samples on one input while processing the other? What could be a successful strategy to accumulate the stream samples without loosing coherence?
The text was updated successfully, but these errors were encountered: