RtlSdrManager 0.5.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package RtlSdrManager --version 0.5.2
                    
NuGet\Install-Package RtlSdrManager -Version 0.5.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RtlSdrManager" Version="0.5.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RtlSdrManager" Version="0.5.2" />
                    
Directory.Packages.props
<PackageReference Include="RtlSdrManager" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RtlSdrManager --version 0.5.2
                    
#r "nuget: RtlSdrManager, 0.5.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RtlSdrManager@0.5.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RtlSdrManager&version=0.5.2
                    
Install as a Cake Addin
#tool nuget:?package=RtlSdrManager&version=0.5.2
                    
Install as a Cake Tool

RTL-SDR Manager Library for .NET

NuGet Version NuGet Downloads License .NET Version

A modern, high-performance .NET library for managing RTL-SDR devices with support for async operations, multiple tuner types, and advanced features like KerberosSDR.

✨ Features

  • 🚀 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 - Suppress or capture native library diagnostic messages

📦 Installation

Via NuGet Package Manager

# .NET CLI
dotnet add package RtlSdrManager

# Package Manager Console (Visual Studio)
Install-Package RtlSdrManager

# PackageReference (in .csproj)
<PackageReference Include="RtlSdrManager" Version="0.5.2" />

Prerequisites

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/releases

Linux (Ubuntu/Debian):

sudo apt-get install librtlsdr-dev

macOS:

brew install librtlsdr

🚀 Quick Start

Basic Usage

using 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");

Console Output Suppression

By default, the library suppresses all console output from librtlsdr (like "Found Rafael Micro R820T tuner" and "[R82XX] PLL not locked!") by redirecting native stdout/stderr file descriptors to /dev/null (Unix/macOS) or NUL (Windows). You can control this behavior globally:

// Disable suppression globally (default is true)
RtlSdrDeviceManager.SuppressLibraryConsoleOutput = false;

// Open a device - will now show librtlsdr messages
manager.OpenManagedDevice(0, "my-rtl-sdr");
var device = manager["my-rtl-sdr"];
device.SampleRate = Frequency.FromMHz(2);  // Will show librtlsdr output

// Re-enable suppression globally
RtlSdrDeviceManager.SuppressLibraryConsoleOutput = true;
device.SampleRate = Frequency.FromMHz(2.4);  // Silent

Note: The suppression uses a global singleton pattern (v0.5.1+) to prevent file descriptor corruption when multiple devices are opened simultaneously. Changes to the suppression setting apply immediately to all devices.

Synchronous Sample Reading

// 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}");
}

Asynchronous Sample Reading

// 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");

Manual Gain Control

// 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();

Frequency Operations

// 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");
}

Advanced Features

Bias Tee (for powering external LNAs)
// Enable bias tee on GPIO 0 (most common)
device.SetBiasTee(BiasTeeModes.Enabled);

// For R820T tuners, specify GPIO pin
device.SetBiasTeeGPIO(gpio: 0, BiasTeeModes.Enabled);
Direct Sampling (HF reception)
// 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;
Frequency Correction (PPM)
// Set frequency correction in PPM
device.FrequencyCorrection = 10; // +10 PPM
KerberosSDR Support
// 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);

📚 Documentation

For more detailed information and advanced usage scenarios:

Sample Applications

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

🔧 Building from Source

Requirements

  • .NET 9.0 SDK or later
  • librtlsdr native library

Build Commands

# 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.sh

Build Output

The build process creates:

  • NuGet packagesartifacts/packages/
  • Library binariesartifacts/binaries/RtlSdrManager/
  • Sample binariesartifacts/binaries/Samples/

Running Samples

# Using the convenience script
./runsample.sh

# Or manually
dotnet run --project samples/RtlSdrManager.Samples

🏗️ Architecture

RtlSdrManager/
├── 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

🤝 Contributing

Contributions are welcome! Please feel free to submit issues, fork the repository, and create pull requests.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. 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)

📋 System Requirements

  • .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

📝 Supported Devices

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

📜 License

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.

🙏 Acknowledgments

📊 Project Status

  • 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

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.5.3 84 3/7/2026
0.5.2 141 1/17/2026
0.5.1 267 11/27/2025 0.5.1 is deprecated because it is no longer maintained.
0.5.0 249 10/23/2025 0.5.0 is deprecated because it is no longer maintained.

v0.5.2 (2026-01-17):

           FIXES:
           - Fixed permanent stdout redirection that broke console applications (Spectre.Console, etc.)
           - Console output suppression now uses scoped suppression with reference counting
           - Suppression only active during device operations, stdout restored between operations
           - Default changed to SuppressLibraryConsoleOutput = false (show librtlsdr messages)
           - Preserves file descriptor corruption fix from v0.5.1 (global singleton with reference counting)

           BREAKING CHANGES:
           - Default behavior changed: librtlsdr messages now shown by default
           - Applications can set RtlSdrDeviceManager.SuppressLibraryConsoleOutput = true to suppress

           See CHANGELOG.md for complete details and upgrade guide.