Eccentric Developments


Patching rtl_fm

Currently I'm working on a project that, by the use of the rtl_fm software and several RTL2832U USB devices, records FM audio into MP3 files. During initial development, working with only three devices was no problem at all, until it was time to add more USB receivers to the setup.

Four devices where no problem, but five (or more, for that matter), presented a new challenge. The USB dongles with index over 3, failed to initialize printing the error

Failed to submit transfer 4!

Looking around the web for a solution, I found the following thread in the rtl-sdr forums http://www.rtl-sdr.com/forum/viewtopic.php?f=7&t=142, showing that I was not the only one having that problem.

Users in that forum suggested using virtual machines to drive more than four devices, others found that using rtl_tcp with a low buffer setting fixed the error. I couldn't use rtl_tcp, so VM's was the alternative to try.

None the less, I wanted to save resources, and as such, went with what I though where ""lightweight VM's"": Docker. Only to find, after lots of fiddling around, that the setup was not going to work; what I missed?, this blog post https://blog.docker.com/2016/03/containers-are-not-vms/... Docker was not the way to go; back to square one.

I didn't want to go full virtualization, at least not yet. I figured that maybe, by finding out why rtl_tcp worked while no other tool of the rtl-sdr software did, would give me hint on what to do.

Although rtl_tcp didn't offer much of a clue; lots of fiddling with rtl_test, got me to a point where running several instances of it worked flawlessly, by using an option that forced synced output... BINGO!.

A solution was possible, but after reading the manual for rtl_fm there was no way for using synced output, like for rtl_tcp. What to do?, implement it!.

Using the code for synced output in rtl_tcp, I wrote the same functionality in rtl_fm; and lo and behold!, the server was now able to run 15 RTL2832U USB devices simultaneously; more might be possible, but don't have any more devices right now.

Server driving 15 rtl-sdr usb devices

The picture shows the server running 15 instances of rtl_fm, each working with a RTL2832U receiver. In the screenshot the uptime is over 13 hours, but right now the processes have been running for several days without problems.

After all, the problem seems to be some sort of shared buffer that lib_usb uses to temporarily store the device stream, and then deliver asynchronous updates to rtl_fm; more devices use more buffer until it runs out, which seems to trigger the errors. A more in depth investigation is required to find where the problem truly resides.


You can find the patch for rtl_fm here: https://github.com/niofis/rtl-sdr/, simply clone and compile. I already make a pull request, and if everything goes well, you'll get the new functionality trough official updates.

To use, set the -S switch when running rtl_fm.

rtl_fm -S <other options>

UPDATE:

I received the following message from keenerd, the owner of the fork of rtl-sdr, from which I based my modifications:

Sorry, I am not going to merge this.

Synchronous mode doesn't work. Rtl_fm used to use synchronous mode. It produced constant minor glitches that made data decoding impossible. Don't use it.

The whole ""many simultaneous dongles"" problem is a well-known issue related to LibUSB. All you need to do is reduce the DEFAULT_BUF_NUMBER in librtlsdr.c and recompile.

So there you have it, synchronous mode is discouraged. Although I haven't had any issues with using this mode, on a span of several days, I still went and made the recommended adjustments.

The suggested modifications work pretty good, running 15 RTL2832U receivers simultaneously with no issues what so ever.