A modern, high-performance .NET library for managing RTL-SDR devices with support for async operations, multiple tuner types, and advanced features like KerberosSDR.
- π Async/Await Support - Non-blocking sample reading with concurrent queue buffering
- ποΈ Multiple Tuner Support - E4000, R820T/R828D, FC0012, FC0013, FC2580
- π§ Advanced Configuration - Gain control, frequency correction, direct sampling, bias tee
- π‘ KerberosSDR Ready - Frequency dithering and GPIO control for coherent SDR arrays
- π Type-Safe API - Strongly-typed frequency values with unit conversions
- πΎ Cross-Platform - Works on Windows, Linux, and macOS
- β‘ High Performance - LibraryImport P/Invoke for optimal native interop
- π‘οΈ Production Ready - Proper exception handling, disposal patterns, and null safety
- π Console Output Control - Scoped suppression of native library diagnostic messages
# .NET CLI
dotnet add package RtlSdrManager
# Package Manager Console (Visual Studio)
Install-Package RtlSdrManager
# PackageReference (in .csproj)
<PackageReference Include="RtlSdrManager" Version="0.5.2" />You must have the librtlsdr native library installed on your system:
Windows:
# Using Chocolatey
choco install rtl-sdr
# Or download from: https://github.com/osmocom/rtl-sdr/releasesLinux (Ubuntu/Debian):
sudo apt-get install librtlsdr-devmacOS:
brew install librtlsdrusing RtlSdrManager;
using RtlSdrManager.Modes;
// Get the singleton device manager
var manager = RtlSdrDeviceManager.Instance;
// Check available devices
Console.WriteLine($"Found {manager.CountDevices} RTL-SDR device(s)");
// Open the first device with a friendly name
manager.OpenManagedDevice(0, "my-rtl-sdr");
// Configure the device
var device = manager["my-rtl-sdr"];
device.CenterFrequency = Frequency.FromMHz(1090); // ADS-B frequency
device.SampleRate = Frequency.FromMHz(2);
device.TunerGainMode = TunerGainModes.AGC;
device.AGCMode = AGCModes.Enabled;
device.ResetDeviceBuffer();
Console.WriteLine($"Tuner: {device.TunerType}");
Console.WriteLine($"Center Frequency: {device.CenterFrequency.MHz} MHz");By default, the library shows diagnostic messages from librtlsdr (like "Found Rafael Micro R820T tuner" and "[R82XX] PLL not locked!"). You can suppress these messages globally:
// Enable suppression globally (default is false - messages shown)
RtlSdrDeviceManager.SuppressLibraryConsoleOutput = true;
// Open a device - suppressed only during operation
manager.OpenManagedDevice(0, "my-rtl-sdr"); // librtlsdr messages hidden
var device = manager["my-rtl-sdr"];
device.SampleRate = Frequency.FromMHz(2.4); // librtlsdr messages hidden
// Disable suppression - show messages again
RtlSdrDeviceManager.SuppressLibraryConsoleOutput = false;
device.CenterFrequency = Frequency.FromMHz(1090); // Will show librtlsdr outputNote: Suppression uses scoped suppression (v0.5.2+) with reference-counted global singleton pattern:
- Stdout/stderr redirected to
/dev/null(Unix/macOS) orNUL(Windows) only during device operations - Console restored between operations, allowing console applications (Spectre.Console, etc.) to work properly
- Prevents file descriptor corruption when multiple devices are opened simultaneously
// Read samples synchronously (blocking)
var samples = device.ReadSamples(256 * 1024);
foreach (var sample in samples)
{
// Process I/Q samples
Console.WriteLine($"I: {sample.I}, Q: {sample.Q}");
}// Configure async buffer
device.MaxAsyncBufferSize = 512 * 1024;
device.DropSamplesOnFullBuffer = true;
// Start async reading in background
device.StartReadSamplesAsync();
// Option 1: Event-based (recommended for real-time processing)
device.SamplesAvailable += (sender, args) =>
{
var samples = device.GetSamplesFromAsyncBuffer(args.SampleCount);
// Process samples in real-time
};
// Option 2: Manual polling (for custom processing logic)
while (running)
{
if (device.AsyncBuffer.TryDequeue(out var data))
{
// Process data
Console.WriteLine($"Received {data.Samples.Length} samples");
}
else
{
await Task.Delay(100);
}
}
// Stop reading when done
device.StopReadSamplesAsync();
// Clean up
manager.CloseManagedDevice("my-rtl-sdr");// Switch to manual gain mode
device.TunerGainMode = TunerGainModes.Manual;
// Get supported gain values
var gains = device.SupportedTunerGains;
Console.WriteLine($"Supported gains: {string.Join(", ", gains)} dB");
// Set specific gain
device.TunerGain = 42.1; // dB
// Or use convenience methods
device.SetMaximumTunerGain();
device.SetMinimumTunerGain();// Create frequencies with different units
var freq1 = Frequency.FromHz(1090_000_000);
var freq2 = Frequency.FromKHz(1090_000);
var freq3 = Frequency.FromMHz(1090);
var freq4 = Frequency.FromGHz(1.09);
// Convert between units
Console.WriteLine($"{freq1.Hz} Hz");
Console.WriteLine($"{freq1.KHz} KHz");
Console.WriteLine($"{freq1.MHz} MHz");
Console.WriteLine($"{freq1.GHz} GHz");
// Arithmetic operations
var shifted = freq1 + Frequency.FromKHz(100); // Add 100 KHz offset
var doubled = freq1 * 2;
// Comparison
if (freq1 > Frequency.FromMHz(100))
{
Console.WriteLine("Above 100 MHz");
}// Enable bias tee on GPIO 0 (most common)
device.SetBiasTee(BiasTeeModes.Enabled);
// For R820T tuners, specify GPIO pin
device.SetBiasTeeGPIO(gpio: 0, BiasTeeModes.Enabled);// Enable direct sampling on I-ADC
device.DirectSamplingMode = DirectSamplingModes.I_ADC;
// Or on Q-ADC
device.DirectSamplingMode = DirectSamplingModes.Q_ADC;
// Disable
device.DirectSamplingMode = DirectSamplingModes.Disabled;// Set frequency correction in PPM
device.FrequencyCorrection = 10; // +10 PPM// Enable KerberosSDR mode (required for these features)
device.KerberosSDRMode = KerberosSDRModes.Enabled;
// Enable frequency dithering (for R820T only)
device.FrequencyDitheringMode = FrequencyDitheringModes.Enabled;
// Control GPIO pins directly
device.SetGPIO(gpio: 1, GPIOModes.Enabled);For more detailed information and advanced usage scenarios:
- Basic Setup - Getting started with device initialization
- Device Management - Managing multiple RTL-SDR devices
- Manual Gain Control - Configuring tuner gain settings
- Direct Sampling - Using direct sampling modes for HF
- Frequency Correction - PPM frequency correction
- Bias Tee - Enabling bias tee for powering external LNAs
- KerberosSDR - Advanced features for KerberosSDR arrays
Check out the samples/ directory for complete working examples:
- Demo1 - Event-based async sample reading
- Demo2 - Manual polling from async buffer
- Demo3 - Synchronous sample reading
- Demo4 - Device information and configuration
- .NET 9.0 SDK or later
- librtlsdr native library
# Clone the repository
git clone https://github.com/nandortoth/rtlsdr-manager.git
cd rtlsdr-manager
# Build the entire solution
dotnet build
# Run tests (if available)
dotnet test
# Create NuGet packages
dotnet pack --configuration Release
# Or use the convenience script
./build.shThe build process creates:
- NuGet packages β
artifacts/packages/ - Library binaries β
artifacts/binaries/RtlSdrManager/ - Sample binaries β
artifacts/binaries/Samples/
# Using the convenience script
./runsample.sh
# Or manually
dotnet run --project samples/RtlSdrManager.SamplesRtlSdrManager/
βββ src/
β βββ RtlSdrManager/ # Main library
β βββ Exceptions/ # Custom exception types
β βββ Hardware/ # Hardware type definitions
β βββ Interop/ # P/Invoke wrappers
β βββ Modes/ # Enumeration types
βββ samples/
β βββ RtlSdrManager.Samples/ # Example applications
βββ docs/ # Documentation
Contributions are welcome! Please feel free to submit issues, fork the repository, and create pull requests.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure your code:
- Follows the EditorConfig style guidelines
- Builds without warnings
- Includes XML documentation for public APIs
- Includes unit tests for new features (when applicable)
- .NET Runtime: 9.0 or later
- Operating System: Windows, Linux, macOS
- Hardware: RTL-SDR compatible device (RTL2832U-based)
- Native Library: librtlsdr installed on the system
This library supports RTL-SDR devices with the following tuners:
| Tuner | Frequency Range | Notes |
|---|---|---|
| Elonics E4000 | 52-1100 MHz, 1250-2200 MHz | No longer manufactured |
| Rafael Micro R820T | 24-1766 MHz | Most common, excellent performance |
| Rafael Micro R828D | 24-1766 MHz | Similar to R820T |
| Fitipower FC0012 | 22-948.6 MHz | Basic performance |
| Fitipower FC0013 | 22-1100 MHz | Basic performance |
| FCI FC2580 | 146-308 MHz, 438-924 MHz | Good performance |
This project is licensed under the GNU General Public License v3.0 or later - see the LICENSE.md file for details.
RTL-SDR Manager Library for .NET
Copyright (C) 2018-2025 Nandor Toth
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
- NuGet Package: https://www.nuget.org/packages/RtlSdrManager/
- GitHub Repository: https://github.com/nandortoth/rtlsdr-manager
- Issue Tracker: https://github.com/nandortoth/rtlsdr-manager/issues
- Changelog: CHANGELOG.md
- librtlsdr: https://github.com/osmocom/rtl-sdr
- Osmocom rtl-sdr project for the excellent native library
- KerberosSDR project for coherent SDR extensions
- All contributors and users of this library
- β Stable - Production ready
- β Actively Maintained - Regular updates and bug fixes
- β .NET 9.0 - Modern .NET with latest features
- β Cross-Platform - Windows, Linux, macOS support
Made with β€οΈ by Nandor Toth