mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Phase 3 (batch 18): move MOX (TX core) into the controller
SetMOX now carries the TX engine/network logic: DoNotTx/RXOnly safety gates, drive recalc, the PTT relay sequence (relay-before-PTT on TX-on, PTT-before-relay on TX-off), mic-source selection (web/HW-PTT/default), KeepRXDuringTX, SetTXRun, and the non-DUP TX->RX FlushRX + post-TX mute. New controller fields FWebClientActive (mirrored from the web server in the thin ApplyMOX wrapper) and FWebMicActive (moved from MainForm), plus DefaultMicSource. UI render (BtnMOX style, FSpecView TX overlay/mode, grid, FDUCPendingCount reset) moved to OnControllerState(rfTransmitting). Also fix a pre-existing status-bar bug: web TX was labelled 'TX radio mic' (the old if/else folded any non-soundcard source into radio); now a case shows 'TX web mic' for txmsWeb. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c249b46b17
commit
603e0850cf
+87
-1
@@ -159,6 +159,8 @@ type
|
||||
FDisplayDuplex: Boolean;
|
||||
FHWPTTActive: Boolean;
|
||||
FHWPTTStartedTX: Boolean;
|
||||
FWebClientActive: Boolean; // выставляет web-слой (connect/disconnect клиента)
|
||||
FWebMicActive: Boolean; // True если текущий TX идёт через txmsWeb
|
||||
FSendAudioToRadio: Boolean;
|
||||
FAudioOutDevName: string;
|
||||
FAudioInDevName: string;
|
||||
@@ -223,6 +225,10 @@ type
|
||||
// (band/xvtr cal, TUN/drive%, PA max). Чистая функция над состоянием.
|
||||
function CalcDriveByte: Byte;
|
||||
|
||||
// Источник микрофона по умолчанию для MOX-кнопки/Web-TX: звуковая карта
|
||||
// если настроена, иначе HW mic-стрим трансивера. HW PTT → txmsRadio в SetMOX.
|
||||
function DefaultMicSource: TTXMicSource;
|
||||
|
||||
// ---- Управление диапазонами (состояние + DSP; рендер через события) ----
|
||||
// MakeBandSettings — снимок текущего состояния в запись диапазона.
|
||||
// SaveCurrentBand — сохраняет текущее состояние в кэш+конфиг (или в XVTR-слот).
|
||||
@@ -1251,8 +1257,88 @@ begin
|
||||
Changed(rfANF);
|
||||
end;
|
||||
|
||||
function TRadioController.DefaultMicSource: TTXMicSource;
|
||||
begin
|
||||
if FAudioInDevName <> '' then Result := txmsSoundCard
|
||||
else Result := txmsRadio;
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetMOX(On_: Boolean);
|
||||
begin FTransmitting := On_; Changed(rfTransmitting); { TODO wiring: ApplyMOX } end;
|
||||
var
|
||||
WasTransmitting: Boolean;
|
||||
begin
|
||||
// Safety: блокируем TX на бэндах с DoNotTx (Alex) и на RX-only трансвертере.
|
||||
if On_ and FDevConnected and (FCurrentXvtr < 0)
|
||||
and FAlexSettings.DoNotTx[EnsureRange(FCurrentBand, 0, 10)] then
|
||||
Exit;
|
||||
if On_ and (FCurrentXvtr >= 0) and (FCurrentXvtr < CFG_XVTR_COUNT)
|
||||
and FXvtrSettings.Entries[FCurrentXvtr].RXOnly then
|
||||
Exit;
|
||||
WasTransmitting := FTransmitting;
|
||||
FTransmitting := On_;
|
||||
if On_ then FDriveLevel := CalcDriveByte;
|
||||
// Сетевая PTT-последовательность TX-on: сначала реле (Alex bit27=1, drive) без
|
||||
// PTT, затем PTT=1 — переключаем реле раньше передачи.
|
||||
if FTransmitting and Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then
|
||||
begin
|
||||
FNetwork.ClearDUCIQQueue;
|
||||
FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslate(ActiveTXFreqHz),
|
||||
FDriveLevel, True, True, True);
|
||||
FNetwork.SendFullHP; // 1й пакет: Alex bit27=1 (T/R relay), drive — без PTT
|
||||
FNetwork.SendPTT(True); // 2й пакет: PTT=1 после переключения реле
|
||||
end;
|
||||
if FWDSPReady and Assigned(FDSPEngine) then
|
||||
begin
|
||||
// Mic source автоматически по источнику TX:
|
||||
// Web TX → txmsWeb; HW PTT → txmsRadio; MOX/CAT → DefaultMicSource.
|
||||
if FTransmitting then
|
||||
begin
|
||||
if FWebClientActive then
|
||||
begin
|
||||
FWebMicActive := True;
|
||||
FDSPEngine.SetTXMicSource(txmsWeb);
|
||||
end
|
||||
else if FHWPTTActive then
|
||||
FDSPEngine.SetTXMicSource(txmsRadio)
|
||||
else
|
||||
FDSPEngine.SetTXMicSource(DefaultMicSource);
|
||||
end
|
||||
else if FWebMicActive then
|
||||
begin
|
||||
FWebMicActive := False;
|
||||
FDSPEngine.SetTXMicSource(DefaultMicSource);
|
||||
end;
|
||||
// В non-DUP RX-IQ пакеты дропаются на входе DSP-потока во время TX, чтобы
|
||||
// TX leakage не накапливался в RXA pipeline / FFT-истории анализатора.
|
||||
FDSPEngine.KeepRXDuringTX := FDisplayDuplex;
|
||||
FDSPEngine.SetTXRun(FTransmitting);
|
||||
if WasTransmitting and (not FTransmitting) and (not FDisplayDuplex) then
|
||||
begin
|
||||
FDSPEngine.FlushRX;
|
||||
if Assigned(FAudioOut) then
|
||||
FAudioOut.Clear;
|
||||
{$IFDEF WINDOWS}
|
||||
// Windows: на TX→RX дропаем И RX-IQ, И аудио-выход — radio FPGA TX-buffer +
|
||||
// PA slew-down дотравливают «хвост» (на Windows тянется 200–500мс).
|
||||
FDSPEngine.BeginPostTXMute(250);
|
||||
{$ENDIF}
|
||||
end;
|
||||
// SetTXRun переключает FActiveDisplayID на TX_DISP_ID; при DUP возвращаем
|
||||
// источник на RX, чтобы видеть приём во время передачи.
|
||||
if FTransmitting and FDisplayDuplex then
|
||||
FDSPEngine.SetDisplaySourceTX(False);
|
||||
end;
|
||||
// Сетевая PTT-последовательность TX-off: сначала снимаем PTT, затем реле RX.
|
||||
if (not FTransmitting) and Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then
|
||||
begin
|
||||
FNetwork.SendPTT(False); // 1й пакет: PTT=0 — сначала снимаем PTT
|
||||
FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslate(ActiveTXFreqHz),
|
||||
FDriveLevel, False, True, True);
|
||||
FNetwork.ClearDUCIQQueue;
|
||||
FNetwork.SendFullHP; // 2й пакет: Alex bit27=0 (T/R relay RX)
|
||||
end;
|
||||
Changed(rfTransmitting);
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetTune(On_: Boolean);
|
||||
begin FTuning := On_; Changed(rfTuning); { TODO wiring: ApplyTUN } end;
|
||||
|
||||
Reference in New Issue
Block a user