mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
Merge branch 'refactor/extract-modules'
Extract helpers out of MainForm into structured modules: - BoardUtils: BoardTypeName, FreqToBandIdx (removes duplication with DeviceForm) - WisdomBuilder: TWisdomBuildThread + TWisdomProgressDialog - UISync: TDeviceFoundSync/TStatusUISync/TDDCSeqSync via callbacks - PlatformUtils: HasOpenGLSpectrumSwitch, CurrentScreenDPI Minor cleanup: unused local constants, stale comments in AudioOutput.
This commit is contained in:
+2
-9
@@ -186,10 +186,7 @@ const
|
||||
PA_CONTINUE = LongInt(0);
|
||||
PA_NO_DEV = TPaDeviceIndex(-1);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Callback — точная копия pa_out_cb из оригинала
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Callback modeled after pa_out_cb from piHPSDR/portaudio.c
|
||||
function PaOutCallback(inputBuffer, outputBuffer: Pointer;
|
||||
framesPerBuffer: LongWord;
|
||||
timeInfo: Pointer;
|
||||
@@ -567,11 +564,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// WriteDouble — точная копия audio_write() из оригинала
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// WriteDouble — точная копия audio_write() из piHPSDR/portaudio.c
|
||||
// WriteDouble — modeled after audio_write() from piHPSDR/portaudio.c
|
||||
// Вызывается per-sample из Write. Мьютекс держится весь цикл в Write.
|
||||
procedure TAudioOutput.WriteDouble(Left, Right: Double);
|
||||
var
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
unit BoardUtils;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
function BoardTypeName(BoardType: Integer): string;
|
||||
function FreqToBandIdx(Hz: Double): Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses SysUtils;
|
||||
|
||||
function BoardTypeName(BoardType: Integer): string;
|
||||
begin
|
||||
case BoardType of
|
||||
1: Result := 'HERMES (ANAN-10/100)';
|
||||
2: Result := 'HERMES-E (ANAN-10E/100B)';
|
||||
3: Result := 'ANGELIA (ANAN-100D)';
|
||||
4: Result := 'ORION (ANAN-200D)';
|
||||
5: Result := 'ORION MkII (ANAN-7000/8000)';
|
||||
6: Result := 'HERMES-LITE 2';
|
||||
10: Result := 'SATURN (G2)';
|
||||
else Result := Format('Unknown Board #%d', [BoardType]);
|
||||
end;
|
||||
end;
|
||||
|
||||
function FreqToBandIdx(Hz: Double): Integer;
|
||||
const
|
||||
BAND_LO: array[0..10] of Double = (
|
||||
1800000, 3500000, 5330000, 7000000, 10100000,
|
||||
14000000, 18068000, 21000000, 24890000, 28000000, 50000000);
|
||||
BAND_HI: array[0..10] of Double = (
|
||||
2000000, 4000000, 5410000, 7300000, 10150000,
|
||||
14350000, 18168000, 21450000, 24990000, 29700000, 54000000);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
for i := 0 to 10 do
|
||||
if (Hz >= BAND_LO[i]) and (Hz <= BAND_HI[i]) then
|
||||
begin
|
||||
Result := i;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
+2
-18
@@ -6,10 +6,8 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FlatButton, FlatEdit, FlatListBox, AppTheme, Forms, Controls, Graphics, Dialogs,
|
||||
StdCtrls, ExtCtrls, ComCtrls, IniFiles;
|
||||
|
||||
// Декодирование типа платы (совпадает с MainForm.BoardTypeName)
|
||||
function BoardTypeName(BoardType: Integer): string;
|
||||
StdCtrls, ExtCtrls, ComCtrls, IniFiles,
|
||||
BoardUtils;
|
||||
|
||||
const
|
||||
DEVICE_CFG_FILE = 'hpsdr_devices.ini';
|
||||
@@ -114,20 +112,6 @@ type
|
||||
|
||||
implementation
|
||||
|
||||
function BoardTypeName(BoardType: Integer): string;
|
||||
begin
|
||||
case BoardType of
|
||||
1: Result := 'HERMES (ANAN-10/100)';
|
||||
2: Result := 'HERMES-E (ANAN-10E/100B)';
|
||||
3: Result := 'ANGELIA (ANAN-100D)';
|
||||
4: Result := 'ORION (ANAN-200D)';
|
||||
5: Result := 'ORION MkII (ANAN-7000/8000)';
|
||||
6: Result := 'HERMES-LITE 2';
|
||||
10: Result := 'SATURN (G2)';
|
||||
else Result := Format('Unknown Board #%d', [BoardType]);
|
||||
end;
|
||||
end;
|
||||
|
||||
const
|
||||
CLR_BG = TColor($00121212);
|
||||
CLR_PANEL = TColor($001A1A1A);
|
||||
|
||||
+5
-277
@@ -26,7 +26,6 @@ uses
|
||||
FlatButton, FlatSlider, FlatDropDown, AppTheme, Forms, Controls, Graphics, Dialogs,
|
||||
StdCtrls, ExtCtrls, Buttons, Menus, Math, Types,
|
||||
OpenGLContext,
|
||||
FlatProgressBar,
|
||||
LCLIntf, LCLType, GraphType,
|
||||
HPSDRProtocol, HPSDRNetwork,
|
||||
WDSP, WDSPEngine, AudioOutput, AudioInput,
|
||||
@@ -37,7 +36,8 @@ uses
|
||||
WidebandView,
|
||||
StatusBar,
|
||||
PlatformUtils,
|
||||
WinFirewall;
|
||||
WinFirewall,
|
||||
BoardUtils, WisdomBuilder, UISync;
|
||||
|
||||
const
|
||||
CLR_BG = TColor($00101010);
|
||||
@@ -138,45 +138,6 @@ type
|
||||
Display: string;
|
||||
end;
|
||||
|
||||
// Синхронизирующий объект для OnDeviceFound
|
||||
TDeviceFoundSync = class
|
||||
private
|
||||
FForm: TObject; // TMainForm, через forward ref
|
||||
FDev: THPSDRDevice;
|
||||
FEntry: string;
|
||||
public
|
||||
constructor Create(AForm: TObject; const D: THPSDRDevice; const E: string);
|
||||
procedure Execute;
|
||||
end;
|
||||
|
||||
// Синхронизирующий объект для HP Status
|
||||
TStatusUISync = class
|
||||
private
|
||||
FForm: TObject;
|
||||
FFwdW: Double;
|
||||
FSWRV: Double;
|
||||
FSupplyV: Double;
|
||||
FSupplyA: Double;
|
||||
FPLLLock: Boolean;
|
||||
FHWPTT: Boolean;
|
||||
FADCOverload: Byte;
|
||||
public
|
||||
constructor Create(AForm: TObject; FW, SW, SV, SA: Double; PLL, HWPTT: Boolean;
|
||||
ADCOverload: Byte);
|
||||
procedure Execute;
|
||||
end;
|
||||
|
||||
// Синхронизирующий объект для DDC IQ
|
||||
TDDCSeqSync = class
|
||||
private
|
||||
FForm: TObject;
|
||||
FDDCIdx: Integer;
|
||||
FSeq: LongWord;
|
||||
public
|
||||
constructor Create(AForm: TObject; Idx: Integer; Seq: LongWord);
|
||||
procedure Execute;
|
||||
end;
|
||||
|
||||
{ TMainForm }
|
||||
TMainForm = class(TForm)
|
||||
private
|
||||
@@ -750,30 +711,6 @@ type
|
||||
var Handled: Boolean);
|
||||
end;
|
||||
|
||||
TWisdomBuildThread = class(TThread)
|
||||
private
|
||||
FDirectory: string;
|
||||
FError: string;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(const ADirectory: string);
|
||||
property ErrorText: string read FError;
|
||||
end;
|
||||
|
||||
TWisdomProgressDialog = class(TForm)
|
||||
private
|
||||
FInfoLabel: TLabel;
|
||||
FProgress: TFlatProgressBar;
|
||||
FTimer: TTimer;
|
||||
FThread: TWisdomBuildThread;
|
||||
FPhase: Integer;
|
||||
procedure TimerTick(Sender: TObject);
|
||||
public
|
||||
constructor Create(AOwner: TComponent; AThread: TWisdomBuildThread;
|
||||
const ATheme: TAppTheme); reintroduce;
|
||||
end;
|
||||
|
||||
var
|
||||
MainForm: TMainForm;
|
||||
|
||||
@@ -783,20 +720,6 @@ uses SettingsForm;
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
function HasOpenGLSpectrumSwitch: Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
S: string;
|
||||
begin
|
||||
Result := False;
|
||||
for I := 1 to ParamCount do
|
||||
begin
|
||||
S := LowerCase(ParamStr(I));
|
||||
if (S = '--opengl') or (S = '-opengl') or (S = '/opengl') then
|
||||
Exit(True);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMainForm.LeftPanelButtonWidth(PanelWidth, ColCount,
|
||||
ColIndex: Integer): Integer;
|
||||
var
|
||||
@@ -822,179 +745,10 @@ begin
|
||||
LEFT_PANEL_BTN_GAP);
|
||||
end;
|
||||
|
||||
constructor TWisdomBuildThread.Create(const ADirectory: string);
|
||||
begin
|
||||
inherited Create(False);
|
||||
FreeOnTerminate := False;
|
||||
FDirectory := ADirectory;
|
||||
FError := '';
|
||||
end;
|
||||
|
||||
procedure TWisdomBuildThread.Execute;
|
||||
var
|
||||
DirA: AnsiString;
|
||||
begin
|
||||
try
|
||||
if not Assigned(@WDSPwisdom) then Exit;
|
||||
DirA := AnsiString(FDirectory);
|
||||
WDSPwisdom(PAnsiChar(DirA));
|
||||
except
|
||||
on E: Exception do
|
||||
FError := E.ClassName + ': ' + E.Message;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TWisdomProgressDialog.Create(AOwner: TComponent;
|
||||
AThread: TWisdomBuildThread; const ATheme: TAppTheme);
|
||||
begin
|
||||
inherited CreateNew(AOwner);
|
||||
FThread := AThread;
|
||||
FPhase := 0;
|
||||
|
||||
Caption := 'WDSP Wisdom';
|
||||
Width := 520;
|
||||
Height := 140;
|
||||
Position := poScreenCenter;
|
||||
BorderStyle := bsDialog;
|
||||
BorderIcons := [];
|
||||
Color := ATheme.BG;
|
||||
Font.Name := 'Courier New';
|
||||
Font.Size := 9;
|
||||
Font.Color := ATheme.Text;
|
||||
|
||||
FInfoLabel := TLabel.Create(Self);
|
||||
FInfoLabel.Parent := Self;
|
||||
FInfoLabel.SetBounds(16, 16, 480, 40);
|
||||
FInfoLabel.AutoSize := False;
|
||||
FInfoLabel.WordWrap := True;
|
||||
FInfoLabel.Font.Color := ATheme.Text;
|
||||
FInfoLabel.Caption :=
|
||||
'Creating FFTW wisdom for WDSP. This is done once and may take a while on the first run.';
|
||||
|
||||
FProgress := TFlatProgressBar.Create(Self);
|
||||
FProgress.Parent := Self;
|
||||
FProgress.SetBounds(16, 72, 480, 22);
|
||||
FProgress.Min := 0;
|
||||
FProgress.Max := 100;
|
||||
FProgress.Position := 0;
|
||||
FProgress.SetAppTheme(ATheme);
|
||||
|
||||
FTimer := TTimer.Create(Self);
|
||||
FTimer.Interval := 250;
|
||||
FTimer.OnTimer := TimerTick;
|
||||
FTimer.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TWisdomProgressDialog.TimerTick(Sender: TObject);
|
||||
var
|
||||
P: PAnsiChar;
|
||||
S: string;
|
||||
begin
|
||||
FPhase := (FPhase + 7) mod 101;
|
||||
FProgress.Position := FPhase;
|
||||
|
||||
if Assigned(@wisdom_get_status) then
|
||||
begin
|
||||
P := wisdom_get_status;
|
||||
if P <> nil then
|
||||
begin
|
||||
S := Trim(string(AnsiString(P)));
|
||||
if S <> '' then
|
||||
FInfoLabel.Caption := S;
|
||||
end;
|
||||
end;
|
||||
|
||||
if Assigned(FThread) and FThread.Finished then
|
||||
begin
|
||||
FTimer.Enabled := False;
|
||||
ModalResult := mrOk;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ===========================================================================
|
||||
// Общая функция декодирования типа платы — используется везде
|
||||
// ===========================================================================
|
||||
|
||||
function BoardTypeName(BoardType: Integer): string;
|
||||
begin
|
||||
case BoardType of
|
||||
1: Result := 'HERMES (ANAN-10/100)';
|
||||
2: Result := 'HERMES-E (ANAN-10E/100B)';
|
||||
3: Result := 'ANGELIA (ANAN-100D)';
|
||||
4: Result := 'ORION (ANAN-200D)';
|
||||
5: Result := 'ORION MkII (ANAN-7000/8000)';
|
||||
6: Result := 'HERMES-LITE 2';
|
||||
10: Result := 'SATURN (G2)';
|
||||
else Result := Format('Unknown Board #%d', [BoardType]);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ===========================================================================
|
||||
// Sync helpers
|
||||
// ===========================================================================
|
||||
|
||||
constructor TDeviceFoundSync.Create(AForm: TObject;
|
||||
const D: THPSDRDevice; const E: string);
|
||||
begin
|
||||
inherited Create;
|
||||
FForm := AForm;
|
||||
FDev := D;
|
||||
FEntry := E;
|
||||
end;
|
||||
|
||||
procedure TDeviceFoundSync.Execute;
|
||||
begin
|
||||
TMainForm(FForm).DoAddDevice(FDev, FEntry);
|
||||
end;
|
||||
|
||||
constructor TStatusUISync.Create(AForm: TObject;
|
||||
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean; ADCOverload: Byte);
|
||||
begin
|
||||
inherited Create;
|
||||
FForm := AForm;
|
||||
FFwdW := FW;
|
||||
FSWRV := SW;
|
||||
FSupplyV := SV;
|
||||
FSupplyA := SA;
|
||||
FPLLLock := PLL;
|
||||
FHWPTT := HWPTT;
|
||||
FADCOverload := ADCOverload;
|
||||
end;
|
||||
|
||||
procedure TStatusUISync.Execute;
|
||||
begin
|
||||
TMainForm(FForm).DoUpdateStatus(FFwdW, FSWRV, FSupplyV, FSupplyA, FPLLLock, FHWPTT,
|
||||
FADCOverload);
|
||||
end;
|
||||
|
||||
constructor TDDCSeqSync.Create(AForm: TObject; Idx: Integer; Seq: LongWord);
|
||||
begin
|
||||
inherited Create;
|
||||
FForm := AForm;
|
||||
FDDCIdx := Idx;
|
||||
FSeq := Seq;
|
||||
end;
|
||||
|
||||
procedure TDDCSeqSync.Execute;
|
||||
begin
|
||||
TMainForm(FForm).DoUpdateDDCSeqOrNoDevice(FDDCIdx, FSeq);
|
||||
end;
|
||||
|
||||
// ===========================================================================
|
||||
// FormCreate / FormDestroy
|
||||
// ===========================================================================
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// Settings helpers
|
||||
// ===========================================================================
|
||||
|
||||
function CurrentScreenDPI: Integer;
|
||||
begin
|
||||
Result := Screen.PixelsPerInch;
|
||||
if Result <= 0 then Result := 96;
|
||||
end;
|
||||
|
||||
procedure TMainForm.RestoreWindowBounds;
|
||||
var
|
||||
L, T, Wd, Ht, SavedDPI, CurDPI: Integer;
|
||||
@@ -1666,7 +1420,6 @@ const
|
||||
LEFT_W = 232;
|
||||
TOP_VFO_W = 244;
|
||||
TOP_VFO_FREQ_H = 47;
|
||||
TOP_VFO_BTN_H = 14;
|
||||
var
|
||||
i, X, Y, W: Integer;
|
||||
B: TFlatButton;
|
||||
@@ -2381,7 +2134,6 @@ const
|
||||
MARGIN = 4;
|
||||
TOP_OFFSET = 2;
|
||||
TOP_VFO_FREQ_H = 47;
|
||||
VFO_BTN_W = 20;
|
||||
VFO_BTN_FREQ_GAP = 4;
|
||||
VFO_FREQ_LEFT_PAD = 2;
|
||||
VFO_FREQ_RIGHT_PAD = 8;
|
||||
@@ -3394,7 +3146,7 @@ begin
|
||||
Entry := Format('%s %s FW:%d DDC:%d',
|
||||
[Dev.IPAddress, BoardName,
|
||||
Dev.FirmwareVersion, Dev.NumDDCs]);
|
||||
Sync := TDeviceFoundSync.Create(Self, Dev, Entry);
|
||||
Sync := TDeviceFoundSync.Create(DoAddDevice, Dev, Entry);
|
||||
try
|
||||
M := Sync.Execute;
|
||||
TThread.Synchronize(nil, M);
|
||||
@@ -3483,7 +3235,7 @@ begin
|
||||
end else
|
||||
SWRV := 1.0;
|
||||
if not IsTx then FwdW := 0;
|
||||
Sync := TStatusUISync.Create(Self, FwdW, SWRV, SupplyV, SupplyA,
|
||||
Sync := TStatusUISync.Create(DoUpdateStatus, FwdW, SWRV, SupplyV, SupplyA,
|
||||
(Status.StatusBits and HPS_PLL_LOCKED) <> 0,
|
||||
(Status.StatusBits and HPS_PTT) <> 0,
|
||||
Status.ADCOverload);
|
||||
@@ -3886,7 +3638,7 @@ begin
|
||||
if Length(Devs) = 0 then
|
||||
begin
|
||||
// DDCIdx = -1 is the sentinel for "no device found"
|
||||
Sync := TDDCSeqSync.Create(FForm, -1, 0);
|
||||
Sync := TDDCSeqSync.Create(FForm.DoUpdateDDCSeqOrNoDevice, -1, 0);
|
||||
try
|
||||
M := Sync.Execute;
|
||||
TThread.Synchronize(nil, M);
|
||||
@@ -4393,30 +4145,6 @@ end;
|
||||
// Idx=0 → VFO-A активен, Idx=1 → VFO-B активен.
|
||||
// Перестройка всегда происходит на частоту активного VFO (не на оффсет).
|
||||
// CTUN при этом сбрасывается чтобы не было путаницы с оффсетом.
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// FreqToBandIdx — возвращает индекс диапазона для частоты Hz, или -1
|
||||
// ---------------------------------------------------------------------------
|
||||
function FreqToBandIdx(Hz: Double): Integer;
|
||||
const
|
||||
// Границы диапазонов [Low, High] в Гц (приблизительные)
|
||||
BAND_LO: array[0..10] of Double = (
|
||||
1800000, 3500000, 5330000, 7000000, 10100000,
|
||||
14000000, 18068000, 21000000, 24890000, 28000000, 50000000);
|
||||
BAND_HI: array[0..10] of Double = (
|
||||
2000000, 4000000, 5410000, 7300000, 10150000,
|
||||
14350000, 18168000, 21450000, 24990000, 29700000, 54000000);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
for i := 0 to 10 do
|
||||
if (Hz >= BAND_LO[i]) and (Hz <= BAND_HI[i]) then
|
||||
begin
|
||||
Result := i;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ActiveVfoFreq — частота активного VFO
|
||||
|
||||
+23
-1
@@ -11,11 +11,13 @@ unit PlatformUtils;
|
||||
interface
|
||||
|
||||
function QtPlatformAllowsOpenGLControls: Boolean;
|
||||
function HasOpenGLSpectrumSwitch: Boolean;
|
||||
function CurrentScreenDPI: Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
SysUtils;
|
||||
SysUtils, Forms;
|
||||
|
||||
function QtPlatformAllowsOpenGLControls: Boolean;
|
||||
var
|
||||
@@ -39,4 +41,24 @@ begin
|
||||
Result := SessionType <> 'wayland';
|
||||
end;
|
||||
|
||||
function HasOpenGLSpectrumSwitch: Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
S: string;
|
||||
begin
|
||||
Result := False;
|
||||
for I := 1 to ParamCount do
|
||||
begin
|
||||
S := LowerCase(ParamStr(I));
|
||||
if (S = '--opengl') or (S = '-opengl') or (S = '/opengl') then
|
||||
Exit(True);
|
||||
end;
|
||||
end;
|
||||
|
||||
function CurrentScreenDPI: Integer;
|
||||
begin
|
||||
Result := Screen.PixelsPerInch;
|
||||
if Result <= 0 then Result := 96;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
unit UISync;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, HPSDRNetwork;
|
||||
|
||||
type
|
||||
TAddDeviceProc = procedure(const Dev: THPSDRDevice; const Entry: string) of object;
|
||||
TUpdateStatusProc = procedure(FwdW, SWRV, SupplyV, SupplyA: Double;
|
||||
PLLLock, HWPTT: Boolean; ADCOverload: Byte) of object;
|
||||
TUpdateDDCSeqOrNoDeviceProc = procedure(DDCIdx: Integer; Seq: LongWord) of object;
|
||||
|
||||
TDeviceFoundSync = class
|
||||
private
|
||||
FCallback: TAddDeviceProc;
|
||||
FDev: THPSDRDevice;
|
||||
FEntry: string;
|
||||
public
|
||||
constructor Create(ACallback: TAddDeviceProc; const D: THPSDRDevice;
|
||||
const E: string);
|
||||
procedure Execute;
|
||||
end;
|
||||
|
||||
TStatusUISync = class
|
||||
private
|
||||
FCallback: TUpdateStatusProc;
|
||||
FFwdW: Double;
|
||||
FSWRV: Double;
|
||||
FSupplyV: Double;
|
||||
FSupplyA: Double;
|
||||
FPLLLock: Boolean;
|
||||
FHWPTT: Boolean;
|
||||
FADCOverload: Byte;
|
||||
public
|
||||
constructor Create(ACallback: TUpdateStatusProc;
|
||||
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean; ADCOverload: Byte);
|
||||
procedure Execute;
|
||||
end;
|
||||
|
||||
TDDCSeqSync = class
|
||||
private
|
||||
FCallback: TUpdateDDCSeqOrNoDeviceProc;
|
||||
FDDCIdx: Integer;
|
||||
FSeq: LongWord;
|
||||
public
|
||||
constructor Create(ACallback: TUpdateDDCSeqOrNoDeviceProc;
|
||||
Idx: Integer; Seq: LongWord);
|
||||
procedure Execute;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TDeviceFoundSync.Create(ACallback: TAddDeviceProc;
|
||||
const D: THPSDRDevice; const E: string);
|
||||
begin
|
||||
inherited Create;
|
||||
FCallback := ACallback;
|
||||
FDev := D;
|
||||
FEntry := E;
|
||||
end;
|
||||
|
||||
procedure TDeviceFoundSync.Execute;
|
||||
begin
|
||||
FCallback(FDev, FEntry);
|
||||
end;
|
||||
|
||||
constructor TStatusUISync.Create(ACallback: TUpdateStatusProc;
|
||||
FW, SW, SV, SA: Double; PLL, HWPTT: Boolean; ADCOverload: Byte);
|
||||
begin
|
||||
inherited Create;
|
||||
FCallback := ACallback;
|
||||
FFwdW := FW;
|
||||
FSWRV := SW;
|
||||
FSupplyV := SV;
|
||||
FSupplyA := SA;
|
||||
FPLLLock := PLL;
|
||||
FHWPTT := HWPTT;
|
||||
FADCOverload := ADCOverload;
|
||||
end;
|
||||
|
||||
procedure TStatusUISync.Execute;
|
||||
begin
|
||||
FCallback(FFwdW, FSWRV, FSupplyV, FSupplyA, FPLLLock, FHWPTT, FADCOverload);
|
||||
end;
|
||||
|
||||
constructor TDDCSeqSync.Create(ACallback: TUpdateDDCSeqOrNoDeviceProc;
|
||||
Idx: Integer; Seq: LongWord);
|
||||
begin
|
||||
inherited Create;
|
||||
FCallback := ACallback;
|
||||
FDDCIdx := Idx;
|
||||
FSeq := Seq;
|
||||
end;
|
||||
|
||||
procedure TDDCSeqSync.Execute;
|
||||
begin
|
||||
FCallback(FDDCIdx, FSeq);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,129 @@
|
||||
unit WisdomBuilder;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, Controls, ExtCtrls, StdCtrls,
|
||||
WDSP, AppTheme, FlatProgressBar;
|
||||
|
||||
type
|
||||
TWisdomBuildThread = class(TThread)
|
||||
private
|
||||
FDirectory: string;
|
||||
FError: string;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(const ADirectory: string);
|
||||
property ErrorText: string read FError;
|
||||
end;
|
||||
|
||||
TWisdomProgressDialog = class(TForm)
|
||||
private
|
||||
FInfoLabel: TLabel;
|
||||
FProgress: TFlatProgressBar;
|
||||
FTimer: TTimer;
|
||||
FThread: TWisdomBuildThread;
|
||||
FPhase: Integer;
|
||||
procedure TimerTick(Sender: TObject);
|
||||
public
|
||||
constructor Create(AOwner: TComponent; AThread: TWisdomBuildThread;
|
||||
const ATheme: TAppTheme); reintroduce;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor TWisdomBuildThread.Create(const ADirectory: string);
|
||||
begin
|
||||
inherited Create(False);
|
||||
FreeOnTerminate := False;
|
||||
FDirectory := ADirectory;
|
||||
FError := '';
|
||||
end;
|
||||
|
||||
procedure TWisdomBuildThread.Execute;
|
||||
var
|
||||
DirA: AnsiString;
|
||||
begin
|
||||
try
|
||||
if not Assigned(@WDSPwisdom) then Exit;
|
||||
DirA := AnsiString(FDirectory);
|
||||
WDSPwisdom(PAnsiChar(DirA));
|
||||
except
|
||||
on E: Exception do
|
||||
FError := E.ClassName + ': ' + E.Message;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TWisdomProgressDialog.Create(AOwner: TComponent;
|
||||
AThread: TWisdomBuildThread; const ATheme: TAppTheme);
|
||||
begin
|
||||
inherited CreateNew(AOwner);
|
||||
FThread := AThread;
|
||||
FPhase := 0;
|
||||
|
||||
Caption := 'WDSP Wisdom';
|
||||
Width := 520;
|
||||
Height := 140;
|
||||
Position := poScreenCenter;
|
||||
BorderStyle := bsDialog;
|
||||
BorderIcons := [];
|
||||
Color := ATheme.BG;
|
||||
Font.Name := 'Courier New';
|
||||
Font.Size := 9;
|
||||
Font.Color := ATheme.Text;
|
||||
|
||||
FInfoLabel := TLabel.Create(Self);
|
||||
FInfoLabel.Parent := Self;
|
||||
FInfoLabel.SetBounds(16, 16, 480, 40);
|
||||
FInfoLabel.AutoSize := False;
|
||||
FInfoLabel.WordWrap := True;
|
||||
FInfoLabel.Font.Color := ATheme.Text;
|
||||
FInfoLabel.Caption :=
|
||||
'Creating FFTW wisdom for WDSP. This is done once and may take a while on the first run.';
|
||||
|
||||
FProgress := TFlatProgressBar.Create(Self);
|
||||
FProgress.Parent := Self;
|
||||
FProgress.SetBounds(16, 72, 480, 22);
|
||||
FProgress.Min := 0;
|
||||
FProgress.Max := 100;
|
||||
FProgress.Position := 0;
|
||||
FProgress.SetAppTheme(ATheme);
|
||||
|
||||
FTimer := TTimer.Create(Self);
|
||||
FTimer.Interval := 250;
|
||||
FTimer.OnTimer := TimerTick;
|
||||
FTimer.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TWisdomProgressDialog.TimerTick(Sender: TObject);
|
||||
var
|
||||
P: PAnsiChar;
|
||||
S: string;
|
||||
begin
|
||||
FPhase := (FPhase + 7) mod 101;
|
||||
FProgress.Position := FPhase;
|
||||
|
||||
if Assigned(@wisdom_get_status) then
|
||||
begin
|
||||
P := wisdom_get_status;
|
||||
if P <> nil then
|
||||
begin
|
||||
S := Trim(string(AnsiString(P)));
|
||||
if S <> '' then
|
||||
FInfoLabel.Caption := S;
|
||||
end;
|
||||
end;
|
||||
|
||||
if Assigned(FThread) and FThread.Finished then
|
||||
begin
|
||||
FTimer.Enabled := False;
|
||||
ModalResult := mrOk;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -214,6 +214,18 @@
|
||||
<Filename Value="PlatformUtils.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="BoardUtils.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="WisdomBuilder.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="UISync.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="SpectrumViewOpengl.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
|
||||
Reference in New Issue
Block a user