mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Add channel memory: CH button, dropdown, editor form, smart CTCSS/RPT auto-clear
- New ChannelStore.pas: TChannel record + JSON persistence (channels.json) - New ChannelsForm.pas: full channel editor (list + fields, pre-fills from current radio state) - CH button in RX block: left-click opens dropdown, right-click opens editor - Active channel: button highlights with channel name, deactivates on VFO move - ApplyChannel: auto-switches XVTR/HF band based on channel frequency; saves old band state before switching to prevent cache corruption - SaveCurrentBand: skip save when VFO > 61 MHz (prevents HF cache corruption from VHF channel application without XVTR) - DeactivateXvtr: save full XVTR state (was only saving LastFreq) - CTCSS/RPT from channel marked as auto: cleared automatically when tuning away from channel frequency; survives band switches via FXvtrSettings auto-flags - TXvtrEntry: add LastCTCSSAutoActive, LastFMRptAutoActive fields Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
unit FMRepeater;
|
||||
|
||||
{ FM repeater offset helpers — constants, default offsets, auto-direction logic. }
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
RPT_NONE = 0;
|
||||
RPT_MINUS = 1;
|
||||
RPT_PLUS = 2;
|
||||
|
||||
RPT_2M_BEGIN = 144000000.0;
|
||||
RPT_2M_END = 148000000.0;
|
||||
RPT_70CM_BEGIN = 430000000.0;
|
||||
RPT_70CM_END = 440000000.0;
|
||||
RPT_DEFAULT_2M = 600000.0; // 0.600 MHz
|
||||
RPT_DEFAULT_70CM = 7600000.0; // 7.600 MHz
|
||||
|
||||
// European 2m repeater input segment: auto-enable minus direction
|
||||
RPT_AUTO_MINUS_LO = 145600000.0; // 145.600 MHz
|
||||
RPT_AUTO_MINUS_HI = 145787500.0; // 145.7875 MHz
|
||||
|
||||
{ Returns default offset (Hz) for the given visible frequency.
|
||||
70 cm band → 7.600 MHz; everything else → 0.600 MHz. }
|
||||
function RptDefaultOffsetHz(FreqHz: Double): Double;
|
||||
|
||||
{ Returns RPT_MINUS when FreqHz falls in the 2 m auto-minus segment,
|
||||
RPT_NONE otherwise. }
|
||||
function RptAutoDir(FreqHz: Double): Integer;
|
||||
|
||||
{ Formats OffsetHz as MHz with 3 decimal places, e.g. "0.600". }
|
||||
function RptFormatOffset(OffsetHz: Double): string;
|
||||
|
||||
{ Parses a MHz string ("0.600", "7.6", "7,600") to Hz.
|
||||
Returns 0 on parse error or out-of-range value. }
|
||||
function RptParseOffset(const S: string): Double;
|
||||
|
||||
implementation
|
||||
|
||||
uses SysUtils;
|
||||
|
||||
function RptDefaultOffsetHz(FreqHz: Double): Double;
|
||||
begin
|
||||
if (FreqHz >= RPT_70CM_BEGIN) and (FreqHz <= RPT_70CM_END) then
|
||||
Result := RPT_DEFAULT_70CM
|
||||
else
|
||||
Result := RPT_DEFAULT_2M;
|
||||
end;
|
||||
|
||||
function RptAutoDir(FreqHz: Double): Integer;
|
||||
begin
|
||||
if (FreqHz >= RPT_AUTO_MINUS_LO) and (FreqHz <= RPT_AUTO_MINUS_HI) then
|
||||
Result := RPT_MINUS
|
||||
else
|
||||
Result := RPT_NONE;
|
||||
end;
|
||||
|
||||
function RptFormatOffset(OffsetHz: Double): string;
|
||||
begin
|
||||
Result := Format('%.3f', [OffsetHz / 1000000.0]);
|
||||
end;
|
||||
|
||||
function RptParseOffset(const S: string): Double;
|
||||
var
|
||||
V: Double;
|
||||
Code: Integer;
|
||||
Norm: string;
|
||||
begin
|
||||
Norm := StringReplace(Trim(S), ',', '.', [rfReplaceAll]);
|
||||
Val(Norm, V, Code);
|
||||
if (Code = 0) and (V > 0.0) and (V <= 100.0) then
|
||||
Result := V * 1000000.0
|
||||
else
|
||||
Result := 0.0;
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user