diff --git a/RadioController.pas b/RadioController.pas index 6fa1e75..9725ba6 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -463,6 +463,7 @@ type function PlutoTxAttForDrive: Double; // дБ<0 под текущий FDrivePercent procedure ApplyPlutoTxAtten; // ставит att по FTransmitting/FTuning procedure SetPlutoTxMaxAtt(Db: Double); // потолок на drive=100% (внешний усилитель) + procedure ApplyWDSPDrive(Pct: Integer); // цифровой drive WDSP: Pluto=1.0 (мощность — атт), HPSDR=Pct/100 // Диапазоны / трансвертеры / спан procedure SetBand(Idx: Integer); @@ -2104,7 +2105,7 @@ begin if V < 0 then V := 0 else if V > 100 then V := 100; FDrivePercent := V; FDriveLevel := CalcDriveByte; - if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetDriveLevel(FDrivePercent / 100.0); + ApplyWDSPDrive(FDrivePercent); ApplyPlutoTxAtten; // Pluto: drive живьём меняет TX-аттенюацию во время передачи PushNetworkState; // протолкнуть новый drive в радио (если подключено+Running) Changed(rfDrive); @@ -2122,8 +2123,10 @@ begin // На тюне (TUN) уровень берём из TX-настроек (TUNLevel), иначе из drive%. if FTuning then Pct := FTXSettings.TUNLevel else Pct := FDrivePercent; if Pct < 0 then Pct := 0 else if Pct > 100 then Pct := 100; - // dB-линейно: 0% → TX_OFF, 100% → FPlutoTxMaxAttDb (потолок под внешний тракт). - Result := TX_OFF + (Pct / 100.0) * (FPlutoTxMaxAttDb - TX_OFF); + if Pct <= 0 then begin Result := TX_OFF; Exit; end; // 0% → TX практически выкл + // power-linear: мощность ∝ drive%. dB = потолок + 20·log10(pct/100); 100% → потолок, + // 50% → −6 дБ, 10% → −20 дБ. (Раньше dB-линейно от −89.75 — низкие % улетали в −80 дБ.) + Result := FPlutoTxMaxAttDb + 20.0 * Log10(Pct / 100.0); if Result > FPlutoTxMaxAttDb then Result := FPlutoTxMaxAttDb; if Result < TX_OFF then Result := TX_OFF; end; @@ -2146,6 +2149,16 @@ begin SaveGlobalSettings; // персист потолка (per-device) end; +procedure TRadioController.ApplyWDSPDrive(Pct: Integer); +// На Pluto мощность задаётся ОДИН раз — железной аттенюацией (PlutoTxAttForDrive), +// поэтому цифровой уровень WDSP держим на максимуме (1.0), а не режем по drive%. +// HPSDR — как раньше, Pct/100 (реальная мощность там — drive-байт в радио). +begin + if not (FWDSPReady and Assigned(FDSPEngine)) then Exit; + if IsPluto then FDSPEngine.SetDriveLevel(1.0) + else FDSPEngine.SetDriveLevel(EnsureRange(Pct, 0, 100) / 100.0); +end; + procedure TRadioController.SetAtten(Idx: Integer); begin if Idx < 0 then Idx := 0 else if Idx > 2 then Idx := 2; @@ -2603,8 +2616,7 @@ begin FDSPEngine.SetTXTone(True, FTXSettings.TUNFreq, 1.0); FTuning := True; FDriveLevel := CalcDriveByte; // CalcDriveByte увидит FTuning=True (TUN-уровень) - if FWDSPReady and Assigned(FDSPEngine) then - FDSPEngine.SetDriveLevel(FTXSettings.TUNLevel / 100.0); + ApplyWDSPDrive(FTXSettings.TUNLevel); if not FTransmitting then SetMOX(True); // PTT + run TXA-канал end else @@ -2614,8 +2626,7 @@ begin FDSPEngine.SetTXTone(False, 0, 0); FTuning := False; FDriveLevel := CalcDriveByte; // вернуть обычный drive% - if FWDSPReady and Assigned(FDSPEngine) then - FDSPEngine.SetDriveLevel(FDrivePercent / 100.0); + ApplyWDSPDrive(FDrivePercent); if Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then begin FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslateTX(ActiveTXFreqHz),