Technical Information - The RAW_IO Problem

The biggest issue I have identified so far with using SDRs on Windows for ARM devices, is that all the computers I have tested so far suffer from sample drops at practically any samplerate when using libusb-based SDRs. While I do think there is something amiss with either the Windows build itself, or the Qualcomm drivers provided - there is something we can do about it. It is a 2-part fix:

  1. Patch LibUSB to support RAW_IO when using the WinUSB backend
  2. Patch SDR libs that utilize libusb with bulk transfers to use RAW_IO

What is RAW_IO?

According to Microsoft, RAW_IO is a pipe policy that affects how programs interact with WinUSB devices. "If enabled, transfers bypass queuing and error handling to boost performance for multiple read requests." Microsoft recommends its use when "performance is a priority and the application submits simultaneous read requests to the same endpoint." Well... that perfectly describes how many SDRs interface with your PC, including AirSpys, HackRFs, and RTL-SDR.

So, why do these libraries not utilize RAW_IO? Simple: libusb, the standardized library they all use for device access, does not support RAW_IO. At least, not yet. There is a PR open with libusb to implement a simple API that can check if RAW_IO is available, then enable it. The patch was originally written by martinling, a HackRF developer, and is being carried forward by HannesFranke-smartoptics.

In all the native releases available on this site, the RAW_IO-enabled version of libusb has been used. To use it, the new RAW_IO API is implemented into the AirSpy, AirSpy HF, HackRF, and RTL-SDR libraries. In my testing, there are no sample drops at all with these patches. Patched sources for libs used on this site:

Is this a good idea?

The question has been raised: is it a good idea to implement a RAW_IO within libusb since it's specific to Windows? I would argue yes, it is. It is unsafe for libusb to automatically use RAW_IO because transfers need to be specifically formatted to work properly. So, its use must be opt-in - a method the current PR utilizes. The RAW_IO policy exists in Windows, it helps with many types of devices, and Microsoft themselves recommend it in use-cases like SDRs. It makes little sense to not support it. I feel that the current libusb PR is a great way to handle it, because developers using libusb can opt-in to the API. It will simply do nothing if called on an unsupported platform, so there are no real losers with this change.

Additionally, I would make the case that the above mentioned USB libraries should implement RAW_IO once libusb officially supports it, even for their Intel-based builds. It has been well documented over the years that Windows SDR users drop more samples than Linux users on the same intel-based machine. It is likely that RAW_IO will solve these problems in specific situations - an opinion that is anecdotally confirmed by WinUSB developers across the internet. This change can cause no harm in SDR libraries since they always use well-formed bulk transfer requests, so it should be implemented because it is documented to only be beneficial.


Volk Profile

Volk is a common library used by SDR applications for SIMD operations. In its current state, Volk's NEON/NEONv8 kernels do not work on Windows for ARM64. There is a PR open here that still needs a bit of work, but does successfully enable support for NEON on Windows - resulting in significantly better performance. The official SatDump build, and unofficial SDR++ ARM64 build, are built against this patched version of volk. In order to utilize the optimized kernels, you must run volk_profile on your computer.

Click here to download it for Windows on ARM64.