mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feature(rx): плавный аттенюатор 0..31 дБ в UI, память на диапазон, компенсация уровней
Аттенюатор был только в web и только тремя ступенями (0/-10/-20), а его дБ
никуда не возвращались — при ATT 20 дБ S-метр и спектр уезжали на 20 дБ, и
свежая калибровка уровней была верна лишь при ATT=0.
- RadioController: SetAtten(Db) 0..31 (как умеет железо) вместо индекса *10.
AttenCalDB входит в SMeterCalFor и DispCalFor — стрелка, спектр, водопад и
паны компенсируются, шкала dBm остаётся абсолютной (как Thetis/piHPSDR).
У AD936x аттенюатора нет, там поправка 0 (усиление тракта — hardwaregain).
- Память на диапазон/слот трансвертера по образцу RxGainMode/RxGainDb:
TBandSettings.AttenDB (band 'atten_db') и TXvtrEntry.LastAttenDB
('last_atten_db'); восстановление и отправка в железо — в ApplyBandDSP,
сбор — в MakeBandSettings/SaveCurrentBand, вход в слот — через B.AttenDB.
SetAtten сразу кладёт значение в кэш диапазона/слота (JSON пишется общим
сохранением, а не на каждый шаг ползунка — как у drive).
- MainForm: ряд «ATT [ползунок] NNdB» в RX-блоке левой панели, отступы как у
VOL; на Pluto ряд скрыт и RX-блок ужимается (LayoutLeftPanel двигает
панели ниже). Внешние изменения приходят по rfAtten.
- Web: select → ползунок 0..31 с цифрой, attn_idx -> attn_db, cmd attn {db:}.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+35
-7
@@ -601,7 +601,7 @@ type
|
||||
procedure ToggleMute;
|
||||
procedure SetDrive(V: Integer);
|
||||
procedure DriveBy(Delta: Integer);
|
||||
procedure SetAtten(Idx: Integer);
|
||||
procedure SetAtten(Db: Integer); // ADC step attenuator, дБ (0..31)
|
||||
|
||||
// ---- Мультислайсы (софт-fan-out) ----
|
||||
// Создаёт слайс на TargetHz: заводит WDSP-канал в движке + свой аудио-выход
|
||||
@@ -635,6 +635,8 @@ type
|
||||
// Офсет спектра/водопада (дБ) для дисплея: PanId 0 = главный, 1..N — пан.
|
||||
// Колбэк движка (display-поток), см. TOnDispCalQuery.
|
||||
function DispCalFor(PanId: Integer): Double;
|
||||
// Поправка на шаговый аттенюатор ADC (дБ) — входит в оба офсета выше.
|
||||
function AttenCalDB: Double;
|
||||
procedure SetSliceDevice(Id, DevIndex: Integer; const DevName: string);
|
||||
function SliceCount: Integer;
|
||||
function GetSlice(Id: Integer; out S: TCtrlSlice): Boolean;
|
||||
@@ -2094,7 +2096,17 @@ end;
|
||||
|
||||
function TRadioController.SMeterCalFor(VisibleHz: Double): Double;
|
||||
begin
|
||||
Result := CalLookup(VisibleHz, FCal.SMeterBandDB, FCal.SMeterXvtrDB);
|
||||
Result := CalLookup(VisibleHz, FCal.SMeterBandDB, FCal.SMeterXvtrDB)
|
||||
+ AttenCalDB;
|
||||
end;
|
||||
|
||||
function TRadioController.AttenCalDB: Double;
|
||||
// Шаговый аттенюатор ADC режет вход — чтобы шкала dBm оставалась абсолютной,
|
||||
// его дБ возвращаются в показания (так же делают Thetis и piHPSDR). У AD936x
|
||||
// такого аттенюатора нет: там усиление тракта — hardwaregain.
|
||||
begin
|
||||
if IsPluto then Result := 0.0
|
||||
else Result := FAtten;
|
||||
end;
|
||||
|
||||
function TRadioController.DispCalFor(PanId: Integer): Double;
|
||||
@@ -2105,7 +2117,7 @@ begin
|
||||
if (PanId > 0) and (PanId < MAX_PANS) then Hz := FPanFreqHz[PanId]
|
||||
else Hz := FCenterFreq;
|
||||
if Hz <= 0 then Exit(0.0);
|
||||
Result := CalLookup(Hz, FCal.DispBandDB, FCal.DispXvtrDB);
|
||||
Result := CalLookup(Hz, FCal.DispBandDB, FCal.DispXvtrDB) + AttenCalDB;
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetSliceDevice(Id, DevIndex: Integer;
|
||||
@@ -2808,6 +2820,7 @@ begin
|
||||
// Аппаратный AGC AD936x — на диапазон (усиление тракта разное на 2м и QO-100).
|
||||
Result.RxGainMode := FRxGainMode;
|
||||
Result.RxGainDb := FRxGainDb;
|
||||
Result.AttenDB := FAtten; // шаговый аттенюатор ADC — тоже на диапазон
|
||||
// Waterfall AGC/NF — глобальные (не диапазонные)
|
||||
end;
|
||||
|
||||
@@ -2846,6 +2859,7 @@ begin
|
||||
FXvtrSettings.Entries[i].LastPanSlider := FPanSlider;
|
||||
FXvtrSettings.Entries[i].LastRxGainMode := FRxGainMode;
|
||||
FXvtrSettings.Entries[i].LastRxGainDb := FRxGainDb;
|
||||
FXvtrSettings.Entries[i].LastAttenDB := FAtten;
|
||||
end;
|
||||
FSettings.SaveXvtr(FDevMAC, FXvtrSettings);
|
||||
Exit;
|
||||
@@ -2975,6 +2989,11 @@ begin
|
||||
ApplyRxGainToBackend;
|
||||
Changed(rfRxGain); // UI: кнопки FAST/SLOW/HYB/MAN + ползунок
|
||||
|
||||
// --- Шаговый аттенюатор ADC (openHPSDR) — на диапазон/слот трансвертера.
|
||||
FAtten := EnsureRange(B.AttenDB, 0, 31);
|
||||
if Assigned(FNetwork) then FNetwork.SetStepAtten(Byte(FAtten));
|
||||
Changed(rfAtten);
|
||||
|
||||
// --- FM squelch / CTCSS / step / repeater ---
|
||||
FFMSQOn := B.FMSQOn;
|
||||
FFMSQLevel := B.FMSQLevel;
|
||||
@@ -3646,12 +3665,20 @@ begin
|
||||
else FDSPEngine.SetDriveLevel(EnsureRange(Pct, 0, 100) / 100.0);
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetAtten(Idx: Integer);
|
||||
procedure TRadioController.SetAtten(Db: Integer);
|
||||
// Шаговый аттенюатор ADC — плавный 0..31 дБ (как в железе openHPSDR), а не
|
||||
// три фиксированные ступени. Уровни S-метра/спектра компенсируются на ту же
|
||||
// величину (CalLookup), поэтому шкала dBm остаётся абсолютной.
|
||||
begin
|
||||
if Idx < 0 then Idx := 0 else if Idx > 2 then Idx := 2;
|
||||
FAtten := Idx;
|
||||
if Assigned(FNetwork) then FNetwork.SetStepAtten(FAtten * 10);
|
||||
FAtten := EnsureRange(Db, 0, 31);
|
||||
if Assigned(FNetwork) then FNetwork.SetStepAtten(Byte(FAtten));
|
||||
Changed(rfAtten);
|
||||
// Персист — вместе с диапазоном/слотом (SaveCurrentBand на выходе из них),
|
||||
// писать JSON на каждый шаг ползунка незачем, как и у drive.
|
||||
if (FCurrentXvtr >= 0) and (FCurrentXvtr < CFG_XVTR_COUNT) then
|
||||
FXvtrSettings.Entries[FCurrentXvtr].LastAttenDB := FAtten
|
||||
else if (FCurrentBand >= 0) and (FCurrentBand < CFG_BAND_COUNT) then
|
||||
FBandCache[FCurrentBand].AttenDB := FAtten;
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetBand(Idx: Integer);
|
||||
@@ -3742,6 +3769,7 @@ begin
|
||||
B.FMRptOffsetHz := E.LastFMRptOffsetHz;
|
||||
B.RxGainMode := E.LastRxGainMode; // hw-AGC слота (AD936x)
|
||||
B.RxGainDb := E.LastRxGainDb;
|
||||
B.AttenDB := E.LastAttenDB; // аттенюатор ADC слота
|
||||
B.VfoA := Vis;
|
||||
B.VfoB := FVfoB;
|
||||
ApplyBandDSP(B);
|
||||
|
||||
Reference in New Issue
Block a user