# SDRDriverBase

## class SDRDriverBase[source]

Bases: [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC "(in Python v3.15)")

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`](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") by default, and a driver overrides only those its
hardware supports. A driver owns its own transport and holds no reference back to
[`InstroSDR`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.InstroSDR.md#instro.unstable.sdr.InstroSDR "instro.unstable.sdr.InstroSDR").

Configuration methods take keyword-only `direction` and `channel`, defaulting to the
first receive path. Acquisition ([`read_iq`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.read_iq "instro.unstable.sdr.SDRDriverBase.read_iq"), [`fetch_iq`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.fetch_iq "instro.unstable.sdr.SDRDriverBase.fetch_iq"), [`get_backlog`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_backlog "instro.unstable.sdr.SDRDriverBase.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`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.close "instro.unstable.sdr.SDRDriverBase.close") | Close the underlying transport or SDR handle. |
| --- | --- |
| [`fetch_iq`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.fetch_iq "instro.unstable.sdr.SDRDriverBase.fetch_iq") | Return the next contiguous block from the receive stream, blocking until it is available. |
| [`get_antenna`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_antenna "instro.unstable.sdr.SDRDriverBase.get_antenna") | Return the selected antenna port. |
| [`get_backlog`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_backlog "instro.unstable.sdr.SDRDriverBase.get_backlog") | Return how many samples are waiting to be fetched from the receive stream. |
| [`get_bandwidth`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_bandwidth "instro.unstable.sdr.SDRDriverBase.get_bandwidth") | Return the IF or filter bandwidth. |
| [`get_center_freq`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_center_freq "instro.unstable.sdr.SDRDriverBase.get_center_freq") | Return the RF center frequency the radio is tuned to. |
| [`get_freq_correction`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_freq_correction "instro.unstable.sdr.SDRDriverBase.get_freq_correction") | Return the reference oscillator correction. |
| [`get_frequency_range`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_frequency_range "instro.unstable.sdr.SDRDriverBase.get_frequency_range") | Return the lowest and highest tunable center frequency. |
| [`get_gain`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_gain "instro.unstable.sdr.SDRDriverBase.get_gain") | Return the overall gain. |
| [`get_gain_mode`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_gain_mode "instro.unstable.sdr.SDRDriverBase.get_gain_mode") | Report whether automatic gain control is in control. |
| [`get_gain_range`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_gain_range "instro.unstable.sdr.SDRDriverBase.get_gain_range") | Return the lowest and highest settable gain. |
| [`get_num_channels`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_num_channels "instro.unstable.sdr.SDRDriverBase.get_num_channels") | Return the number of signal paths in a direction. |
| [`get_sample_rate`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_sample_rate "instro.unstable.sdr.SDRDriverBase.get_sample_rate") | Return the IQ sample rate the radio accepted. |
| [`get_sample_rate_range`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.get_sample_rate_range "instro.unstable.sdr.SDRDriverBase.get_sample_rate_range") | Return the lowest and highest settable sample rate. |
| [`list_antennas`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.list_antennas "instro.unstable.sdr.SDRDriverBase.list_antennas") | List the selectable antenna ports. |
| [`open`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.open "instro.unstable.sdr.SDRDriverBase.open") | Open the underlying transport or SDR handle. |
| [`read_iq`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.read_iq "instro.unstable.sdr.SDRDriverBase.read_iq") | Read one time-aligned receive block, with the timebase it was taken on. |
| [`set_antenna`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.set_antenna "instro.unstable.sdr.SDRDriverBase.set_antenna") | Select an antenna port. |
| [`set_bandwidth`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.set_bandwidth "instro.unstable.sdr.SDRDriverBase.set_bandwidth") | Set the IF or filter bandwidth. |
| [`set_center_freq`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.set_center_freq "instro.unstable.sdr.SDRDriverBase.set_center_freq") | Tune the RF center frequency. |
| [`set_freq_correction`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.set_freq_correction "instro.unstable.sdr.SDRDriverBase.set_freq_correction") | Correct the reference oscillator's frequency error. |
| [`set_gain`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.set_gain "instro.unstable.sdr.SDRDriverBase.set_gain") | Set the overall gain. |
| [`set_gain_mode`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.set_gain_mode "instro.unstable.sdr.SDRDriverBase.set_gain_mode") | Hand gain to the radio's automatic gain control, or take manual control. |
| [`set_sample_rate`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.set_sample_rate "instro.unstable.sdr.SDRDriverBase.set_sample_rate") | Set the IQ sample rate. |
| [`start`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.start "instro.unstable.sdr.SDRDriverBase.start") | Begin continuous acquisition. |
| [`stop`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.stop "instro.unstable.sdr.SDRDriverBase.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*](https://docs.python.org/3/builtins/functions.html#float "(in Python v3.15)"))

      Center frequency in Hz.
    - **direction** ([*Direction*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      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*](https://docs.python.org/3/builtins/functions.html#float "(in Python v3.15)"))

      Sample rate in samples per second.
    - **direction** ([*Direction*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      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`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.InstroSDR.md#instro.unstable.sdr.InstroSDR "instro.unstable.sdr.InstroSDR") derives every IQ timestamp from it.

Parameters:
:   - **n_samples** ([*int*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)"))

      Samples to read per channel.
    - **channels** (*Sequence**[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]*)

      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*](https://docs.python.org/3/builtins/functions.html#float "(in Python v3.15)"))

      Gain in dB.
    - **direction** ([*Direction*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *float* – Gain in dB.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://docs.python.org/3/builtins/functions.html#bool "(in Python v3.15)"))

      `True` for AGC, `False` for manual gain.
    - **direction** ([*Direction*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *bool* – `True` when AGC is in control.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *tuple[float, float]* – `(low, high)` in dB.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://docs.python.org/3/builtins/functions.html#float "(in Python v3.15)"))

      Bandwidth in Hz.
    - **direction** ([*Direction*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *float* – Bandwidth in Hz.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://docs.python.org/3/builtins/functions.html#float "(in Python v3.15)"))

      Correction in parts per million.
    - **direction** ([*Direction*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *float* – Correction in parts per million.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *list[str]* – Antenna port names.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

      Port name, one of [`list_antennas`](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.SDRDriverBase.md#instro.unstable.sdr.SDRDriverBase.list_antennas "instro.unstable.sdr.SDRDriverBase.list_antennas").
    - **direction** ([*Direction*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *str* – Port name.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channels** (*Sequence**[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*]*)

      Channels the stream covers.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

    Stream to end.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://docs.python.org/3/builtins/functions.html#int "(in Python v3.15)"))

    Samples to return per channel.

Returns:
:   *IQCapture* – One row per channel the stream covers.

Raises:
:   - [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – If `n_samples` exceeds what the stream can buffer.
    - [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – If the driver does not support streaming.

### get_backlog() → int[source]

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

Returns:
:   *int* – Samples per channel.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

    Direction to count.

Returns:
:   *int* – Signal paths. `0` means the radio cannot use that direction at all.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *tuple[float, float]* – `(low, high)` in Hz.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – 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*](https://dev.nominal.io/instro/ref/instruments/generated/instro.unstable.sdr.types.Direction.md#instro.unstable.sdr.types.Direction "instro.unstable.sdr.Direction"))

      Signal path, `Direction.RX` or `Direction.TX`.
    - **channel** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)"))

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

Returns:
:   *tuple[float, float]* – `(low, high)` in samples per second.

Raises:
:   [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError "(in Python v3.15)") – If the driver does not support reporting a sample rate range.
