github aethersdr/AetherSDR v26.8.2
AetherSDR v26.8.2 — Experimental Hermes-Lite 2 & Icom IC-705, SPE Expert Amps

5 hours ago

57 commits across 14 contributors since v26.8.1. Full detail in CHANGELOG.md.

New radio families — Hermes-Lite 2 and Icom IC-705

This release introduces experimental support for two more radios on the vendor-neutral IRadioBackend seam: the Hermes-Lite 2 and the Icom IC-705. Experimental means exactly that — both are new, neither is a supported radio family yet, and FlexRadio remains the supported target. See Supported Hardware for what each backend does and does not do today.

We want to hear from you on both. Bug reports and feature requests against the experimental backends are open and wanted — file a bug report or a feature request, and say which radio and which firmware you are on. Reports from testers are how these families move from experimental to supported.

Headlines

SPE Expert amplifiers — 1.3K-FA / 1.5K-FA / 2K-FA.

  • A second peripheral amplifier following the ACOM precedent, entirely outside the radio seam. Serial (115200 8N1) or ser2net TCP, raw or telnet, both verified on real hardware; poll-silence detection, so a TCP link that outlives the amp being switched off is reported as such; model identification from the status ID field; and an RFC 2217 DTR/RTS power-ON pulse that works over the network. The applet carries power / antenna-SWR / ATU-SWR gauges — the power gauge rescales with the selected LOW/MID/HIGH level, matching the amp's own display — plus V/I/temperature readouts, warning and alarm banners, and the front-panel keystrokes. (#4531)

Spots, schedules and band data — three new overlays.

  • N1MM+ / DXLog contest bandmap spots over a SmartSDR-CAT-compatible UDP XML listener, with dupe / needed-multiplier / CQ / busy / bust status on the panadapter and eight configurable status→colour swatches. Default port 12060 matches the FocusHelperN1MMPort SmartSDR documents, so existing broadcast configs work unchanged. N1MM is the only feed that explicitly says when to add, update and remove, so spots are keyed by callsign+band rather than deduped by frequency. (#4678)
  • The EiBi shortwave broadcast schedule in its own SpotHub tab — auto-start, live spot counter, forced re-download, conditional If-Modified-Since updates on a 7-day threshold, and a customisable spot colour that repaints active markers live. Resolves 289 country codes, 560 language/mode codes, target areas and 1,629 transmitter sites into rich-text tooltips. (#4822)
  • The KiwiSDR DX Community database as an independent, opt-in overlay for shortwave utility, beacon, broadcast and DX spots: cyan diamond markers on the band-plan strip, tooltips with frequency, station, mode, passband cuts and notes, and click-to-tune that sets frequency, filter bandwidth and — with SpotHub's Auto on — the mode, through a normalising whitelist so an unrecognised mode string can never reach the radio as a command. (#4828)
  • US 60m follows the FCC Report & Order that took effect on 13 February 2026. The ARRL plan still carried the pre-2026 five-channel allocation, drawing a 100 W channel over spectrum capped at 9.15 W ERP and omitting 15 kHz US operators have had since February. The new 5351.5 – 5366.5 kHz segment is added with its own colour so the power boundary reads straight off the panadapter, the retired 5358.5 kHz channel is removed, and the four retained channels keep their historic numbering (1, 2, 4, 5) so markers still agree with your existing logs. Separately, the 60m band edges clipped the top 1.3 kHz of the 5405 kHz channel, so band-stack entries in that sliver saved under "Other" and digital-mode band matching failed. (#4762)
  • Smaller items in the same area: the SpotHub Time column sorts at last (only Freq ever returned a sort value, so once you sorted by frequency there was no way back) (#4751); a status-message field in the FreeDV Reporter panel that stays in sync with SpotHub → FreeDV (#4757); and KiwiSDR receiver lists import and export as CSV, merging on a normalised endpoint so re-importing the same file is idempotent — passwords are never exported, they stay in the OS keychain (#4753).

Spectrum, waterfall and 3D FFT.

  • K4-style mini-pan — a small, detachable ±5/±10 kHz window centred on the active VFO, independent of the main panadapter and usable when it is hidden (Minimal Mode) or alongside third-party contest logging. It is an independent top-level window, so it floats over other applications and survives AetherSDR being minimised. Live on a FLEX-6500 at ~26 Hz/bin, five times finer than the 200 kHz main pan. (#4562)
  • The 3D stacked-trace wedges close. Every row covered the same frequency span while the far rows narrowed with perspective, leaving two empty black triangles flanking the surface. A new 3D Span slider sits under Display → 3D VIEW, and 0 restores today's rendering exactly. (#4779)
  • 3D FFT works on the Raspberry Pi 5 againdss_mesh is the only shader using the flat qualifier, no 140 slice existed, and the Pi's v3d driver fell back to a 120 slice the shader cannot compile against. Desktop GPUs picked the 150 slice, which is why CI never saw it. (#4754) 3D FFT history outlines render on Linux/OpenGL too. (#4730)
  • Windows panadapters are no longer blank under software OpenGL — with AETHER_NO_GPU or QT_OPENGL=software, the panadapter chose OpenGL while the hidden WAVE scope had already chosen D3D11 for the same top-level window, and Qt rejects mixed QRhi APIs in one backing store (13,804 QRhiWidget: No QRhi messages, every panadapter transparent). The default D3D11 path is unchanged. (#4748)
  • A headless Wayland session automatically prefers xcb — the typical VNC/wayvnc case, where there is no DRM scanout, so every frame's makeCurrent fails with EGL_BAD_MATCH and AETHER_NO_GPU=1 does not help. Detection is deliberately tri-state, a user-set QT_QPA_PLATFORM still wins, and the decision is logged at startup so it is diagnosable from a support bundle. (#4755)
  • Waterfall interpolation is clamped at history boundaries, ending the occasional bright, dark or scrambled horizontal line during rapid pan or zoom (#4794), and Waterfall Blanker rows stay in one frequency frame instead of permanently retaining a shifted row (#4802).
  • A GPU that fails mid-session now says sorenderFailed() fired with nothing listening, leaving a blank panadapter and no explanation. Each GPU spectrum widget now shows a persistent warning card over the affected pan. (#4787)
  • Off-screen slice indicators centre on a single click — the active indicator, the one you are most likely to be chasing, emitted nothing at all. (#4795)

Receive DSP and audio.

  • MNR delivers the attenuation it advertised — its minimum-statistics estimator took a raw minimum across 25 periodograms and left the Wiener gain near unity; maximum-strength stationary attenuation goes from 4.54 dB to 24.4 dB, scale-invariant within 1 dB, with +18.8 dB SNR improvement on speech-like input for −2.8 dB of desired-signal level. Your existing strength setting now removes far more noise than it did, so start lower than you are used to. The redundant Enable MNR checkbox is gone with it — the method selector is the sole enable, consistent with every other AetherDSP method. (#4807)
  • DFNR no longer pumps on stereo — it drove a delayed dry stereo signal with a fast processed-to-dry power envelope, the same family of fault already fixed in RN2. (#4788)
  • The AetherVoice EQ canvas caches its layers instead of rebuilding the band response, grid, labels and band-plan decoration on the GUI thread every analyzer frame: on the same Windows VM, 73.1% → 37.4% of one core at 1280×900, and 82.8% → 43.1% at 2200×1300. (#4808)
  • Audio mute commands reach the model. The three mute setters sent their command and returned, never assigning and never emitting, and FlexBackend is the only parser of those statuses — so on every other backend the flags sat at their false initialisers for the whole session: mute the headphones, nudge the volume, and the glyph silently flipped back. (#4772) The title-bar headphone mute also reconciles with the radio, so a second Multi-Flex client changing it no longer leaves the icon lying (#4733), and the header speaker emoji follows local PC audio mute (#4628).

CW keying, to spec.

  • Iambic sidetone timing. workerLoop() armed each deadline as now() + duration, read after the previous wait returned, so every element ran long by a fresh error that never self-corrected. Deadlines now advance on an absolute steady_clock grid anchored at squeeze start, tracked in nanoseconds, and key transitions are timestamped into a lock-free ring and mapped to exact sample offsets instead of being quantised to an audio-block boundary. Measured on real hardware (Intel MBP, HaliKey Serial): 45.70 ms/unit → 40.002 ms/unit at a 30 WPM setting — 26.26 WPM → 29.998 WPM. (#4823)
  • Mode B no longer drops the trailing element on a clean simultaneous release. The memory latch ran only at condition-variable wakes, and a wake caused by a release always observes post-release state, so the keyer behaved like Mode A — routine on the serial path, where a 10 ms poll collapses both edges into one event. (#4810)

Copy Assist (speech-to-text).

  • A GPU that cannot be used falls back to CPU instead of taking the app down. On a machine whose Vulkan stack enumerates GPUs but cannot create a logical device, Copy Assist crashed the process silently. It is the second GPU attempt that kills it, not the first — nothing in try/catch can intercept it, so the fix is to never make the second attempt. The selector now labels unusable devices, resolves to the first usable one (else CPU), and says in plain language when a fallback has happened; previously the dialog went on naming a GPU that was running nothing while the queue grew from 7.6 s to 22.5 s with no explanation. (#4767)
  • Enabling speaker labels no longer freezes the GUI — rebuilding the engine on the GUI thread performed an unbounded worker-thread join, so ONNX work already in flight blocked Qt event processing and could starve radio servicing. (#4739)
  • Segment overlap for boundary-word recovery — when an utterance is force-closed by the max-length cap the cut can fall mid-word, and each segment is decoded independently, so the straddling word is mangled or dropped. A small window of trailing audio now carries into the next segment, at zero inference cost and across all three backends. Opt-in, off by default — a "Boundary overlap" slider at 0 ms. (#4837, RFC #4821)

Controllers, MIDI and TCI.

  • Rotary action mapping for the Ulanzi Dial — a Tuning: rotary action selector covering frequency, filter bandwidth, slice and master volume, panadapter zoom, RIT/XIT, AGC-T, RF gain, APF, CW speed and RF power, with the dial-press combo relabelled Single tap:. Filter-preset stepping now scales by the magnitude of the rotary step rather than discarding it, and an unrecognised action ID is validated before dispatch and short-circuits as a harmless no-op. (#4702, #4758, #4834)
  • Manual MIDI binding entry and per-row editing — a Manual… button beside Learn types in a binding's channel, message type and note/CC number directly, and a ✎ button on each row reopens the same form pre-filled to correct what Learn captured wrong, without re-learning. The settings format is untouched, so a file written by this build loads in older ones. (#4790)
  • TCI: a use-after-free in the DAX RX path is fixed — reproduced under ASan on the parent commit, triggered deterministically by a client switching from 48 kHz to native 24 kHz with sub-threshold samples still staged. (#4789)
  • TCI: malformed volume: and modulation: input is rejected, not reinterpreted. An empty volume: argument parsed to 0.0 — and 0 dB is the top of the range, so the malformed command landed on the loudest value it can express. An unrecognised modulation name silently set USB while the notification echoed the client's own wrong name. (#4848)
  • The aether.cat log category is relabelled "TCI / CAT / rigctld"TciServer.cpp is 69.7% of its call sites, and operators chasing a TCI problem scanned the checkbox grid, saw no mention of TCI, and reasonably concluded there was none to turn on. (#4761)

Platform and packaging.

  • Windows: vcomp140.dll now ships app-local. AetherSDR.exe genuinely imports the MSVC OpenMP runtime, and our packaging never shipped it — leaving one file as the single machine-wide dependency in the entire payload, so any other installer that repaired, downgraded or removed the VC++ redistributable took AetherSDR down, and reinstalling AetherSDR could not fix it. All three Windows artifacts were affected. A new check-deploy-dependencies.ps1 CI gate walks every PE in the payload and fails when an MSVC runtime import is not app-local, checked before the System32 probe — build machines have the redistributable installed, which is exactly how this shipped unnoticed through every release since ASR landed. (#4782)
  • Linux: the Connect to Radio dialog reopens reliably under xcb. Once connected the dialog auto-hides, and reopening it called show() successfully — isVisible() reported true — yet nothing appeared, not even in the window switcher, making it impossible to disconnect. xprop confirmed the window wedged in the ICCCM Withdrawn state under Mutter/XWayland. This matters because QT_QPA_PLATFORM=xcb is the practical workaround for the native-Wayland render stalls in #4725. (#4803)

GUI and workflow.

  • A thumbnail view for the Choose Background Image dialog, with an Explorer-style small-icons/thumbnails toggle and a preview pane that grows with the dialog. Decoding runs off the GUI thread behind the same decompression-bomb guard used for callsign photos. (#4726)
  • The analog power gauge picks the right scale at connect instead of coming up on 120 W and only correcting after a band change. (#4845)
  • The FFTW wisdom popup stopped strobing — a deliberate infinite opacity animation past 90% caused the reported flashing and, supplying no elapsed time or status, left a slow process still looking frozen. It is now a low-key activity indicator with a monotonic timer and a "still working" explanation after 10 quiet seconds. (#4729)
  • The PGXL fan-mode dropdown fits its widest item — its hand-rolled stylesheet set a 10px font on the combo but not on its popup, a separate top-level window that does not inherit it, so "Fan: Contest" was elided on a large enough default font. Root cause and fix worked out by the triage bot on the issue. (#4731, #4752)
  • Every model-lifetime callback is installed once. Two self-connections were owned by the RadioModel rather than the replaceable backend, so every radio-family switch accumulated another capability publication and TX-power push. (#4599, #4626)

Tests, tooling and docs.

  • An undefined downcast that aborted the sanitizer job before a single result line printed is gone. (#4740, #4741)
  • HERMES.md gains §22 on WDSP channel-open cost and FFTW wisdom plus a corrected §14.6; docs/CERTIFICATION.md gains lessons 1.19–1.31 from the Icom bring-up — the first radio brought up with radiocert in hand rather than after the fact; and there are new design notes for the SPE amplifier, the Icom CI-V backend and HL2 frequency calibration.

Contributors

Big thanks to @rfoust (13 PRs — the MNR estimator rebuild, DFNR stereo, the AetherVoice EQ layer cache, the waterfall interpolation and Blanker frame fixes, QRhi failure surfacing, the software-OpenGL and Linux/OpenGL 3D FFT fixes, the TCI RX buffer lifetime, the ASR speaker-label freeze, the FFTW wisdom popup, off-screen slice centring, and the model-lifetime callback sweep), @jensenpat (9 PRs — HL2 manual notch filters and frequency calibration, the first-connect freeze and wisdom persistence, AM/SAM DC blocking, the CWX/DVK/FDX capability gates, the transmit-loopback test rehabilitation, the Icom CI-V backend and the IC-705 bring-up, and the 60m band-plan update), @M7HNF-Ian (8 PRs — the SpotHub Time sort, the PGXL fan-mode dropdown, KiwiSDR CSV import/export, the FreeDV Reporter message field, the power-gauge scale fix, the ASR tap channel-count fix, the overlay-menu stylesheet scoping, and the TCI input-validation fixes), @nonoo (6 PRs — the Ulanzi rotary action mapping and its two follow-ups, the EiBi and KiwiSDR DX spot overlays, and the header speaker-mute glyph), @nigelfenton (5 PRs — networked Icom backend work including a panadapter crash fix, the AetherModem seam-backend TX fix, the aether.cat relabel, the sanitizer downcast fix, and the HID report-size note), @skerker (4 PRs — the ASR GPU failure latch and CPU fallback, manual MIDI binding entry, and both CW keyer fixes), @K5PTB (3 PRs — the RPi5 shader dialect fix, headless-Wayland platform selection, and ASR segment overlap), @ten9876 (3 PRs — the audio-mute model mirror, the 3D stacked-trace wedge closure, and the Windows OpenMP runtime packaging with its CI gate), @opalito (SPE Expert amplifier support), @nreed97 (N1MM/DXLog spot ingestion), @motoham88 (the K4-style mini-pan), @wa2n-code (the background-image thumbnail dialog), @g4ivv (the xcb Connect dialog reopen), and @Krishnanand-G (the title-bar headphone mute reconcile).

Thanks also to @csylvain (KB3CS) for catching that the 60m triage was arguing from superseded law, @rsaue for a Mode B root-cause analysis that verified accurate in full, and @williamscody for the keyer timing logs that made both halves of the sidetone fix measurable.

73, Pat KI6BCJ & Claude (AI dev partner)


Downloads

Linux AppImage (x86_64 / aarch64), macOS DMG (Apple Silicon + Intel, signed + notarized), Windows installer (setup.exe) + portable ZIP, and the Stream Deck and StreamController plugins are attached below — built and signed by CI workflows on this tag.

Full diff: v26.8.1...v26.8.2

Verifying releases: see docs/VERIFYING-RELEASES.md. Signing key: docs/RELEASE-SIGNING-KEY.pub.asc.

Don't miss a new AetherSDR release

NewReleases is sending notifications on new releases.