SDRDriverBase#

class SDRDriverBase[source]#

Bases: ABC

Contract every vendor SDR driver implements.

Abstract methods cover what every radio can do: open, tune, set a rate, and return samples. The rest raise NotImplementedError by default, and a driver overrides only those its hardware supports. A driver owns its own transport and holds no reference back to InstroSDR.

Configuration methods take keyword-only direction and channel, defaulting to the first receive path. Acquisition (read_iq, fetch_iq, get_backlog) is receive-only.

Example

A receive-only, single-channel driver over a vendor SDK:

class MyVendorSDR(SDRDriverBase):
    def __init__(self, device_index: int = 0):
        self._device_index = device_index
        self._device = None

    def open(self) -> None:
        from vendor_sdk import Radio  # keeps the SDK optional at import time

        self._device = Radio(self._device_index)

    def close(self) -> None:
        self._device.close()

    def set_center_freq(self, frequency_hz, *, direction=Direction.RX, channel="0"):
        self._device.center_freq = frequency_hz

    ...  # get_center_freq, set_sample_rate, get_sample_rate

    def read_iq(self, n_samples, *, channels=("0",)) -> IQCapture:
        samples = np.asarray(self._device.read_samples(n_samples), dtype=np.complex128)
        return IQCapture(
            samples=samples.reshape(1, -1),
            sample_period_ns=1e9 / self._device.sample_rate,
            channels=("0",),
            center_freq_hz=(self._device.center_freq,),
        )

Methods

close

Close the underlying transport or SDR handle.

fetch_iq

Return the next contiguous block from the receive stream, blocking until it is available.

get_antenna

Return the selected antenna port.

get_backlog

Return how many samples are waiting to be fetched from the receive stream.

get_bandwidth

Return the IF or filter bandwidth.

get_center_freq

Return the RF center frequency the radio is tuned to.

get_freq_correction

Return the reference oscillator correction.

get_frequency_range

Return the lowest and highest tunable center frequency.

get_gain

Return the overall gain.

get_gain_mode

Report whether automatic gain control is in control.

get_gain_range

Return the lowest and highest settable gain.

get_num_channels

Return the number of signal paths in a direction.

get_sample_rate

Return the IQ sample rate the radio accepted.

get_sample_rate_range

Return the lowest and highest settable sample rate.

list_antennas

List the selectable antenna ports.

open

Open the underlying transport or SDR handle.

read_iq

Read one time-aligned receive block, with the timebase it was taken on.

set_antenna

Select an antenna port.

set_bandwidth

Set the IF or filter bandwidth.

set_center_freq

Tune the RF center frequency.

set_freq_correction

Correct the reference oscillator's frequency error.

set_gain

Set the overall gain.

set_gain_mode

Hand gain to the radio's automatic gain control, or take manual control.

set_sample_rate

Set the IQ sample rate.

start

Begin continuous acquisition.

stop

End a direction's stream and release its buffers.

abstractmethod open() → None[source]#

Open the underlying transport or SDR handle.

abstractmethod close() → None[source]#

Close the underlying transport or SDR handle.

abstractmethod set_center_freq(
frequency_hz: float,
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → None[source]#

Tune the RF center frequency.

Parameters:
  • frequency_hz (float)

    Center frequency in Hz.

  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

abstractmethod get_center_freq(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → float[source]#

Return the RF center frequency the radio is tuned to.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

float – Center frequency in Hz.

abstractmethod set_sample_rate(
sample_rate_hz: float,
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → None[source]#

Set the IQ sample rate.

Parameters:
  • sample_rate_hz (float)

    Sample rate in samples per second.

  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

abstractmethod get_sample_rate(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → float[source]#

Return the IQ sample rate the radio accepted.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

float – Sample rate in samples per second.

abstractmethod read_iq(
n_samples: int,
*,
channels: Sequence[str] = ('0',),
) → IQCapture[source]#

Read one time-aligned receive block, with the timebase it was taken on.

sample_period_ns on the result must describe the block returned, not the rate last requested: InstroSDR derives every IQ timestamp from it.

Parameters:
  • n_samples (int)

    Samples to read per channel.

  • channels (Sequence[str])

    Receive channels to read, e.g. ("0",).

Returns:

IQCapture – One row per channel in channels.

set_gain(
gain_db: float,
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → None[source]#

Set the overall gain.

Override where the radio exposes a single gain figure.

Parameters:
  • gain_db (float)

    Gain in dB.

  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Raises:

NotImplementedError – If the driver does not support gain control.

get_gain(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → float[source]#

Return the overall gain.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

float – Gain in dB.

Raises:

NotImplementedError – If the driver does not support gain control.

set_gain_mode(
automatic: bool,
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → None[source]#

Hand gain to the radio’s automatic gain control, or take manual control.

Parameters:
  • automatic (bool)

    True for AGC, False for manual gain.

  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Raises:

NotImplementedError – If the driver does not support a gain mode.

get_gain_mode(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → bool[source]#

Report whether automatic gain control is in control.

Many radios cannot read this back.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

bool – True when AGC is in control.

Raises:

NotImplementedError – If the driver does not support gain mode readback.

get_gain_range(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → tuple[float, float][source]#

Return the lowest and highest settable gain.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

tuple[float, float] – (low, high) in dB.

Raises:

NotImplementedError – If the driver does not support reporting a gain range.

set_bandwidth(
bandwidth_hz: float,
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → None[source]#

Set the IF or filter bandwidth.

Some radios tie this to the sample rate.

Parameters:
  • bandwidth_hz (float)

    Bandwidth in Hz.

  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Raises:

NotImplementedError – If the driver does not support bandwidth control.

get_bandwidth(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → float[source]#

Return the IF or filter bandwidth.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

float – Bandwidth in Hz.

Raises:

NotImplementedError – If the driver does not support bandwidth control.

set_freq_correction(
ppm: float,
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → None[source]#

Correct the reference oscillator’s frequency error.

Parameters:
  • ppm (float)

    Correction in parts per million.

  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Raises:

NotImplementedError – If the driver does not support frequency correction.

get_freq_correction(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → float[source]#

Return the reference oscillator correction.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

float – Correction in parts per million.

Raises:

NotImplementedError – If the driver does not support frequency correction.

list_antennas(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → list[str][source]#

List the selectable antenna ports.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

list[str] – Antenna port names.

Raises:

NotImplementedError – If the driver does not support antenna selection.

set_antenna(
antenna: str,
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → None[source]#

Select an antenna port.

Parameters:
  • antenna (str)

    Port name, one of list_antennas.

  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Raises:

NotImplementedError – If the driver does not support antenna selection.

get_antenna(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → str[source]#

Return the selected antenna port.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

str – Port name.

Raises:

NotImplementedError – If the driver does not support antenna selection.

start(
*,
direction: Direction = Direction.RX,
channels: Sequence[str] = ('0',),
) → None[source]#

Begin continuous acquisition.

One stream covers one direction and its whole channel set, chosen here.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channels (Sequence[str])

    Channels the stream covers.

Raises:

NotImplementedError – If the driver does not support streaming.

stop(
*,
direction: Direction = Direction.RX,
) → None[source]#

End a direction’s stream and release its buffers.

Parameters:

direction (Direction)

Stream to end.

Raises:

NotImplementedError – If the driver does not support streaming.

fetch_iq(
n_samples: int,
) → IQCapture[source]#

Return the next contiguous block from the receive stream, blocking until it is available.

Parameters:

n_samples (int)

Samples to return per channel.

Returns:

IQCapture – One row per channel the stream covers.

Raises:
get_backlog() → int[source]#

Return how many samples are waiting to be fetched from the receive stream.

Returns:

int – Samples per channel.

Raises:

NotImplementedError – If the driver does not support streaming.

get_num_channels(
*,
direction: Direction = Direction.RX,
) → int[source]#

Return the number of signal paths in a direction.

Parameters:

direction (Direction)

Direction to count.

Returns:

int – Signal paths. 0 means the radio cannot use that direction at all.

Raises:

NotImplementedError – If the driver does not support reporting channel counts.

get_frequency_range(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → tuple[float, float][source]#

Return the lowest and highest tunable center frequency.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

tuple[float, float] – (low, high) in Hz.

Raises:

NotImplementedError – If the driver does not support reporting a frequency range.

get_sample_rate_range(
*,
direction: Direction = Direction.RX,
channel: str = '0',
) → tuple[float, float][source]#

Return the lowest and highest settable sample rate.

Parameters:
  • direction (Direction)

    Signal path, Direction.RX or Direction.TX.

  • channel (str)

    Channel on that path, e.g. "0".

Returns:

tuple[float, float] – (low, high) in samples per second.

Raises:

NotImplementedError – If the driver does not support reporting a sample rate range.