mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Add FM mode improvements: NFM/FM filters, CTCSS, squelch; ADC and web settings
FM modulation: - Replace 10 generic FM filter buttons with NFM (2.5kHz dev/11kHz BW) and FM (5.0kHz dev/16kHz BW); deviation applied to both RX and TX via WDSP - Add FM squelch panel (SQL toggle + slider 0..100, per-band save/restore) with WDSP SetRXAFMSQRun/SetRXAFMSQThreshold (threshold = level/200.0) - Add CTCSS panel with on/off toggle and custom flat-button tone picker popup (38 standard tones 67.0..250.3 Hz, default 67.0); tone selection and enable state saved per band via SetTXACTCSS* - FM panels (SQL, CTCSS) shown only in FM mode, layout via RelayoutBelowBands - PanelFilter height shrinks in FM mode so panels sit tight below filters - FlatButton: handle CMTextChanged to invalidate on Caption change ADC settings (Dither/Random): - Add DitherEnabled/RandomEnabled to TGlobalSettings (default true) - Pass as bitmask to ConfigureDDCs DDC Specific packet bytes 5/6 - Exposed in Settings → Advanced tab with live apply via ApplyADCSettings Web server settings: - Add TWebSettings (enabled, port, bind_addr, user, pass) stored globally - WebServer: configurable port/bind IP via ParseIPv4; Reconfigure method - Exposed in Settings → Advanced tab with live apply via ApplyWebSettings Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,8 @@ type
|
||||
AGCTop: Integer;
|
||||
CTun: Boolean;
|
||||
SpanHz: Double;
|
||||
FMSQOn: Boolean;
|
||||
FMSQLevel: Integer; // 0..100 → WDSP threshold 0.0..0.5
|
||||
end;
|
||||
|
||||
// TX-настройки per-device. Хранятся в JSON-секции "tx" под MAC,
|
||||
@@ -104,6 +106,15 @@ type
|
||||
TXSpecGridStep: Double; // grid step in dB, e.g. 10
|
||||
end;
|
||||
|
||||
// Web-сервер — глобальные настройки (не привязаны к устройству, секция "web").
|
||||
TWebSettings = record
|
||||
Enabled: Boolean;
|
||||
Port: Integer; // 1..65535
|
||||
BindAddr: string; // e.g. '0.0.0.0' (все интерфейсы)
|
||||
User: string;
|
||||
Pass: string;
|
||||
end;
|
||||
|
||||
// Transverter (XVTR) entry — один трансвертер.
|
||||
// Видимая частота VFO в [FreqBegin..FreqEnd] транслируется в IF-частоту,
|
||||
// которую слышит трансивер: f_IF = f_visible - LOOffset + LOError.
|
||||
@@ -197,6 +208,9 @@ type
|
||||
// --- PA (Power Amplifier) settings ---
|
||||
PAMaxPower: Double; // максимальная выходная мощность, Вт (5..200)
|
||||
PABandCal: array[0..CFG_BAND_COUNT-1] of Double; // калибровка на диапазон 38.8..100.0
|
||||
// --- ADC settings ---
|
||||
DitherEnabled: Boolean; // DDC Specific byte 5 — уменьшает интермодуляцию
|
||||
RandomEnabled: Boolean; // DDC Specific byte 6 — рандомизация ADC
|
||||
// --- CAT (Computer Aided Transceiver) settings ---
|
||||
// До 4 последовательных портов (Linux: /dev/ttyS0, Windows: COM1 и т.д.)
|
||||
CATSerialEnabled: array[0..3] of Boolean;
|
||||
@@ -264,6 +278,10 @@ type
|
||||
class procedure DefaultXvtr(out X: TXvtrSettings);
|
||||
function LoadXvtr(const MAC: array of Byte; out X: TXvtrSettings): Boolean;
|
||||
procedure SaveXvtr(const MAC: array of Byte; const X: TXvtrSettings);
|
||||
// Web-сервер — глобальные настройки (секция "web" в корне JSON).
|
||||
class procedure DefaultWeb(out W: TWebSettings);
|
||||
procedure LoadWebSettings(out W: TWebSettings);
|
||||
procedure SaveWebSettings(const W: TWebSettings);
|
||||
// Тема — глобальная настройка, не привязана к устройству
|
||||
procedure SaveTheme(ALightTheme: Boolean);
|
||||
function LoadTheme: Boolean;
|
||||
@@ -309,6 +327,8 @@ begin
|
||||
B.AGCTop := 90;
|
||||
B.CTun := False;
|
||||
B.SpanHz := 192000;
|
||||
B.FMSQOn := False;
|
||||
B.FMSQLevel := 30;
|
||||
end;
|
||||
|
||||
class procedure TSettingsManager.DefaultGlobal(out G: TGlobalSettings);
|
||||
@@ -362,6 +382,9 @@ begin
|
||||
end;
|
||||
G.CATTcpEnabled := False;
|
||||
G.CATTcpPort := 19090;
|
||||
// ADC — включены по умолчанию: поддерживаются на Hermes, Angelia, Orion
|
||||
G.DitherEnabled := True;
|
||||
G.RandomEnabled := True;
|
||||
end;
|
||||
|
||||
constructor TSettingsManager.Create(const FilePath: string);
|
||||
@@ -578,6 +601,9 @@ begin
|
||||
end;
|
||||
G.CATTcpEnabled := JB(GObj,'cat_tcp_enabled', False);
|
||||
G.CATTcpPort := JI(GObj,'cat_tcp_port', 19090);
|
||||
// ADC settings
|
||||
G.DitherEnabled := JB(GObj,'dither_enabled', True);
|
||||
G.RandomEnabled := JB(GObj,'random_enabled', True);
|
||||
|
||||
for i := 0 to CFG_BAND_COUNT-1 do
|
||||
begin
|
||||
@@ -654,6 +680,9 @@ begin
|
||||
end;
|
||||
JW(O,'cat_tcp_enabled',G.CATTcpEnabled);
|
||||
JW(O,'cat_tcp_port',G.CATTcpPort);
|
||||
// ADC settings
|
||||
JW(O,'dither_enabled',G.DitherEnabled);
|
||||
JW(O,'random_enabled',G.RandomEnabled);
|
||||
end;
|
||||
|
||||
procedure TSettingsManager.SaveBand(const MAC: array of Byte; BandIdx: Integer;
|
||||
@@ -667,6 +696,7 @@ begin
|
||||
JW(O,'filter_idx',B.FilterIdx); JW(O,'filter_bw',B.FilterBW);
|
||||
JW(O,'agc_mode',B.AGCMode); JW(O,'agc_top',B.AGCTop);
|
||||
JW(O,'ctun',B.CTun); JW(O,'span_hz',B.SpanHz);
|
||||
JW(O,'fmsq_on',B.FMSQOn); JW(O,'fmsq_level',B.FMSQLevel);
|
||||
end;
|
||||
|
||||
function TSettingsManager.LoadBand(const MAC: array of Byte; BandIdx: Integer;
|
||||
@@ -687,6 +717,8 @@ begin
|
||||
B.AGCTop := JI(O,'agc_top', B.AGCTop);
|
||||
B.CTun := JB(O,'ctun', B.CTun);
|
||||
B.SpanHz := JD(O,'span_hz', B.SpanHz);
|
||||
B.FMSQOn := JB(O,'fmsq_on', B.FMSQOn);
|
||||
B.FMSQLevel := JI(O,'fmsq_level', B.FMSQLevel);
|
||||
end;
|
||||
|
||||
procedure TSettingsManager.SaveWindowBounds(L, T, W, H: Integer);
|
||||
@@ -1137,6 +1169,40 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
class procedure TSettingsManager.DefaultWeb(out W: TWebSettings);
|
||||
begin
|
||||
W.Enabled := True;
|
||||
W.Port := 8080;
|
||||
W.BindAddr := '0.0.0.0';
|
||||
W.User := 'admin';
|
||||
W.Pass := 'hpsdr';
|
||||
end;
|
||||
|
||||
procedure TSettingsManager.LoadWebSettings(out W: TWebSettings);
|
||||
var O: TJSONObject;
|
||||
begin
|
||||
DefaultWeb(W);
|
||||
if FRoot.Find('web') = nil then Exit;
|
||||
O := EnsureObj(FRoot, 'web');
|
||||
W.Enabled := JB(O, 'enabled', True);
|
||||
W.Port := EnsureRange(JI(O, 'port', 8080), 1, 65535);
|
||||
W.BindAddr := JS(O, 'bind_addr', '0.0.0.0');
|
||||
W.User := JS(O, 'user', 'admin');
|
||||
W.Pass := JS(O, 'pass', 'hpsdr');
|
||||
end;
|
||||
|
||||
procedure TSettingsManager.SaveWebSettings(const W: TWebSettings);
|
||||
var O: TJSONObject;
|
||||
begin
|
||||
O := EnsureObj(FRoot, 'web');
|
||||
JW(O, 'enabled', W.Enabled);
|
||||
JW(O, 'port', W.Port);
|
||||
JWS(O, 'bind_addr', W.BindAddr);
|
||||
JWS(O, 'user', W.User);
|
||||
JWS(O, 'pass', W.Pass);
|
||||
Save;
|
||||
end;
|
||||
|
||||
procedure TSettingsManager.SaveTheme(ALightTheme: Boolean);
|
||||
var O: TJSONObject;
|
||||
begin
|
||||
|
||||
Reference in New Issue
Block a user