-
Notifications
You must be signed in to change notification settings - Fork 12
FAQ
Answers to common questions about installing, configuring, and running NovaSDR. These answers reflect the actual runtime behavior of the backend and UI.
Note
NovaSDR was previously named "PhantomSDR-Plus". You may still see legacy identifiers (for example, "PhantomSDR+ v2.0.0") in logs; they will be harmonized over time.
NovaSDR is a web-enabled SDR server written in C++. It ingests raw samples (IQ or real) from stdin and exposes spectrum/waterfall and audio over WebSockets. It serves a Svelte-based UI as static files from server.html_root.
- Config parsing, runtime and endpoints are set up in
broadcast_server::broadcast_server() - CLI and config loading are handled in
main()
No. NovaSDR serves the built frontend itself. Just point [server].html_root to your built frontend/dist/, start the server, and open the printed address (default http://localhost:9002).
Primarily Linux x86_64 with Meson/Ninja. Other platforms may work if dependencies are available, but are not first-class targets.
Core libraries include FFTW3f, zstd, FLAC++, zlib, Boost (system, iostreams), and libcurl. See Installation for distro-specific commands.
Install and configure your GPU runtime, then set:
-
accelerator = "opencl"for OpenCL, or -
accelerator = "cuda"for NVIDIA GPUs, or -
accelerator = "mkl"for MKL (if compiled with MKL)
If an accelerator is requested but not compiled in, the server will log a critical error and exit. Selection takes place in broadcast_server::broadcast_server().
NovaSDR reads a TOML file (default config.toml). Pass a different file with --config path.
- Parsing and validation happen in
main()andbroadcast_server::broadcast_server()
Under [input], you must provide:
-
sps(input sample rate, integer) -
frequency(center/baseband frequency in Hz) -
signal("iq"or"real")
If any of these are missing, NovaSDR fails fast with a clear error. See Configuration for a full reference and a minimal known-good example.
- For
iq, the effective spectrum base isfrequency - sps/2. - For
real, the effective spectrum base isfrequency.
This is used to map FFT bins to absolute frequency and derive default passbands for initial demodulation. Details are in broadcast_server::broadcast_server().
Start at 131072. Larger sizes increase memory and CPU usage but improve resolution. If you see “Out of memory” or high CPU:
- Reduce
fft_size(for example,65536) - Reduce
sps(sample rate)
Memory sizing and FFT level preparation occur around broadcast_server::broadcast_server().
Default to:
waterfall_compression = "zstd"audio_compression = "flac"
Opus/AV1 require building the server with those codecs. NovaSDR will otherwise fail fast with an explicit message. Implementation in broadcast_server::broadcast_server().
NovaSDR reads from stdin. Pipe samples from your SDR capture tool:
- RTL-SDR
- Tool:
rtl_sdr - Format:
u8 - Signal:
"iq"
- Tool:
- HackRF One
- Tool:
hackrf_transfer - Format:
s8 - Signal:
"iq"
- Tool:
- Airspy HF+
- Tool:
airspy_rx - Format:
s16 - Signal:
"iq"
- Tool:
- SDRplay RSP1A
- Tool:
rx_sdr -d driver=sdrplay - Format:
s16 - Signal:
"iq"
- Tool:
- RX888 MK2
- Tool:
rx888_stream - Format:
s16 - Signal:
"real"(typical for direct sampling)
- Tool:
Driver and format selection are handled in main().
Yes. See the repository example configs and Devices for usage guidance and safe defaults.
The UI derives the WebSocket base URL from the current browser origin:
export const waterfall = new SpectrumWaterfall(baseUri + "/waterfall");export const audio = new SpectrumAudio(baseUri + "/audio");export const events = new SpectrumEvents(baseUri + "/events");
Adjust input.brightness_offset in small steps (for example, -6 to +6) and restart the server.
- Confirm the tuned frequency is inside captured bandwidth for your
spsandsignal. - Ensure a suitable default mode:
[input.defaults] frequency = 100900000 modulation = "WBFM" # AM | SAM | FM | WBFM | USB | LSB
Default passband selection per mode is derived in broadcast_server::broadcast_server().
Set:
[server]
otherusers = 1Set:
[websdr]
register_online = true
name = "Your Station"
grid_locator = "JO62"NovaSDR will periodically update sdr-list.xyz in a background thread:
- Lower
input.sps - Lower
input.fft_size - Keep
audio_compression = "flac"andwaterfall_compression = "zstd" - Use
fft_threads = 1unless you have headroom
Start conservative:
-
sps = 2_048_000(for RTL-SDR) -
fft_size = 131072(reduce further if needed)
Only if your CPU has spare cores and you measure a real benefit. Threaded FFTs are initialized around main().
NovaSDR provides a built-in static server and WebSockets. If exposing it:
- Use host firewalls to allow only required ports
- Track resource usage and connection limits under
[limits] - Consider running as a service user with restricted permissions
Not currently documented as a built-in feature. A typical approach is to place NovaSDR behind a TLS-terminating gateway. If you prefer not to introduce external infrastructure, keep NovaSDR on non-public networks.
-
--debugincreases verbosity -
--log path/to/file.logwrites logs to a file
CLI argument parsing is implemented in main().
- Start with Quick Start for a minimal path to sound
- Use Troubleshooting for precise fixes
- Review the complete Configuration
- Open issues or PRs following Contributing