-
Notifications
You must be signed in to change notification settings - Fork 3
Home
Use multiple SoapySDR supported devices under a single device wrapper.
Since SoapyMultiSDR is a bit of a meta-wrapper, it makes use of the prefix multi:
(much like remote:
for SoapyRemote) to pass arguments to the underlying drivers that would conflict with arguments we want to pass directly to SoapyMultiSDR. This is especially useful for the driver keyword which is used inside the factory lookup itself to filter out support modules. But MultiSDR supports any argument in general by simply stripping the prefix whenever its found.
For example, to simultaneously request the "multi" driver, and to request the underlying driver as rtlsdr use:
driver=multi,multi:driver=rtlsdr
The example above would specify the rtlsdr driver for all internal devices. But that's not going to be sufficient for MultiSDR as it needs arguments to be specified for each device. Therefore MultiSDR also supports "indexing-format" for specifying a specific device in the list of devices. For example:
driver=multi,multi:driver=rtlsdr,serial[0]=00000001,serial[1]=00000002
SoapyMultiSDR can see there are two devices because it has two indexed keywords. And subsequently re-formats the internal device args to the format expected by the underlying SoapySDR device. The example above gets interpreted internally as:
- Device 0 args:
driver=rtlsdr,serial=00000001
- Device 1 args:
driver=rtlsdr,serial=00000002
Alternatively, one can also skip the multi:
prefix and use the index format instead.
Although this may seem redundant for homogeneous devices. Example again using indexes:
driver=multi,driver[0]=rtlsdr,driver[1]=rtlsdr,serial[0]=00000001,serial[1]=00000002
Once we have a MultiSDR device instance, we can make all of the regular SoapySDR API calls. But first, understand how named parameters and channels are transformed so that API calls can be mapped to a specific device and to specific channels on that device.
Channel mappings are very strait forward. The indexes grow sequentially for each device, so that the first indexes map to device 0, and the next indexes to the next device and so on. The API call getNumChannels()
is critical here because it tells the channel logic how many channels are on each device, and subsequently effects the indexing. Take for example a MultiSDR of two devices where getNumChannels() == 2. Then the indexing would operate as follows:
-
setGain(dir, 0, dB)
is transformed internally todevice0->setGain(dir, 0, dB)
-
setGain(dir, 1, dB)
is transformed internally todevice0->setGain(dir, 1, dB)
-
setGain(dir, 2, dB)
is transformed internally todevice1->setGain(dir, 0, dB)
-
setGain(dir, 3, dB)
is transformed internally todevice1->setGain(dir, 1, dB)
Global API calls with string named parameters (like readSensor) don't have a specific channel space which can be segmented for the multi-device, we must modify the string name itself. Therefore, the calls use the same index formatting once again to map parameters to a specific device.
For example, if each underlying device had a sensor named foo
, then the names presented as the multi device would be foo[0]
and foo[1]
:
-
readSensor("foo[0]")
is transformed internally todevice0->readSensor("foo")
Although it hurts to think about, the MultiSDR system is fully inceptive by supporting a SoapyMultiSDR made up of individual SoapyRemotes or a SoapyRemote that proxies for a local SoapyMultiSDR. Note that many of the arguments don't get prefixed because they don't really need to be mutated between layers since they are ignored in these layers:
driver=multi,multi:driver=remote,remote=host,remote:driver=rtlsdr,serial[0]=00000001,serial[1]=00000002
-
driver=multi
specifies the multi support module -
multi:driver=remote
uses the remote support module for each internal device -
remote=host
specifies the remote host (could use index format if different hosts) -
remote:driver=rtlsdr
specifies the rtl driver on the remote node -
serial[0]=00000001
specifies the specific device serial number
driver=remote,remote:driver=multi,remote=host,multi:driver=rtlsdr,serial[0]=00000001,serial[1]=00000002
-
driver=remote
specifies the remote support module -
remote:driver=multi
specifies the multi driver on the remote end -
remote=host
specifies the remote host (could use index format if different hosts) -
multi:driver=rtlsdr
specifies the rtl driver on the remote node in the multi module -
serial[0]=00000001
specifies the specific device serial number
- FAQ
- Build guide
- Driver guide
- SoapySDR header files
- Doxygen documentation
- Python binding support
- LuaJIT binding support
- .NET binding support
- GO binding support
- Rust binding support
- Julia binding support
- Pothos SDR Tutorial
- Help and support
- Pothos users' group
- Twitter @pothosware
- IRC chat #pothos
- Slack workspace
- Contract services
- Developer blog
- Contributing
- Donate
- Example support
- Remote access
- Multi device
- Device sharing
- SIMD converters
- Audio devices
- Osmo support
- NovenaRF support
- EVB7 support
- UHD support
- Blade RF support
- Hack RF support
- RTL-SDR support
- SDR Play support
- Radioberry support
- Red Pitaya support
- Lime Suite support
- Airspy support
- Airspy HF+ support
- PlutoSDR support
- Skylark Iris module
- Funcube Dongle Pro+
- IC-R8600 Receiver
- Epiq Sidekiq
- NetSDR support
- XTRX support
- RTL TCP support
- SpyServer support