mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
fix(web): детализация спектра/водопада — честный размер кадра, поток 'W', настройка разрешения
Веб-пульт рисовал заметно грубее десктопа, и часть причин копилась давно. Клиент вообще не разбирал бинарный фрейм 0x57: водопад рисовался из кадра СПЕКТРА, а собственный поток водопада (свой детектор и усреднение wf_avg_time_ms) уходил в никуда, занимая половину трафика. Теперь водопад идёт из своего потока. Адаптер слал константу 1024 вместо реального числа точек. Разрешение анализатора = ширина панадаптера, и при узкой панели (грид из двух колонок, маленькое окно) кадр короче — хвост буфера, нули = 0 dBm, уезжал клиенту белой полосой, а частотная шкала сжималась. В демоне это обходили DAEMON_SPEC_WIDTH. Длина фрейма теперь равна числу заполненных точек; клиент и так считал N из byteLength. Децимация под потолок протокола делила «i*Count div N» — на нецелом отношении соседние группы получались по 1 и 2 точки, а смещение max-детектора зависит от размера группы: по спектру шла гребёнка ±3 дБ, в водопаде — вертикальная рябь. Заменено на целочисленный фактор (группы одинаковой ширины). Водопад терял 2 кадра из 3: анализатор даёт до 60 кадров/с, web шлёт 20 строк/с, а бралась просто «последняя». Введено двухступенчатое накопление max-hold (DSP-поток → PushState → PushLoop) по идиоме TWaterfallView.SetWaterfallData — короткие посылки CW/FT8 больше не проваливаются между строками. Отдельно исправлено в headless: PushState демона (20 Гц) и PushLoop (20 Гц) идут вразнобой, и на дрейфе фаз одна и та же строка уезжала клиенту дважды (водопад двоил и полз рывками), а на остановленном RX прокручивалась застывшая строка. Фрейм 'W' теперь отправляется только при реально пришедшем от DSP кадре (FWfAccumFresh → WfNew → FWfFresh). Спектр так не гейтится — это живая кривая. Рендер в браузере: значение бина для пикселя берётся максимумом по диапазону вместо «ближайшего» (узкие сигналы мерцали и пропадали на узком экране), при бинах реже пикселей — интерполяция; сглаживание спектра вынесено отдельным проходом по всем бинам (в цикле по пикселям часть бинов не обновлялась вовсе); строка водопада рисуется из сырых бинов, IIR ~200 мс остался только для слежения за уровнями AGC — он размазывал водопад по вертикали. Потолок точек кадра вынесен в настройку web.spec_pixels (Settings → Advanced → Web Server → Spectrum: 1024/2048/4096, дефолт 1024). Буферы кадра и WS-фреймы выросли под 4096 (WEB_SPEC_MAX, синхронно с WDSPEngine.SPECTRUM_PIXELS). В демоне эта же настройка задаёт ширину анализатора — рендера там нет, поэтому DAEMON_SPEC_WIDTH убран. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+14
-2
@@ -468,7 +468,12 @@ var
|
||||
StatusText, BoardText, IPText, SupplyText: string;
|
||||
PLLText, RXText, TXText, SeqText: string;
|
||||
ViewCenter, ViewSpan: Double;
|
||||
WfNew: Boolean;
|
||||
begin
|
||||
// Пришла ли от DSP новая строка водопада с прошлого пуша. Снимаем ДО пуша:
|
||||
// без этого сервер повторно отправлял бы прежнюю строку, когда кадров нет
|
||||
// (RX остановлен) или когда пуш случился чаще кадров — водопад двоил.
|
||||
WfNew := FController.FWfAccumFresh;
|
||||
// Видимое окно (центр+span) с учётом зума: пиксели спектра уже зумлены
|
||||
// анализатором, web-метки/маппинг должны соответствовать.
|
||||
FController.GetViewWindow(ViewCenter, ViewSpan);
|
||||
@@ -558,9 +563,13 @@ begin
|
||||
FController.InQO100,
|
||||
FController.FRxMuteOnTx);
|
||||
|
||||
// Счётчики — РЕАЛЬНЫЕ: кадр короче потолка (web.spec_pixels), когда
|
||||
// разрешение анализатора (= ширина панадаптера) меньше него — узкая панель,
|
||||
// грид из двух колонок. Константа здесь отправляла хвост буфера — нули
|
||||
// (0 dBm) поверх шкалы и сжатый по частоте спектр.
|
||||
FServer.PushSpectrum(
|
||||
FController.FSpectrumBuf, 1024,
|
||||
FController.FWaterfallBuf,
|
||||
FController.FSpectrumBuf, FController.FSpectrumBufCount,
|
||||
FController.FWaterfallBuf, FController.FWaterfallBufCount, WfNew,
|
||||
FController.FLastSMeter,
|
||||
FController.FVfoA, FController.FMode, FController.FFilterBW, FController.FAGCMode, FController.FAGCTop,
|
||||
ViewSpan, FController.ActiveVolume,
|
||||
@@ -576,6 +585,9 @@ begin
|
||||
FController.FLastFwdW, FController.FLastSWR, FController.FPAMaxPower,
|
||||
StatusText, BoardText, IPText, SupplyText,
|
||||
PLLText, RXText, TXText, SeqText);
|
||||
|
||||
// Строка забрана — следующий кадр DSP начинает новое накопление.
|
||||
if WfNew then FController.FWfAccumFresh := False;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user