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
+8 -6
View File
@@ -199,14 +199,16 @@ procedure TWebAdapter.OnSpan(Hz: Integer);
begin FSyncInt := Hz; FController.Invoke(@SyncSpan); end;
procedure TWebAdapter.SyncSpan;
// span ≡ sample rate. Принимаем только валидные значения (как десктоп-оверлей);
// span ≡ sample rate. Валидируем по пресетам текущего бэкенда (единый источник,
// как десктоп-оверлей) — иначе Pluto-рейты (960k/2304k/…) отбрасывались бы.
// SetSampleRate сам пересоздаёт WDSP-канал + персистит (idempotent при том же rate).
const
ValidSpans: array[0..5] of Integer = (48000, 96000, 192000, 384000, 768000, 1536000);
var i: Integer;
var
Presets: TBackendRateArray;
i: Integer;
begin
for i := 0 to High(ValidSpans) do
if ValidSpans[i] = FSyncInt then
Presets := FController.SampleRatePresets;
for i := 0 to High(Presets) do
if Presets[i] = FSyncInt then
begin
FController.SetSampleRate(FSyncInt);
Exit;