Commit Graph
100 Commits
Author SHA1 Message Date
sjgandOpenAI Codex f537e1a11b [feat](trx-client): add configurable initial map zoom
Add an HTTP frontend config option for the initial APRS map zoom,
expose it through frontend metadata, and apply it in the web UI.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 16:35:12 +01:00
sjgandOpenAI Codex 8c6c370563 [style](trx-frontend): rebalance aprs overlay title spacing
Tighten the spacing inside the APRS title while adding more room
between the title and the clear action.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:33:32 +01:00
sjgandOpenAI Codex 1ae44a714f [style](trx-frontend): reduce aprs clear text size
Scale the APRS overlay inline clear text down for better balance
with the enlarged APRS title.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:31:28 +01:00
sjgandOpenAI Codex 21a019a0fa [style](trx-frontend): enlarge aprs overlay title
Increase the APRS overlay header base text size so the title reads
larger alongside the clear action.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:28:50 +01:00
sjgandOpenAI Codex 81dca146cf [style](trx-frontend): enlarge aprs clear text
Increase the APRS overlay inline clear text size for stronger
readability.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:25:49 +01:00
sjgandOpenAI Codex 5b3d0c0865 [style](trx-frontend): increase aprs overlay text size
Increase the APRS overlay header text and make the inline clear text
match the row's base text size.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:24:32 +01:00
sjgandOpenAI Codex aa73a4bc00 [style](trx-frontend): simplify aprs overlay clear action
Render the APRS overlay clear action as inline clickable text inside
a span wrapper instead of a button-like control.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:23:08 +01:00
sjgandOpenAI Codex eec147c26f [style](trx-frontend): reduce aprs overlay header height
Cut the APRS overlay header sizing further so the row reads much
smaller and no longer dominates the overlay.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:20:46 +01:00
sjgandOpenAI Codex 579ce31bbd [style](trx-frontend): inset aprs overlay from edges
Offset the APRS overlay slightly from the waterfall edges so it reads
as a hovering strip and leaves the waterfall visible at the sides.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:20:08 +01:00
sjgandOpenAI Codex 69253959c8 [style](trx-frontend): shrink aprs overlay clear control
Reduce the APRS overlay clear control so it no longer sets the
header row height.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:18:42 +01:00
sjgandOpenAI Codex 17a643d070 [style](trx-frontend): polish aprs overlay clear control
Wrap the APRS overlay clear action in a styled span and place it
next to the APRS title for a tighter header layout.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:16:20 +01:00
sjgandOpenAI Codex 26e51447d7 [style](trx-frontend): tighten aprs overlay header
Reduce the APRS overlay header height by trimming spacing and scaling
down the clear control chrome.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:14:39 +01:00
sjgandClaude Sonnet 4.6 b24d6663a2 [style](trx-frontend-http): align RDS bar border-radius with UI standard
Replace 999px pill on #rds-ps-overlay with 6px to match the rest of
the UI button rounding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:13:20 +01:00
sjgandClaude Sonnet 4.6 436e1d8e23 [style](trx-frontend-http): align APRS bar border-radius with UI standard
Replace 999px pill radii with 6px (overlay), 4px (clear btn, pin),
3px (clear icon) — matching the standard button radius used throughout
the rest of the UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:12:53 +01:00
sjgandOpenAI Codex b6848c0c8e [style](trx-frontend): refine aprs web controls
Restyle the APRS clear button and tighten the APRS overlay bar to use
more compact, polished chrome while keeping the existing behavior.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:06:36 +01:00
sjgandClaude Sonnet 4.6 39c4f1d800 [style](trx-frontend-http): tighten APRS bar entry spacing further
Reduce line-height to 1.05, use 0.1rem vertical padding + hairline
border-bottom to separate entries instead of whitespace.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:01:59 +01:00
sjgandClaude Sonnet 4.6 c60b764acb [style](trx-frontend-http): restyle APRS bar clear button as slim rect
Smaller font (0.65em), horizontal padding only, line-height-based
height, tighter border-radius — produces a flat wide rectangle tag
rather than a square button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 15:00:52 +01:00
sjgandClaude Sonnet 4.6 1b34d75a31 [style](trx-frontend-http): sticky APRS bar header on scroll
Make the APRS/Clear header row position:sticky so it stays visible
when the frame list is scrolled. Adds a subtle backdrop-blur background
and a divider border so frames slide cleanly beneath it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:59:40 +01:00
sjgandClaude Sonnet 4.6 8359beae5c [style](trx-frontend-http): tighten APRS bar entry spacing
Remove inter-frame gap and reduce line-height 1.45→1.2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:59:09 +01:00
sjgandClaude Sonnet 4.6 3e5df90c8f [style](trx-frontend-http): APRS bar clear button rounded rect
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:58:02 +01:00
sjgandClaude Sonnet 4.6 8e353620de [style](trx-frontend-http): replace coord sub-line with inline pin button
When a frame carries a position, show a small 📍 button between the
timestamp and callsign on the same line. Title tooltip shows the
coordinates; clicking navigates to the Map tab. Removes the two-line
per-entry layout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:56:24 +01:00
sjgandClaude Sonnet 4.6 a7ba1eec5f [style](trx-frontend-http): tighten APRS bar spacing, shrink clear btn, remove cap
- Reduce frame line-height 1.45→1.3 and pos sub-line to 1.1 to close
  the gap between the info and coordinate rows within each entry
- Shrink clear button (smaller padding, 0.78em font)
- Remove 5-entry cap; full history visible via scroll

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:55:37 +01:00
sjgandClaude Sonnet 4.6 7c810729ed [fix](trx-frontend-http): fix APRS bar coords visibility, cap at 5 entries
Coordinates were clipped by white-space:nowrap on the frame row.
Split each frame into a .aprs-bar-frame-main line (nowrap+ellipsis)
and a separate .aprs-bar-frame-pos line for the coordinate button,
so coordinates are always visible regardless of info length.
Restore 5-entry cap (slice from history).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:51:02 +01:00
sjgandClaude Sonnet 4.6 5987a0b4a8 [feat](trx-frontend-http): add Clear button to APRS bar overlay
Small pill-shaped button in the header row, right-aligned. Clicking
it delegates to the existing aprs-clear-btn, clearing history, the
packet panel, and the bar in one shot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:49:48 +01:00
sjgandClaude Sonnet 4.6 37966ea29a [feat](trx-frontend-http): clicking APRS bar coords navigates to Map
Add window.navigateToAprsMap(lat, lon) which activates the Map tab
and pans to the given position at zoom 13. APRS bar frames that carry
a position render a clickable coordinate button that calls this
function. Button is styled inline with the frame text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:49:04 +01:00
sjgandClaude Sonnet 4.6 8ffe73c539 [fix](trx-server): drop CRC-failed APRS frames before sending to clients
Guard both the live broadcast (decode_tx.send) and the history store
(record_aprs_packet) so CRC-failed packets are never forwarded to
connected clients or replayed on reconnect. The decode logger still
receives all frames for debugging.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:47:54 +01:00
sjgandClaude Sonnet 4.6 df612aae00 [fix](trx-frontend-http): APRS bar shows full history, no truncation
Drop APRS_BAR_MAX cap and the separate aprsBarFrames ring buffer;
drive the bar directly from aprsPacketHistory (CRC-ok frames only).
Remove the 60-char info truncation. CSS opacity fading still kicks in
after frame 5; older frames are reachable by scrolling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:46:40 +01:00
sjgandClaude Sonnet 4.6 b552829c95 [style](trx-frontend-http): APRS bar spans full waterfall width
Stretch overlay edge-to-edge (left/right: 0), drop side borders and
border-radius for a full-width band look. Also enable pointer-events,
user-select, and overflow-y: auto so frames are scrollable and
copy-able.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:44:11 +01:00
sjgandClaude Sonnet 4.6 350087855f [fix](trx-frontend-http): gate APRS bar to PKT mode, reject CRC failures
- Hide bar whenever mode != PKT; app.js calls window.updateAprsBar()
  on every server-pushed mode change so the bar disappears immediately
- CRC-failed frames are excluded from the bar (both live and history
  restore); the [CRC] rendering path is removed
- Offset bar 1.2 rem from left edge for visual breathing room

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:41:39 +01:00
sjgandOpenAI Codex cbefdc15c4 [docs](trx-frontend): rename audio control labels
Update the web audio control labels in the markup and initialize the
same labels from JavaScript for consistency.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:41:13 +01:00
sjgandClaude Sonnet 4.6 aa367239de [fix](trx-rs): update PKT and AM default bandwidths
PKT: default 25 kHz, max 50 kHz (was 3 kHz / 25 kHz).
AM:  default 9 kHz,  max 20 kHz (was 6 kHz / 15 kHz).

Applied consistently across the UI mode-defaults table
(trx-frontend-http), server initial-mode logic (trx-server), and the
SoapySDR DSP channel (trx-backend-soapysdr).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:37:28 +01:00
sjgandClaude Sonnet 4.6 62c5889619 [feat](trx-frontend-http): add APRS bar overlay on overview strip
Show the last 5 received APRS frames as a compact overlay in the
bottom-left corner of the waterfall strip, styled similarly to the
RDS PS overlay (backdrop blur, pill border). Frames fade out by
recency via CSS sibling-selector opacity steps. Bar auto-hides when
empty and is cleared by the APRS clear button. Restored from
localStorage on page load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:37:17 +01:00
sjgandOpenAI Codex fce024b090 [style](trx-frontend): improve mobile web layout
Refine the mobile layout for the web frontend, add a sticky bottom tab bar,
and style the GitHub footer link as a badge.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:32:36 +01:00
sjgandClaude Sonnet 4.6 99ff619b9a [docs](trx-rs): add architecture and code design overview
Adds OVERVIEW.md with a comprehensive description of the project
architecture, crate layout, key types, data flow diagrams, DSP
pipeline, plugin system, and configuration reference.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 14:25:17 +01:00
sjgandOpenAI Codex 56d6d12d9e [refactor](trx-backend-soapysdr): extract spectrum snapshot helper
Move the spectrum FFT snapshot logic into a dedicated dsp module so dsp.rs stays focused on pipeline orchestration.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:58:30 +01:00
sjgandOpenAI Codex 08b8c80cc3 [refactor](workspace): split soapysdr demod and dsp modules
Split the SoapySDR backend demod and dsp code into focused modules while keeping behavior stable, and include the resulting formatting updates.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:55:48 +01:00
sjgandClaude Opus 4.6 441cdd3adb [style](trx-frontend): use select element for WFM denoise control
Replace the checkbox with an On/Off select dropdown to match the
styling of the other WFM controls (Deemp, Audio) in the controls row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:41:13 +01:00
sjgandClaude Opus 4.6 64bb9a0d42 [feat](trx-rs): expose WFM stereo denoise toggle in UI
Wire the StereoDenoise processor through the full stack:
- Add SetWfmDenoise command variant and RigCat trait method (trx-core)
- Add wfm_denoise field to RigFilterState with default true
- Add protocol command and bidirectional mapping (trx-protocol)
- Add rig_task command handler (trx-server)
- Implement set_wfm_denoise in SoapySdrRig backend
- Add /set_wfm_denoise API endpoint (trx-frontend-http)
- Add denoise checkbox in WFM controls with SSE sync and
  localStorage persistence

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:29:02 +01:00
sjgandOpenAI Codex 46bc96ddf2 [fix](workspace): resolve clippy warnings
Clean up the workspace so cargo clippy passes across all targets and features.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:22:44 +01:00
sjgandClaude Opus 4.6 523f3992f5 [feat](trx-backend-soapysdr): add WFM stereo denoise processor
Add frequency-selective attenuation of the L-R difference signal to
reduce stereo hiss on weak FM broadcasts. Uses the quadrature component
(diff_q) as a noise reference per US7292694B2 (Wildhagen/Sony).

The algorithm splits sum, diff_i, and diff_q into 6 overlapping subbands,
estimates per-band SNR from smoothed |diff_q|² noise power, and applies
an energy-weighted broadband gain to the original diff signal. This
preserves clean stereo content (<4 dB loss) while attenuating noise-only
diff channels (>6 dB reduction).

Enabled by default; toggled via set_denoise_enabled() / set_wfm_denoise().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 13:17:30 +01:00
sjgandOpenAI Codex cb5467ba34 [fix](trx-backend-soapysdr): retune wfm stereo gain
Increase the stereo matrix gain to 1.2 and trim the WFM output gain slightly to rebalance the decoded audio path.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:28:30 +01:00
sjgandOpenAI Codex d133b9082b [fix](trx-frontend): disable marker overlay for non-sdr
Collapse the shared signal marker overlay when no spectrum data is available so the non-SDR signal graph renders cleanly.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:22:24 +01:00
sjgandClaude Opus 4.6 ca6b83c967 [fix](trx-backend-soapysdr): raise wfm stereo matrix gain to unity
Output gain clamp catches any peaks from full-deviation signals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:22:15 +01:00
sjgandClaude Opus 4.6 313c9b39a6 [fix](trx-backend-soapysdr): increase wfm stereo matrix gain to 0.80
More stereo headroom for broadcast audio. With WFM_OUTPUT_GAIN at 0.35
the effective output is 0.28 peak, well within clipping margin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:19:50 +01:00
sjgandClaude Opus 4.6 f7c10a0185 [fix](trx-backend-soapysdr): remove agc from wfm chain, use fixed output gain
Replace both IQ AGC and audio AGC in the WFM path with a fixed output
gain of 0.35. AGC pumping on broadcast audio degrades stereo separation
and introduces audible artifacts. The IQ hard limiter already normalizes
input magnitude, and the WFM decoder's internal deemphasis + matrix gain
provides consistent output levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:17:14 +01:00
sjgandOpenAI Codex c2b287e000 [fix](trx-frontend): fix audio callback parse error
Rename the duplicate callback-local variable so app.js loads cleanly and dependent plugin scripts can access shared helpers.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:08:22 +01:00
sjgandClaude Opus 4.6 8ec442da0a [docs](trx-rs): add DSP chain performance optimization guidelines
Document lessons learned from WFM stereo decoder and audio encoding
optimization: quadrature NCO, double-angle identities, AVX2 batching,
polyphase resampler design, filter matching, stereo detection decimation,
and opus encoder tuning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:06:27 +01:00
sjgandOpenAI Codex a61f901024 [fix](trx-frontend): restore non-sdr signal graph and audio meter
Keep the non-SDR signal graph visible and drive the audio level bar from decoded sample levels instead of packet size.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:06:11 +01:00
sjgandOpenAI Codex f9492633d9 [fix](trx-frontend): add footer project link and safari favicon fix
Add the trx-rs GitHub link in the footer and make favicon handling more explicit for Safari.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 11:03:47 +01:00
sjgandOpenAI Codex f8507698f4 [fix](trx-frontend): hide signal visuals for non-sdr
Hide the combined waterfall and spectrum block when filter controls are unavailable so non-SDR rigs do not show those visuals.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:59:09 +01:00
sjgandOpenAI Codex 99c6ff0e87 [fix](trx-frontend): unify signal markers and clamp axis labels
Render the BW and tuned-frequency markers on a shared overlay and keep spectrum axis labels bold and inside their box.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:54:15 +01:00
sjgandClaude Opus 4.6 00a453f18c [perf](trx-server): set opus complexity to 5 and raise default bitrate to 256k
Set opus encoder complexity from default (9-10) to 5 for both cpal and
SDR audio paths, significantly reducing encoding CPU usage with minimal
quality impact at these bitrates. Raise default bitrate from 192 kbps to
256 kbps for higher fidelity stereo audio.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:42:00 +01:00
sjgandOpenAI Codex e3c7231650 [fix](trx-frontend): group signal visuals in main tab
Wrap the waterfall and spectrum in a shared main-tab block so lower sections and other tabs keep consistent spacing.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:37:53 +01:00
sjgandOpenAI Codex 6e8b23052d [fix](trx-frontend): unify markers and active theme toggle
Keep the waterfall and spectrum markers visually continuous and style the theme toggle to match the active theme.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:35:13 +01:00
sjgandOpenAI Codex bfbf18ae21 [fix](trx-frontend): add room in rds overlay
Increase the RDS overlay padding and width so the waterfall badge has more breathing room.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:32:41 +01:00
sjgandOpenAI Codex da2cc91925 [fix](trx-frontend): restore sdr frequency accent and waterfall gap
Keep the SDR frequency input accented without extra VFOs and restore the bottom spacing below the waterfall.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:31:35 +01:00
sjgandOpenAI Codex 93108c1248 [fix](trx-frontend): tighten two-state step scale toggle
Resize the step scale control so it reads as a balanced two-option toggle instead of a leftover segmented control.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:27:11 +01:00
sjgandOpenAI Codex 816780aa6b [fix](trx-frontend): compact wfm controls layout
Align the WFM options into a concise control strip with consistent sizes and spacing in the main window.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:25:52 +01:00
sjgandOpenAI Codex 3ea516d27c [fix](trx-frontend): clarify tune step labels
Rename the tune-step scale labels so the divisor toggle reads clearly in the frequency controls.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:22:56 +01:00
sjgandOpenAI Codex ec1ea49092 [fix](trx-frontend): show bw label only during resize
Lift the bandwidth label slightly and render it only while the bandwidth edges are being dragged.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:20:48 +01:00
sjgandOpenAI Codex a2872dece5 [fix](trx-frontend): mirror spectrum controls on waterfall
Remove the gap under the waterfall and extend tuning markers plus wheel, click, and bandwidth drag interactions to the overview canvas.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:18:29 +01:00
sjgandOpenAI Codex 740d678357 [fix](trx-frontend): increase spectrum headroom and match heights
Add 10 dB of spectrum headroom and keep the overview waterfall the same height as the spectrum plot.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:14:22 +01:00
sjgandClaude Opus 4.6 626d5e2ec5 [perf](trx-backend-soapysdr): quadrature NCO and decimated stereo detection
Replace per-sample sin_cos(pilot_phase) with a quadrature NCO that
advances via complex rotation (4 muls + 2 adds vs transcendental).
Renormalize every 1024 samples to prevent magnitude drift.

Decimate stereo detection logic (pilot coherence, lock, drive,
hysteresis) to run every 16 composite samples instead of every sample.
Accumulate pilot_mag and pilot_abs over the window and process averaged
values, scaling the IIR coefficients accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:07:16 +01:00
sjgandOpenAI Codex 52aeb7b694 [fix](trx-frontend): remove top bar overlap with waterfall
Keep the top bar above the waterfall and remove the rounded logo box styling.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 10:02:32 +01:00
sjgandOpenAI Codex a9aee190d3 [fix](trx-frontend): move logo bar content into top bar
Move the logo/header cluster into the top bar on the left side.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:56:39 +01:00
sjgandClaude Opus 4.6 0c35051630 [perf](trx-backend-soapysdr): eliminate per-sample sin_cos and atan2 calls
Derive sin/cos of PLL phase error directly from I/Q arms (q/mag, i/mag)
instead of calling atan2 + sin_cos. Use double-angle identity to compute
38 kHz carrier (sin2θ = 2·sinθ·cosθ, cos2θ = 2·cos²θ-1) from the
rotated pilot sin/cos, eliminating the second sin_cos call entirely.
Drop Butterworth from 6th to 4th order (resampler Blackman-Harris now
handles stopband). Use power-of-2 bitmask for ring buffer indexing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:52:51 +01:00
sjgandClaude Opus 4.6 4f99c23e7a [perf](trx-backend-soapysdr): reduce polyphase resampler phases from 128 to 64
Halves the coefficient bank from 128×32 to 64×32 (16 KB → 8 KB) for
better L1 cache utilization while maintaining sufficient fractional
sample resolution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:47:13 +01:00
sjgandClaude Opus 4.6 7eb88b6669 [perf](trx-backend-soapysdr): use circular buffer for wfm resampler history
Replace shift_append (O(N) rotate_left per sample) with a circular buffer
index for O(1) writes. The polyphase resampler now reads from the ring
buffer directly, eliminating 3 × 32-element memmoves per composite sample.
Remove unused dot_product functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:46:35 +01:00
sjgandClaude Opus 4.6 132cd5b950 [perf](trx-backend-soapysdr): batch wfm discriminator with avx2 atan2
Pre-compute all FM discriminator outputs using demod_fm_with_prev which
processes 8 samples at a time via AVX2 atan2, then iterate the scalar
results through the rest of the stereo pipeline. Eliminates per-sample
f32::atan2 calls from the inner loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:42:49 +01:00
sjgandClaude Opus 4.6 36d0e7e862 [perf](trx-backend-soapysdr): reduce wfm resampler taps from 64 to 32
With Blackman-Harris window and proper cutoff (~0.24), 32 taps still
provides 60+ dB stopband rejection. Halves the per-sample MAC count
from 192 to 96 across the three resampler channels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:41:26 +01:00
sjgandClaude Opus 4.6 380231a68f [perf](trx-backend-soapysdr): improve wfm stereo resampler and pilot rejection
Increase polyphase resampler phases from 32 to 128 for finer fractional
sample positioning. Replace Hamming window with Blackman-Harris for ~92 dB
stopband rejection. Add pilot notch on composite signal before diff demod
to prevent 19 kHz × 38 kHz intermod products in the stereo difference
path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:37:11 +01:00
sjgandClaude Opus 4.6 700e5c9fab [perf](trx-backend-soapysdr): increase wfm resampler taps and filter order
Increase polyphase resampler taps from 16 to 64 for sharper anti-alias
stopband rejection. Upgrade sum/diff lowpass filters from 4th-order to
6th-order Butterworth (three biquad stages) for ~36 dB/octave rolloff,
improving stereo separation by better rejecting the 38 kHz subcarrier
residuals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:19:11 +01:00
sjgandClaude Opus 4.6 1ba9c9dd3e [fix](trx-backend-soapysdr): widen wfm audio bandwidth to 18 kHz
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:11:50 +01:00
sjgandClaude Opus 4.6 4994a869f9 [fix](trx-backend-soapysdr): compute resampler cutoff from actual rate ratio
The fixed WFM_RESAMP_CUTOFF of 0.94 passed frequencies up to 94 kHz at
200 kHz composite rate, while the output Nyquist is only ~24 kHz. The
38 kHz demod products in the stereo diff path were only ~31 dB attenuated
by the Butterworth and aliased back into 10-20 kHz audio, causing treble
corruption in stereo mode. Now the cutoff is computed as
audio_rate / composite_rate, properly anti-aliasing the polyphase
resampler output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 09:07:07 +01:00
sjgandClaude Opus 4.6 a5e66ed287 [fix](trx-backend-soapysdr): revert wfm resampler taps back to 16
32 taps caused audio silence on real signals. Revert to 16 taps
which works correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 02:20:42 +01:00
sjgandClaude Opus 4.6 edb456e843 [fix](trx-backend-soapysdr): replace avx2 atan2 with high-precision polynomial
Replace the low-accuracy 0.273 linear atan approximation with a
7th-order minimax polynomial (max error ~2.4e-7 rad vs ~0.004 rad).
Use branchless |y|>|x| argument reduction instead of y/x division
with quadrant fixup, avoiding division-by-zero and NaN branches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 02:10:02 +01:00
sjgandClaude Opus 4.6 cb4b81ca94 [fix](trx-backend-soapysdr): use precise atan2 in wfm discriminator and pll
Replace fast_atan2 polynomial approximation with f32::atan2 in the WFM
stereo decoder's FM discriminator and pilot PLL. The approximation
introduced harmonic distortion (~0.22 deg error) that manifested as
treble artifacts on strong/overdeviated broadcast signals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 02:04:06 +01:00
sjgandClaude Opus 4.6 8f6a5af4ec [fix](trx-backend-soapysdr): hard-limit iq magnitude before wfm discriminator
Normalize IQ samples exceeding unit magnitude before the FM
discriminator. The discriminator only uses phase, so clamping
amplitude prevents overdeviated signals from producing clipped
composite baseband without losing frequency information.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:58:16 +01:00
sjgandClaude Opus 4.6 13de90d664 [fix](trx-backend-soapysdr): increase wfm resampler taps from 16 to 32
Doubles the polyphase FIR length for the composite-to-audio rate
converter, improving stopband rejection from ~25 dB to ~50 dB.
This reduces treble distortion from imaging artifacts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:55:59 +01:00
sjgandClaude Opus 4.6 8d0dc17317 [chore](trx-backend-soapysdr): remove unused smoothstep01
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:49:27 +01:00
sjgandClaude Opus 4.6 815efdb1ae [fix](trx-backend-soapysdr): match sum/diff filters and simplify stereo blend
- Set STEREO_DIFF_BW_HZ = AUDIO_BW_HZ so both filter paths have
  identical group delay (improves multitone separation by ~10 dB).
- Zero out STEREO_SEPARATION_PHASE_TRIM (unnecessary with matched filters).
- Replace gradual blend ramp with binary blend: full stereo at pilot
  lock, mono when unlocked. The hysteresis thresholds already handle
  noisy signals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:48:16 +01:00
sjgandClaude Opus 4.6 13576f73aa [test](trx-backend-soapysdr): add multi-tone wfm stereo separation test
Test L-only and R-only signals with tones at 400, 2000, 8000 and
14000 Hz to catch frequency-dependent group delay and phase trim
issues that the single 1 kHz test misses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:42:39 +01:00
sjg 33b218fce3 [perf](trx-backend-soapysdr): reduce frame emission overhead
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:41:34 +01:00
sjgandClaude Opus 4.6 2ed4aaf46d [fix](trx-backend-soapysdr): tune wfm stereo filter bw and matrix gain
Restore AUDIO_BW_HZ to 15.8 kHz for cleaner mono path, widen
STEREO_DIFF_BW_HZ to 18 kHz for better high-frequency stereo detail,
and raise STEREO_MATRIX_GAIN from 0.30 to 0.50 (mathematically correct
unity gain for the L=(S+D)/2 stereo matrix).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:37:15 +01:00
sjg e7997f8492 [perf](trx-backend-soapysdr): use ring history for wfm resampler
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:34:50 +01:00
sjgandClaude Opus 4.6 a6c3a85c8d [fix](trx-backend-soapysdr): match wfm sum/diff filter cutoffs at 18 kHz
Raise both AUDIO_BW_HZ and STEREO_DIFF_BW_HZ to 18 kHz so the L+R and
L-R filter paths have identical group delay across the full audio band.
The previous mismatch (15.8 vs 14.5 kHz) caused frequency-dependent
phase errors in the stereo matrix that degraded real-world separation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:31:34 +01:00
sjg f9691fee1e [perf](trx-backend-soapysdr): vectorize wfm discriminator angle
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:30:41 +01:00
sjg 72219956d9 [perf](trx-backend-soapysdr): trim wfm resampler taps
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:21:50 +01:00
sjgandClaude Opus 4.6 b2ce62646c [fix](trx-backend-soapysdr): improve wfm stereo blend threshold
Raise the stereo blend floor from 0.55 to 0.75 at pilot lock and lower
the full-blend ceiling from stereo_detect_level 0.92 to 0.70.  This
gives real-world signals with moderate pilot strength much better L/R
separation (~17 dB immediately at lock vs ~5 dB before) and reaches
full unity blend sooner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:20:38 +01:00
sjg 926a02e043 [perf](trx-backend-soapysdr): streamline wfm decode loop
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:19:47 +01:00
sjg b42e557a25 [perf](trx-backend-soapysdr): pack iq fir filtering
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:17:16 +01:00
sjg 198efa2092 [perf](trx-backend-soapysdr): update fir overlap in place
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:13:10 +01:00
sjg 7a6467320b [perf](trx-backend-soapysdr): reuse fir scratch buffers
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:10:34 +01:00
sjg ca0f236f4a [perf](trx-backend-soapysdr): reduce mixer and buffer overhead
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:07:19 +01:00
sjg bec3fc72d3 [fix](trx-backend-soapysdr): widen wfm stereo image
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 01:03:05 +01:00
sjg 6f37f9c66b [fix](trx-backend-soapysdr): refine wfm stereo tracking
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 00:58:20 +01:00
sjg e84a0599fa [feat](trx-backend-soapysdr): add avx2 wfm hot paths
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 00:52:53 +01:00
sjg 3e88c3f5d9 [feat](trx-backend-soapysdr): speed up fir and widen wfm resampler
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 00:50:04 +01:00
sjg 5411607b63 [fix](trx-backend-soapysdr): honor frontend wfm bandwidth
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 00:46:08 +01:00
sjg 17c70f89e5 [fix](trx-backend-soapysdr): fully reset wfm decoder on tune
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-01 00:41:28 +01:00