mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
feat(waterfall): палитры Inferno/Turbo + gamma, разрешение до 4096, HiDPI
- SPECTRUM_PIXELS 1024→4096 + настройка display_pixels (лимит точек анализатора, SetDisplayResLimit); web-зеркало остаётся 1024 — max-децимация в SnapshotPixels - палитры водопада Classic/Inferno/Turbo + регулятор gamma (в LUT), настройки wf_palette/wf_gamma, страница Waterfall → группа Rendering - GL-водопад переведён на общий LUT/AGC-уровни базового класса (убраны дубли ColorForDB/UpdateLevels) - явные glViewport в GL-вьюхах умножаются на PixelScale (HiDPI), текстура водопада — в физической ширине Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+42
-14
@@ -281,6 +281,9 @@ type
|
||||
FWfManualHigh: Double;
|
||||
FWfManualLow: Double;
|
||||
FWfAGCOffset: Double;
|
||||
FWfPalette: Integer; // 0=Classic, 1=Inferno, 2=Turbo
|
||||
FWfGamma: Double; // контраст палитры водопада
|
||||
FDisplayPixels: Integer; // потолок точек анализатора
|
||||
FSpecRefLevel: Double;
|
||||
FSpecRange: Double;
|
||||
FSpecGridStep: Double;
|
||||
@@ -688,6 +691,7 @@ begin
|
||||
FPAMaxPower := 100.0;
|
||||
FPlutoTxMaxAttDb := -10.0; // ADI-дефолт: линейный режим выходных каскадов
|
||||
FWfAGCEnabled := True; FDitherEnabled := True; FRandomEnabled := True;
|
||||
FWfPalette := 0; FWfGamma := 1.0; FDisplayPixels := 4096;
|
||||
FFMStepOn := True;
|
||||
FLocalAudio := True; // GUI: звук на локальную карту; демон выключит явно
|
||||
FLastSMeter := -130; FLastSWR := 1; FLastSupplyV := -1; FLastSupplyA := -1;
|
||||
@@ -709,6 +713,7 @@ begin
|
||||
// Роутинг аудио слайсов на их звуковухи — внутренний, вешаем сразу (не
|
||||
// зависит от фронтенда, в отличие от OnAudio/OnSpectrum).
|
||||
FDSPEngine.OnSliceAudio := OnSliceAudioReady;
|
||||
FDSPEngine.SetDisplayResLimit(FDisplayPixels);
|
||||
|
||||
// QO-100 beacon lock: эталон частоты = декодер (см. ServiceBeaconLock).
|
||||
FBeaconRefHz := 10489750000.0; // центральный BPSK-маяк NB-транспондера (downlink)
|
||||
@@ -1256,18 +1261,40 @@ begin
|
||||
if Result then S := FSlices[idx];
|
||||
end;
|
||||
|
||||
// Снимок кадра для web-зеркала: протокол фиксирован на 1024 точки, поэтому
|
||||
// при большем разрешении анализатора децимируем max-детектором (не обрезаем).
|
||||
procedure SnapshotPixels(const Pixels: array of Single; Count: Integer;
|
||||
var Dst: array of Single; out DstCount: Integer);
|
||||
var
|
||||
i, j, S0, S1, N: Integer;
|
||||
V: Single;
|
||||
begin
|
||||
N := Length(Dst);
|
||||
if Count > Length(Pixels) then Count := Length(Pixels);
|
||||
if Count <= N then
|
||||
begin
|
||||
for i := 0 to Count - 1 do Dst[i] := Pixels[i];
|
||||
DstCount := Count;
|
||||
Exit;
|
||||
end;
|
||||
for i := 0 to N - 1 do
|
||||
begin
|
||||
S0 := Int64(i) * Count div N;
|
||||
S1 := (Int64(i) + 1) * Count div N - 1;
|
||||
V := Pixels[S0];
|
||||
for j := S0 + 1 to S1 do
|
||||
if Pixels[j] > V then V := Pixels[j];
|
||||
Dst[i] := V;
|
||||
end;
|
||||
DstCount := N;
|
||||
end;
|
||||
|
||||
procedure TRadioController.OnSpectrumReady(const Pixels: array of Single;
|
||||
Count: Integer);
|
||||
// DSP-поток: сохраняем последний кадр для web-зеркала и отдаём сырьё наружу
|
||||
// (UI рисует FSpecView). Децимации у спектра нет.
|
||||
var
|
||||
i, N: Integer;
|
||||
begin
|
||||
N := Count;
|
||||
if N > Length(FSpectrumBuf) then N := Length(FSpectrumBuf);
|
||||
for i := 0 to N - 1 do
|
||||
FSpectrumBuf[i] := Pixels[i];
|
||||
FSpectrumBufCount := N;
|
||||
SnapshotPixels(Pixels, Count, FSpectrumBuf, FSpectrumBufCount);
|
||||
if Assigned(FOnSpectrumData) then FOnSpectrumData(Pixels, Count);
|
||||
end;
|
||||
|
||||
@@ -1275,14 +1302,8 @@ procedure TRadioController.OnWaterfallReady(const Pixels: array of Single;
|
||||
Count: Integer);
|
||||
// DSP-поток: web-зеркало получает КАЖДЫЙ кадр; децимация рендера водопада —
|
||||
// забота фронтенда (OnWaterfallData).
|
||||
var
|
||||
i, N: Integer;
|
||||
begin
|
||||
N := Count;
|
||||
if N > Length(FWaterfallBuf) then N := Length(FWaterfallBuf);
|
||||
for i := 0 to N - 1 do
|
||||
FWaterfallBuf[i] := Pixels[i];
|
||||
FWaterfallBufCount := N;
|
||||
SnapshotPixels(Pixels, Count, FWaterfallBuf, FWaterfallBufCount);
|
||||
if Assigned(FOnWaterfallData) then FOnWaterfallData(Pixels, Count);
|
||||
end;
|
||||
|
||||
@@ -1892,6 +1913,9 @@ begin
|
||||
Result.WfManualHigh := FWfManualHigh;
|
||||
Result.WfManualLow := FWfManualLow;
|
||||
Result.WfAGCOffset := FWfAGCOffset;
|
||||
Result.WfPalette := FWfPalette;
|
||||
Result.WfGamma := FWfGamma;
|
||||
Result.DisplayPixels := FDisplayPixels;
|
||||
Result.SpecRefLevel := FSpecRefLevel;
|
||||
Result.SpecRange := FSpecRange;
|
||||
Result.SpecGridStep := FSpecGridStep;
|
||||
@@ -3478,6 +3502,10 @@ begin
|
||||
FWfManualHigh := FLoadedGlobal.WfManualHigh;
|
||||
FWfManualLow := FLoadedGlobal.WfManualLow;
|
||||
FWfAGCOffset := FLoadedGlobal.WfAGCOffset;
|
||||
FWfPalette := EnsureRange(FLoadedGlobal.WfPalette, 0, 2);
|
||||
FWfGamma := EnsureRange(FLoadedGlobal.WfGamma, 0.3, 3.0);
|
||||
FDisplayPixels := EnsureRange(FLoadedGlobal.DisplayPixels, 64, 4096);
|
||||
if FWDSPReady then FDSPEngine.SetDisplayResLimit(FDisplayPixels);
|
||||
FShowSpectrum := FLoadedGlobal.ShowSpectrum;
|
||||
FShowWaterfall := FLoadedGlobal.ShowWaterfall;
|
||||
FShowWideband := FLoadedGlobal.ShowWideband;
|
||||
|
||||
Reference in New Issue
Block a user