The SV1BTL-version can be found here: https://github.com/sv1btl/PhantomSDR-Plus ..it is compatible with the normal version, but enhanced.

Upgrade to v. 4.2.0

Started by Emmanuel SV1BTL, Sep 20, 2026, 06:31 PM

Previous topic - Next topic

Emmanuel SV1BTL

New in v.4.2.0

  • AI noise reduction. A new AI button with a strength slider sits under SQ in the Audio & Buffer panel (on the /mobile page, in the Audio tab under Squelch). It removes band noise from speech with RNNoise, a small neural network trained on voice — in the same spirit as RM Noise, but everything runs inside the listener's own browser: nothing is sent to an outside server, there is no account, and the receiver's CPU load does not change. The slider sets how strongly it works while someone is talking (default 50%); between words it works harder on its own. On a noisy SSB band the hiss between words drops by about 10 dB at 50% and by 20 dB or more at 100%, while the speech keeps its level, and the leftover hiss stays smooth; on weak stations the filter smooths its decisions more on its own. Voice modes only (USB, LSB, AM, SAM): in CW, FM, data modes and C-QUAM it steps aside, because the network treats a CW tone as noise. The decoders always get the audio from before it. See docs/USER_GUIDE.md under AI Noise Reduction.
  • The QRG Sync button is now labelled TCI-CAT, after the protocol it speaks; it works as before.
  • Four more receivers set up by the installer, on every supported Linux. The receiver question in install.sh (Debian and Ubuntu) and in install_fedora.sh, install_arch.sh and install_opensuse.sh now installs the complete driver chain for the SDRplay RSP1A (option 3, the open-source libmirisdr-5 driver with SoapyMiri), the RigExpert Fobos SDR (option 5, new, with two launchers: start-fobos-hf.sh for HF1/HF2 direct sampling 0-25 MHz and start-fobos.sh for the RF path) and the Airspy HF+ (option 6, new): SoapySDR, the driver, rx_sdr and a udev rule, so the start script runs without sudo. The HackRF One (option 7, new, with start-hackrf.sh) needs only the distribution's hackrf package and a udev rule; its example config now reads the HackRF's samples as signed (s8), as they are. Each receiver's part is also a script of its own — setup-rsp1a.sh, setup-fobos.sh, setup-airspyhf.sh, setup-hackrf.sh — that adds a receiver to a station already installed. start-rsp1a.sh keeps using SDRplay's own API where that is installed, so existing RSP1A stations carry on unchanged.

As usual:
Download: https://github.com/sv1btl/PhantomSDR-Plus
Demo: http://phantomsdr.no-ip.org:8900

Emmanuel SV1BTL


Emmanuel SV1BTL

#2
UPDATES TO RECENT VERSION 4.2.0

------------------------------------------------------------------------------
WHAT CHANGED IN update.sh
------------------------------------------------------------------------------

update.sh is the updater: run without arguments it reports what a new release would change, and with --apply it writes the files, leaving your configuration, your markers, your site information and your logs alone. The version you have works, but it had faults that only show at the worst moment, and one habit worth changing.

Backups are now easy to find. Every file an update overwrites is still saved first, but it used to go into a hidden folder called .update-backups, which does not appear in a file manager or in a plain ls — a backup nobody can find is not much of a backup, least of all with the receiver off the air. Backups now go into a plain visible folder instead:

  update-backups/phantomsdr-backup-20260923-164530.zip

One dated archive for each update, holding only the files that run actually replaced, each at the path it has in your tree. You can copy it to another machine as a single file, open it anywhere, or unpack it straight back over the installation. Where zip is not installed the archive is written as .tar.gz instead; nothing else differs. The three most recent are kept. Backups made by the older version are still there and can still be restored, and they are counted in the same three.

To put back what the last update replaced, either of these does it:

  ./update.sh --restore LAST
  ./update.sh --restore phantomsdr-backup-20260923-164530.zip

Each archive also carries a restore.sh that works on its own, if update.sh itself is ever the problem. Unpack the archive and give it your installation directory:

  ./restore.sh /home/$USER/PhantomSDR-Plus

Restoring could damage the updater. --restore puts back every file the update replaced, and update.sh is one of those files, so it was rewriting itself while it was still running — the one thing a self-updating script must never do. It now runs from a copy outside the tree while it restores, as it already did while it applied.

An update could disturb a running diversity relay. If you run the WebSDR diversity relay, its service was left running while its program file was replaced underneath it. It is now stopped with the rest and started again when the update finishes. As before, only the services belonging to the directory being updated are touched, so a second installation on the same machine is left alone.

The sample configuration files can be updated again. config.example.*.toml was protected so heavily that an improved sample could never reach you. Those files are now offered instead: you are asked before one is replaced, and you can keep yours, take the new one, or take the new one alongside yours as config.example.rtlsdr.toml.new and compare them at your leisure. Your real configuration — config.toml and config-<receiver>.toml — remains untouchable and is never even mentioned.

Smaller things: --help was cut short and never printed the environment settings it documents; every --apply left a stray temporary file behind in /tmp; and --prune, used before your first --apply, quietly did nothing instead of explaining that it has no earlier update to compare against.


------------------------------------------------------------------------------
REPLIES IN THE CHAT
------------------------------------------------------------------------------

Every chat message now has a small "↪ Reply" button next to its time. Clicking it shows "Replying to <name>: <first words of the message>" above the input box; type and send as usual, or press ✕ or Esc to cancel. The reply appears indented under the message it answers, with a short quote line naming who and what it answers. If that is higher up the list, the chat scrolls to it rather than to the bottom. A reply to a reply joins the same thread, so threads are one level deep. The same works on /mobile.

Nothing changed in the server for this. A reply is an ordinary chat message that begins with a small marker naming the message it answers, for example "[RE:2026-09-25 12:00:01|SV1BTL]"; the server stores and relays it like any other line, and the web page reads the marker. Some consequences worth knowing:

  - The server still keeps only the last 20 messages. When the original has left that history, a reply stays where it arrived and shows only "↪ <name> <time>".
  - The marker takes about 30 to 40 of the 200 characters a message may have.
  - A browser tab left open from before your rebuild shows the marker as plain text until it is reloaded.
  - Deleting a message from the admin panel works exactly as before. Deleting an original leaves its replies with the quote line only.

On the desktop page the arrow keys now move the cursor inside the chat box in both layouts; in one of them they used to tune the receiver instead.


------------------------------------------------------------------------------
RTTY, PSK31, NAVTEX, CW, FT8 AND FAX DECODERS
------------------------------------------------------------------------------

All of this is in the decoder windows of the web page; nothing changed in the server program. Everything below except FT8 was measured on synthetic signals with calibrated noise, SNR given in a 3 kHz bandwidth (2500 Hz for FT8 and fax); FT8 was measured on real recordings, as its paragraph says.

RTTY copies much better. The decoder looked for the start of each character only once per bit, so it read every character up to half a bit late or early, and once it lost step it tended to stay out of step for whole lines. It now finds the start of each character to the exact sample. On a clean signal that used to garble a quarter of the text now and then; for amateur RTTY (45.45 baud, 170 Hz) it now copies without errors down to 0 dB, with about 1.5% errors at −3 dB (was about 10%) and 20% at −6 dB (was 47%).

Three more faults are fixed. On weak signals a single noise click could stop decoding for the rest of the transmission, with no text and no error; it no longer can. With audio at 24 kHz or more the decoder printed nothing at all; it now works at any audio rate. And the ASCII setting in the Encoding list never decoded anything; it does now.

The SNR reading is real. It used to be a fixed proportion of the signal level and showed about 26 dB whatever was on the frequency. It is now measured on the two tones themselves and reads within about 1 dB of the true SNR from +20 dB down to −5 dB. An empty frequency reads about −12 to −15 dB.

There is a squelch. A new "Squelch (SNR)" slider, shown for Amateur RTTY and Weather RTTY, stops noise printing as random letters. Amateur RTTY starts at −5 dB and Weather RTTY at −8 dB; the far left turns it off. While it is closed the SNR figure is grey. Lower it if you want to try for very weak signals.

The receiver filter is narrower. Amateur RTTY had a 410 Hz filter, wide enough that a stronger station 250 Hz away wiped out the copy completely. It now uses 300 Hz, which removes that neighbour and still copies a signal tuned 40 Hz off. Weather RTTY goes from 690 to 594 Hz. The filter now also follows the decoder when Auto-tune or Auto-shift moves the tones, and when you change the Baud setting; before, it stayed where it was and could cut a tone off. NAVTEX/SITOR keeps its filter as it was.

Auto-shift now only changes the shift when a real two-tone signal is present.

PSK31 reports SNR on the same scale. Its reading was a genuine measurement, but about 17 dB higher than the RTTY figure and never below 0. It now shows SNR in 3 kHz like RTTY, within about 1 dB from +20 down to −5 dB, so 0 dB on the PSK31 panel is now a strong signal. The label reads "SNR" for PSK31; Olivia keeps "S/N", because its figure is the FEC quality. PSK31 decoding itself did not change, and neither did Olivia.

NAVTEX headers are read. Every message banner in the NAVTEX window used to read "ZCZC ????", with the real header (for example JA01: station, subject, serial number) printed as text on the line below it. The decoder tried to read the header the moment "ZCZC" arrived, before the rest of it had. It now waits for the whole header, so the banner reads "ZCZC JA01". The stray "NNN" that ended every message, just before the NNNN banner, is gone too; "N" in the text itself, as in a wind from NNW, still prints.

NAVTEX shows messages you tuned into late. Text received outside a ZCZC ... NNNN frame used to be thrown away, so if you tuned in after a message had started, or its header was lost to noise, you saw nothing until the next message. Such a message is now shown under a "(header missed)" banner. It only opens once several characters in a row arrive with both of their NAVTEX transmissions agreeing, which noise practically never produces: half an hour of pure noise opened nothing. It closes at NNNN as usual, with "(signal lost)" if the signal goes first, or when a new message begins. The decoder also works out the right order of the two copies of each character by itself now; before, someone joining in the middle got that right only half the time, and then lost NAVTEX's error protection without any sign of it. Messages that start normally decode at least as well as before.

CW stays quiet on an empty channel. The CW decoder locked onto plain noise and printed a stream of junk, a couple of hundred characters every five minutes, mostly E, I and bracketed dot-dash patterns. It now prints only when there is a clear difference between key-down and key-up, which two hours of pure noise never reached, while a signal still readable at −10 dB has plenty. The speed and tone shown in the window are held back the same way. Weak-signal copy did not change.

CW copies slow and Farnsworth sending. With Farnsworth spacing (characters sent fast, with longer gaps between them) the decoder could lose its speed lock in the middle of a QSO and print every element as a dash: "TTTT TTT". Slow CW, 8 to 12 wpm, started the same way. With wide Farnsworth spacing every letter also came out as a word of its own ("C Q C Q"). Both are fixed; from 8 to 40 wpm, and Farnsworth at every stretch tried, it now copies with a few percent of errors or fewer at 0 dB.

FT8, FT4 and FT2 show a real SNR. The SNR next to each decode was not a signal-to-noise ratio at all but a rescaled internal match score, and it hardly moved with the signal: a station WSJT-X reads at −20 dB showed about +1 dB, one at +10 dB about +5 dB. It is now measured on the decoded signal itself, against the noise around it, and referred to 2500 Hz as WSJT-X does. Checked on the 31 test recordings that come with the ft8_lib decoder library, 255 of whose decodes also have WSJT-X's readings: the two now agree on average across the whole range from −15 to +14 dB, typically within about 3 dB for a single decode. Decoding itself did not change; every one of the 354 messages in those recordings still decodes. FT4 and FT2 use the same method, but there are no test recordings for them, so compare them with WSJT-X on the air if you can. If you run the automatic spot reporter (autorun), its PSKReporter spots carry this SNR, so they are now correct as well; restart autorun after the update so it loads the new decoder.

The FT8 decoder is a separate file, frontend/public/decoders/ft8_lib.wasm, which the frontend build copies into place. Browsers keep this kind of file for a long time, so after the rebuild everyone should reload the page with a hard refresh (Ctrl+Shift+R, or Cmd+Shift+R on a Mac), or FT8 may keep showing the old numbers. The new file is 48254 bytes; the old one was 37297. jsdsp/ft8_wasm/wasm_wrapper.c is its source, included for anyone who builds the decoder themselves; the page does not need it.

Weather fax keeps the whole chart. The decoder recognises the start and stop signals of a fax by their 300 Hz and 450 Hz rhythm, but it only looked at the first quarter of each line. A hatched area in a chart whose spacing happened to match that rhythm was taken for a start signal, and the decoder then threw away the next 20 seconds of the chart as phasing lines. It now requires the rhythm across the whole line, which the real start and stop signals always fill and chart content practically never does. That margin also let the detection threshold come down, so start and stop are now recognised on much weaker signals (down to about 0 dB SNR, from about +2 dB). Charts received that weak used to come out shifted sideways, because the decoder never saw the start signal and so never lined the picture up. At the very weakest levels the line-up now also averages the phasing lines before it measures them. On test transmissions the chart now lines up to within 1% of the line from strong signals down to about −1 dB.

The fax timetables were checked time by time against the current NOAA worldwide radiofax schedule (edition of 7 March 2025) and all matched. Two things it lists were missing and have been added: the Chilean station CBM Punta Arenas (4322 and 8696 kHz), now in the station list with its own timetable, and four extra Charleville (VMC) broadcasts at 0000, 0345, 0500 and 0515 UTC that go out on 11030 kHz only, beamed towards Tasmania.


------------------------------------------------------------------------------
SHORTER AUDIO DELAY
------------------------------------------------------------------------------

Listeners now hear the receiver noticeably sooner. Nothing changed in the server program, in audio_sps (it stays at 12000, as the decoders need) or in fft_size; all of it is in the web page.

Most of the delay was in the listener's browser, in the part that unpacks the compressed audio. The server sends a 35 ms packet of FLAC audio every 35 ms, but the decoder the page used collected its output into fixed chunks of about 85 ms before letting any of it through: it gave nothing for the first five packets and then released a chunk every two or three packets, holding back about 160 ms on average and up to 200 ms. No setting could avoid it. The page now has its own FLAC decoder that releases each packet the moment it arrives. FLAC is lossless, so this can be checked exactly: on 20 seconds of real receiver audio it produced the same samples as ffmpeg, all 240 240 of them, and the sound and its level are unchanged. The digital decoders still receive the same 12 kHz audio.

The playback buffer no longer grows and stays grown. After any network hiccup the extra audio that arrived in a burst used to stay queued for the rest of the session, so a listener who once had a bad second kept the extra delay until they reloaded. A small difference between the listener's sound card clock and the receiver's clock also slowly shrank the buffer until the audio broke up for a moment, or grew it without limit. The page now watches how much spare audio is actually needed and, when the buffer has more than that for a minute, removes a few milliseconds at a time; when it runs short, it adds a few. The cut or the repeat is made where the sound repeats itself, one cycle of a tone or one voice pitch period, so it cannot be heard. Only what goes to the loudspeaker is touched: the decoders and the recorder still receive every sample. If the listener's connection turns out to need the larger buffer after all, the page waits longer before trimming again.

Phones start with a smaller safety margin: 50 ms instead of 100 ms. That is the second buffer step, which phones use by default; on the desktop page it is the x2 setting. Now that the buffer adjusts itself to the connection, the margin is only extra safety on top of the worst delay the connection showed in the last minute. A listener whose audio still breaks up can move the buffer control one step higher, as before.

Measured on a phone over home Wi-Fi: 140 ms from the packet leaving the server to the loudspeaker (35 ms of packet, 105 ms of buffer), against 231 ms with the old decoder, which also held its roughly 160 ms of audio out of sight of that figure. With the lower margin a phone should settle below 100 ms after its first minute. The network between the receiver and the listener adds to this and is outside anyone's control.

Three page addresses help to look into it. Adding ?diag=1 to the address of /mobile shows the delay and the state of the buffer under the controls; on the desktop page it writes the same line to the browser console (F12) every ten seconds. Adding ?flac=wasm brings back the old decoder and ?drain=0 turns the buffer adjustment off, so either can be compared with the new behaviour. These affect only the browser tab they are typed into.


QuotePlease unzip the file and replace the files in ~/PhantomSDR-Plus folder.
Then recompile both backend AND frontend and restart the server.

Powered by EzPortal