mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
Add flat FM RAW transmit path
This commit is contained in:
+50
-4
@@ -447,6 +447,7 @@ type
|
||||
FTXWfAvgTimeMS: Double;
|
||||
|
||||
FMode: Integer;
|
||||
FTXMode: Integer; // may differ from RX when a slice is TX source
|
||||
FRawFMDeviation: Double;
|
||||
FSMeter: Double;
|
||||
FFilterLow: Integer;
|
||||
@@ -486,6 +487,9 @@ type
|
||||
procedure ApplyRXDMRToChan(Chan: Integer);
|
||||
procedure ApplyRXRawToChan(Chan: Integer);
|
||||
procedure ApplyWFMSettings;
|
||||
// Mode-dependent TX overlay. FM RAW uses the flat WFM modulator and
|
||||
// bypasses every speech processor without overwriting the saved TX setup.
|
||||
procedure ApplyTXModeSettings(Mode: Integer);
|
||||
// --- Мультислайсы ---
|
||||
function FindSliceIdx(Id: Integer): Integer; // -1 если нет
|
||||
function SliceInRate(Idx: Integer): Integer; // входной rate слайса (его пан)
|
||||
@@ -1006,8 +1010,10 @@ end;
|
||||
function TWDSPEngine.ModeToWDSPTX(Mode: Integer): Integer;
|
||||
// txaMode расходится с rxaMode после DRM — отдельный маппинг только для WFM.
|
||||
begin
|
||||
if Mode = MODE_WFM then Result := WDSP_TX_WFM
|
||||
else if Mode in [MODE_DMR, MODE_FMRAW] then Result := WDSP_FM
|
||||
// The narrow FM modulator has mandatory speech pre-emphasis. FM RAW uses
|
||||
// wfmmod even at NFM deviation because that path has an explicit flat mode.
|
||||
if Mode in [MODE_WFM, MODE_FMRAW] then Result := WDSP_TX_WFM
|
||||
else if Mode = MODE_DMR then Result := WDSP_FM
|
||||
else Result := ModeToWDSP(Mode);
|
||||
end;
|
||||
|
||||
@@ -1148,6 +1154,36 @@ begin
|
||||
SetTXAWFMPreEmphTau (TXA_CHAN, WFM_TAU_DE_US);
|
||||
end;
|
||||
|
||||
procedure TWDSPEngine.ApplyTXModeSettings(Mode: Integer);
|
||||
begin
|
||||
if not FInitialized then Exit;
|
||||
if Mode = MODE_FMRAW then
|
||||
begin
|
||||
// Decoder/modem-grade FM input. A full-scale PCM peak produces the
|
||||
// selected peak deviation. Keep only a broad linear-phase AF bandpass;
|
||||
// APRS and other external modems must not see voice EQ, dynamics or emphasis.
|
||||
SetTXAWFMDeviation (TXA_CHAN, FRawFMDeviation);
|
||||
SetTXAWFMAFFreqs (TXA_CHAN, 20.0, 7000.0);
|
||||
SetTXAWFMPreEmphRun (TXA_CHAN, 0);
|
||||
SetTXABandpassFreqs (TXA_CHAN, 20.0, 7000.0);
|
||||
SetTXABandpassRun (TXA_CHAN, 1);
|
||||
SetTXAPanelGain1 (TXA_CHAN, 1.0);
|
||||
SetTXACompressorRun (TXA_CHAN, 0);
|
||||
SetTXALevelerSt (TXA_CHAN, 0);
|
||||
SetTXAALCSt (TXA_CHAN, 0);
|
||||
SetTXAPHROTRun (TXA_CHAN, 0);
|
||||
SetTXAEQRun (TXA_CHAN, 0);
|
||||
SetTXACTCSSRun (TXA_CHAN, 0);
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Restore the user's normal voice/data chain after leaving FM RAW.
|
||||
SetTXABandpassRun(TXA_CHAN, 1);
|
||||
ApplyTXChainSettings;
|
||||
if Mode = MODE_WFM then ApplyWFMSettings;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWDSPEngine.ClampToNyquist(Hz, Rate: Integer): Integer;
|
||||
var Limit: Integer;
|
||||
begin
|
||||
@@ -1196,6 +1232,7 @@ begin
|
||||
FInitialized := False;
|
||||
FAnalyzerOpen := False;
|
||||
FMode := MODE_USB;
|
||||
FTXMode := MODE_USB;
|
||||
FFilterLow := 100;
|
||||
FFilterHigh := 2400;
|
||||
FAGCMode := agcMedium;
|
||||
@@ -1688,7 +1725,8 @@ begin
|
||||
// изредка фазовый разрыв PostGen-тона (всплеск на водопаде + щелчок).
|
||||
);
|
||||
|
||||
SetTXAMode(TXA_CHAN, ModeToWDSPTX(FMode));
|
||||
FTXMode := FMode;
|
||||
SetTXAMode(TXA_CHAN, ModeToWDSPTX(FTXMode));
|
||||
SetTXAPanelRun(TXA_CHAN, 1);
|
||||
// PatchPanel: 1=Q, 2=I. Mic подаётся в I (FTXIn[i*2]), Q=0 — выбираем I.
|
||||
SetTXAPanelSelect(TXA_CHAN, 2);
|
||||
@@ -2819,6 +2857,7 @@ end;
|
||||
procedure TWDSPEngine.SetMode(Mode: Integer);
|
||||
begin
|
||||
FMode := Mode;
|
||||
FTXMode := Mode;
|
||||
if not FInitialized then Exit;
|
||||
// Rate — до режима: setDSPSamplerate_rxa перестраивает всю цепь (в т.ч. wfmd),
|
||||
// а SetRXAMode затем пересчитает bpsnba под уже актуальный dsp_rate.
|
||||
@@ -2833,6 +2872,7 @@ begin
|
||||
SetRXAWFMDeemphRun (RXA_CHAN, 0);
|
||||
end
|
||||
else if Mode = MODE_FMRAW then ApplyRXRawToChan(RXA_CHAN);
|
||||
ApplyTXModeSettings(FTXMode);
|
||||
// НЕ вызываем ApplyDefaultFilter — фильтр устанавливается явно из UI
|
||||
end;
|
||||
|
||||
@@ -3081,6 +3121,7 @@ begin
|
||||
FRawFMDeviation := EnsureRange(Deviation, 500.0, 10000.0);
|
||||
if not FInitialized then Exit;
|
||||
if FMode = MODE_FMRAW then SetRXAWFMDeviation(RXA_CHAN, FRawFMDeviation);
|
||||
if FTXMode = MODE_FMRAW then SetTXAWFMDeviation(TXA_CHAN, FRawFMDeviation);
|
||||
// One calibration value applies to every active FM RAW decoder output.
|
||||
FSliceLock.Enter;
|
||||
try
|
||||
@@ -3127,13 +3168,18 @@ end;
|
||||
|
||||
procedure TWDSPEngine.SetTXMode(Mode: Integer);
|
||||
begin
|
||||
FTXMode := Mode;
|
||||
if not FInitialized then Exit;
|
||||
SetTXAMode(TXA_CHAN, ModeToWDSPTX(Mode));
|
||||
SetTXAMode(TXA_CHAN, ModeToWDSPTX(FTXMode));
|
||||
ApplyTXModeSettings(FTXMode);
|
||||
end;
|
||||
|
||||
procedure TWDSPEngine.SetTXFilter(Low, High: Integer);
|
||||
begin
|
||||
if not FInitialized then Exit;
|
||||
// In FM RAW this is an RF-channel-width update mirrored from the RX UI,
|
||||
// not an audio passband request. The flat modem AF passband is fixed above.
|
||||
if FTXMode = MODE_FMRAW then Exit;
|
||||
SetTXABandpassFreqs(TXA_CHAN, Low, High);
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user