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 // CTCSS tones (38 standard tones). Здесь (а не в MainForm), чтобы таблица // была доступна TRadioController для FDSPEngine.SetTXCTCSS. Имена тонов // (CTCSS_NAMES) остаются в MainForm — это UI-метки выпадающего списка. CTCSS_COUNT = 38; CTCSS_TONES: array[0..CTCSS_COUNT-1] of Double = ( 67.0, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8, 136.5, 141.3, 146.2, 151.4, 156.7, 162.2, 167.9, 173.8, 179.9, 186.2, 192.8, 203.5, 210.7, 218.1, 225.7, 233.6, 241.8, 250.3); { 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.