- Add PanelRXBlock between TX and Band with CTUN, VOL, NR/NB/SNB/ANF/MUTE
- Move AGC panel to sit directly below RX block for logical RX grouping
- Move DUP button into TX panel below MOX/TUN
- Rename PanelRX → PanelAGC to match its content
- Standardize block label top (2px) and first-control top (16px) across all
panels: AGC, SQL, CTCSS, STEP were inconsistent
- Fix left panel width restore after hide: save actual DPI-scaled width before
zeroing instead of hardcoding 232, preventing panel truncation on Win32 with
display scaling enabled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
(ClickFreq div StepHz)*StepHz always snapped downward; replaced with
((ClickFreq + StepHz/2) div StepHz)*StepHz so clicks above the midpoint
between two steps correctly snap to the higher one.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
RefreshAudioDevices was firing OnRXDevChange/OnTXDevChange when restoring
the combo selection, which called ApplyAudioDevice(-1,'') and wiped
FAudioOutDevName/FAudioInDevName before LoadValues could use them.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract helpers out of MainForm into structured modules:
- BoardUtils: BoardTypeName, FreqToBandIdx (removes duplication with DeviceForm)
- WisdomBuilder: TWisdomBuildThread + TWisdomProgressDialog
- UISync: TDeviceFoundSync/TStatusUISync/TDDCSeqSync via callbacks
- PlatformUtils: HasOpenGLSpectrumSwitch, CurrentScreenDPI
Minor cleanup: unused local constants, stale comments in AudioOutput.
Replaces TProgressBar in TWisdomProgressDialog with TFlatProgressBar,
drawn entirely via Canvas (plain rectangle, no native widget styling).
Dialog now receives the active TAppTheme so both dark and light themes
are applied consistently to background, label, and progress bar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- LFM: Position = poDesigned (was poScreenCenter, overriding our restore)
- RestoreWindowBounds: remove position scaling (L,T invariant across DPI);
scale size correctly per backend: LCLWin32 uses CurDPI/SavedDPI (physical px),
Qt6/GTK/Cocoa use SavedDPI/CurDPI (logical px, inverse); fix min-size
inflation on Qt6 (was MulDiv(900,DPI,96) which exceeds logical screen width
at 150%+ scale, forcing window to 0,0)
- SaveWindowBounds moved from FormDestroy to FormClose while window is still
stable; add guard for bogus RestoredLeft/Top values on Qt6 when maximized
- RestoreWindowBounds stores FRestoreL/T and re-applies position in AfterShowTick
(200ms after show) when WM frame extents are already known to Qt, fixing the
systematic right/down drift caused by unknown frame extents at FormCreate time
- Save and restore WindowState (maximized flag); skip AfterShowTick position
re-apply when window is maximized
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove ResizeSMeter (Pango font measurement + multiple SetBounds) from 60 Hz timer tick;
it is still called on actual resize events
- Throttle UpdateAGCLines WDSP API calls from 60 Hz to ~10 Hz (every 6 ticks)
- Optimize spectrum alpha-fix loop: write-only byte access instead of read-modify-write DWORD
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SpectrumView: rewrite DrawSpectrumGradient to blend directly into
FSpectrumBitmap via ScanLine instead of TLazIntfImage+BitBlt (stale DC
on win32). Add alpha=$FF fixup pass so pf32bit Canvas.Draw renders via
StretchBlt not AlphaBlend. Remove FSpecGradImg/FSpecGradBmp fields.
MainForm: mask exZeroDivide/exInvalidOp in FormCreate so WDSP DLL
divide-by-zero does not crash the DSP thread on win32 (Qt6 already
masks FPU exceptions globally).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add SampleRateOverlay.pas: TCustomControl overlay (top-left of spectrum)
with hide-panel button and 6 span buttons (48k–1536k), same hit-test
pattern as VfoOverlay
- Consolidate toolbar: move PanelTopVfoGroup and PanelSMeterRight into
PanelToolbar (height 72) instead of floating on the form
- Remove PanelSpanButtons (alTop spacer) that caused the ~1cm black strip
at the top of the spectrum
- Add separator line inside PanelToolbar anchored to its bottom edge,
with 16px left/right margins
- Fix left panel blocks starting Y offset (was 38, now 0)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AGC button in DSP row shows current mode (FAST/MED/SLOW/LONG/OFF).
Click toggles a picker row below; selecting a mode closes it, fires
OnAGCChange, and syncs MainForm BtnAGCMode buttons and DSP engine.
Overlay height expands 136→159 px while picker is open.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves CTCSS tone picker and FM step picker from inline TPanel+TFlatButton
arrays into a standalone FlatDropDown.pas module. TFlatDropDown owns the
popup panel, handles positioning and item selection, and fires OnSelect.
ApplyStyle syncs button colors on theme change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Third button row mirrors MainForm NR (cycle 0-4), NB (cycle 0-2),
SNB and ANF toggles. OnDSPChange event syncs state back to MainForm
buttons and DSP engine. Overlay height tightened to match top/bottom
padding.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- FM filter row now shows only NFM (11 kHz) and FM (16 kHz) matching MainForm
- OnModeFilterSelect updates FFMDeviation and FFilter index for FM mode
- Mode and filter button widths distributed evenly (proportional, not fixed BtnW)
- S-meter inset by extra 4 px on each side
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TSpectrumView remains the public facade for MainForm; waterfall, S-meter,
and ruler rendering are now in isolated units. Dead code removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Gives 44ms jitter margin for WiFi connections. Sound card mic path
is unaffected — StallCount never increments when FOnPullMic fills
the ring every tick.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pre-roll bug: when MIC_PREROLL_SAMP is an exact multiple of OPUS_FRAME_SAMP
(1920/960=2), the N<=Want branch filled the buffer but never flushed it,
losing the first 40ms of audio and leaving the ring empty long enough for
silence blocks to be injected into WDSP.
StallCount threshold raised from 2 to 4 (~43ms) to cover OS scheduler
jitter of up to 22ms, preventing false silence injection when an Opus
frame arrives slightly late relative to the DSP tick.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Opus decodes 960 samples per frame; the TX DSP thread consumes
512-sample blocks. 960 mod 512 = 448, so the ring always kept a
sub-threshold tail, causing TTXDSPThread to skip ticks and starve
the DUC hardware every ~20 ms.
FlushMicToCallback accumulates samples in FMicStageBuf and calls
FOnWebMic only when a full 512-sample block is ready. The remainder
stays in the buffer until the next Opus frame arrives. This ensures
FTXMicRing always receives data in multiples of 512, eliminating
the 0 < Avail < 512 dead-zone entirely.
FMicStageLen is reset together with FMicPreRollPos on new TX session
to prevent stale samples from a previous session mixing in.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WebOnMic: drop intermediate Singles[] array, read PSingle directly.
PushAudio: replace per-frame SetLength/array of Byte with pre-allocated
FWsAudioBuf field — eliminates heap allocation from the DSP thread.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove manual "Mic Source" (Radio/SoundCard) setting from UI and storage;
source is now determined automatically in ApplyMOX: HW PTT → txmsRadio,
MOX button/CAT → txmsSoundCard if audio device configured, else txmsRadio
- Replace "Line in" checkbox with "Mic jack" combo (Mic In / Line In);
when Line In is selected, Mic Boost is hidden and Line In Gain (-34.5..+12 dB,
step 1.5 dB) is shown and sent as DUC Specific byte 51
- Add Tip/Ring connector selector (Orion/OrionMkII boards 4/5 only, byte 50 bit 3);
control is hidden for other board types
- Fix byte 50 bit 1 (Mic Boost) suppressed when Line In is active
- Fix byte 51 comment polarity (was reversed: 0=+12dB; correct: 0=-34.5dB)
- New JSON fields: mic_line_in, mic_tip_ring, line_in_gain_db; mic_source removed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>