feat(beacon): автопоиск маяка в окне лупы (кнопка AUTO)

Лупа сделала прицеливание возможным, но целиться всё равно надо руками. AUTO
находит маяк сам, в текущем окне лупы: что видно, то и обыскивается — заодно
зумом можно сузить область поиска.

Критерий — не «самый громкий», иначе поймается первая же SSB-станция. Копим
min-hold по кадрам лупы (~1.6 с): у маяка несущая непрерывна и минимум остаётся
высоким, а речь, телеграф и цифра в паузах проваливаются к шуму и срезаются
минимумом. Это тот самый «непрерывный след», который видно на водопаде, только
числом.

По накопленному: шумовой пол = медиана, кандидат = максимум скользящего среднего
шириной с полосу приёма (±450 Гц) — среднее по полосе, а не отдельный бин, потому
что маяк это плато ~900 Гц, и по такой мере он выигрывает у узкой пораженки с той
же высотой пика. Порог 6 дБ над полом; центр уточняется центроидом превышения,
чтобы наведение село на середину плато.

- Тумблер рядом с FOLLOW, состояние в настройках (beacon_zoom_auto).
- На локе автопоиск молчит: в контур не лезем.
- После наведения выдержка ~3 с — дать декодеру попробовать захватиться.
- Нашли там же, где уже стоит наведение (ближе 150 Гц) — не трогаем.
  BeaconSeedAtHz дёргает Reseed, и без этой проверки при слабом сигнале
  автопоиск сбрасывал бы захват по кругу, мешая декодеру сойтись.
- В накопление идут только свежие кадры: таймер формы (25 Гц) быстрее
  анализатора (15 к/с), и повторный учёт кадра сокращал бы окно наблюдения,
  ради которого min-hold и заведён.

В строке захвата появляется пометка AUTO — и только пока автопоиск реально
работает: на локе она гаснет, чтобы не обещать действие, которого нет.

Сборка ewsdr (--ws=qt6) и ewsdrd — ОК. На эфире не проверено.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 13:01:26 +03:00
co-authored by Claude Opus 5
parent 51599b2457
commit 8569236214
3 changed files with 202 additions and 5 deletions
+4
View File
@@ -339,6 +339,7 @@ type
FBcnZoomSpanHz: Double; // ширина окна лупы, Гц
FBcnZoomOffsetHz: Double; // центр = FBeaconRefHz + этот сдвиг
FBcnZoomFollow: Boolean; // держать наведение декодера в окне
FBcnZoomAuto: Boolean; // автопоиск маяка в окне лупы
// ---- DMR 4FSK receive decoder ----
FDMRDec: TDMRDecoder; // 48 kHz FM discriminator -> DMR worker
@@ -1327,6 +1328,7 @@ begin
FBcnZoomSpanHz := 40000.0;
FBcnZoomOffsetHz := 0.0;
FBcnZoomFollow := True;
FBcnZoomAuto := False;
FBeaconDec.SetInvert(FBeaconDecInvert);
FDSPEngine.SetBeaconDecoder(FBeaconDec);
@@ -3959,6 +3961,7 @@ begin
Result.BeaconZoomSpanHz := FBcnZoomSpanHz;
Result.BeaconZoomOffsetHz := FBcnZoomOffsetHz;
Result.BeaconZoomFollow := FBcnZoomFollow;
Result.BeaconZoomAuto := FBcnZoomAuto;
Result.AudioSampleRate := FAudioOut.SampleRate;
Result.ShowSpectrum := FShowSpectrum;
Result.ShowWaterfall := FShowWaterfall;
@@ -7355,6 +7358,7 @@ begin
FBcnZoomSpanHz := EnsureRange(FLoadedGlobal.BeaconZoomSpanHz, 600.0, 200000.0);
FBcnZoomOffsetHz := EnsureRange(FLoadedGlobal.BeaconZoomOffsetHz, -500000.0, 500000.0);
FBcnZoomFollow := FLoadedGlobal.BeaconZoomFollow;
FBcnZoomAuto := FLoadedGlobal.BeaconZoomAuto;
if FWDSPReady then FDSPEngine.SetDisplayResLimit(FDisplayPixels);
FShowSpectrum := FLoadedGlobal.ShowSpectrum;
FShowWaterfall := FLoadedGlobal.ShowWaterfall;