jasonherald/rtl-sdr

GitHub: jasonherald/rtl-sdr

用 Rust 编写的跨平台软件无线电接收应用,提供 Linux GTK4 和 macOS SwiftUI 双原生界面,内置本地语音转录和频率扫描功能。

Stars: 0 | Forks: 0

# SDR-RS 使用 Rust 编写的软件无线电应用—— [SDR++](https://github.com/AlexandreRouma/SDRPlusPlus) 的移植版,提供两种原生 UI:**Linux 上的 GTK4 / libadwaita** 和 **macOS 26+ 上的 SwiftUI**。两个前端共享一个用 Rust 编写的无头引擎;macOS 应用通过手工编写的 C ABI (`sdr-ffi`) 和一个 Swift 包 (`SdrCoreKit`) 来驱动它。 ![SDR-RS](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/98497cad95074413.png) ## 功能 ### 电台 - 8 种解调模式:WFM、NFM、AM、DSB、USB、LSB、CW、RAW - RTL-SDR 硬件支持 — 通过 `rusb` (libusb 包装器) 实现的 `librtlsdr` 纯 Rust 移植版(支持全部 5 个调谐器系列) - TCP/UDP 网络 IQ 信号源与接收器 - 支持循环播放的 WAV 文件 IQ 回放 - 音频陷波滤波器 (双二阶 IIR,20-20,000 Hz) - 带噪声底跟踪的自动静噪 - CTCSS 音调静噪 — 51 个标准亚音级别 (67.0–254.1 Hz),使用 Goertzel 滤波器检测并带有邻频抑制门控和持续命中防抖;支持每个书签独立选择音调和调整阈值 - 语音活动静噪 — 包络音节检测器 (2–10 Hz 语音节奏) 和 SNR 比率检测器 (语音频段与带外功率),与 CTCSS 和功率静噪一起控制扬声器通路 - 带有完整状态捕获/恢复的书签调谐配置文件 (包括每个信道的 CTCSS + 语音静噪) - **扫描器** — 经典的顺序扫描器 (启用扫描的书签、优先信道、可配置的驻留/挂起时间、会话锁定、空轮转恢复)。与录音和转录互斥,因此同一时间只有一个处于活动状态。F8 键切换主开关。手动调谐 / 书签调用 / 解调模式更改会自动停止扫描器。 ### 网络 - **rtl_tcp 服务器** — 通过 TCP 将本地 RTL-SDR 流传输到局域网内的其他机器。单客户端模型 (一次只允许一个用户;第二次连接会被 FIN 拒绝)。通过 mDNS 发布 `_rtl_tcp._tcp.local.` 广播,这样客户端无需输入 `host:port` 即可发现您。兼容 GQRX / SDR++ / 任何 rtl_tcp 客户端。 - **rtl_tcp 客户端** — 连接到远程 rtl_tcp 服务器 (本软件,或标准的 `rtl_tcp`、SpyServer TCP 等)。实时 mDNS 浏览器列出局域网内的服务器;收藏常用项以便一键重连,并在收藏菜单中显示上次连接的元数据 (调谐器、增益)。在瞬态网络中断时自动重连。 - **可选的 LZ4 流压缩** — 在两个 sdr-rs 对等端之间,rtl_tcp 服务器和客户端通过向后兼容的 `RTLX` 握手协商数据流的 LZ4 压缩。与所有普通客户端保持线缆级兼容 (默认关闭;可在“通过网络共享”面板中按服务器启用)。适用于 Wi-Fi / 酒店 / 拥塞链接,在这些环境中未压缩的 2.4 Msps 会使链路饱和;mDNS 会广播 `codecs=`,以便支持压缩的客户端知道何时发送扩展问候。 ### 显示 - Cairo 渲染的 FFT 频谱图和滚动瀑布图 - 带有智能 Hz/kHz/MHz/GHz 标签的频率轴 - 频谱缩放 (滚动缩放,限制在 FFT 带宽内) - 带有拖动调谐和带宽手柄的 VFO 叠加层 - 当带宽或偏移量偏离默认值时显示浮动的“重置 VFO”按钮;微调框上带有逐字段带宽重置图标,用于单维度撤销 - 可配置的 FFT 大小、窗函数、色彩映射表和 dB 范围 ### 录音 - 音频 WAV 录音 (48 kHz 立体声,IEEE float 32-bit) - IQ WAV 录音 (预抽取的原始采样) - 瀑布图 PNG 导出,带有桌面通知和点击打开功能 ### 转录 在构建时选择以下两个互斥的后端之一(见下文安装部分): **Whisper 后端** — 通过 `whisper-rs` 实现的 OpenAI Whisper,支持多语言,GPU 支持成熟 - 6 种模型大小:tiny (75 MB)、base (142 MB)、small (466 MB)、medium (1.5 GB)、large-v3 (3.1 GB) 以及 **large-v3-turbo** (1.6 GB,比 large-v3 快约 8 倍,英语准确率几乎相当) - 可选 GPU 加速:CUDA (NVIDIA)、ROCm/HIP (AMD)、Vulkan、Metal - RMS 门控分块推理,带有可配置的静音阈值 **Sherpa-onnx 后端** — k2-fsa 的 sherpa-onnx,仅支持英语 (目前),支持流式和离线模式 - **流式 Zipformer** — 真正的实时转录,支持逐字实时字幕 - **Moonshine Tiny / Base** — UsefulSensors 的边缘优化离线模型 (27M / 61M 参数) - **Parakeet-TDT 0.6b v3** — NVIDIA 出品,OpenASR 排行榜第一名 (600M 参数,准确率最高) - **运行时模型切换** — 无需重启应用即可从下拉菜单更改模型 - **带显示模式切换的实时字幕** — 流式模型在提交日志下方呈现一行原位斜体文本;用户可以切换至“仅最终结果”模式 - **Silero VAD** — 离线模型使用 Silero 语音活动检测,并带有针对嘈杂 RF 音频 (NFM/扫描器) 的用户可调阈值滑块 - **自动断句分段** — 在 NFM 信道上使用离线转录模型时,自动断句会在静噪闭合边缘对长录音进行分段,使得每次传输成为独立的转录提交,而不是一大段文本。当两个条件同时满足时,开关会自动出现。 - 首次使用时自动下载模型和 VAD,并附带捆绑的进度启动画面 **两个后端共有:** - 带有时间戳提交日志的滑出式转录面板 - 基于 FFT 的频谱噪声门预处理器,用于更清晰的识别 - 独立于音量的音频分接头 (转录不受音量旋钮影响) - 活跃会话期间锁定设置,以防止会话中途的配置冲突 **Apple SpeechAnalyzer 后端 (仅限 macOS 应用)** — 设备端、Neural-Engine 加速、随操作系统附带 - 使用 Apple 的 `SpeechAnalyzer` + `SpeechTranscriber` 框架 (WWDC 2025, macOS 26+) - 零二进制膨胀 — 除了操作系统在首次使用时获取的少量区域设置资产外,无需下载模型 - 右侧转录面板中的实时部分 + 最终结果 - 隐私保护:设备端推理,无网络路径 - 独立于 Linux 上的 Whisper / Sherpa 技术栈 — 它们仍然是 Linux 的转录路径 ### 集成 - [RadioReference.com](https://www.radioreference.com) 频率数据库浏览器 — 按 ZIP 编码搜索,按类别/机构浏览,作为书签导入 (需要 RadioReference 高级账户) - 通过 OS 密钥环 (GNOME Keyring / macOS Keychain) 进行安全的凭证存储 - 带有目录设置和账户管理的偏好设置窗口 - PipeWire 音频输出 (Linux),CoreAudio 输出 (macOS — 在设置中选择设备) - 带有点击打开功能的桌面通知 (GNotification) ### 底层实现 - 22 个成员的工作区 (根二进制文件 + 21 个库 crate),具有清晰的依赖边界 - 纯 DSP 函数 (无多线程、无 I/O、无副作用) - 热路径上每帧零堆分配 - DSP 线程和音频线程之间基于锁的 SPSC 音频环形缓冲区 - 用于 glibc 内存区管理的 `mallopt(M_ARENA_MAX)` + 定期的 `malloc_trim` - 带有自动保存的基于 JSON 的配置 ## 构建 ### 依赖项 **始终需要:** - **Rust** — 通过 [`rust-toolchain.toml`](rust-toolchain.toml) 固定到稳定的 1.95.0 版本;在首次调用 `cargo` 时,`rustup` 会自动识别。工作区使用 2024 版本。 - **GTK 4.10+** 和 **libadwaita 1.5+** - **PipeWire** 开发库 (Linux 音频) - **libusb** (用于 RTL-SDR USB 访问) - **libdbus** (用于安全凭证存储) **仅 Whisper 后端需要** (构建 Sherpa 时不需要): - **cmake** + **C++ 编译器** (构建时,用于 whisper.cpp) - **libclang** (构建时,用于 bindgen) #### Arch Linux ``` sudo pacman -S gtk4 libadwaita pipewire libusb dbus # Whisper 构建还需要: sudo pacman -S clang cmake ``` #### Ubuntu / Debian ``` sudo apt install libgtk-4-dev libadwaita-1-dev libpipewire-0.3-dev \ libusb-1.0-0-dev libdbus-1-dev # Whisper 构建还需要: sudo apt install libclang-dev cmake g++ ``` #### macOS (在 macOS 上进行 Linux-GTK 构建 — 而非原生 Mac 应用) ``` brew install gtk4 libadwaita libusb # Whisper 构建还需要: brew install llvm cmake ``` 对于**原生 SwiftUI macOS 应用** (在 Mac 上推荐),跳过 GTK 安装,直接跳转到下文的 [`macOS 原生应用`](#macos-native-app) ——它根本不使用 GTK。 ### 编译 ``` cargo build --release ``` ### 安装 ``` make install ``` 安装二进制文件、桌面入口和图标,以便集成到应用启动器中。 ### macOS 原生应用 SwiftUI Mac 应用位于 [`apps/macos/SDRMac`](apps/macos/SDRMac)。它是一个独立的前端,通过位于 [`include/sdr_core.h`](include/sdr_core.h) 的手工编写的 C ABI 和 [`SdrCoreKit`](apps/macos/Packages/SdrCoreKit) Swift 包驱动与 Linux GTK 构建相同的 Rust 引擎。 **系统要求:** macOS 26+ (Tahoe),Xcode 26+。Mac 应用不使用 GTK — 无需执行 `brew install gtk4`。 **构建 + 运行 (release 版,推荐用于实时 RTL-SDR — debug 构建无法跟上 macOS 上的 2 MSps 处理):** ``` make mac-app # cargo --release + xcodebuild Release + .app bundle at apps/macos/build/ open apps/macos/build/sdr-rs.app ``` **Debug / 开发构建:** ``` make mac-app-debug ``` **Swift 端单元测试:** ``` make swift-test ``` **Mac 应用目前已包含的功能:** - RTL-SDR 信号源 (原生 libusb 驱动) — 以及网络 IQ 和 WAV 文件回放 - 全部八种解调模式 (WFM, NFM, AM, DSB, USB, LSB, CW, RAW) - Metal 加速的频谱 + 瀑布图渲染器 - 带有设置中设备选择器的 CoreAudio 输出 (Cmd-,) - 音频 + IQ WAV 录音 - RadioReference 浏览器 (工具栏按钮 → 模态窗口,与 Linux 构建使用相同的凭证钥匙串) - 书签 - **通过 Apple SpeechAnalyzer 进行转录** (右侧滑出面板) — 使用 macOS 内置的设备端语音框架。无需 Whisper/Sherpa 构建机制和第三方模型;macOS 可能会在首次使用时获取少量区域设置资产 (这由面板透明处理,在此期间会显示“正在下载模型…”状态行) - 高级解调控制 (噪声抑制器、FM 中频降噪、WFM 立体声、音频陷波) - 高级信号源控制 (DC 阻塞、IQ 反转、IQ 校正、抽取) - 带有噪声底跟踪的自动静噪 **Mac 应用目前尚未包含的功能:** - CTCSS / 语音活动静噪控制 (引擎已支持;SwiftUI 尚未接入) - 启动画面 (Linux 构建有;Mac 应用直接启动到主窗口) - Sparkle 自动更新 (issue #248) ### 转录后端 (选择其一) Whisper 和 Sherpa-onnx 是互斥的 cargo 特性 — 您在构建时只能选择一个后端。默认是 `whisper-cpu`。**Whisper** GPU 构建需要在构建主机上安装相应的工具包 (CUDA、ROCm、Vulkan SDK),因为 `whisper-rs` 会在构建时编译自己的内核。**Sherpa-cuda** 则不同:`make install` 会自动将所需的 CUDA 12 / cuDNN 9 运行时库侧载到 `~/.cargo/bin/sdr-rs-libs/` 中,并且仅要求主机上存在 NVIDIA 内核驱动 — 请参阅下面的 Sherpa CUDA 说明。 ``` # Whisper 后端(默认)— 多语言,成熟的 GPU 加速 make install CARGO_FLAGS="--release" # Whisper CPU (default) make install CARGO_FLAGS="--release --features whisper-cuda" # NVIDIA GPU make install CARGO_FLAGS="--release --features whisper-hipblas" # AMD ROCm make install CARGO_FLAGS="--release --features whisper-vulkan" # Cross-vendor GPU # Sherpa-onnx 后端 — Zipformer / Moonshine / Parakeet,仅限英语 make install CARGO_FLAGS="--release --no-default-features --features sherpa-cpu" # Sherpa CPU make install CARGO_FLAGS="--release --no-default-features --features sherpa-cuda" # Sherpa + NVIDIA GPU ``` 对于 Sherpa 构建,您可以在运行时从转录面板下拉菜单中选择特定的模型 (Zipformer、Moonshine Tiny/Base 或 Parakeet) — 无需重新构建,切换是位识别器替换。 **Sherpa CUDA 说明:** - `sherpa-cuda` 目前仅支持 linux-x86_64。它针对 k2-fsa sherpa-onnx 预构建版本进行构建,该版本硬性关联到内部针对 CUDA 12.x + cuDNN 9.x 编译的 onnxruntime 1.23.2 构建。CUDA 主要版本之间不兼容 ABI,因此运行 CUDA 13 的主机 (例如当前的 Arch Linux) 无法使用其系统库。 - **您无需在系统上安装 CUDA 12 或 cuDNN 9。** 带有 `sherpa-cuda` 特性的 `make install` 会自动从 NVIDIA 的开发者 redist 服务器下载最少的 NVIDIA CUDA 12 运行时库 (cudart、cublas、cufft、curand、cudnn),并将它们与二进制文件打包在一起。您的系统 CUDA 安装 (如果有的话) 将保持不变。 - **首次构建成本:** 约 1.83 GB 下载量,解压后约 1.2 GB。下载缓存在 `$HOME/.cache/sdr-rs/cuda-redist/` 中 (在执行 `cargo clean` 后依然保留);重新安装是即时的。此外,还需要从 `target/sherpa-onnx-prebuilt/` 下载 k2-fsa 提供的一次性约 235 MB 的 sherpa-onnx CUDA 预构建版本。 - **安装布局:** 二进制文件位于 `~/.cargo/bin/sdr-rs`;运行时库位于相邻的 `~/.cargo/bin/sdr-rs-libs/` 子目录中,因此不会弄乱 `$BINDIR`。二进制文件的 ELF `DT_RPATH` 会自动解析它们。不会在系统范围内安装任何内容。 - 您仍然需要安装可用的 NVIDIA 驱动 (Arch 上的 `nvidia` / `nvidia-utils`) — 用户空间驱动库 `libcuda.so.1` 来自内核驱动包,无法重新分发,并且它必须与您安装的 GPU 硬件匹配。 - 在 PR 稳定期间,sherpa-onnx crate 是从 [jasonherald/sherpa-onnx](https://github.com/jasonherald/sherpa-onnx) 分支 (分支 `feat/rust-sys-cuda-support`) 拉取的,该分支为上游 sys crate 增加了 `cuda` cargo 特性。计划向 k2-fsa 提交上游 PR;一旦合并并发布版本,分支依赖将被替换回 crates.io 上的版本固定。 - **深入了解:** 请参阅 [`docs/cuda-sideload.md`](docs/cuda-sideload.md) 了解完整的基本原理、我们提取的确切 NVIDIA tarball 和版本、`DT_RPATH` 如何通过 `dlopen` 使侧载工作、磁盘成本明细,以及在上游赶上时的重新统一计划。可以使用 `make fetch-cuda-redist` 预填充下载缓存,而无需运行完整的安装。 ### 运行测试 ``` cargo test --workspace ``` ### 代码检查 ``` make lint ``` 运行 `cargo fmt --check`、`cargo clippy`、`cargo test`、`cargo deny` 和 `cargo audit`。 ## 使用方法 ``` sdr-rs ``` 1. 选择信号源 (RTL-SDR 设备、网络或文件) 2. 使用数字选择器设置中心频率 (滚动或点击数字) 3. 选择解调模式 (WFM、NFM、AM、USB、LSB 等) 4. 按下 **播放** ### 键盘快捷键 | 按键 | 操作 | |-----|--------| | 空格 | 播放 / 停止 | | M | 切换解调模式 | | F8 | 切换扫描器 | | F9 | 切换侧边栏 | | Ctrl+B | 切换书签弹出窗口 | | Ctrl+, | 偏好设置 | | Ctrl+/ | 键盘快捷键 | ## 架构 22 个成员的 Rust 工作区 (根二进制文件 + 21 个库 crate) 加上一个通过 C ABI 共享引擎的 macOS Xcode 项目: ``` sdr (binary) Linux entry point sdr-ui GTK4/libadwaita UI (Linux-only) sdr-core Headless engine facade — cross-platform (Linux GTK + macOS SwiftUI) sdr-ffi Hand-rolled C ABI over sdr-core (drives the macOS app) sdr-radio Radio decoder, demod, IF/AF chains sdr-pipeline Threading, streaming, signal path sdr-dsp Pure DSP: math, filters, FFT, demod, resampling sdr-types Foundation types, errors, constants sdr-config JSON config persistence + OS keyring access sdr-rtlsdr Rust port of librtlsdr (5 tuner families) over rusb sdr-radioreference RadioReference.com SOAP API client sdr-transcription Whisper / Sherpa-onnx backends + spectral denoiser + Silero VAD sdr-splash Cross-platform splash controller (subprocess driver) sdr-splash-gtk Linux GTK4 splash window implementation sdr-source-rtlsdr RTL-SDR source module sdr-source-network TCP/UDP IQ source (including rtl_tcp client) sdr-source-file WAV file playback source sdr-sink-audio PipeWire/CoreAudio audio output sdr-sink-network TCP/UDP audio output sdr-server-rtltcp rtl_tcp server — stream local dongle over TCP + CLI binary sdr-rtltcp-discovery mDNS _rtl_tcp._tcp.local. announce + browse sdr-scanner Classic sequential scanner state machine (pure, no I/O) apps/macos/ ├── SDRMac Native SwiftUI app (macOS 26+) ├── Packages/SdrCoreKit Swift wrapper over sdr-ffi's C ABI └── SDRMac.xcodeproj Xcode project ``` **信号链:** 信号源 → 抽取 → 信道滤波器 → 解调器 → 中频链 (静噪) → 音频链 → 音频输出 **转录分接:** 在解调器和音频滤波器之后、音量缩放之前分叉,因此识别器始终能看到全振幅的音频,无论扬声器端正在做什么。Linux 的 Whisper/Sherpa 路径获取 48 kHz 交错立体声;macOS 的 SpeechAnalyzer 路径从引擎内联下采样的独立分接点接收 16 kHz 单声道 f32 — 这是同一管道连接处的两个消费者。 DSP 函数是纯粹的 (无多线程、无 I/O)。多线程和流处理位于 `sdr-pipeline` 中。 **macOS ↔ Rust 边界:** `sdr-ffi` crate 发出工作区中唯一的 `#[no_mangle] extern "C"` 符号;它公开了一个最小的、不透明的句柄 C API,记录在 [`include/sdr_core.h`](include/sdr_core.h) 中,并在每次构建时针对 cbindgen 的输出逐字节进行验证 (`make ffi-header-check`)。Mac 应用通过 `SdrCoreKit` 使用静态库 (`libsdr_ffi.a`),后者将 C 函数包装在惯用的 Swift (`AsyncStream`、`@Observable`、`async/await`) 中。ABI 版本由 major/minor 组成,并同时包含在 C 头文件和 Rust 代码中;编译时断言确保它们保持同步。 ## RadioReference 集成 SDR-RS 可以从 [RadioReference.com](https://www.radioreference.com) (美国最大的无线电通信参考源) 浏览和导入频率。 **设置:** 打开偏好设置 (Ctrl+,) > 账户 > 输入您的 RadioReference 凭证 > 测试并保存。API 访问需要[高级账户](https://www.radioreference.com/premium/)。 **使用方法:** 点击标题栏上的天线图标 > 输入美国 ZIP 编码 > 按类别和机构浏览频率 > 勾选您想要的频率 > 导入。频率将保存为书签,并自动映射解调模式和带宽。 您的凭证存储在您的系统密钥环 (GNOME Keyring / macOS Keychain) 中,仅发送至 RadioReference.com。 ## 负责任的使用 SDR-RS 是一个用于收听未加密无线电传输的个人收听工具。收听公共安全、业余和商业无线电在大多数司法管辖区都是合法的,但请负责任地使用: **以下行为是合法的:** - 出于个人兴趣、教育或业余无线电活动的目的收听未加密的无线电 - 做笔记供自己参考 - 使用转录功能在本地机器上将音频转换为文本 **以下行为是不妥的:** - 发布或共享截获的公共安全通信的文字记录 (美国《通信法》第 605 条禁止泄露或发布截获的通信) - 汇总或出售在无线电中听到的信息 - 使用从无线电监听中获得的信息来识别、跟踪、骚扰或伤害个人 - 解密加密的传输 - 收听蜂窝电话通信 (根据 ECPA 属于违法行为) **隐私注意事项:** 公共安全广播可能包含个人可识别信息 — 姓名、地址、车牌、电话号码。SDR-RS 将所有内容保留在本地: - 转录文本仅存在于内存中,并在应用关闭时清除 - 不会向任何地方上传数据 - 所有转录均在设备端运行 — Linux 上使用 Whisper 或 Sherpa-onnx,macOS 上使用 Apple 的 Speech 框架 - 音频录音仅在您明确启用时才会保存到本地 如果您在共享空间中使用 SDR-RS,请注意其他人可能会看到您屏幕上的转录文本。未来版本可能会添加 PII 模式的自动标记和“锁定转录”模式 (参见 [#219](https://github.com/jasonherald/rtl-sdr/issues/219)、[#220](https://github.com/jasonherald/rtl-sdr/issues/220)、[#221](https://github.com/jasonherald/rtl-sdr/issues/221))。 **了解您当地的法律:** 扫描器法律因司法管辖区而异。美国一些州限制在车辆中使用扫描器。一些国家完全禁止收听某些频率。您有责任了解并遵守您居住地的法律。 ## 安全 有关漏洞报告和安全扫描的详细信息,请参阅 [SECURITY.md](SECURITY.md)。 ## 许可证 MIT ## 致谢 - [SDR++](https://github.com/AlexandreRouma/SDRPlusPlus) 作者 Alexandre Rouma -- 本项目移植的原始 C++ 应用程序 - [RTL-SDR](https://osmocom.org/projects/rtl-sdr/wiki) -- 用于 RTL2832U 设备的原始 C 库
标签:CTCSS, FM/AM/SSB, GTK4, IQ数据流, libadwaita, RTL-SDR, rtl_tcp, Rust, SDR, SDR++, SwiftUI, 信号扫描器, 信噪比, 内核驱动, 可视化界面, 射频, 嵌入式开发, 开源, 无线电监听, 无线电通信, 硬件驱动, 网络协议, 网络流量审计, 解调, 语音转文字, 转录, 软件定义无线电, 通知系统, 音频处理, 频谱分析