[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80508":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":13,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":15,"stars30d":16,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":17,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":14,"starSnapshotCount":14,"syncStatus":15,"lastSyncTime":25,"discoverSource":26},80508,"sdrrat","qewer33\u002Fsdrrat","qewer33","discover the RF spectrum from your terminal",null,"Rust",90,3,1,0,2,7,40.51,false,"main",true,[],"2026-06-12 04:01:28","![banner](.\u002Fassets\u002Fsdrrat_banner.png)\n\n**sdrrat** is a general purpose SDR (Software Defined Radio) receiver TUI (Terminal User Interface) application that interfaces with your SDR hardware and allows you to view the RF spectrum and demodulate signals from your terminal. It's built with Rust, [Ratatui](https:\u002F\u002Fratatui.rs) and [FutureSDR](https:\u002F\u002Fwww.futuresdr.org\u002F).\n\n> [!WARNING]\n> sdrrat is currently **not stable**, please open an issue for any bugs or crashes you encounter\n\n![screenshot](.\u002Fassets\u002Fscreenshot.png)\n## Features\n\n- **RTL-SDR** and **HackRF** support\n- **FFT spectrum** graph\n- **Waterfall spectrogram** graph\n- Source **sample rate** and **gain** control\n- **WBFM, NBFM**  and **AM** demodulation\n- Basic **squelch**\n- **Intuitive and easy to use** terminal user interface (TUI)\n\nWatch the showcase video below!\n\nhttps:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F874f4fe0-34fa-4c63-ad54-e0a77fab1622\n\nsdrrat has most of the basic features you can expect from an SDR receiver, though it's lacking most advanced features. You can request any missing features by opening an issue.\n\n## Installation\n\nInstall the published crate with Cargo:\n\n```bash\ncargo install sdrrat\n```\n\nRequirements:\n\n- `libSoapySDR` plus a driver module for your hardware on `PATH`. On Arch that's `soapysdr` together with `soapyrtlsdr` for RTL-SDR or `soapyhackrf` for HackRF. On Debian\u002FUbuntu the packages are `libsoapysdr0.8` and `soapysdr-module-rtlsdr` \u002F `soapysdr-module-hackrf`.\n- ALSA headers (`libasound2-dev` on Debian\u002FUbuntu) at build time for the audio sink.\n- The usual `pkg-config`, `cmake`, `libusb-1.0-dev` for the underlying RTL-SDR \u002F HackRF C libraries.\n\nRun `SoapySDRUtil --probe=\"driver=rtlsdr\"` (or `driver=hackrf`) to confirm SoapySDR can see your device before launching sdrrat.\n\nDevelopment requirements:\n\n- Rust toolchain with Cargo (edition 2024).\n\n## Key Bindings\n\n### Global\n\n| Key | Action |\n|-----|--------|\n| `q` | Quit (config saves on exit) |\n| `Space` | Start \u002F Stop the data stream |\n| `←` \u002F `→` | Nudge frequency by ±0.1 MHz |\n| `o` | Toggle the spectrum overlay (bandwidth shading + center line) |\n| `d` | Mute \u002F unmute audio (toggles between Off and the last active mode) |\n| `f` | Focus the **VFO** for digit-by-digit tuning |\n| `m` | Focus the **Min\u002FMax** dB-range stepper |\n| `s` | Open the **Source** popup (device, sample rate, gain) |\n| `r` | Open the **Radio** popup (demod mode, squelch) |\n| `h` | Open the in-app **Help** popup |\n\n### VFO mode (after `f`)\n\n| Key | Action |\n|-----|--------|\n| `←` \u002F `→` | Move cursor left\u002Fright by one digit |\n| `↑` \u002F `↓` | Increment \u002F decrement the focused digit (±10ⁿ) |\n| `z` | Zero out all digits to the right of the cursor |\n| `Enter` | Commit and exit |\n| `Esc` | Cancel, restore the frequency from when the popup opened |\n\n### Min\u002FMax mode (after `m`)\n\n| Key | Action |\n|-----|--------|\n| `Tab` | Switch focus between Min and Max |\n| `↑` \u002F `↓` | Adjust focused value by ±5 dB |\n| `Enter` | Commit and exit |\n| `Esc` | Cancel, restore prior bounds |\n\n### Popups\n\n| Key | Action |\n|-----|--------|\n| `Tab` \u002F `↑` \u002F `↓` | Move between fields |\n| `←` \u002F `→` | Cycle value |\n| `Enter` | Confirm |\n| `Esc` | Close |\n\n## Architecture\n\nThere are two threads doing work. The UI thread runs the ratatui draw loop and reads keypresses. The DSP thread owns the SDR hardware and runs all the signal processing. They talk through a couple of `crossbeam_channel`s: one carries FFT magnitude frames toward the UI, the other carries user commands (tune to this frequency, change sample rate, set squelch, etc.) toward the DSP. Neither side ever blocks on the other.\n\nThe DSP thread itself is mostly a thin shell around a [FutureSDR](https:\u002F\u002Ffuturesdr.org\u002F) flowgraph. FutureSDR handles the scheduling of all the actual blocks (the SDR source, the FFT, the FIR filters and resamplers, the audio sink) and we wire it together once at startup. A small command-pump task inside the runtime drains the command channel and forwards changes either to the source block's message ports (frequency, sample rate, gain, which it knows how to pass through to SoapySDR) or to a handful of shared atomics that the DSP blocks read every sample (squelch threshold, current demod mode, audio volume).\n\nA `Supervisor` struct in `main.rs` owns the DSP thread's lifecycle. When you press Space to stop, or change the device or sample rate and press Apply, the supervisor sets a per-thread quit flag, joins the DSP thread, and calls FutureSDR's `stop_and_wait` so every block gets to run its `deinit()` cleanly. The SDR streamer deactivates, the cpal audio stream releases, no orphaned threads. Then on the next Start the supervisor spawns a new thread with fresh channels.\n\n### The flowgraph\n\nThe source is a `seify::Source` configured with a SoapySDR driver string for whichever device is selected. It produces I\u002FQ samples that fan out (via a custom `Tee` block, since FutureSDR's stream buffers are single-reader) to two parallel paths.\n\nThe **spectrum path** is the boring one: 1024-point FFT, magnitude in dB, and a custom `ChunkSink` that batches the f32 samples into FFT-sized frames and pushes them through the channel to the UI. That's what you see drawn as the spectrum graph and the waterfall.\n\nThe **demod path** branches again into two sub-chains:\n\n- The **wideband FM chain** decimates the I\u002FQ stream to about 256 kHz, runs a quadrature discriminator tuned for +\u002F- 75 kHz deviation, resamples down to 48 kHz audio, applies a 75 us de-emphasis filter, and ends in a volume gate.\n- The **narrow chain** decimates harder, down to about 32 kHz, and shares a single `Apply` block that dispatches to either an FM discriminator (for NBFM) or an envelope detector with DC blocking (for AM), depending on the current mode atomic. Because the dispatch is a runtime check on an `AtomicU8`, switching between NBFM and AM doesn't require rebuilding the flowgraph. The same narrow IQ stream feeds a power meter that updates the signal-power atomic the squelch reads.\n\nBoth demod sub-chains end in their own volume gate, and a `Combine` block sums them into the cpal audio sink. At any moment at most one chain has a non-zero volume, so the sum is just whatever's active.\n\nThe exact decimation factors aren't hardcoded. They're computed from whatever sample rate the device is running at, targeting about 256 kHz for WBFM and 32 kHz for narrow modes. That's why changing the sample rate in the Source popup forces a flowgraph rebuild: the FIR filters are designed at build time.\n\n### Module layout\n\n```\nsrc\u002F\n├── main.rs            entry point + DSP supervisor\n├── app\u002F               UI-side state and key handlers\n│   ├── mod.rs         App struct, AppMode, channel I\u002FO, key dispatch\n│   ├── vfo.rs         frequency tuning helpers + VFO key handler\n│   ├── db_range.rs    Y-axis stepper\n│   ├── source.rs      Source popup state + sample-rate \u002F gain options\n│   ├── radio.rs       Radio popup state + mode helpers\n│   └── persist.rs     TOML config load\u002Fsave (via confy)\n├── dsp\u002F               DSP thread + flowgraph\n│   ├── mod.rs         public API\n│   ├── device_kind.rs DeviceKind enum (RTL-SDR, HackRF) + per-device args\u002Frange\n│   ├── command.rs     DspCommand + shared atomics + the command pump\n│   ├── flowgraph.rs   the full FutureSDR flowgraph builder\n│   ├── tee.rs         1-in 2-out fanout block\n│   ├── sink.rs        ChunkSink: batches f32 samples into FFT-sized frames\n│   └── silence.rs     RAII guard that redirects stderr around noisy native calls\n└── ui\u002F                ratatui drawing\n    ├── mod.rs         top-level draw\n    ├── theme.rs       colour constants\n    ├── util.rs        downsample + small layout helpers\n    ├── spectrum.rs    FFT spectrum graph widget\n    ├── waterfall.rs   waterfall graph widget\n    ├── status_bar.rs  bottom controls strip\n    ├── header\u002F        top row (connection status, VFO, dB range)\n    └── popup\u002F         Source \u002F Radio \u002F Help popups + shared chrome\n```\n\n## License\n\nsdrrat is licensed under the MIT license.\n","sdrrat 是一个基于终端的软件定义无线电（SDR）接收器应用，允许用户通过终端界面查看射频频谱并解调信号。该项目使用 Rust 语言编写，并结合了 Ratatui 和 FutureSDR 技术框架，提供了包括 RTL-SDR 和 HackRF 支持、FFT 频谱图显示、瀑布图展示以及基本的 WBFM、NBFM 和 AM 解调功能等核心特性。此外，它还支持源采样率和增益控制，具有直观易用的 TUI 设计。尽管目前尚处于不稳定状态，但 sdrrat 已经具备了作为轻量级 SDR 分析工具的基本功能，适合用于教育、业余无线电爱好者或是需要简单频谱分析与信号监听的场景中。","2026-06-11 04:01:01","CREATED_QUERY"]