FernSDR: The Zero-Dependency C++17 WebSDR Server Delivering 1,600 Listeners on Two Cores
TL;DR: FernSDR by Steven9101 is an open-source, high-performance WebSDR server and browser receiver written from scratch in pure C++17 with zero external runtime dependencies. Benchmarked against ten competing WebSDR platforms (including OpenWebRX, PA3FWM WebSDR, PhantomSDR, and UberSDR), FernSDR achieves an end-to-end audio latency of 227 ms, serves over 1,600 concurrent listeners on just two CPU cores, uses only 8 MB RAM under active load, and delivers 63% audio intelligibility across 24 kbit/s connections. It features process-isolated hardware modules, a dual-transform DSP engine, non-psychoacoustic linear audio streaming (NAC) designed specifically for digital mode decoders like FT8, WFC5 range-coded waterfalls, sunrise/sunset solar band scheduling, and a 127 kB responsive Svelte frontend.
What Is FernSDR?
FernSDR is an open-source Software-Defined Radio receiver server and web client written in C++17 that enables multi-user browser-based radio monitoring with zero runtime dependencies, sandboxed hardware driver modules, custom low-bitrate wire codecs, and real-time digital mode decoding.
+-----------------------------------------------------------------------------------------+
| FERN-SDR SYSTEM TOPOLOGY |
+-----------------------------------------------------------------------------------------+
[ Radio Hardware ] [ Process-Isolated Driver Modules ] [ Core Receiver Daemon ]
┌────────────────┐ ┌─────────────────────────────┐ ┌──────────────────────┐
│ RTL-SDR Blog V4│ ──USB──► │ Fern-RTLSDR (C++/librtlsdr) │ │ │
└────────────────┘ └──────────────┬──────────────┘ │ Shared Transforms: │
┌────────────────┐ │ Pipes (fd 0,1,2,3) │ - Radix-16/4 FFT │
│ RX-888 MkII HF │ ──USB──► ┌──────────────▼──────────────┐ │ - SIMD Kernels: │
└────────────────┘ │ Fern-RX888 (Raw IQ Stream) │ ────► │ AVX-512 / AVX2 │
┌────────────────┐ └──────────────┬──────────────┘ │ NEON / SSE2 │
│ SDRplay RSPdx │ ──API──► ┌──────────────▼──────────────┐ │ - Dual Transform: │
└────────────────┘ │ Fern-SDRPlay (Vendor API) │ │ Channelizer + │
└─────────────────────────────┘ │ Blackman-Harris │
│ Waterfall │
[ Digital Decoders ] │ │
┌────────────────┐ ┌─────────────────────────────┐ │ Shared Processing: │
│ PSK Reporter │ ◄─────── │ Fern-FT8 Decoder Module │ ◄──── │ - Broadcast WFM+RDS │
└────────────────┘ └─────────────────────────────┘ │ - Peak Pyramids │
└──────────┬───────────┘
│
epoll I/O Loop
(WebSocket / HTTP)
│
┌───────────────────────────────────────┴────────────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ Browser Client (Web) │ │ Admin Web Panel │
│ - Svelte + Lucide + Inter │ │ - Real-Time Health & Log │
│ - AudioWorklet (NAC Audio)│ │ - Solar Band Hours Engine │
│ - WebGL2 (WFC5 Waterfall) │ │ - Catalog Module Manager │
│ - Rig CAT Control & ADIF │ │ - Prometheus /metrics │
└───────────────────────────┘ └───────────────────────────┘
When an amateur radio operator sets up a remote listening post, they want two things: clean reception from a quiet rural site, and the ability to share that spectrum with fellow operators or club members over the web.
For more than a decade, the amateur radio community has relied on server platforms like Pieter-Tjerk de Boer’s original PA3FWM WebSDR, OpenWebRX, KiwiSDR, and modern forks like PhantomSDR and UberSDR. While functional, these platforms often suffer from structural bottlenecks: heavy Python interpreters, bloated web dependencies, high memory consumption, lossy voice codecs that distort digital signals, or unstable vendor drivers that crash the entire receiver daemon.
FernSDR solves these issues by rethinking the entire WebSDR stack from first principles.
The Problem with Traditional WebSDR Servers
Running a multi-user WebSDR server presents severe signal processing and networking challenges:
| Architectural Layer | Traditional WebSDR Platforms | FernSDR Solution |
|---|---|---|
| Driver Stability | Monolithic in-process SDK crashes entire daemon on USB timeout or driver panic. | Out-of-process sandboxed modules over standard pipes with automatic recovery. |
| Digital Audio Fidelity | Opus/MP3 codecs use lossy psychoacoustic masking and time warping (breaks FT8). | NAC linear MDCT codec: zero masking, zero time warping, perfect symbol preservation. |
| Waterfall Bandwidth | Heavy uncompressed FFT rows or lossy video streams consuming 100+ kbit/s. | WFC5 range-coded prediction drops spectrum bandwidth to 1.03-1.24 bits per bin. |
| Concurrency & Scaling | 50-200 users saturate dual-core CPU due to GIL locks and unshared demodulators. | Custom radix FFT and SIMD dispatch serve 1,600 users on two cores at 8 MB RAM. |
| Web Client Footprint | Multi-megabyte JavaScript bundles with laggy rendering on mobile devices. | 127 kB total first-load bundle using Svelte, Lucide, and hardware WebGL2 shaders. |
- Driver Instability: Vendor libraries for SDRplay, RTL-SDR, or PCIe digitizers frequently trigger segmentation faults or lock up under unexpected USB disconnects. In a monolithic server, one bad driver call terminates the session for every listener.
- Audio Codec Distortion: Mainstream codecs like Opus and AAC rely on psychoacoustic masking thresholds, pitch prediction, and adaptive time stretching to maintain speech quality at low bitrates. While speech sounds acceptable, these algorithms destroy the precise phase and amplitude relationships required by software modems (FT8, RTTY, PSK31, WSPR, and APRS).
- Waterfall Network Bloat: Waterfall streaming often saturates the server uplink. Sending high-resolution spectrum frames to dozens of users requires megabits of bandwidth unless heavy, lossy video compression is applied.
- Heavy Runtime Stacks: Stacking Python runtimes, WebSockets packages, and external web frameworks creates high CPU overhead and large memory footprints, limiting small single-board computers like the Raspberry Pi to a handful of concurrent users.
FernSDR vs Other WebSDR Platforms: Measured Performance
FernSDR was benchmarked in a controlled laboratory against ten competing WebSDR servers using identical two-core CPU allocations, a shared synthetic RF test band, and real automated browser clients.
| Platform | Latency (Audio) | Max Users (2 Cores) | RSS Memory (4 Users) | 24 kbps Pipe Delivery | Outage Recovery | First Load Bundle |
|---|---|---|---|---|---|---|
| FernSDR | 227 ms | 1,600+ | 8 MB | 63 % | 0.9 s | 127 kB |
| UberSDR | 261 ms | < 400 | 38 MB | Failed | 3.4 s | 340 kB |
| PA3FWM WebSDR | 310 ms | 400 | 45 MB | 12 % | 4.1 s | 180 kB |
| PhantomSDR-Plus | 285 ms | < 400 | 30 MB | 18 % | 2.0 s | 210 kB |
| NovaSDR | 410 ms | < 200 | 62 MB | 7 % | 5.8 s | 512 kB |
| OpenWebRX+ | 520 ms | < 100 | 140 MB | Failed | 6.2 s | 1.8 MB |
| OpenWebRX | 580 ms | < 80 | 165 MB | Failed | 7.5 s | 2.1 MB |
| VertexSDR | 340 ms | < 250 | 55 MB | Unusable | 4.0 s | 130 kB |
| ka9q-web | 290 ms | < 300 | 48 MB | Failed | 3.1 s | 420 kB |
| PhantomSDR | 310 ms | < 350 | 30 MB | 15 % | 2.4 s | 225 kB |
The data demonstrates FernSDR’s optimization:
- Audio Latency: Achieves 227 ms glass-to-glass latency from RF ingest to browser audio output.
- Massive Concurrency: Successfully serves 1,600 concurrent listeners on two CPU cores without dropping audio frames, compared to 400 on PA3FWM WebSDR and under 100 on OpenWebRX.
- Minimal Memory: Idles at just 8 MB of Resident Set Size (RSS) with four active listeners.
- Low-Bandwidth Resilience: Retains 63% audio intelligibility over severely choked 24 kbit/s network links.
- Rapid Re-synchronization: Recovers and resynchronizes live audio within 0.9 seconds after a 15-second network drop.
- Ultralight Assets: Ships a complete, full-featured web client in a 127 kB initial bundle.
Process Isolation: The Sandboxed Module Architecture
FernSDR isolates hardware drivers and digital decoders into external sub-processes using a strict Unix pipe contract. The main receiver executable links only standard system libraries (libc, libstdc++, libm, pthread) and never loads hardware vendor SDKs into its own address space.
+─────────────────────────────────────────────────────────────────────────────────────────+
| MODULE INTER-PROCESS PROTOCOL |
+─────────────────────────────────────────────────────────────────────────────────────────+
FernSDR Main Daemon Hardware Module Process (e.g. Fern-RTLSDR)
=================== =========================================
│ │
│ ── fd 0: JSON Commands {"type":"open", ...} ───────────► │
│ │
│ ◄── fd 1: Raw IQ Sample Stream (u8, s16, f32) ────────── │
│ │
│ ◄── fd 2: Human-Readable Diagnostic Log Lines ────────── │
│ │
│ ◄── fd 3: JSON Telemetry Events {"type":"stats", ...} ── │
│ │
Module Communication Contract
Every input module runs as an unprivileged process with exactly four active file descriptors:
- fd 0 (Inbound Commands): Line-delimited JSON messages sent from FernSDR to the module (e.g.
open,set,stop). - fd 1 (Sample Data): Continuous stream of raw complex IQ or real RF samples in native formats (
u8,s16,f32). - fd 2 (Logging): Standard human-readable log output, captured in a rolling 200-line buffer for the
/admindiagnostic console. - fd 3 (Telemetry Events): Structured JSON event stream reporting hardware state, dropped sample counts, ADC clipping alerts, and tuner temperatures.
If a USB dongle is unplugged or a vendor driver panics, the module exits or triggers EPIPE. FernSDR catches the broken pipe, logs the event to the admin panel, and initiates an automatic module restart without interrupting other active bands or disconnecting web listeners.
Decoders (such as the Fern-FT8 module) operate under additional security restrictions: they execute within strict seccomp system call filters and Landlock filesystem boundaries with lowest CPU scheduling priority.
Under the Hood: High-Throughput DSP and Dual-Transform Engine
FernSDR’s digital signal processing pipeline achieves extreme efficiency through custom vector kernels and shared computation.
+─────────────────────────────────────────────────────────────────────────────────────────+
| FERNSDR CORE DSP PIPELINE FLOW |
+─────────────────────────────────────────────────────────────────────────────────────────+
Raw RF Samples (from Module)
│
▼
┌───────────────────────────────────────────────────────────────────────────────────────┐
│ 2 MiB Huge-Page Aligned Input Buffer (Direct Interleaved Split) │
└───────────────────────────────────┬───────────────────────────────────────────────────┘
│
┌────────────────────────────┴────────────────────────────┐
▼ ▼
┌────────────────────────────────────────┐ ┌────────────────────────────────────────┐
│ Polyphase Channelizer FFT │ │ Waterfall Spectrum FFT │
│ - Sine-Window Transform │ │ - Blackman-Harris Window (< -85 dB) │
│ - Modulo Phase Correction (-pi*bin*b) │ │ - 32,768-Point Primary Resolution │
│ - SIMD AVX-512 / AVX2 / NEON Kernels │ │ - Multi-Resolution Peak Pyramid │
└───────────────────┬────────────────────┘ └───────────────────┬────────────────────┘
│ │
┌────────────┴────────────┐ │
▼ ▼ │
┌──────────────┐ ┌──────────────┐ │
│ Shared WFM │ │ Per-Listener │ │
│ Demodulator │ │ Demodulator │ │
│ + RDS Decoder│ │ (USB/LSB/CW) │ │
└──────┬───────┘ └──────┬───────┘ │
│ │ │
└────────────┬────────────┘ │
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ NAC Audio Encoder │ │ WFC5 Range Encoder │
│ (Linear MDCT, 17 Bands) │ │ (Spatio-Temporal Model) │
└────────────┬────────────┘ └────────────┬────────────┘
│ │
└──────────────────────┬──────────────────────┘
▼
WebSocket Framing Loop
1. Vectorized Radix FFTs
The FFT engine avoids external libraries like FFTW. Instead, it implements hand-optimized assembly kernels using compile-time templates and runtime CPU dispatch:
- Small Transforms (up to 256 points): Completely unrolled butterfly passes.
- Medium Transforms (up to 16k/32k points): Four-step vector passes with transposed intermediate layouts.
- Large Transforms (up to 524k points): Radix-16 initial pass over L2 cache boundaries, streaming through radix-4 blocks.
- Vector Units: Automatically selects AMD AVX-512 (16 lanes), Intel AVX2 with FMA (8 lanes), ARM NEON (4 lanes), or SSE2 at startup.
2. Dual-Transform Architecture
A common compromise in SDR design is using a single FFT for both audio extraction and waterfall visualization. This creates severe compromises:
- A channelizer window needs a sine profile for perfect Princen-Bradley overlap-add reconstruction, but sine windows have high sidelobes (-23 dB) that smear strong broadcast carriers across dozens of kilohertz on a visual display.
- FernSDR decouples the two pipelines completely:
- Channelizer: Runs a sine-window polyphase filter bank with half-bin phase correction (
-pi * center_bin * b) that prevents phase discontinuities across block boundaries. - Waterfall: Runs an independent Blackman-Harris windowed FFT with sidelobes suppressed below -85 dB, providing sharp visual dynamic range without carrier bleed.
- Channelizer: Runs a sine-window polyphase filter bank with half-bin phase correction (
3. Shared Computation
When twenty listeners tune to the same local FM broadcast station, FernSDR computes the 200 kHz wideband FM discriminator and RDS decoding once on the band thread (core/shared_fm.h). Each listener’s session simply taps the resulting audio buffer, applying individual squelch, volume, and filtering. Similarly, waterfall rows matching full-band resolution are range-coded once and broadcast to all clients viewing that zoom level.
Custom Wire Codecs: NAC and WFC5
FernSDR doesn’t use generic media codecs. It introduces two custom wire formats engineered specifically for software-defined radio communications:
+─────────────────────────────────────────────────────────────────────────────────────────+
| CUSTOM WIRE CODEC SUMMARY |
+─────────────────────────────────────────────────────────────────────────────────────────+
1. NAC (Noise and Audio Codec)
- Target: Linear, phase-coherent audio for human ears and digital modems.
- Transform: 256-sample sine-windowed MDCT with 128-sample hop (21.3 ms delay at 12 kHz).
- Subbands: 17 bark-scaled frequency bands with Rice entropy coding.
- Integrity: 0% time warping, 0% psychoacoustic masking, 0% pitch synthesis.
2. WFC5 (Waterfall Codec Version 5)
- Target: High-dynamic-range spectrum tiles over constrained bandwidth.
- Compression: 2D spatio-temporal gradient prediction + LZMA binary range coding.
- Efficiency: 1.03 to 1.24 bits per bin (32% reduction over Rice-coded WFC4).
- Rendering: Client-side WebGL2 fragment shader with R16F floating-point texture maps.
NAC: Audio Fidelity for Digital Modes
Traditional WebSDRs using Opus or MP3 codecs fail when listeners feed browser audio into digital decoders (WSJT-X, JS8Call, FLDIGI, MMSSTV). Psychoacoustic algorithms discard low-amplitude tones adjacent to strong carriers, and time-stretching algorithms destroy FSK/PSK symbol clock recovery.
NAC (Noise and Audio Codec) is a linear, mathematically reversible transform codec:
- Reversible MDCT: Uses a 256-sample Princen-Bradley sine window with a 128-sample hop (21.3 ms delay at 12 kHz).
- Zero Synthesis: Strictly avoids pitch predictors, bandwidth extension, or psychoacoustic dropouts.
- 17 Bark-Scale Subbands: Concentrates quantizer resolution in lower frequency bins where human ears and digital tones require fine fidelity.
- Rice Coding: Residuals are zig-zag mapped and encoded using adaptive Golomb-Rice entropy coding.
WFC5: Range-Coded Waterfall Compression
Transmitting 32,768 FFT bins at 12 to 20 frames per second can overwhelm network connections. FernSDR’s WFC5 codec applies advanced data compression techniques:
- 2D Predictive Modeling: Uses directional gradient predictors (
clamp(L + T - TL)and2*L - LL) combining horizontal neighbor bins and historical vertical frames. - LZMA Binary Range Coder: Replaces static Rice codes with an adaptive 11-bit probability range coder that tracks dynamic RF noise floors.
- Bandwidth Savings: Compresses 1 dB and 2 dB spectrum lines down to 1.03 – 1.24 bits per FFT bin, allowing fluid 60 FPS waterfall displays over 3G cellular or low-speed rural DSL connections.
Comprehensive Feature Tour
FernSDR delivers rich interfaces for both casual radio listeners and station administrators.
+-----------------------------------------------------------------------------------------+
| FERNSDR WEB CLIENT INTERFACE |
+-----------------------------------------------------------------------------------------+
[ 14.074.000 MHz ] [ USB ] [ Filter: 2.8 kHz ] [ AGC: Medium ] [ NR: On ] [ Notch: Auto]
┌───────────────────────────────────────────────────────────────────────────────────────┐
│ Visual Spectrum Scope (WebGL2 Hardware Rendered) │
│ - S-Meter Calibrated in dBm / S-Units │
│ - IARU Region 1/2/3 Band Plan Overlays (FT8, WSPR, CW, Calling Frequencies) │
├───────────────────────────────────────────────────────────────────────────────────────┤
│ Real-Time Waterfall with Historical Rewind Buffer │
│ - Four High-Contrast Palettes (including Colorblind-Safe Modes) │
│ - Drag-to-Tune Passband Filter with Independent IF Shift │
├───────────────────────────────────────────────────────────────────────────────────────┤
│ Integrated Digital Decoder & Tools Suite │
│ - Live FT8 Decodes with Click-to-Tune World Map & PSK Reporter Integration │
│ - VFO A/B Switching, Frequency Bookmarks, Audio File Recorder, ADIF Logbook Export │
│ - Bidirectional Rig CAT Control (Kenwood, Yaesu, Icom, Elecraft, FlexRadio) │
└───────────────────────────────────────────────────────────────────────────────────────┘
What Listeners Get
- Broad Demodulation Modes: USB, LSB, CW, CW-L (Lower sideband CW), AM, Synchronous AM (SAM), Narrow FM (NFM), Double Sideband (DSB), and Wide FM (WFM) with live RDS decoding (Programme Service, RadioText, PTY).
- Advanced Audio Processing: Four-speed AGC or manual gain control, spectral noise reduction, automatic notch filtering, threshold-free auto squelch, bass/treble equalizers, FM de-emphasis, and CTCSS sub-audible tone decoding/squelching.
- Interactive Waterfall & Spectrum: Multi-touch zoom and drag navigation, four color palettes, peak hold traces, and band-plan markers for IARU Regions 1-3, US, UK, Canada, Germany, Australia, and Japan.
- Waterfall History Rewind: Operators can enable disk-backed waterfall archiving, letting users scroll back in time through previous hours of spectrum activity.
- Integrated FT8 Decoding: Built-in multi-channel FT8 decoding renders callsigns, signal reports, and grid squares on an interactive world map. Clicking any spotted callsign automatically tunes the receiver.
- Hardware Rig Control (CAT): Supports serial CAT control for Yaesu, Icom, Kenwood, Elecraft, and FlexRadio transceivers. The web receiver can track your physical radio dial in real time (compatible with CATSync).
- Mobile-Optimized Interface: Responsive single-page application built with Svelte. On smartphones, tuning controls slide up smoothly in a thumb-friendly bottom sheet.
+-----------------------------------------------------------------------------------------+
| FERNSDR OPERATOR ADMIN PANEL |
+-----------------------------------------------------------------------------------------+
[ /admin Dashboard ]
┌───────────────────────────────────────────────────────────────────────────────────────┐
│ Band Diagnostics: Live sample rates, gain levels, ADC clipping alerts, dropped buffers│
│ Listener Monitor: Active connections, IP locations, stream rates, persistent chat mute│
│ Solar Band Hours: Automated sunrise/sunset band switching (e.g. 40m Night / 20m Day) │
│ Catalog Manager: One-click module installation and background driver updates │
│ Widget Builder: Space weather, solar flux index, greyline map, real-time lightning │
│ System Health: Prometheus /metrics export, configuration validator, one-click backup│
└───────────────────────────────────────────────────────────────────────────────────────┘
What Station Operators Get
- Web-Based Administration (
/admin): Fully responsive administration console accessible from desktop or mobile browsers. - Solar “Band Hours” Scheduling: Configure bands to activate and deactivate automatically based on time of day or astronomical sunrise/sunset calculations at your station grid square. A single RTL-SDR can monitor 40m at night and switch to 20m at dawn.
- One-Click Module Catalog: Install, update, and configure hardware drivers and decoders directly from the web interface without touching the command line.
- Built-in Sidebar Widgets: Embed real-time space weather monitors, solar flux indices, geomagnetic storm alerts, interactive greyline day/night maps, Blitzortung lightning maps, and custom station info cards.
- Automated Rollbacks & Backups: Updates execute with automated safety rollbacks if health checks fail. Full station configurations can be exported into a single portable backup file.
- Enterprise Monitoring: Exposes standard Prometheus endpoints (
/metrics),/api/status, and/api/healthfor integration with Grafana and network monitoring systems.
Deployment and Quick Start Guide
FernSDR can be deployed in minutes on any modern Linux distribution (Debian, Ubuntu, Alpine, Fedora, Arch) across x86_64, aarch64, or armhf hardware.
+─────────────────────────────────────────────────────────────────────────────────────────+
| FERNSDR DEPLOYMENT OPTIONS |
+─────────────────────────────────────────────────────────────────────────────────────────+
Option A: Automated Universal One-Liner (Recommended)
─────────────────────────────────────────────────────
curl -fsSL https://github.com/Steven9101/FernSDR/releases/latest/download/install.sh | sudo sh
Option B: Official Docker Container
───────────────────────────────────
docker run -d --name fernsdr \
--restart unless-stopped \
--device /dev/bus/usb \
-p 8073:8073 \
-v fernsdr_data:/var/lib/fernsdr \
ghcr.io/steven9101/fernsdr:latest
Option C: Manual Build from Source (C++17 & Svelte)
──────────────────────────────────────────────────
git clone https://github.com/Steven9101/FernSDR.git
cd FernSDR
tools/source-install.sh --service
1. Universal One-Line Installer
The official installer detects your processor architecture, init system (systemd, OpenRC, runit, or SysV init), sets up a dedicated unprivileged fernsdr user, configures udev rules for SDR hardware, generates a secure administrative password, and launches the service:
curl -fsSL https://github.com/Steven9101/FernSDR/releases/latest/download/install.sh | sudo sh
During setup, the installer prompts for your deployment scenario:
- Home Network: Listens on port 8073 with plain HTTP administration permitted from local RFC1918 subnets.
- Public Server with Domain Name: Listens on
127.0.0.1and automatically provisions a Caddy reverse proxy with Let’s Encrypt TLS certificates. - Public Server without Domain Name: Listens on port 8073 and restricts the admin panel to secure SSH tunnels (
ssh -L 8073:localhost:8073 user@server).
2. Docker Deployment
For containerized homelabs and Kubernetes clusters, pull the official static image:
docker run -d \
--name fernsdr \
--restart unless-stopped \
--device /dev/bus/usb \
-p 8073:8073 \
-v /opt/fernsdr/data:/var/lib/fernsdr \
ghcr.io/steven9101/fernsdr:latest
3. Production Configuration (fernsdr.conf)
Station settings are stored in a simple, human-readable configuration file at /var/lib/fernsdr/fernsdr.conf:
[site]
name = 9M2PJU WebSDR Listening Post
location = Kuala Lumpur, Malaysia
grid = OJ03ub
max_users = 500
[server]
bind = 0.0.0.0
port = 8073
dsp_workers = 4
[band.20m]
name = 20 Meters HF
module = rtlsdr
module.device = serial:00000001
module.gain = auto
center = 14.175M
sample_rate = 2.4M
hours = sunset-30m to sunrise+30m
[band.40m]
name = 40 Meters HF
module = rtlsdr
module.device = serial:00000001
module.gain = auto
center = 7.100M
sample_rate = 2.4M
hours = sunrise+30m to sunset-30m
Frequently Asked Questions (FAQ)
What hardware SDR devices does FernSDR support?
FernSDR supports RTL-SDR dongles (RTL2832U, Blog V3/V4), RX-888 MkII (direct sampling 0-64 MHz), and SDRplay RSP devices via dedicated modules. Any other radio (HackRF, Airspy, LimeSDR, PlutoSDR) connects smoothly by piping raw IQ samples into standard input or over UDP multicast.
Can I decode digital modes like FT8 from the audio stream?
Yes. FernSDR uses a custom linear MDCT audio codec (NAC) that avoids lossy psychoacoustic masking and time warping. You can pipe browser audio directly into WSJT-X, JS8Call, FLDIGI, or Direwolf with full decoding reliability.
How does FernSDR serve 1,600 users on two CPU cores?
FernSDR shares heavy signal processing across all listeners. It calculates one master FFT per band, one WFM demodulator per broadcast frequency, and one range-coded waterfall stream per zoom level, using vectorized AVX-512, AVX2, and NEON SIMD kernels.
Does FernSDR require Node.js or Python to run on the server?
No. The compiled server is a standalone, dependency-free C++17 binary that links only standard system C/C++ runtimes. Node.js is used strictly during development to compile frontend Svelte components into static browser assets.
How do I secure the web admin panel?
FernSDR generates a cryptographically random admin password upon installation. In public deployments, the installer configures automated HTTPS certificates via Caddy or restricts the admin panel to localhost, requiring an SSH tunnel for remote administrative access.
Sources and Further Reading
- FernSDR GitHub Repository: github.com/Steven9101/FernSDR
- Official FernSDR Project Portal: fernsdr.org
- Live Public WebSDR Demo: demo.fernsdr.org
- FernSDR Architecture Documentation: github.com/Steven9101/FernSDR/blob/main/docs/ARCHITECTURE.md
- FernSDR Codec Specification (NAC & WFC): github.com/Steven9101/FernSDR/blob/main/docs/CODEC.md
- FernSDR Performance Lab Measurements: github.com/Steven9101/FernSDR/blob/main/docs/PERFORMANCE.md
- FernSDR Module IPC Interface: github.com/Steven9101/FernSDR/blob/main/docs/MODULES.md
- PA3FWM WebSDR Technical Reference: websdr.org
- OpenWebRX Project Portal: openwebrx.de
- PSK Reporter Digital Reception Map: pskreporter.info
73 de 9M2PJU



Post Comment