Soapy SDR update: features and improvements

Soapy SDR has become an increasingly excellent way to get SDR hardware into a user-friendly API and accessible within a wide ecosystem of existing SDR applications. Soapy SDR started as an abstraction interface to give users a consistent API across a variety of devices (see the previous blog entry). But there has been a ton of new work these last few weeks to introduce new APIs, and to wrap Soapy SDR into existing interfaces such as gr-osmosdr and uhd.

Lather up your device or application with Soapy SDR:

  • Making a Soapy device module is as easy as overloading a few dozen C++ calls. Anyone designing new SDR hardware should definitely consider using Soapy SDR.
  • Making a new SDR application? Need a C++, C, or Python API? Write your application once with Soapy SDR to support any current or future devices.

New devices

The Novena RF is a SDR daughtercard for the Novena, an open hardware laptop. With the help of Soapy SDR, the Novena laptop and its companion RF card can enter the exicting world of SDR applications.

New interfaces

Previously, various support wrappers made gr-osmosdr and uhd devices available through the Soapy SDR interface. But now, in the other direction, one can now use Soapy devices under the gr-osmosdr and uhd interfaces. This gives Soapy devices immediate access to a number of applications using GNU Radio through gr-osmosdr and gr-uhd, as well as applications written against the uhd API like osmo-trx and OpenBTS.

New APIs

I have a rule that I try to follow when creating new abstractions. There should be at least two use cases in-order to "get it right" (hopefully). With the recent work on a new Zynq based SDR and Novena RF, and including existing SDR devices, I have my motivations for improvement.

Direct buffer access

The new streaming API additions provide direct buffer access to the user. Direct buffer access means that the API call provides the user with a DMA buffer without memory copies or sample conversions. Its as close to the metal as you can get. Even for devices that don't strictly have "DMA", this API can still be useful with libusb or network style devices for the same reason.

Many applications find it easier to provide the stream buffer to the driver. But if you can change your application to accept buffers from the driver, then there may be a worthwhile performance advantage to be gained. Also, it should be noted that this API is only useful when the vendor actually implements these calls for their device.

Tunable elements

Many devices out there tend to have a tunable element in the RF frontend that covers most of the frequency range, and a tunable element in the digital baseband domain, usually a CORDIC (the LMS7002M actually has both). The CORDIC is for frequency hopping, tuning offsets, and error correction.

To make this use case easier, the API has new overloads to set frequency, get frequency, and query the tunable range on a per-element basis. In addition, the default algorithm to tune the overall signal path will do the right thing to tune the available elements, and to parse the optional user-provided tuner arguments. And if thats wrong, the vendor can overload this call as well.

Stream status

To support asynchronous status indications from streams (both RX and TX), a readStreamStatus() API call has been added to query associated flags, times, and status codes.


Many thanks to the folks over at the Novena RF project for motivating improvements for Soapy SDR -- making it easier for anyone to get involved in SDR.

Last edited: Mon, Mar 2 2015 - 09:06PM