mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feat(slices): мультислайс-TX — выбор TX-слайса, кросс-банд (Flex-паритет)
- RadioController: FTxSliceId (0=главный VFO, >0=слайс), SetTxSlice эксклюзивно; ActiveTXFreqHz/ActiveTXMode с TX-слайса, режим применяется в SetMOX(True) перед SetTXRun; TxBandIdx для PA-кал и safety DoNotTx при кросс-банде; RemoveSlice сбрасывает TX-слайс. - HPSDRNetwork: TX-антенна выбиралась по RX-бэнду → по TX-частоте (TxAnt[FreqToBandIndex(TXFreqHz)]). - MainForm/PanafallPanel: клик TX на флаге слайса → SetTxSlice, TX-бейджи (янтарь=выбран, красный=передаёт), RefreshTxIndicators по rfTransmitting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+57
-4
@@ -263,6 +263,7 @@ type
|
||||
FTransmitting: Boolean;
|
||||
FTuning: Boolean;
|
||||
FSplitTxB: Boolean;
|
||||
FTxSliceId: Integer; // 0 = главный VFO (A/B split); >0 = слайс-источник TX
|
||||
FVfoLock: Boolean; // блокировка перестройки VFO (Andromeda Lock)
|
||||
FDisplayDuplex: Boolean;
|
||||
// QO-100 full-duplex self-monitor: True — RX-аудио глушится на TX (по умолч.),
|
||||
@@ -427,6 +428,13 @@ type
|
||||
// uplink-LO не подвержен дрейфу LNB).
|
||||
function XvtrTranslateTX(VisibleHz: Double): Double;
|
||||
function ActiveTXFreqHz: Double;
|
||||
// Режим передающего тракта: слайс-источник TX (FTxSliceId) либо главный FMode.
|
||||
function ActiveTXMode: Integer;
|
||||
// Диапазон для калибровки драйва/антенны TX (банд TX-слайса при кросс-банде).
|
||||
function TxBandIdx: Integer;
|
||||
// Выбор слайса-источника передачи (0 = главный VFO). Эксклюзивно.
|
||||
procedure SetTxSlice(SliceId: Integer);
|
||||
property TxSliceId: Integer read FTxSliceId;
|
||||
// Складывает коррекцию маяка dLock в LOError активного трансвертера (живая
|
||||
// калибровка LNB), ретюнит радио и троттлингом сохраняет на диск.
|
||||
procedure ApplyBeaconLOError(dLock: Double);
|
||||
@@ -1489,6 +1497,8 @@ var idx: Integer;
|
||||
begin
|
||||
idx := FindSliceIndex(Id);
|
||||
if idx < 0 then Exit;
|
||||
// Удаляемый слайс был источником TX — вернуть передачу на главный VFO.
|
||||
if FTxSliceId = Id then SetTxSlice(0);
|
||||
if Assigned(FDSPEngine) then FDSPEngine.RemoveSlice(Id);
|
||||
if FSlices[idx].Audio <> nil then
|
||||
begin
|
||||
@@ -1757,7 +1767,12 @@ begin
|
||||
end;
|
||||
|
||||
function TRadioController.ActiveTXFreqHz: Double;
|
||||
var S: TCtrlSlice;
|
||||
begin
|
||||
// Мультислайс-TX: если выбран слайс-источник — передаём на его частоте
|
||||
// (слайсы не несут repeater-конфиг, FM-сдвиг не применяем).
|
||||
if (FTxSliceId > 0) and GetSlice(FTxSliceId, S) then
|
||||
Exit(S.TargetHz);
|
||||
// TX-VFO задаётся ТОЛЬКО селектором FSplitTxB (UI: кнопки TX-A/TX-B),
|
||||
// независимо от активного RX-VFO. Раньше при не-split TX ошибочно следовал
|
||||
// за активным RX (TX-A горит, но передача шла на B при активном B).
|
||||
@@ -1770,6 +1785,41 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TRadioController.ActiveTXMode: Integer;
|
||||
var S: TCtrlSlice;
|
||||
begin
|
||||
if (FTxSliceId > 0) and GetSlice(FTxSliceId, S) then Result := S.Mode
|
||||
else Result := FMode;
|
||||
end;
|
||||
|
||||
function TRadioController.TxBandIdx: Integer;
|
||||
begin
|
||||
// При TX на слайсе другого диапазона (только КВ) калибровка/антенна — по
|
||||
// банду TX-частоты, иначе главный банд.
|
||||
Result := FCurrentBand;
|
||||
if (FTxSliceId > 0) and (FCurrentXvtr < 0) then
|
||||
begin
|
||||
Result := FreqToBandIdx(ActiveTXFreqHz, IsPluto);
|
||||
if (Result < 0) or (Result >= CFG_BAND_COUNT) then Result := FCurrentBand;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetTxSlice(SliceId: Integer);
|
||||
var S: TCtrlSlice;
|
||||
begin
|
||||
if SliceId < 0 then SliceId := 0;
|
||||
// Слайс-источник должен существовать (0 = главный всегда валиден).
|
||||
if (SliceId > 0) and not GetSlice(SliceId, S) then Exit;
|
||||
if FTxSliceId = SliceId then Exit;
|
||||
FTxSliceId := SliceId;
|
||||
// Передающий тракт под режим нового источника (idle-канал, применится к PTT).
|
||||
if FWDSPReady and Assigned(FDSPEngine) then
|
||||
FDSPEngine.SetTXMode(ActiveTXMode);
|
||||
FDriveLevel := CalcDriveByte; // калибровка драйва банда TX-слайса
|
||||
PushNetworkState; // TX-частота/Alex через ActiveTXFreqHz/TxBandIdx
|
||||
Changed(rfTransmitting); // UI: перерисовать TX-бейджи флагов/оверлей
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// QO-100 beacon lock
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -2118,8 +2168,8 @@ begin
|
||||
FXvtrSettings.Entries[FCurrentXvtr].Enabled;
|
||||
if XvtrActive then
|
||||
Cal := FVHFBandCal[FCurrentXvtr]
|
||||
else if (FCurrentBand >= 0) and (FCurrentBand < CFG_BAND_COUNT) then
|
||||
Cal := FPABandCal[FCurrentBand]
|
||||
else if (TxBandIdx >= 0) and (TxBandIdx < CFG_BAND_COUNT) then
|
||||
Cal := FPABandCal[TxBandIdx] // банд TX-слайса при кросс-банд TX
|
||||
else
|
||||
Cal := 38.8;
|
||||
|
||||
@@ -3581,7 +3631,7 @@ var
|
||||
begin
|
||||
// Safety: блокируем TX на бэндах с DoNotTx (Alex) и на RX-only трансвертере.
|
||||
if On_ and FDevConnected and (FCurrentXvtr < 0)
|
||||
and FAlexSettings.DoNotTx[EnsureRange(FCurrentBand, 0, 10)] then
|
||||
and FAlexSettings.DoNotTx[EnsureRange(TxBandIdx, 0, 10)] then
|
||||
Exit;
|
||||
if On_ and (FCurrentXvtr >= 0) and (FCurrentXvtr < CFG_XVTR_COUNT)
|
||||
and FXvtrSettings.Entries[FCurrentXvtr].RXOnly then
|
||||
@@ -3640,6 +3690,9 @@ begin
|
||||
// В non-DUP RX-IQ пакеты дропаются на входе DSP-потока во время TX, чтобы
|
||||
// TX leakage не накапливался в RXA pipeline / FFT-истории анализатора.
|
||||
FDSPEngine.KeepRXDuringTX := FDisplayDuplex;
|
||||
// Мультислайс-TX: передающий тракт под режим слайса-источника (SetMode мог
|
||||
// оставить главный режим). Ставим перед стартом TX-потока.
|
||||
if FTransmitting then FDSPEngine.SetTXMode(ActiveTXMode);
|
||||
FDSPEngine.SetTXRun(FTransmitting);
|
||||
if WasTransmitting and (not FTransmitting) and (not FDisplayDuplex) then
|
||||
begin
|
||||
@@ -3677,7 +3730,7 @@ begin
|
||||
// Safety: те же блокировки, что и в SetMOX — TUN это TX через WDSP PostGen-тон,
|
||||
// он тоже должен молчать на бэндах с DoNotTx и на RX-only XVTR.
|
||||
if On_ and FDevConnected and (FCurrentXvtr < 0)
|
||||
and FAlexSettings.DoNotTx[EnsureRange(FCurrentBand, 0, 10)] then Exit;
|
||||
and FAlexSettings.DoNotTx[EnsureRange(TxBandIdx, 0, 10)] then Exit;
|
||||
if On_ and (FCurrentXvtr >= 0) and (FCurrentXvtr < CFG_XVTR_COUNT)
|
||||
and FXvtrSettings.Entries[FCurrentXvtr].RXOnly then Exit;
|
||||
if On_ then
|
||||
|
||||
Reference in New Issue
Block a user