Expand description
Pure-Rust port of librtlsdr — RTL2832U USB control + tuner drivers.
Talks to RTL-SDR dongles directly over USB via rusb, without the
C librtlsdr library or its headers. Covers all five tuner families
shipped in real-world dongles (R820T / R820T2 / R828D, E4000,
FC0012, FC0013, FC2580).
§Quick start
use librtlsdr_rs::{RtlSdrDevice, RtlSdrError};
// Open the first dongle plugged in.
let mut dev = RtlSdrDevice::open(0)?;
// Tune to 100 MHz, 2.048 Msps.
dev.set_center_freq(100_000_000)?;
dev.set_sample_rate(2_048_000)?;
// Manual gain at 14.4 dB (`144` in tenths-of-dB happens to be
// an exact step on the R820T2 gain table). For arbitrary user
// input, snap to the nearest step via [`RtlSdrDevice::closest_gain`]
// first — passing a value not in the tuner's table results in
// the tuner silently rounding (or, on the E4000, returning an
// `InvalidGain` error).
dev.set_tuner_gain_mode(true)?;
dev.set_tuner_gain(144)?;
// Read 64 KB of interleaved I/Q samples.
dev.reset_buffer()?;
let mut buf = vec![0u8; 65_536];
let n = dev.read_sync(&mut buf)?;
assert!(n > 0);§Public surface
The committed surface is intentionally narrow:
RtlSdrDevice— the device handle. All control + streaming methods live here. Open viaRtlSdrDevice::open.- Free enumeration helpers —
get_device_count,get_device_name,get_device_usb_strings,get_index_by_serial. RtlSdrError— the unified error type returned by every fallible operation.TunerType— the IC family identifier returned byRtlSdrDevice::tuner_type.
Sample values are interleaved unsigned 8-bit I/Q pairs, the native
RTL-SDR format. Convert to centred i8 (or f32 in [-1, 1]) at
the consumer if needed; we don’t impose a sample type on the read
path.
§USB context + threading
RtlSdrDevice holds an Arc<rusb::DeviceHandle> internally so
the device handle can be cloned across threads — rusb::DeviceHandle
is Sync, which makes the type shareable between threads. The
control methods on RtlSdrDevice take &mut self and serialise
on the caller; that’s the supported single-thread pattern.
For raw bulk reads on a worker thread (e.g. an rtl_tcp-style
server), call RtlSdrDevice::usb_handle to clone the underlying
handle and use RtlSdrDevice::BULK_ENDPOINT for the endpoint
address. Note that Sync alone does not guarantee that
concurrent bulk and control transfers on the same handle are
safe — rusb’s docs don’t make that claim explicitly, and
libusb’s caveats restrict per-resource concurrent access. If you
mix concurrent bulk and control on one handle, treat it as an
unsupported design assumption you’ve verified against your
libusb version + dongle hardware. The safer pattern is to
quiesce control calls (or do them all from one thread) while a
bulk-read worker is in flight.
§Faithful-port note
The crate is a port of the C librtlsdr source — register
addresses, magic constants, and per-tuner I2C tables are
transcribed directly from the upstream code. Some internal items
aren’t currently called from Rust but are kept for completeness so
future hardware-feature work is a register-table read away rather
than a re-port. Hardware register manipulation requires extensive
integer casts inherent in a faithful port of C driver code.
Re-exports§
pub use device::DeviceInfo;pub use device::ReaderIter;pub use device::RtlSdrDevice;pub use device::RtlSdrDeviceBuilder;pub use device::RtlSdrReader;pub use device::SampleIter;pub use device::get_device_count;pub use device::get_device_name;pub use device::get_device_usb_strings;pub use device::get_index_by_serial;pub use device::list_devices;pub use error::RtlSdrError;pub use error::TunerError;pub use rusb;