mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +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:
+68
-2
@@ -347,6 +347,11 @@ type
|
||||
FPSPopup: TObject; // TPureSignalPopup (cast при использовании)
|
||||
|
||||
PanelRXBlock: TPanel;
|
||||
// Шаговый аттенюатор ADC (openHPSDR): плавные 0..31 дБ. На Pluto ряд
|
||||
// скрыт — там усиление тракта живёт в блоке RF AGC.
|
||||
LblAtt: TLabel;
|
||||
LblAttVal: TLabel;
|
||||
TrkAtt: TFlatSlider;
|
||||
BtnChannels: TFlatButton;
|
||||
FChannelsDropDown: TFlatDropDown;
|
||||
FChannelsForm: TObject; // TChannelsForm (cast при использовании)
|
||||
@@ -706,6 +711,8 @@ type
|
||||
procedure BtnAGCModeClick(Sender: TObject);
|
||||
procedure TrkAGCChange(Sender: TObject);
|
||||
procedure TrkRxGainChange(Sender: TObject);
|
||||
procedure TrkAttChange(Sender: TObject);
|
||||
procedure UpdateAttLabel;
|
||||
// (BtnPlutoGainClick объявлен выше)
|
||||
procedure MeterTimerTick(Sender: TObject);
|
||||
procedure SpectrumTimerTick(Sender: TObject);
|
||||
@@ -762,6 +769,13 @@ uses SettingsForm;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
const
|
||||
// Высота RX-блока левой панели: с рядом ATT (openHPSDR) и без него (Pluto —
|
||||
// там усиление тракта в блоке RF AGC). Переключает LayoutLeftPanel, он же
|
||||
// двигает панели ниже.
|
||||
RX_BLOCK_H = 96;
|
||||
RX_BLOCK_H_ATT = 120;
|
||||
|
||||
function TMainForm.LeftPanelButtonWidth(PanelWidth, ColCount,
|
||||
ColIndex: Integer): Integer;
|
||||
var
|
||||
@@ -1505,6 +1519,12 @@ begin
|
||||
TrkVolume.Position := FController.ActiveVolume; // RX или TX-монитор
|
||||
rfRxGain:
|
||||
UpdateRxGainUI;
|
||||
rfAtten:
|
||||
if TrkAtt <> nil then
|
||||
begin
|
||||
TrkAtt.Position := FController.FAtten;
|
||||
UpdateAttLabel;
|
||||
end;
|
||||
rfDrive:
|
||||
begin
|
||||
TrkDrive.Position := FController.FDrivePercent; // слайдер ← drive%
|
||||
@@ -2028,7 +2048,7 @@ begin
|
||||
// RX block: CTUN + VOL + NR/NB/SNB/ANF/MUTE
|
||||
PanelRXBlock := TPanel.Create(Self);
|
||||
PanelRXBlock.Parent := PanelLeft;
|
||||
PanelRXBlock.SetBounds(0, Y, LEFT_W, 96);
|
||||
PanelRXBlock.SetBounds(0, Y, LEFT_W, RX_BLOCK_H_ATT);
|
||||
PanelRXBlock.BevelOuter := bvNone;
|
||||
MakeLbl(PanelRXBlock, 'RX', 4, 2);
|
||||
|
||||
@@ -2084,7 +2104,29 @@ begin
|
||||
LeftPanelButtonLeft(LEFT_W, 5, 4), 70,
|
||||
LeftPanelButtonWidth(LEFT_W, 5, 4), BTN_SM, BtnMuteClick);
|
||||
|
||||
Inc(Y, 100);
|
||||
// Шаговый аттенюатор ADC — плавный 0..31 дБ (железо openHPSDR так и умеет,
|
||||
// ступени 0/10/20 были только в web-UI). Показания S-метра/спектра на эти
|
||||
// дБ компенсируются в контроллере, шкала dBm остаётся абсолютной.
|
||||
LblAtt := TLabel.Create(Self);
|
||||
LblAtt.Parent := PanelRXBlock; LblAtt.Left := 4; LblAtt.Top := 106;
|
||||
LblAtt.Caption := 'ATT'; LblAtt.Font.Color := CLR_TEXTDIM;
|
||||
LblAtt.Font.Name := 'Courier New'; LblAtt.Font.Size := 7;
|
||||
|
||||
TrkAtt := TFlatSlider.Create(Self);
|
||||
TrkAtt.Parent := PanelRXBlock; TrkAtt.Left := 34; TrkAtt.Top := 102;
|
||||
TrkAtt.Width := LEFT_W - 76; TrkAtt.Height := 16;
|
||||
TrkAtt.Min := 0; TrkAtt.Max := 31; // ADC step attenuator, дБ
|
||||
TrkAtt.Position := FController.FAtten;
|
||||
TrkAtt.OnChange := TrkAttChange;
|
||||
|
||||
LblAttVal := TLabel.Create(Self);
|
||||
LblAttVal.Parent := PanelRXBlock;
|
||||
LblAttVal.Left := LEFT_W - 38; LblAttVal.Top := 106;
|
||||
LblAttVal.Font.Color := CLR_TEXT; LblAttVal.Font.Name := 'Courier New';
|
||||
LblAttVal.Font.Size := 7;
|
||||
UpdateAttLabel;
|
||||
|
||||
Inc(Y, RX_BLOCK_H_ATT + 4);
|
||||
|
||||
// AGC controls
|
||||
PanelAGC := TPanel.Create(Self);
|
||||
@@ -7933,6 +7975,19 @@ begin
|
||||
FController.SetRxGain(TrkRxGain.Position); // переводит в manual
|
||||
end;
|
||||
|
||||
procedure TMainForm.TrkAttChange(Sender: TObject);
|
||||
begin
|
||||
if FSyncingFromController then Exit;
|
||||
FController.SetAtten(TrkAtt.Position);
|
||||
UpdateAttLabel;
|
||||
end;
|
||||
|
||||
procedure TMainForm.UpdateAttLabel;
|
||||
begin
|
||||
if LblAttVal <> nil then
|
||||
LblAttVal.Caption := Format('%ddB', [FController.FAtten]);
|
||||
end;
|
||||
|
||||
procedure TMainForm.BtnPlutoGainClick(Sender: TObject);
|
||||
begin
|
||||
if FSyncingFromController then Exit;
|
||||
@@ -7966,6 +8021,17 @@ procedure TMainForm.LayoutLeftPanel(Pluto: Boolean);
|
||||
var baseTop: Integer;
|
||||
begin
|
||||
if (PanelPlutoAGC = nil) or (PanelAGC = nil) or (PanelBands = nil) then Exit;
|
||||
// Шаговый аттенюатор — только у openHPSDR; у AD936x усиление тракта в блоке
|
||||
// RF AGC ниже, поэтому ряд ATT убираем и RX-блок ужимаем.
|
||||
if (TrkAtt <> nil) and (LblAtt <> nil) and (LblAttVal <> nil) then
|
||||
begin
|
||||
TrkAtt.Visible := not Pluto;
|
||||
LblAtt.Visible := not Pluto;
|
||||
LblAttVal.Visible := not Pluto;
|
||||
if Pluto then PanelRXBlock.Height := RX_BLOCK_H
|
||||
else PanelRXBlock.Height := RX_BLOCK_H_ATT;
|
||||
PanelAGC.Top := PanelRXBlock.Top + PanelRXBlock.Height + 4;
|
||||
end;
|
||||
baseTop := PanelAGC.Top + PanelAGC.Height + 4;
|
||||
PanelPlutoAGC.Top := baseTop;
|
||||
PanelPlutoAGC.Visible := Pluto;
|
||||
|
||||
Reference in New Issue
Block a user