mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
fix(tx): полоса ЧМ на передаче — занимаемая полоса, а не кромки bp0
TXFilterEdgesHz была тонкой обёрткой над TXSignedEdges, то есть отдавала в отрисовку кромки аудио-полосовика перед модулятором. У SSB/CW/DIGI/AM это то же самое, что полоса вокруг несущей, а у ЧМ — нет: FM RAW рисовался как (20..7000), WFM как (20..15000), то есть полоса уезжала вверх от несущей и визуально «переключалась на USB». Теперь у экранных кромок своя семантика — Карсон ±(девиация + верхний срез аудио) для FM/WFM/FM RAW, остальные режимы как были. TXSignedEdges и SetTXABandpassFreqs не тронуты: bp0 остаётся портом Thetis, в эфире ничего не меняется. Попутно 20.0/7000.0 из трёх мест FM RAW сведены в RAW_AF_LOW/RAW_AF_HIGH. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+28
-5
@@ -78,6 +78,10 @@ const
|
|||||||
WFM_AF_HIGH = 15000.0;
|
WFM_AF_HIGH = 15000.0;
|
||||||
WFM_TAU_DE_US = 50.0e-6; // Европа/Россия (Америка — 75 мкс)
|
WFM_TAU_DE_US = 50.0e-6; // Европа/Россия (Америка — 75 мкс)
|
||||||
DMR_DEVIATION = 2500.0;
|
DMR_DEVIATION = 2500.0;
|
||||||
|
// FM RAW: плоский baseband для внешних декодеров — одна величина на RX-AF,
|
||||||
|
// TX-AF и bp0 (раньше 20/7000 стояли числами в трёх местах).
|
||||||
|
RAW_AF_LOW = 20.0;
|
||||||
|
RAW_AF_HIGH = 7000.0;
|
||||||
// Потолок dsp_rate для WFM. Вещательному каналу (200 кГц) хватает 192 кГц,
|
// Потолок dsp_rate для WFM. Вещательному каналу (200 кГц) хватает 192 кГц,
|
||||||
// а гнать цепь на полном IQ-rate нельзя: при 576 кГц dsp_size стал бы 12288,
|
// а гнать цепь на полном IQ-rate нельзя: при 576 кГц dsp_size стал бы 12288,
|
||||||
// и fircore спланировал бы FFT на 2*12288 = 24576 точек. Это не степень
|
// и fircore спланировал бы FFT на 2*12288 = 24576 точек. Это не степень
|
||||||
@@ -1167,7 +1171,7 @@ procedure TWDSPEngine.ApplyRXRawToChan(Chan: Integer);
|
|||||||
begin
|
begin
|
||||||
// Decoder-grade discriminator: no broadcast de-emphasis or limiter.
|
// Decoder-grade discriminator: no broadcast de-emphasis or limiter.
|
||||||
SetRXAWFMDeviation (Chan, FRawFMDeviation);
|
SetRXAWFMDeviation (Chan, FRawFMDeviation);
|
||||||
SetRXAWFMAFFilter (Chan, 20.0, 7000.0);
|
SetRXAWFMAFFilter (Chan, RAW_AF_LOW, RAW_AF_HIGH);
|
||||||
SetRXAWFMDeemphRun (Chan, 0);
|
SetRXAWFMDeemphRun (Chan, 0);
|
||||||
SetRXAWFMLimRun (Chan, 0);
|
SetRXAWFMLimRun (Chan, 0);
|
||||||
end;
|
end;
|
||||||
@@ -1221,7 +1225,7 @@ begin
|
|||||||
// Плоский baseband для внешних декодеров (совпадает с RX AF в ApplyRXRawToChan
|
// Плоский baseband для внешних декодеров (совпадает с RX AF в ApplyRXRawToChan
|
||||||
// и с явным SetTXABandpassFreqs в ApplyTXModeSettings). РЧ-ширина FILT_RAW_BW
|
// и с явным SetTXABandpassFreqs в ApplyTXModeSettings). РЧ-ширина FILT_RAW_BW
|
||||||
// (6..25 кГц) — селективность RX, к аудио-полосовику отношения не имеет.
|
// (6..25 кГц) — селективность RX, к аудио-полосовику отношения не имеет.
|
||||||
begin Lo := 20.0; Hi := 7000.0; end;
|
begin Lo := RAW_AF_LOW; Hi := RAW_AF_HIGH; end;
|
||||||
else
|
else
|
||||||
begin Lo := L; Hi := H; end; // прочее — как есть
|
begin Lo := L; Hi := H; end; // прочее — как есть
|
||||||
end;
|
end;
|
||||||
@@ -1236,9 +1240,9 @@ begin
|
|||||||
// selected peak deviation. Keep only a broad linear-phase AF bandpass;
|
// selected peak deviation. Keep only a broad linear-phase AF bandpass;
|
||||||
// APRS and other external modems must not see voice EQ, dynamics or emphasis.
|
// APRS and other external modems must not see voice EQ, dynamics or emphasis.
|
||||||
SetTXAWFMDeviation (TXA_CHAN, FRawFMDeviation);
|
SetTXAWFMDeviation (TXA_CHAN, FRawFMDeviation);
|
||||||
SetTXAWFMAFFreqs (TXA_CHAN, 20.0, 7000.0);
|
SetTXAWFMAFFreqs (TXA_CHAN, RAW_AF_LOW, RAW_AF_HIGH);
|
||||||
SetTXAWFMPreEmphRun (TXA_CHAN, 0);
|
SetTXAWFMPreEmphRun (TXA_CHAN, 0);
|
||||||
SetTXABandpassFreqs (TXA_CHAN, 20.0, 7000.0);
|
SetTXABandpassFreqs (TXA_CHAN, RAW_AF_LOW, RAW_AF_HIGH);
|
||||||
SetTXAPanelGain1 (TXA_CHAN, 1.0);
|
SetTXAPanelGain1 (TXA_CHAN, 1.0);
|
||||||
SetTXACompressorRun (TXA_CHAN, 0);
|
SetTXACompressorRun (TXA_CHAN, 0);
|
||||||
SetTXALevelerSt (TXA_CHAN, 0);
|
SetTXALevelerSt (TXA_CHAN, 0);
|
||||||
@@ -3715,8 +3719,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWDSPEngine.TXFilterEdgesHz(out Lo, Hi: Integer);
|
procedure TWDSPEngine.TXFilterEdgesHz(out Lo, Hi: Integer);
|
||||||
var L, H: Double;
|
// ЭКРАННЫЕ кромки — занимаемая полоса вокруг несущей, а НЕ bp0. У SSB/CW/DIGI/
|
||||||
|
// AM/DSB это одно и то же, поэтому здесь и стояла обёртка над TXSignedEdges.
|
||||||
|
// Но у ЧМ bp0 — АУДИО-полосовик ПЕРЕД модулятором: у FM RAW он (20..7000), у
|
||||||
|
// WFM (20..15000), и полоса на спектре уезжала вверх от несущей — визуально
|
||||||
|
// «переключалась на USB». Для ЧМ считаем по Карсону: ±(девиация + верхний срез
|
||||||
|
// аудио), симметрично несущей. У MODE_FM TXSignedEdges отдаёт ровно эту
|
||||||
|
// величину и без нас (порт Thetis), но пусть формула будет в одном месте.
|
||||||
|
var L, H, Half: Double;
|
||||||
begin
|
begin
|
||||||
|
Half := 0.0;
|
||||||
|
case FTXMode of
|
||||||
|
MODE_FM: Half := FTXFMDeviation + FTXFMHighCut;
|
||||||
|
MODE_WFM: Half := WFM_DEVIATION + WFM_AF_HIGH;
|
||||||
|
MODE_FMRAW: Half := FRawFMDeviation + RAW_AF_HIGH;
|
||||||
|
end;
|
||||||
|
if Half > 0.0 then
|
||||||
|
begin
|
||||||
|
Lo := -Round(Half);
|
||||||
|
Hi := Round(Half);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
TXSignedEdges(FTXMode, L, H);
|
TXSignedEdges(FTXMode, L, H);
|
||||||
Lo := Round(L);
|
Lo := Round(L);
|
||||||
Hi := Round(H);
|
Hi := Round(H);
|
||||||
|
|||||||
Reference in New Issue
Block a user