mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feat(audio): раздельная громкость RX и TX-монитора + фикс синка слайдера
Две сохраняемые громкости: FVolume (RX) и FTxMonVolume (self-monitor даунлинка на передаче, дефолт 40). Контекст монитора = TX + DUP + RX MUTE off (тот же гейт, что аудио в движке). В этом контексте слайдер/SetVolume правят FTxMonVolume, иначе FVolume; ActiveVolume — активная под контекст. Автопереключение громкости RX<->TX-монитор на T/R (SetMOX) и при смене RX MUTE / DUP во время передачи (ApplyActiveVolume). Обе персистятся (tx_mon_volume в конфиге). Веб выровнен на ActiveVolume. Фикс: слайдер громкости не синхронизировался с загруженным значением после подключения (в rfDevice синкался только drive, volume пропущен) → слайдер оставался на 70, движок брал сохранённое → «прыжок» при первом касании. Добавлен TrkVolume.Position := ActiveVolume в rfDevice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+41
-5
@@ -237,7 +237,8 @@ type
|
||||
FBeaconDecInvert: Boolean; // зеркальный baseband (QO-100/LNB) — деф. True
|
||||
|
||||
// ---- Аудио / TX ----
|
||||
FVolume: Integer;
|
||||
FVolume: Integer; // громкость RX
|
||||
FTxMonVolume: Integer; // громкость self-monitor RX-аудио на TX (RX MUTE off, DUP)
|
||||
FMuted: Boolean;
|
||||
FDrivePercent: Integer; // драйв 0..100 % (UI-уровень, источник истины)
|
||||
FDriveLevel: Byte; // вычисляемый hardware-байт (CalcDriveByte)
|
||||
@@ -495,6 +496,15 @@ type
|
||||
// Громкость / mute / drive / аттенюатор
|
||||
procedure SetVolume(V: Integer);
|
||||
procedure VolumeBy(Delta: Integer);
|
||||
// True — сейчас звучит self-monitor даунлинка на передаче (TX + DUP + RX MUTE
|
||||
// off). В этом контексте SetVolume/слайдер правят FTxMonVolume, иначе FVolume.
|
||||
function MonitoringTX: Boolean;
|
||||
// Активная громкость под текущий контекст (RX или TX-монитор) — то, что видит
|
||||
// слайдер (rfVolume) и получает движок.
|
||||
function ActiveVolume: Integer;
|
||||
// Применить активную громкость к движку + синхронизировать слайдер (rfVolume).
|
||||
// Зовётся на T/R-переходах и смене RX MUTE / DUP.
|
||||
procedure ApplyActiveVolume;
|
||||
procedure SetMute(On_: Boolean);
|
||||
procedure ToggleMute;
|
||||
procedure SetDrive(V: Integer);
|
||||
@@ -694,7 +704,7 @@ begin
|
||||
FAGCMode := 1; FAGCTop := 90;
|
||||
FRxGainMode := 2; FRxGainDb := 40; // Pluto: slow_attack по умолчанию
|
||||
FRxMuteOnTx := True; // QO-100 self-monitor выкл по умолчанию (RX заглушён на TX)
|
||||
FVolume := 70; FDrivePercent := 50; FDriveLevel := 0; FAtten := 0;
|
||||
FVolume := 70; FTxMonVolume := 40; FDrivePercent := 50; FDriveLevel := 0; FAtten := 0;
|
||||
FCenterFreq := FVfoA; FSpanHz := 192000; FSampleRate := 192000;
|
||||
FNextSliceId := 1; // мультислайсы: генератор id
|
||||
FillChar(FSlices, SizeOf(FSlices), 0);
|
||||
@@ -1881,6 +1891,7 @@ begin
|
||||
Result := FLoadedGlobal; // несёт не-радио поля (тема/FPS/digits/CAT) round-trip
|
||||
|
||||
Result.Volume := FVolume;
|
||||
Result.TxMonVolume := FTxMonVolume;
|
||||
Result.DriveLevel := FDrivePercent;
|
||||
Result.PAMaxPower := FPAMaxPower;
|
||||
Result.PlutoTxMaxAttDb := FPlutoTxMaxAttDb;
|
||||
@@ -2470,16 +2481,37 @@ end;
|
||||
procedure TRadioController.RxGainBy(Delta: Integer);
|
||||
begin SetRxGain(FRxGainDb + Delta); end;
|
||||
|
||||
function TRadioController.MonitoringTX: Boolean;
|
||||
begin
|
||||
// Звук даунлинка на передаче идёт только в full-duplex (DUP) при выключенном
|
||||
// RX MUTE — тот же гейт, что в движке (FKeepRXDuringTX and FMonitorRXDuringTX).
|
||||
Result := FTransmitting and FDisplayDuplex and (not FRxMuteOnTx);
|
||||
end;
|
||||
|
||||
function TRadioController.ActiveVolume: Integer;
|
||||
begin
|
||||
if MonitoringTX then Result := FTxMonVolume else Result := FVolume;
|
||||
end;
|
||||
|
||||
procedure TRadioController.ApplyActiveVolume;
|
||||
begin
|
||||
if FWDSPReady and Assigned(FDSPEngine) then
|
||||
FDSPEngine.SetVolume(ActiveVolume / 100.0);
|
||||
Changed(rfVolume); // слайдер/оверлей ← ActiveVolume
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetVolume(V: Integer);
|
||||
begin
|
||||
if V < 0 then V := 0 else if V > 100 then V := 100;
|
||||
FVolume := V;
|
||||
if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetVolume(FVolume / 100.0);
|
||||
// Правим ту громкость, что сейчас активна: на TX-мониторе — FTxMonVolume,
|
||||
// иначе FVolume. Обе персистятся; слайдер редактирует активную.
|
||||
if MonitoringTX then FTxMonVolume := V else FVolume := V;
|
||||
if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetVolume(ActiveVolume / 100.0);
|
||||
Changed(rfVolume);
|
||||
end;
|
||||
|
||||
procedure TRadioController.VolumeBy(Delta: Integer);
|
||||
begin SetVolume(FVolume + Delta); end;
|
||||
begin SetVolume(ActiveVolume + Delta); end;
|
||||
|
||||
procedure TRadioController.SetMute(On_: Boolean);
|
||||
begin
|
||||
@@ -2906,6 +2938,7 @@ begin
|
||||
// но здесь — чтобы тумблер DUP действовал и в момент передачи.
|
||||
if FWDSPReady and Assigned(FDSPEngine) then
|
||||
FDSPEngine.KeepRXDuringTX := FDisplayDuplex;
|
||||
ApplyActiveVolume; // смена DUP на передаче может включить/выключить TX-монитор
|
||||
Changed(rfDuplex);
|
||||
end;
|
||||
|
||||
@@ -2921,6 +2954,7 @@ procedure TRadioController.SetRxMuteOnTx(On_: Boolean);
|
||||
begin
|
||||
FRxMuteOnTx := On_;
|
||||
ApplyRxMuteToEngine;
|
||||
ApplyActiveVolume; // на передаче тумблер монитора меняет активную громкость
|
||||
Changed(rfRxMuteOnTx);
|
||||
end;
|
||||
|
||||
@@ -3150,6 +3184,7 @@ begin
|
||||
FNetwork.SendFullHP; // 2й пакет: Alex bit27=0 (T/R relay RX)
|
||||
end;
|
||||
ApplyPlutoTxAtten; // Pluto: TX-мощность по drive на передаче, OFF на приёме
|
||||
ApplyActiveVolume; // T/R: переключаем громкость RX ↔ TX-монитор (если monitoring)
|
||||
Changed(rfTransmitting);
|
||||
end;
|
||||
|
||||
@@ -3502,6 +3537,7 @@ begin
|
||||
if FTXSettings.TXSpecGridStep > 0 then
|
||||
FTXSpecGridStep := FTXSettings.TXSpecGridStep;
|
||||
FVolume := FLoadedGlobal.Volume;
|
||||
FTxMonVolume := EnsureRange(FLoadedGlobal.TxMonVolume, 0, 100);
|
||||
FActiveVfo := EnsureRange(FLoadedGlobal.ActiveVfo, 0, 1); // битый конфиг не должен дать невалидный VFO
|
||||
FPAMaxPower := FLoadedGlobal.PAMaxPower;
|
||||
FPlutoTxMaxAttDb := EnsureRange(FLoadedGlobal.PlutoTxMaxAttDb, -50.0, 0.0);
|
||||
|
||||
Reference in New Issue
Block a user