feat: unify sample-rate presets across desktop + web UIs

Sample-rate (span) presets were duplicated in three places and none was
authoritative: HPSDR set hardcoded in the desktop overlay (SPAN_RATES),
Pluto set in backend caps, and a separate hardcoded list in the web JS.
The web showed HPSDR rates even on Pluto, and the web adapter silently
dropped any rate outside a hardcoded HPSDR whitelist (so Pluto-only rates
like 960k/2304k never switched).

Single source of truth = backend caps -> controller:
- HPSDRNetwork.Caps now fills RatePresets [48k..1536k] (was nil).
- RadioBackend: named type TBackendRateArray.
- TRadioController.SampleRatePresets returns BackendCaps.RatePresets.

Both UIs derive from it:
- Desktop: ApplyBackendCapsToUI always feeds the overlay from
  SampleRatePresets (overlay no longer owns the HPSDR list).
- Web: WebServer.SetRatePresets + rate_presets in state JSON; hosts
  (daemon OnState/startup, GUI ApplyBackendCapsToUI/startup) push
  SampleRatePresets; JS builds span buttons dynamically from it.
- WebAdapter.SyncSpan validates against SampleRatePresets instead of a
  hardcoded whitelist, so any backend rate is accepted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 13:52:03 +03:00
co-authored by Claude Opus 4.8
parent d78d835485
commit 6b695ce756
8 changed files with 87 additions and 21 deletions
+13 -4
View File
@@ -478,6 +478,7 @@ type
procedure OnAlexSettingsChange(const A: TAlexSettings);
procedure OnXvtrSettingsChange(const X: TXvtrSettings);
procedure PushXvtrToWeb;
procedure PushRatePresetsToWeb; // backend sample-rate пресеты → web
// XVTR helpers
function FindXvtrIdxForFreq(FreqHz: Double): Integer;
function XvtrTranslate(VisibleHz: Double): Double;
@@ -882,6 +883,7 @@ begin
if FWebEnabled then FWebServer.Start;
PushXvtrToWeb;
PushDeviceListToWeb; // saved-устройства сразу видны web-overlay
PushRatePresetsToWeb; // дефолтный бэкенд до connect; перезапишется на смене
FillChar(FCATLastGlobal, SizeOf(FCATLastGlobal), 0);
FCATLastGlobal.CATTcpPort := 19090;
for i := 0 to 3 do
@@ -3678,12 +3680,11 @@ begin
Caps := FController.BackendCaps;
if Assigned(FSampleRateOverlay) then
begin
if (Caps.SampleRateMode = srmContinuous) and (Length(Caps.RatePresets) > 0) then
FSampleRateOverlay.SetRatePresets(Caps.RatePresets)
else
FSampleRateOverlay.SetRatePresetsDefault; // HPSDR 48k..1536k
// Единый источник — контроллер (caps бэкенда). UI больше не владеет списком.
FSampleRateOverlay.SetRatePresets(FController.SampleRatePresets);
FSampleRateOverlay.SetCurrentRate(FController.FSampleRate);
end;
PushRatePresetsToWeb; // тот же источник зеркалим в web-морду
// Отдельный Pluto RF-AGC блок под AGC: показываем и сдвигаем панели ниже.
LayoutLeftPanel(Caps.HasHWGain);
@@ -5366,6 +5367,14 @@ begin
end;
end;
procedure TMainForm.PushRatePresetsToWeb;
// Пресеты sample-rate бэкенда → web (HPSDR/Pluto разные). Единый источник —
// FController.SampleRatePresets, как и для desktop-оверлея.
begin
if FWebServer = nil then Exit;
FWebServer.SetRatePresets(FController.SampleRatePresets);
end;
procedure TMainForm.PushXvtrToWeb;
var
Arr: TWebXvtrArray;