2852 lines
78 KiB
C
2852 lines
78 KiB
C
/*
|
||
Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO
|
||
|
||
This file is part of QtSoundModem
|
||
|
||
QtSoundModem is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
QtSoundModem is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
newsamp
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
||
|
||
*/
|
||
|
||
// UZ7HO Soundmodem Port by John Wiseman G8BPQ
|
||
|
||
#include "UZ7HOStuff.h"
|
||
|
||
void make_core_BPF(UCHAR snd_ch, short freq, short width);
|
||
void make_core_TXBPF(UCHAR snd_ch, float freq, float width);
|
||
void make_core_INTR(UCHAR snd_ch);
|
||
void make_core_LPF(UCHAR snd_ch, short width);
|
||
void wf_pointer(int snd_ch);
|
||
|
||
char modes_name[modes_count][20] =
|
||
{
|
||
"AFSK AX.25 300bd","AFSK AX.25 1200bd","AFSK AX.25 600bd","AFSK AX.25 2400bd",
|
||
"BPSK AX.25 1200bd","BPSK AX.25 600bd","BPSK AX.25 300bd","BPSK AX.25 2400bd",
|
||
"QPSK AX.25 4800bd","QPSK AX.25 3600bd","QPSK AX.25 2400bd","BPSK FEC 4x100bd",
|
||
"DW QPSK V26A 2400bd","DW 8PSK V27 4800bd","DW QPSK V26B 2400bd", "ARDOP Packet"
|
||
};
|
||
|
||
typedef struct wavehdr_tag {
|
||
unsigned short * lpData; /* pointer to locked data buffer */
|
||
int dwBufferLength; /* length of data buffer */
|
||
int dwBytesRecorded; /* used for input only */
|
||
int * dwUser; /* for client's use */
|
||
int dwFlags; /* assorted flags (see defines) */
|
||
int dwLoops; /* loop control counter */
|
||
struct wavehdr_tag *lpNext; /* reserved for driver */
|
||
int * reserved; /* reserved for driver */
|
||
} WAVEHDR, *PWAVEHDR, * NPWAVEHDR, * LPWAVEHDR;
|
||
|
||
extern int pnt_change[5];
|
||
int debugmode = 0;
|
||
extern float src_buf[5][2048];
|
||
extern Byte RCVR[5];
|
||
|
||
int SatelliteMode = 0;
|
||
|
||
int UDPServerPort = 8884;
|
||
int UDPClientPort = 8888;
|
||
int TXPort = 8884;
|
||
|
||
BOOL Firstwaterfall = 1;
|
||
BOOL Secondwaterfall = 1;
|
||
|
||
int multiCore = FALSE;
|
||
|
||
/*
|
||
type
|
||
TComboBox = class(StdCtrls.TComboBox)
|
||
private
|
||
procedure CMMouseWheel(var msg TCMMouseWheel); message CM_MOUSEWHEEL;
|
||
end;
|
||
TData16 = array [0..4095] of smallint;
|
||
PData16 = ^TData16;
|
||
TWaveHeader = record
|
||
RIFF dword;
|
||
ChunkLen integer;
|
||
WAVE dword;
|
||
fmt dword;
|
||
FormatLen integer;
|
||
Format word;
|
||
Channels word;
|
||
Frequency integer;
|
||
BytesPS integer;
|
||
BlockAlign word;
|
||
BitsPS word;
|
||
data dword;
|
||
DataLen integer
|
||
end;
|
||
TForm1 = class(TForm)
|
||
Panel5 TPanel;
|
||
ServerSocket1 TServerSocket;
|
||
MainMenu1 TMainMenu;
|
||
Settings1 TMenuItem;
|
||
OutputVolume1 TMenuItem;
|
||
InputVolume1 TMenuItem;
|
||
CoolTrayIcon1 TCoolTrayIcon;
|
||
ImageList1 TImageList;
|
||
ABout1 TMenuItem;
|
||
Panel1 TPanel;
|
||
Panel2 TPanel;
|
||
View1 TMenuItem;
|
||
Firstwaterfall1 TMenuItem;
|
||
Secondwaterfall1 TMenuItem;
|
||
Panel3 TPanel;
|
||
StringGrid1 TStringGrid;
|
||
Devices1 TMenuItem;
|
||
Statustable1 TMenuItem;
|
||
Monitor1 TMenuItem;
|
||
Panel4 TPanel;
|
||
PaintBox2 TPaintBox;
|
||
Filters1 TMenuItem;
|
||
Clearmonitor1 TMenuItem;
|
||
RxRichEdit1 TRxRichEdit;
|
||
MemoPopupMenu1 TPopupMenu;
|
||
Copytext1 TMenuItem;
|
||
Label1 TLabel;
|
||
Label5 TLabel;
|
||
ApplicationEvents1 TApplicationEvents;
|
||
PaintBox1 TPaintBox;
|
||
PaintBox3 TPaintBox;
|
||
ServerSocket2 TServerSocket;
|
||
Font1 TMenuItem;
|
||
FontDialog1 TFontDialog;
|
||
N1 TMenuItem;
|
||
Calibration1 TMenuItem;
|
||
Panel9 TPanel;
|
||
Panel6 TPanel;
|
||
Label4 TLabel;
|
||
Shape2 TShape;
|
||
ComboBox2 TComboBox;
|
||
SpinEdit2 TSpinEdit;
|
||
Panel7 TPanel;
|
||
Label3 TLabel;
|
||
Shape1 TShape;
|
||
ComboBox1 TComboBox;
|
||
SpinEdit1 TSpinEdit;
|
||
Panel8 TPanel;
|
||
Label2 TLabel;
|
||
TrackBar1 TTrackBar;
|
||
CheckBox1 TCheckBox;
|
||
OpenDialog1 TOpenDialog;
|
||
procedure FormCreate(Sender TObject);
|
||
procedure TrackBar1Change(Sender TObject);
|
||
procedure PaintBox1MouseMove(Sender TObject; Shift TShiftState; X,
|
||
Y Integer);
|
||
procedure PaintBox1MouseDown(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
procedure ServerSocket1ClientRead(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
procedure ServerSocket1ClientError(Sender TObject;
|
||
Socket TCustomWinSocket; ErrorEvent TErrorEvent;
|
||
var ErrorCode Integer);
|
||
procedure OutputVolume1Click(Sender TObject);
|
||
procedure InputVolume1Click(Sender TObject);
|
||
procedure ServerSocket1ClientConnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
procedure ServerSocket1ClientDisconnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
procedure CoolTrayIcon1Click(Sender TObject);
|
||
procedure CoolTrayIcon1Cycle(Sender TObject; NextIndex Integer);
|
||
procedure ABout1Click(Sender TObject);
|
||
procedure PaintBox3MouseDown(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
procedure PaintBox3MouseMove(Sender TObject; Shift TShiftState; X,
|
||
Y Integer);
|
||
procedure Firstwaterfall1Click(Sender TObject);
|
||
procedure Secondwaterfall1Click(Sender TObject);
|
||
procedure Devices1Click(Sender TObject);
|
||
procedure Statustable1Click(Sender TObject);
|
||
procedure Monitor1Click(Sender TObject);
|
||
procedure FormPaint(Sender TObject);
|
||
procedure Filters1Click(Sender TObject);
|
||
procedure SpinEdit1Change(Sender TObject);
|
||
procedure SpinEdit2Change(Sender TObject);
|
||
procedure Clearmonitor1Click(Sender TObject);
|
||
procedure Copytext1Click(Sender TObject);
|
||
procedure PaintBox3MouseUp(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
procedure PaintBox1MouseUp(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
procedure ApplicationEvents1Minimize(Sender TObject);
|
||
procedure ApplicationEvents1Restore(Sender TObject);
|
||
procedure ServerSocket2ClientConnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
procedure ServerSocket2ClientDisconnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
procedure ServerSocket2ClientError(Sender TObject;
|
||
Socket TCustomWinSocket; ErrorEvent TErrorEvent;
|
||
var ErrorCode Integer);
|
||
procedure ServerSocket2ClientRead(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
procedure Font1Click(Sender TObject);
|
||
procedure Calibration1Click(Sender TObject);
|
||
procedure ComboBox1Change(Sender TObject);
|
||
procedure ComboBox1KeyDown(Sender TObject; var Key Word;
|
||
Shift TShiftState);
|
||
procedure ComboBox1KeyPress(Sender TObject; var Key Char);
|
||
procedure ComboBox2Change(Sender TObject);
|
||
procedure FormDestroy(Sender TObject);
|
||
private
|
||
{ Private declarations }
|
||
procedure BufferFull(var Msg TMessage); Message MM_WIM_DATA;
|
||
procedure BufferFull1(var Msg TMessage); Message MM_WOM_DONE;
|
||
procedure make_wave_buf(snd_ch byte; buf PChar);
|
||
procedure disp2(snd_ch byte);
|
||
procedure create_timer1;
|
||
procedure free_timer1;
|
||
procedure show_panels;
|
||
procedure show_combobox;
|
||
procedure Timer_Event2;
|
||
procedure waterfall_init;
|
||
procedure waterfall_free;
|
||
public
|
||
{ Public declarations }
|
||
function get_idx_by_name(name string) word;
|
||
function frame_monitor(s,code string; tx_stat boolean) string;
|
||
procedure ChangePriority;
|
||
procedure put_frame(snd_ch byte; frame,code string; tx_stat,excluded boolean);
|
||
procedure show_grid;
|
||
procedure RX2TX(snd_ch byte);
|
||
procedure TX2RX(snd_ch byte);
|
||
procedure WriteIni;
|
||
procedure ReadIni;
|
||
procedure init_8P4800(snd_ch byte);
|
||
procedure init_DW2400(snd_ch byte);
|
||
procedure init_AE2400(snd_ch byte);
|
||
procedure init_MP400(snd_ch byte);
|
||
procedure init_Q4800(snd_ch byte);
|
||
procedure init_Q3600(snd_ch byte);
|
||
procedure init_Q2400(snd_ch byte);
|
||
procedure init_P2400(snd_ch byte);
|
||
procedure init_P1200(snd_ch byte);
|
||
procedure init_P600(snd_ch byte);
|
||
procedure init_P300(snd_ch byte);
|
||
procedure init_300(snd_ch byte);
|
||
procedure init_600(snd_ch byte);
|
||
procedure init_1200(snd_ch byte);
|
||
procedure init_2400(snd_ch byte);
|
||
procedure init_speed(snd_ch byte);
|
||
procedure get_filter_values(idx byte; var dbpf,dtxbpf,dbpftap,dlpf,dlpftap word);
|
||
procedure show_mode_panels;
|
||
procedure show_modes;
|
||
procedure show_freq_a;
|
||
procedure show_freq_b;
|
||
procedure ChkSndDevName;
|
||
procedure StartRx;
|
||
procedure StartTx(snd_ch byte);
|
||
procedure StopRx;
|
||
procedure StopTx(snd_ch byte);
|
||
procedure StartAGW;
|
||
procedure StartKISS;
|
||
procedure wf_scale;
|
||
procedure wf_pointer(snd_ch byte);
|
||
end;
|
||
|
||
var
|
||
/*/
|
||
|
||
BOOL MinOnStart = 0;
|
||
//RS TReedSolomon;
|
||
// Form1 TForm1;
|
||
// WaveFormat TWaveFormatEx;
|
||
int Channels = 2;
|
||
int BitsPerSample = 16;
|
||
float TX_Samplerate = 12000;
|
||
float RX_Samplerate = 12000;
|
||
int RX_SR = 11025;
|
||
int TX_SR = 11025;
|
||
int RX_PPM = 0;
|
||
int TX_PPM = 0;
|
||
int tx_bufsize = 512;
|
||
int rx_bufsize = 512;
|
||
int tx_bufcount = 16;
|
||
int rx_bufcount = 16;
|
||
int mouse_down[2] = {0, 0};
|
||
//UCHAR * RX_pBuf array[257];
|
||
// RX_header array[1..256] of TWaveHdr;
|
||
// TX_pBuf array[1..4,1..256] of pointer;
|
||
//TX_header array[1..4,1..256] of TWaveHdr;
|
||
UCHAR calib_mode[5] = {0,0,0,0};
|
||
UCHAR snd_status [5] = {0,0,0,0};
|
||
UCHAR buf_status [5] = {0,0,0,0};
|
||
UCHAR tx_buf_num1 [5] = {0,0,0,0};
|
||
UCHAR tx_buf_num [5] = {0,0,0,0};
|
||
|
||
extern short active_rx_freq[5];
|
||
|
||
|
||
|
||
int speed[5] = {0,0,0,0};
|
||
int panels[6] = {1,1,1,1,1};
|
||
|
||
short fft_buf[2][8192];
|
||
UCHAR fft_disp[2][1024];
|
||
int fftCount = 0; // FTF samples collected
|
||
|
||
// bm array[1..4] of TBitMap;
|
||
// bm1,bm2,bm3 TBitMap;
|
||
|
||
// WaveInHandle hWaveIn;
|
||
// WaveOutHandle array[1..4] of hWaveOut;
|
||
int RXBufferLength;
|
||
|
||
int grid_time = 0;
|
||
int fft_mult = 0;
|
||
int fft_spd = 3;
|
||
int grid_timer = 0;
|
||
int stop_wf = 0;
|
||
int raduga = DISP_RGB;
|
||
char snd_rx_device_name[32] = "";
|
||
char snd_tx_device_name[32] = "";
|
||
int snd_rx_device = 0;
|
||
int snd_tx_device = 0;
|
||
UCHAR mod_icon_status = MOD_IDLE;
|
||
UCHAR last_mod_icon_status = MOD_IDLE;
|
||
UCHAR icon_timer = 0;
|
||
// TelIni TIniFile;
|
||
char cur_dir[] = "";
|
||
// TimerId1 cardinal;
|
||
// TimerId2 cardinal;
|
||
UCHAR TimerStat1 = TIMER_FREE;
|
||
UCHAR TimerStat2 = TIMER_FREE;
|
||
int stat_log = FALSE;
|
||
|
||
int PTT_device = FALSE;
|
||
int RX_device = FALSE;
|
||
int TX_device = FALSE;
|
||
int TX_rotate = FALSE;
|
||
int UsingBothChannels = FALSE;
|
||
int UsingLeft = FALSE;
|
||
int UsingRight = FALSE;
|
||
|
||
int SCO = FALSE;
|
||
int DualPTT = TRUE;
|
||
UCHAR DebugMode = 0;
|
||
UCHAR TimerEvent = TIMER_EVENT_OFF;
|
||
int nr_monitor_lines = 50;
|
||
int UTC_Time = FALSE;
|
||
int MainPriority = 0;
|
||
// MainThreadHandle THandle;
|
||
UCHAR w_state = WIN_MAXIMIZED;
|
||
|
||
/*
|
||
implementation
|
||
|
||
{$R *.DFM}
|
||
|
||
uses ax25_mod, ax25_demod, ax25, ax25_l2, ax25_ptt, ax25_agw, ax25_about, rgb_rad,
|
||
AX25_set, ax25_filter, AX25_modem_set, kiss_mode, ax25_calibration;
|
||
|
||
procedure TComboBox.CMMouseWheel(var msg TCMMouseWheel);
|
||
begin
|
||
if SendMessage(GetFocus, CB_GETDROPPEDSTATE, 0, 0) = 0 then msg.Result = 1;
|
||
end;
|
||
|
||
procedure TForm1.ChangePriority;
|
||
begin
|
||
case MainPriority of
|
||
0 SetThreadPriority(MainThreadHandle,THREAD_PRIORITY_NORMAL);
|
||
1 SetThreadPriority(MainThreadHandle,THREAD_PRIORITY_ABOVE_NORMAL);
|
||
2 SetThreadPriority(MainThreadHandle,THREAD_PRIORITY_HIGHEST);
|
||
3 SetThreadPriority(MainThreadHandle,THREAD_PRIORITY_TIME_CRITICAL);
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.show_modes;
|
||
var
|
||
s string;
|
||
begin
|
||
s = MODEM_CAPTION+" - Ver "+MODEM_VERSION+" - ["+modes_name[Speed[1]];
|
||
if dualchan then s = s+" - "+modes_name[Speed[2]];
|
||
form1.Caption = s+"]";
|
||
end;
|
||
|
||
procedure TForm1.show_freq_a;
|
||
begin
|
||
SpinEdit1.Value = round(rx_freq[1]);
|
||
SpinEdit1.Refresh;
|
||
end;
|
||
|
||
procedure TForm1.show_freq_b;
|
||
begin
|
||
SpinEdit2.Value = round(rx_freq[2]);
|
||
SpinEdit2.Refresh;
|
||
end;
|
||
*/
|
||
void get_filter_values(UCHAR snd_ch)
|
||
{
|
||
//, unsigned short dbpf,
|
||
//unsigned short dtxbpf,
|
||
//unsigned short dbpftap,
|
||
//unsigned short dlpf,
|
||
//unsigned short dlpftap)
|
||
// speed[snd_ch], bpf[snd_ch], txbpf[snd_ch], bpf_tap[snd_ch], lpf[snd_ch], lpf_tap[snd_ch]);
|
||
|
||
switch (speed[snd_ch])
|
||
{
|
||
case SPEED_8P4800:
|
||
|
||
lpf[snd_ch] = MODEM_8P4800_LPF;
|
||
bpf[snd_ch] = MODEM_8P4800_BPF;
|
||
txbpf[snd_ch] = MODEM_8P4800_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_8P4800_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_8P4800_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_MP400:
|
||
|
||
lpf[snd_ch] = MODEM_MP400_LPF;
|
||
bpf[snd_ch] = MODEM_MP400_BPF;
|
||
txbpf[snd_ch] = MODEM_MP400_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_MP400_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_MP400_LPF_TAP;
|
||
|
||
break;
|
||
|
||
|
||
case SPEED_Q4800:
|
||
|
||
lpf[snd_ch] = MODEM_Q4800_LPF;
|
||
bpf[snd_ch] = MODEM_Q4800_BPF;
|
||
txbpf[snd_ch] = MODEM_Q4800_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_Q4800_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_Q4800_LPF_TAP;
|
||
|
||
break;
|
||
|
||
case SPEED_Q3600:
|
||
|
||
lpf[snd_ch] = MODEM_Q3600_LPF;
|
||
bpf[snd_ch] = MODEM_Q3600_BPF;
|
||
txbpf[snd_ch] = MODEM_Q3600_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_Q3600_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_Q3600_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_Q2400:
|
||
|
||
lpf[snd_ch] = MODEM_Q2400_LPF;
|
||
bpf[snd_ch] = MODEM_Q2400_BPF;
|
||
txbpf[snd_ch] = MODEM_Q2400_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_Q2400_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_Q2400_LPF_TAP;
|
||
|
||
break;
|
||
|
||
case SPEED_DW2400:
|
||
case SPEED_AE2400:
|
||
|
||
|
||
lpf[snd_ch] = MODEM_DW2400_LPF;
|
||
bpf[snd_ch] = MODEM_DW2400_BPF;
|
||
txbpf[snd_ch] = MODEM_DW2400_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_DW2400_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_DW2400_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_P2400:
|
||
|
||
lpf[snd_ch] = MODEM_P2400_LPF;
|
||
bpf[snd_ch] = MODEM_P2400_BPF;
|
||
txbpf[snd_ch] = MODEM_P2400_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_P2400_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_P2400_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_P1200:
|
||
|
||
lpf[snd_ch] = MODEM_P1200_LPF;
|
||
bpf[snd_ch] = MODEM_P1200_BPF;
|
||
txbpf[snd_ch] = MODEM_P1200_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_P1200_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_P1200_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_P600:
|
||
|
||
lpf[snd_ch] = MODEM_P600_LPF;
|
||
bpf[snd_ch] = MODEM_P600_BPF;
|
||
txbpf[snd_ch] = MODEM_P600_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_P600_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_P600_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_P300:
|
||
|
||
lpf[snd_ch] = MODEM_P300_LPF;
|
||
bpf[snd_ch] = MODEM_P300_BPF;
|
||
txbpf[snd_ch] = MODEM_P300_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_P300_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_P300_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_300:
|
||
|
||
lpf[snd_ch] = MODEM_300_LPF;
|
||
bpf[snd_ch] = MODEM_300_BPF;
|
||
txbpf[snd_ch] = MODEM_300_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_300_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_300_LPF_TAP;
|
||
|
||
break;
|
||
|
||
case SPEED_600:
|
||
|
||
lpf[snd_ch] = MODEM_600_LPF;
|
||
bpf[snd_ch] = MODEM_600_BPF;
|
||
txbpf[snd_ch] = MODEM_600_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_600_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_600_LPF_TAP;
|
||
|
||
break;
|
||
|
||
case SPEED_1200:
|
||
|
||
lpf[snd_ch] = MODEM_1200_LPF;
|
||
bpf[snd_ch] = MODEM_1200_BPF;
|
||
txbpf[snd_ch] = MODEM_1200_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_1200_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_1200_LPF_TAP;
|
||
break;
|
||
|
||
case SPEED_2400:
|
||
|
||
lpf[snd_ch] = MODEM_2400_LPF;
|
||
bpf[snd_ch] = MODEM_2400_BPF;
|
||
txbpf[snd_ch] = MODEM_2400_TXBPF;
|
||
BPF_tap[snd_ch] = MODEM_2400_BPF_TAP;
|
||
LPF_tap[snd_ch] = MODEM_2400_LPF_TAP;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void init_2400(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_FSK;
|
||
rx_shift[snd_ch] = 1805;
|
||
rx_baudrate[snd_ch] = 2400;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_1200(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_FSK;
|
||
rx_shift[snd_ch] = 1000;
|
||
|
||
if (stdtones)
|
||
rx_freq[snd_ch] = 1700;
|
||
|
||
rx_baudrate[snd_ch] = 1200;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_600(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_FSK;
|
||
rx_shift[snd_ch] = 450;
|
||
|
||
rx_baudrate[snd_ch] = 600;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_300(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_FSK;
|
||
rx_shift[snd_ch] = 200;
|
||
rx_baudrate[snd_ch] = 300;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_MP400(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_MPSK;
|
||
rx_shift[snd_ch] = 175 /*sbc*/ * 3;
|
||
rx_baudrate[snd_ch] = 100;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
|
||
void init_8P4800(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_8PSK;
|
||
if (stdtones)
|
||
rx_freq[snd_ch] = 1800;
|
||
|
||
rx_shift[snd_ch] = 1600;
|
||
rx_baudrate[snd_ch] = 1600;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_AE2400(int snd_ch)
|
||
{
|
||
qpsk_set[snd_ch].mode = QPSK_V26;
|
||
modem_mode[snd_ch] = MODE_PI4QPSK;
|
||
|
||
if (stdtones)
|
||
rx_freq[snd_ch] = 1800;
|
||
|
||
rx_shift[snd_ch] = 1200;
|
||
rx_baudrate[snd_ch] = 1200;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_DW2400(int snd_ch)
|
||
{
|
||
qpsk_set[snd_ch].mode = QPSK_V26;
|
||
modem_mode[snd_ch] = MODE_QPSK;
|
||
|
||
if (stdtones)
|
||
rx_freq[snd_ch] = 1800;
|
||
|
||
rx_shift[snd_ch] = 1200;
|
||
rx_baudrate[snd_ch] = 1200;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_Q4800(int snd_ch)
|
||
{
|
||
qpsk_set[snd_ch].mode = QPSK_SM;
|
||
modem_mode[snd_ch] = MODE_QPSK;
|
||
rx_shift[snd_ch] = 2400;
|
||
rx_baudrate[snd_ch] = 2400;
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_Q3600(int snd_ch)
|
||
{
|
||
qpsk_set[snd_ch].mode = QPSK_SM;
|
||
modem_mode[snd_ch] = MODE_QPSK;
|
||
rx_shift[snd_ch] = 1800;
|
||
rx_baudrate[snd_ch] = 1800;
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_Q2400(int snd_ch)
|
||
{
|
||
qpsk_set[snd_ch].mode = QPSK_SM;
|
||
modem_mode[snd_ch] = MODE_QPSK;
|
||
rx_shift[snd_ch] = 1200;
|
||
rx_baudrate[snd_ch] = 1200;
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_P2400(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_BPSK;
|
||
rx_shift[snd_ch] = 2400;
|
||
rx_baudrate[snd_ch] = 2400;
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_P1200(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_BPSK;
|
||
rx_shift[snd_ch] = 1200;
|
||
rx_baudrate[snd_ch] = 1200;
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_P600(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_BPSK;
|
||
rx_shift[snd_ch] = 600;
|
||
rx_baudrate[snd_ch] = 600;
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_P300(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_BPSK;
|
||
rx_shift[snd_ch] = 300;
|
||
rx_baudrate[snd_ch] = 300;
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
void init_ARDOP(int snd_ch)
|
||
{
|
||
modem_mode[snd_ch] = MODE_ARDOP;
|
||
rx_shift[snd_ch] = 500;
|
||
rx_freq[snd_ch] = 1500;
|
||
rx_baudrate[snd_ch] = 500;
|
||
|
||
if (modem_def[snd_ch])
|
||
get_filter_values(snd_ch);
|
||
}
|
||
|
||
|
||
void init_speed(int snd_ch);
|
||
|
||
void set_speed(int snd_ch, int Modem)
|
||
{
|
||
speed[snd_ch] = Modem;
|
||
|
||
init_speed(snd_ch);
|
||
|
||
}
|
||
|
||
void init_speed(int snd_ch)
|
||
{
|
||
int low, high;
|
||
|
||
/*
|
||
|
||
if (BPF[snd_ch]>round(rx_samplerate/2) then BPF[snd_ch] = round(rx_samplerate/2);
|
||
if TXBPF[snd_ch]>round(rx_samplerate/2) then TXBPF[snd_ch] = round(rx_samplerate/2);
|
||
if LPF[snd_ch]>round(rx_samplerate/2) then LPF[snd_ch] = round(rx_samplerate/2);
|
||
if BPF[snd_ch]<1 then BPF[snd_ch] = 1;
|
||
if TXBPF[snd_ch]<1 then TXBPF[snd_ch] = 1;
|
||
if LPF[snd_ch]<1 then LPF[snd_ch] = 1;
|
||
if TXDelay[snd_ch]<1 then TXDelay[snd_ch] = 1;
|
||
if TXTail[snd_ch]<1 then TXTail[snd_ch] = 1;
|
||
if BPF_tap[snd_ch]>1024 then BPF_tap[snd_ch] = 1024;
|
||
if LPF_tap[snd_ch]>512 then LPF_tap[snd_ch] = 512;
|
||
if BPF_tap[snd_ch]<8 then BPF_tap[snd_ch] = 8;
|
||
if LPF_tap[snd_ch]<8 then LPF_tap[snd_ch] = 8;
|
||
if not (RCVR[snd_ch] in [0..8]) then RCVR[snd_ch] = 0;
|
||
if not (rcvr_offset[snd_ch] in [0..100]) then rcvr_offset[snd_ch] = 30;
|
||
if not (speed[snd_ch] in [0..modes_count]) then speed[snd_ch] = SPEED_300;
|
||
*/
|
||
switch (speed[snd_ch])
|
||
{
|
||
case SPEED_8P4800:
|
||
init_8P4800(snd_ch);
|
||
break;
|
||
|
||
case SPEED_AE2400:
|
||
init_AE2400(snd_ch);
|
||
break;
|
||
|
||
case SPEED_DW2400:
|
||
init_DW2400(snd_ch);
|
||
break;
|
||
|
||
case SPEED_MP400:
|
||
init_MP400(snd_ch);
|
||
break;
|
||
case SPEED_Q4800:
|
||
init_Q4800(snd_ch);
|
||
break;
|
||
|
||
case SPEED_Q3600:
|
||
init_Q3600(snd_ch);
|
||
break;
|
||
|
||
case SPEED_Q2400:
|
||
init_Q2400(snd_ch);
|
||
break;
|
||
|
||
case SPEED_P2400:
|
||
init_P2400(snd_ch);
|
||
break;
|
||
|
||
case SPEED_P1200:
|
||
init_P1200(snd_ch);
|
||
break;
|
||
|
||
case SPEED_P600:
|
||
init_P600(snd_ch);
|
||
break;
|
||
|
||
case SPEED_P300:
|
||
init_P300(snd_ch);
|
||
break;
|
||
|
||
case SPEED_300:
|
||
|
||
init_300(snd_ch);
|
||
break;
|
||
|
||
case SPEED_600:
|
||
|
||
init_600(snd_ch);
|
||
break;
|
||
|
||
case SPEED_1200:
|
||
|
||
init_1200(snd_ch);
|
||
break;
|
||
|
||
case SPEED_2400:
|
||
|
||
init_2400(snd_ch);
|
||
break;
|
||
|
||
case SPEED_ARDOP:
|
||
|
||
init_ARDOP(snd_ch);
|
||
break;
|
||
}
|
||
|
||
//QPSK_SM: begin move(#0#1#2#3, tx[0], 4); move(#0#32#64#96, rx[0], 4); end;
|
||
//QPSK_V26: begin move(#2#3#1#0, tx[0], 4); move(#96#64#0#32, rx[0], 4); end;
|
||
|
||
|
||
if (modem_mode[snd_ch] == MODE_QPSK || modem_mode[snd_ch] == MODE_PI4QPSK)
|
||
{
|
||
switch (qpsk_set[snd_ch].mode)
|
||
{
|
||
case QPSK_SM:
|
||
|
||
memcpy(&qpsk_set[snd_ch].tx[0], "\0\1\2\3", 4);
|
||
memcpy(&qpsk_set[snd_ch].rx[0], "\x0\x20\x40\x60", 4);
|
||
break;
|
||
|
||
case QPSK_V26:
|
||
|
||
memcpy(&qpsk_set[snd_ch].tx[0], "\2\3\1\0", 4);
|
||
memcpy(&qpsk_set[snd_ch].rx[0], "\x60\x40\0\x20", 4);
|
||
break;
|
||
}
|
||
}
|
||
|
||
tx_shift[snd_ch] = rx_shift[snd_ch];
|
||
tx_baudrate[snd_ch] = rx_baudrate[snd_ch];
|
||
low = roundf(rx_shift[snd_ch] / 2 + RCVR[snd_ch] * rcvr_offset[snd_ch] + 1);
|
||
high = roundf(RX_Samplerate / 2 - (rx_shift[snd_ch] / 2 + RCVR[snd_ch] * rcvr_offset[snd_ch]));
|
||
|
||
if (rx_freq[snd_ch] - low < 0) rx_freq[snd_ch] = low;
|
||
if (high - rx_freq[snd_ch] < 0) rx_freq[snd_ch] = high;
|
||
|
||
tx_freq[snd_ch] = rx_freq[snd_ch];
|
||
|
||
make_core_BPF(snd_ch, rx_freq[snd_ch], bpf[snd_ch]);
|
||
make_core_TXBPF(snd_ch, tx_freq[snd_ch], txbpf[snd_ch]);
|
||
make_core_INTR(snd_ch);
|
||
make_core_LPF(snd_ch, lpf[snd_ch]);
|
||
|
||
/*
|
||
for i = 0 to 16 do
|
||
for j = 0 to nr_emph do with DET[j,i] do
|
||
begin
|
||
minamp[snd_ch] = 0;
|
||
maxamp[snd_ch] = 0;
|
||
ones[snd_ch] = 0;
|
||
zeros[snd_ch] = 0;
|
||
sample_cnt[snd_ch] = 0;
|
||
bit_cnt[snd_ch] = 0;
|
||
bit_osc[snd_ch] = 0;
|
||
frame_status[snd_ch] = FRAME_WAIT;
|
||
end;
|
||
form1.show_modes;
|
||
form1.show_freq_a;
|
||
form1.show_freq_b;
|
||
*/
|
||
wf_pointer(soundChannel[snd_ch]);
|
||
|
||
|
||
}
|
||
|
||
/*
|
||
procedure TForm1.show_combobox;
|
||
var
|
||
i word;
|
||
begin
|
||
for i = 0 to length(modes_name)-1 do
|
||
begin
|
||
ComboBox1.Items.Add(modes_name[i]);
|
||
ComboBox2.Items.Add(modes_name[i]);
|
||
end;
|
||
ComboBox1.ItemIndex = ComboBox1.Items.IndexOf(modes_name[Speed[1]]);
|
||
ComboBox2.ItemIndex = ComboBox2.Items.IndexOf(modes_name[Speed[2]]);
|
||
end;
|
||
|
||
function TForm1.get_idx_by_name(name string) word;
|
||
var
|
||
i word;
|
||
found boolean;
|
||
begin
|
||
i = 0;
|
||
found = FALSE;
|
||
result = 0;
|
||
repeat
|
||
if name = modes_name[i] then
|
||
begin
|
||
found = TRUE;
|
||
result = i;
|
||
end
|
||
else inc(i);
|
||
until found or (i = length(modes_name));
|
||
end;
|
||
|
||
procedure TForm1.ReadIni;
|
||
var
|
||
snd_ch byte;
|
||
begin
|
||
TelIni = TIniFile.Create(cur_dir+"soundmodem.ini");
|
||
with TelIni do
|
||
begin
|
||
UTC_Time = ReadBool("Init","UTCTime",FALSE);
|
||
MainPriority = ReadInteger("Init","Priority",2);
|
||
nr_monitor_lines = ReadInteger("Init","NRMonitorLines",500);
|
||
ptt = ReadString("Init","PTT","NONE");
|
||
stop_wf = ReadBool("Init","StopWF",FALSE);
|
||
raduga = ReadBool("Init","DispMode",DISP_MONO);
|
||
stat_log = ReadBool("Init","StatLog",FALSE);
|
||
SND_RX_DEVICE = ReadInteger("Init","SndRXDevice",0);
|
||
SND_TX_DEVICE = ReadInteger("Init","SndTXDevice",0);
|
||
snd_rx_device_name = ReadString("Init","SndRXDeviceName","");
|
||
snd_tx_device_name = ReadString("Init","SndTXDeviceName","");
|
||
RX_SR = ReadInteger("Init","RXSampleRate",11025);
|
||
TX_SR = ReadInteger("Init","TXSampleRate",11025);
|
||
RX_PPM = ReadInteger("Init","RX_corr_PPM",0);
|
||
TX_PPM = ReadInteger("Init","TX_corr_PPM",0);
|
||
tx_bufcount = ReadInteger("Init","TXBufNumber",32);
|
||
rx_bufcount = ReadInteger("Init","RXBufNumber",32);
|
||
DebugMode = ReadInteger("Init","DisableUnit",0);
|
||
TX_rotate = ReadBool("Init","TXRotate",FALSE);
|
||
DualChan = ReadBool("Init","DualChan",FALSE);
|
||
DualPTT = ReadBool("Init","DualPTT",TRUE);
|
||
SCO = ReadBool("Init","SCO",FALSE);
|
||
stdtones = ReadBool("Init","UseStandardTones",TRUE);
|
||
// Channel A settings
|
||
maxframe[1] = ReadInteger("AX25_A","Maxframe",3);
|
||
fracks[1] = ReadInteger("AX25_A","Retries",15);
|
||
frack_time[1] = ReadInteger("AX25_A","FrackTime",5);
|
||
idletime[1] = ReadInteger("AX25_A","IdleTime",180);
|
||
slottime[1] = ReadInteger("AX25_A","SlotTime",100);
|
||
persist[1] = ReadInteger("AX25_A","Persist",128);
|
||
resptime[1] = ReadInteger("AX25_A","RespTime",1500);
|
||
TXFrmMode[1] = ReadInteger("AX25_A","TXFrmMode",1);
|
||
max_frame_collector[1] = ReadInteger("AX25_A","FrameCollector",6);
|
||
exclude_callsigns[1] = ReadString("AX25_A","ExcludeCallsigns","");
|
||
exclude_APRS_frm[1] = ReadString("AX25_A","ExcludeAPRSFrmType","");
|
||
KISS_opt[1] = ReadBool("AX25_A","KISSOptimization",FALSE);
|
||
dyn_frack[1] = ReadBool("AX25_A","DynamicFrack",FALSE);
|
||
recovery[1] = ReadInteger("AX25_A","BitRecovery",0);
|
||
NonAX25[1] = ReadBool("AX25_A","NonAX25Frm",FALSE);
|
||
MEMRecovery[1] = ReadInteger("AX25_A","MEMRecovery",200);
|
||
IPOLL[1] = ReadInteger("AX25_A","IPOLL",80);
|
||
MyDigiCall[1] = ReadString("AX25_A","MyDigiCall","");
|
||
tx_hitoneraisedb[1] = ReadInteger("AX25_A","HiToneRaise",0);
|
||
// Channel B settings
|
||
maxframe[2] = ReadInteger("AX25_B","Maxframe",3);
|
||
fracks[2] = ReadInteger("AX25_B","Retries",15);
|
||
frack_time[2] = ReadInteger("AX25_B","FrackTime",5);
|
||
idletime[2] = ReadInteger("AX25_B","IdleTime",180);
|
||
slottime[2] = ReadInteger("AX25_B","SlotTime",100);
|
||
persist[2] = ReadInteger("AX25_B","Persist",128);
|
||
resptime[2] = ReadInteger("AX25_B","RespTime",1500);
|
||
TXFrmMode[2] = ReadInteger("AX25_B","TXFrmMode",1);
|
||
max_frame_collector[2] = ReadInteger("AX25_B","FrameCollector",6);
|
||
exclude_callsigns[2] = ReadString("AX25_B","ExcludeCallsigns","");
|
||
exclude_APRS_frm[2] = ReadString("AX25_B","ExcludeAPRSFrmType","");
|
||
KISS_opt[2] = ReadBool("AX25_B","KISSOptimization",FALSE);
|
||
dyn_frack[2] = ReadBool("AX25_B","DynamicFrack",FALSE);
|
||
recovery[2] = ReadInteger("AX25_B","BitRecovery",0);
|
||
NonAX25[2] = ReadBool("AX25_B","NonAX25Frm",FALSE);
|
||
MEMRecovery[2] = ReadInteger("AX25_B","MEMRecovery",200);
|
||
IPOLL[2] = ReadInteger("AX25_B","IPOLL",80);
|
||
MyDigiCall[2] = ReadString("AX25_B","MyDigiCall","");
|
||
tx_hitoneraisedb[2] = ReadInteger("AX25_B","HiToneRaise",0);
|
||
// Modem settings
|
||
pkt_raw_min_len = ReadInteger("Modem","RawPktMinLen",17);
|
||
swap_ptt = ReadBool("Modem","SwapPTTPins",FALSE);
|
||
inv_ptt = ReadBool("Modem","InvPTTPins",FALSE);
|
||
Emph_all[1] = ReadBool("Modem","PreEmphasisAll1",TRUE);
|
||
Emph_all[2] = ReadBool("Modem","PreEmphasisAll2",TRUE);
|
||
emph_db[1] = ReadInteger("Modem","PreEmphasisDB1",0);
|
||
emph_db[2] = ReadInteger("Modem","PreEmphasisDB2",0);
|
||
txbpf[1] = ReadInteger("Modem","TXBPF1",500);
|
||
txbpf[2] = ReadInteger("Modem","TXBPF2",500);
|
||
bpf[1] = ReadInteger("Modem","BPF1",500);
|
||
bpf[2] = ReadInteger("Modem","BPF2",500);
|
||
lpf[1] = ReadInteger("Modem","LPF1",150);
|
||
lpf[2] = ReadInteger("Modem","LPF2",150);
|
||
BPF_tap[1] = ReadInteger("Modem","BPFTap1",256);
|
||
BPF_tap[2] = ReadInteger("Modem","BPFTap2",256);
|
||
LPF_tap[1] = ReadInteger("Modem","LPFTap1",128);
|
||
LPF_tap[2] = ReadInteger("Modem","LPFTap2",128);
|
||
DCD_threshold = ReadInteger("Modem","DCDThreshold",32);
|
||
rx_freq[1] = ReadFloat("Modem","RXFreq1",1700);
|
||
rx_freq[2] = ReadFloat("Modem","RXFreq2",1700);
|
||
CheckBox1.Checked = ReadBool("Modem","HoldPnt",FALSE);
|
||
BIT_AFC = ReadInteger("Modem","AFC",32);
|
||
txdelay[1] = ReadInteger("Modem","TxDelay1",250);
|
||
txdelay[2] = ReadInteger("Modem","TxDelay2",250);
|
||
txtail[1] = ReadInteger("Modem","TxTail1",50);
|
||
txtail[2] = ReadInteger("Modem","TxTail2",50);
|
||
diddles = ReadInteger("Modem","Diddles",0);
|
||
RCVR[1] = ReadInteger("Modem","NRRcvrPairs1",0);
|
||
RCVR[2] = ReadInteger("Modem","NRRcvrPairs2",0);
|
||
rcvr_offset[1] = ReadInteger("Modem","RcvrShift1",30);
|
||
rcvr_offset[2] = ReadInteger("Modem","RcvrShift2",30);
|
||
speed[1] = ReadInteger("Modem","ModemType1",SPEED_1200);
|
||
speed[2] = ReadInteger("Modem","ModemType2",SPEED_1200);
|
||
modem_def[1] = ReadBool("Modem","Default1",TRUE);
|
||
modem_def[2] = ReadBool("Modem","Default2",TRUE);
|
||
AGWServ = ReadBool("AGWHost","Server",TRUE);
|
||
AGWPort = ReadInteger("AGWHost","Port",8000);
|
||
KISSServ = ReadBool("KISS","Server",FALSE);
|
||
KISSPort = ReadInteger("KISS","Port",8100);
|
||
Form1.Top = ReadInteger("Window","Top",0);
|
||
Form1.Left = ReadInteger("Window","Left",0);
|
||
Form1.Height = ReadInteger("Window","Height",656);
|
||
Form1.Width = ReadInteger("Window","Width",764);
|
||
MinOnStart = ReadBool("Window","MinimizedOnStartup",FALSE);
|
||
Firstwaterfall1.checked = ReadBool("Window","Waterfall1",TRUE);
|
||
Secondwaterfall1.checked = ReadBool("Window","Waterfall2",FALSE);
|
||
Statustable1.checked = ReadBool("Window","StatTable",TRUE);
|
||
Monitor1.checked = ReadBool("Window","Monitor",TRUE);
|
||
RXRichEdit1.Font.Size = ReadInteger("Font","Size",RXRichEdit1.Font.Size);
|
||
RXRichEdit1.Font.Name = ReadString("Font","Name",RXRichEdit1.Font.Name);
|
||
end;
|
||
TelIni.Free;
|
||
newAGWPort = AGWPort;
|
||
newAGWServ = AGWServ;
|
||
newKISSPort = KISSPort;
|
||
newKISSServ = KISSServ;
|
||
|
||
RX_SampleRate = RX_SR+RX_SR*0.000001*RX_PPM;
|
||
TX_SampleRate = TX_SR+TX_SR*0.000001*TX_PPM;
|
||
|
||
panels[4] = Monitor1.Checked;
|
||
panels[3] = Statustable1.Checked;
|
||
panels[2] = Firstwaterfall1.Checked;
|
||
panels[1] = Secondwaterfall1.Checked;
|
||
|
||
if tx_bufcount>255 then tx_bufcount = 255;
|
||
if tx_bufcount<2 then tx_bufcount = 2;
|
||
if rx_bufcount>255 then rx_bufcount = 255;
|
||
if rx_bufcount<2 then rx_bufcount = 2;
|
||
|
||
if not (diddles in [0..2]) then diddles = 0;
|
||
|
||
if nr_monitor_lines>65535 then nr_monitor_lines = 65535;
|
||
if nr_monitor_lines<10 then nr_monitor_lines = 10;
|
||
|
||
if not (MainPriority in [0..3]) then MainPriority = 2;
|
||
|
||
for snd_ch = 1 to 2 do
|
||
begin
|
||
|
||
tx_hitoneraise[snd_ch] = power(10,-abs(tx_hitoneraisedb[snd_ch])/20);
|
||
|
||
if IPOLL[snd_ch]<0 then IPOLL[snd_ch] = 0;
|
||
if IPOLL[snd_ch]>65535 then IPOLL[snd_ch] = 65535;
|
||
|
||
if MEMRecovery[snd_ch]<1 then MEMRecovery[snd_ch] = 1;
|
||
if MEMRecovery[snd_ch]>65535 then MEMRecovery[snd_ch] = 65535;
|
||
|
||
get_exclude_list(AnsiUpperCase(MyDigiCall[snd_ch]),list_digi_callsigns[snd_ch]);
|
||
get_exclude_list(AnsiUpperCase(exclude_callsigns[snd_ch]),list_exclude_callsigns[snd_ch]);
|
||
get_exclude_frm(exclude_APRS_frm[snd_ch],list_exclude_APRS_frm[snd_ch]);
|
||
|
||
if resptime[snd_ch]<0 then resptime[snd_ch] = 0;
|
||
if resptime[snd_ch]>65535 then resptime[snd_ch] = 65535;
|
||
if persist[snd_ch]>255 then persist[snd_ch] = 255;
|
||
if persist[snd_ch]<32 then persist[snd_ch] = 32;
|
||
if fracks[snd_ch]<1 then fracks[snd_ch] = 1;
|
||
if frack_time[snd_ch]<1 then frack_time[snd_ch] = 1;
|
||
if idletime[snd_ch]<frack_time[snd_ch] then idletime[snd_ch] = 180;
|
||
|
||
if not (Emph_db[snd_ch] in [0..nr_emph]) then Emph_db[snd_ch] = 0;
|
||
if not (Recovery[snd_ch] in [0..1]) then Recovery[snd_ch] = 0;
|
||
if not (TXFrmMode[snd_ch] in [0..1]) then TXFrmMode[snd_ch] = 0;
|
||
if not (max_frame_collector[snd_ch] in [0..6]) then max_frame_collector[snd_ch] = 6;
|
||
if not (maxframe[snd_ch] in [1..7]) then maxframe[snd_ch] = 3;
|
||
|
||
if not (qpsk_set[snd_ch].mode in [0..1]) then qpsk_set[snd_ch].mode = 0;
|
||
init_speed(snd_ch);
|
||
end;
|
||
TrackBar1.Position = DCD_threshold;
|
||
|
||
// Check device ID
|
||
ChkSndDevName;
|
||
end;
|
||
|
||
procedure TForm1.WriteIni;
|
||
begin
|
||
TelIni = TIniFile.Create(cur_dir+"soundmodem.ini");
|
||
with TelIni do
|
||
begin
|
||
WriteInteger("Init","Priority",MainPriority);
|
||
WriteBool("Init","UTCTime",UTC_Time);
|
||
WriteInteger("Init","NRMonitorLines",nr_monitor_lines);
|
||
WriteString("Init","PTT",ptt);
|
||
WriteBool("Init","DispMode",raduga);
|
||
WriteBool("Init","StopWF",stop_wf);
|
||
WriteBool("Init","StatLog",stat_log);
|
||
WriteInteger("Init","SndRXDevice",SND_RX_DEVICE);
|
||
WriteInteger("Init","SndTXDevice",SND_TX_DEVICE);
|
||
WriteString("Init","SndRXDeviceName",snd_rx_device_name);
|
||
WriteString("Init","SndTXDeviceName",snd_tx_device_name);
|
||
WriteInteger("Init","RXSampleRate",RX_SR);
|
||
WriteInteger("Init","TXSampleRate",TX_SR);
|
||
WriteInteger("Init","RX_corr_PPM",RX_PPM);
|
||
WriteInteger("Init","TX_corr_PPM",TX_PPM);
|
||
WriteInteger("Init","DisableUnit",DebugMode);
|
||
WriteBool("Init","TXRotate",TX_rotate);
|
||
WriteBool("Init","DualChan",DualChan);
|
||
WriteBool("Init","DualPTT",DualPTT);
|
||
WriteBool("Init","SCO",SCO);
|
||
WriteInteger("Init","TXBufNumber",tx_bufcount);
|
||
WriteInteger("Init","RXBufNumber",rx_bufcount);
|
||
WriteBool("Init","UseStandardTones",stdtones);
|
||
// Channel A settings
|
||
WriteInteger("AX25_A","Maxframe",maxframe[1]);
|
||
WriteInteger("AX25_A","Retries",fracks[1]);
|
||
WriteInteger("AX25_A","FrackTime",frack_time[1]);
|
||
WriteInteger("AX25_A","IdleTime",idletime[1]);
|
||
WriteInteger("AX25_A","SlotTime",slottime[1]);
|
||
WriteInteger("AX25_A","Persist",persist[1]);
|
||
WriteInteger("AX25_A","RespTime",resptime[1]);
|
||
WriteInteger("AX25_A","TXFrmMode",TXFrmMode[1]);
|
||
WriteInteger("AX25_A","FrameCollector",max_frame_collector[1]);
|
||
WriteString("AX25_A","ExcludeCallsigns",exclude_callsigns[1]);
|
||
WriteString("AX25_A","ExcludeAPRSFrmType",exclude_APRS_frm[1]);
|
||
WriteBool("AX25_A","KISSOptimization",KISS_opt[1]);
|
||
WriteBool("AX25_A","DynamicFrack",dyn_frack[1]);
|
||
WriteInteger("AX25_A","BitRecovery",recovery[1]);
|
||
WriteBool("AX25_A","NonAX25Frm",NonAX25[1]);
|
||
WriteInteger("AX25_A","MEMRecovery",MEMRecovery[1]);
|
||
WriteInteger("AX25_A","IPOLL",IPOLL[1]);
|
||
WriteString("AX25_A","MyDigiCall",MyDigiCall[1]);
|
||
WriteInteger("AX25_A","HiToneRaise",tx_hitoneraisedb[1]);
|
||
// Channel B settings
|
||
WriteInteger("AX25_B","Maxframe",maxframe[2]);
|
||
WriteInteger("AX25_B","Retries",fracks[2]);
|
||
WriteInteger("AX25_B","FrackTime",frack_time[2]);
|
||
WriteInteger("AX25_B","IdleTime",idletime[2]);
|
||
WriteInteger("AX25_B","SlotTime",slottime[2]);
|
||
WriteInteger("AX25_B","Persist",persist[2]);
|
||
WriteInteger("AX25_B","RespTime",resptime[2]);
|
||
WriteInteger("AX25_B","TXFrmMode",TXFrmMode[2]);
|
||
WriteInteger("AX25_B","FrameCollector",max_frame_collector[2]);
|
||
WriteString("AX25_B","ExcludeCallsigns",exclude_callsigns[2]);
|
||
WriteString("AX25_B","ExcludeAPRSFrmType",exclude_APRS_frm[2]);
|
||
WriteBool("AX25_B","KISSOptimization",KISS_opt[2]);
|
||
WriteBool("AX25_B","DynamicFrack",dyn_frack[2]);
|
||
WriteInteger("AX25_B","BitRecovery",recovery[2]);
|
||
WriteBool("AX25_B","NonAX25Frm",NonAX25[2]);
|
||
WriteInteger("AX25_B","MEMRecovery",MEMRecovery[2]);
|
||
WriteInteger("AX25_B","IPOLL",IPOLL[2]);
|
||
WriteString("AX25_B","MyDigiCall",MyDigiCall[2]);
|
||
WriteInteger("AX25_B","HiToneRaise",tx_hitoneraisedb[2]);
|
||
// Modem settings
|
||
if not modem_def[1] then
|
||
begin
|
||
WriteInteger("Modem","BPF1",bpf[1]);
|
||
WriteInteger("Modem","TXBPF1",txbpf[1]);
|
||
WriteInteger("Modem","LPF1",lpf[1]);
|
||
WriteInteger("Modem","BPFTap1",BPF_tap[1]);
|
||
WriteInteger("Modem","LPFTap1",LPF_tap[1]);
|
||
end;
|
||
if not modem_def[2] then
|
||
begin
|
||
WriteInteger("Modem","BPF2",bpf[2]);
|
||
WriteInteger("Modem","TXBPF2",txbpf[2]);
|
||
WriteInteger("Modem","LPF2",lpf[2]);
|
||
WriteInteger("Modem","BPFTap2",BPF_tap[2]);
|
||
WriteInteger("Modem","LPFTap2",LPF_tap[2]);
|
||
end;
|
||
WriteInteger("Modem","RawPktMinLen",pkt_raw_min_len);
|
||
WriteBool("Modem","SwapPTTPins",swap_ptt);
|
||
WriteBool("Modem","InvPTTPins",inv_ptt);
|
||
WriteInteger("Modem","PreEmphasisDB1",emph_db[1]);
|
||
WriteInteger("Modem","PreEmphasisDB2",emph_db[2]);
|
||
WriteBool("Modem","PreEmphasisAll1",emph_all[1]);
|
||
WriteBool("Modem","PreEmphasisAll2",emph_all[2]);
|
||
WriteBool("Modem","Default1",modem_def[1]);
|
||
WriteBool("Modem","Default2",modem_def[2]);
|
||
WriteInteger("Modem","DCDThreshold",DCD_threshold);
|
||
WriteBool("Modem","HoldPnt",CheckBox1.Checked);
|
||
WriteFloat("Modem","RXFreq1",rx_freq[1]);
|
||
WriteFloat("Modem","RXFreq2",rx_freq[2]);
|
||
WriteFloat("Modem","AFC",BIT_AFC);
|
||
WriteInteger("Modem","TxDelay1",txdelay[1]);
|
||
WriteInteger("Modem","TxDelay2",txdelay[2]);
|
||
WriteInteger("Modem","TxTail1",txtail[1]);
|
||
WriteInteger("Modem","TxTail2",txtail[2]);
|
||
WriteInteger("Modem","Diddles",diddles);
|
||
WriteInteger("Modem","NRRcvrPairs1",RCVR[1]);
|
||
WriteInteger("Modem","NRRcvrPairs2",RCVR[2]);
|
||
WriteInteger("Modem","RcvrShift1",rcvr_offset[1]);
|
||
WriteInteger("Modem","RcvrShift2",rcvr_offset[2]);
|
||
WriteInteger("Modem","ModemType1",speed[1]);
|
||
WriteInteger("Modem","ModemType2",speed[2]);
|
||
WriteBool("AGWHost","Server",newAGWServ);
|
||
WriteInteger("AGWHost","Port",newAGWPort);
|
||
WriteBool("KISS","Server",newKISSServ);
|
||
WriteInteger("KISS","Port",newKISSPort);
|
||
WriteInteger("Window","Top",Form1.Top);
|
||
WriteInteger("Window","Left",Form1.Left);
|
||
WriteInteger("Window","Height",Form1.Height);
|
||
WriteInteger("Window","Width",Form1.Width);
|
||
WriteBool("Window","Waterfall1",Firstwaterfall1.checked);
|
||
WriteBool("Window","Waterfall2",Secondwaterfall1.checked);
|
||
WriteBool("Window","StatTable",Statustable1.checked);
|
||
WriteBool("Window","Monitor",Monitor1.checked);
|
||
WriteBool("Window","MinimizedOnStartup",MinOnStart);
|
||
WriteInteger("Font","Size",RXRichEdit1.Font.Size);
|
||
WriteString("Font","Name",RXRichEdit1.Font.Name);
|
||
end;
|
||
TelIni.Free;
|
||
end;
|
||
|
||
procedure TForm1.ChkSndDevName;
|
||
var
|
||
DevInCaps TWaveInCapsA;
|
||
DevOutCaps TWaveOutCapsA;
|
||
i,k,numdevs integer;
|
||
RXDevList,TXDevList TStringList;
|
||
begin
|
||
RXDevList = TStringList.Create;
|
||
TXDevList = TStringList.Create;
|
||
numdevs = WaveOutGetNumDevs;
|
||
if numdevs>0 then
|
||
for k = 0 to numdevs-1 do
|
||
begin
|
||
waveOutGetDevCaps(k,@DevOutCaps,sizeof(DevOutCaps));
|
||
TXDevList.Add(DevOutCaps.szpname);
|
||
end;
|
||
numdevs = WaveInGetNumDevs;
|
||
if numdevs>0 then
|
||
for k = 0 to numdevs-1 do
|
||
begin
|
||
waveInGetDevCaps(k,@DevInCaps,sizeof(DevInCaps));
|
||
RXDevList.Add(DevInCaps.szpname);
|
||
end;
|
||
// TX Dev
|
||
if (snd_tx_device<0) or (snd_tx_device> = TXDevList.Count) then snd_tx_device = 0;
|
||
if TXDevList.Count>0 then
|
||
if TXDevList.Strings[snd_tx_device]<>snd_tx_device_name then
|
||
begin
|
||
i = TXDevList.IndexOf(snd_tx_device_name);
|
||
if i> = 0 then snd_tx_device = i else snd_tx_device_name = TXDevList.Strings[snd_tx_device];
|
||
end;
|
||
// RX Dev
|
||
if (snd_rx_device<0) or (snd_rx_device> = RXDevList.Count) then snd_rx_device = 0;
|
||
if RXDevList.Count>0 then
|
||
if RXDevList.Strings[snd_rx_device]<>snd_rx_device_name then
|
||
begin
|
||
i = RXDevList.IndexOf(snd_rx_device_name);
|
||
if i> = 0 then snd_rx_device = i else snd_rx_device_name = RXDevList.Strings[snd_rx_device];
|
||
end;
|
||
RXDevList.Free;
|
||
TXDevList.Free;
|
||
end;
|
||
|
||
procedure TForm1.startrx;
|
||
var
|
||
OpenResult MMRESULT;
|
||
Loop integer;
|
||
ErrorText string;
|
||
Begin
|
||
RX_device = TRUE;
|
||
RXBufferLength = rx_bufsize * Channels * (BitsPerSample div 8);
|
||
with WaveFormat do
|
||
begin
|
||
wFormatTag = WAVE_FORMAT_PCM;
|
||
nChannels = Channels;
|
||
nSamplesPerSec = RX_SR;
|
||
nAvgBytesPerSec = RX_SR * Channels * (BitsPerSample div 8);
|
||
nBlockAlign = Channels * (BitsPerSample div 8);
|
||
wBitsPerSample = BitsPerSample;
|
||
cbSize = 0;
|
||
end;
|
||
OpenResult = waveInOpen (@WaveInHandle,SND_RX_DEVICE,@WaveFormat,integer(Self.Handle),0,CALLBACK_WINDOW);
|
||
if OpenResult = MMSYSERR_NOERROR then
|
||
begin
|
||
for Loop = 1 to rx_bufcount do
|
||
begin
|
||
GetMem(RX_pbuf[Loop], RXBufferLength);
|
||
RX_header[Loop].lpData = RX_pbuf[Loop];
|
||
RX_header[Loop].dwBufferLength = RXBufferLength;
|
||
RX_header[Loop].dwUser = Loop;
|
||
RX_header[Loop].dwFlags = 0;
|
||
RX_header[Loop].dwLoops = 0;
|
||
OpenResult = WaveInPrepareHeader(WaveInhandle, @RX_header[Loop], sizeof(TWaveHdr));
|
||
if OpenResult = MMSYSERR_NOERROR then WaveInAddBuffer(WaveInHandle, @RX_header[Loop], sizeof(TWaveHdr))
|
||
else
|
||
begin
|
||
case OpenResult of
|
||
MMSYSERR_INVALHANDLE ErrorText = "device handle is invalid";
|
||
MMSYSERR_NODRIVER ErrorText = "no device driver present";
|
||
MMSYSERR_NOMEM ErrorText = "memory allocation error, could be incorrect samplerate";
|
||
else ErrorText = "unknown error";
|
||
end;
|
||
MessageDlg(format("Error adding buffer %d device (%s)",[Loop, ErrorText]), mtError, [mbOk], 0);
|
||
end;
|
||
end;
|
||
WaveInStart(WaveInHandle);
|
||
end
|
||
else
|
||
begin
|
||
case OpenResult of
|
||
MMSYSERR_ERROR ErrorText = "unspecified error";
|
||
MMSYSERR_BADDEVICEID ErrorText = "device ID out of range";
|
||
MMSYSERR_NOTENABLED ErrorText = "driver failed enable";
|
||
MMSYSERR_ALLOCATED ErrorText = "device already allocated";
|
||
MMSYSERR_INVALHANDLE ErrorText = "device handle is invalid";
|
||
MMSYSERR_NODRIVER ErrorText = "no device driver present";
|
||
MMSYSERR_NOMEM ErrorText = "memory allocation error, could be incorrect samplerate";
|
||
MMSYSERR_NOTSUPPORTED ErrorText = "function isn""t supported";
|
||
MMSYSERR_BADERRNUM ErrorText = "error value out of range";
|
||
MMSYSERR_INVALFLAG ErrorText = "invalid flag passed";
|
||
MMSYSERR_INVALPARAM ErrorText = "invalid parameter passed";
|
||
MMSYSERR_HANDLEBUSY ErrorText = "handle being used simultaneously on another thread (eg callback)";
|
||
MMSYSERR_INVALIDALIAS ErrorText = "specified alias not found";
|
||
MMSYSERR_BADDB ErrorText = "bad registry database";
|
||
MMSYSERR_KEYNOTFOUND ErrorText = "registry key not found";
|
||
MMSYSERR_READERROR ErrorText = "registry read error";
|
||
MMSYSERR_WRITEERROR ErrorText = "registry write error";
|
||
MMSYSERR_DELETEERROR ErrorText = "registry delete error";
|
||
MMSYSERR_VALNOTFOUND ErrorText = "registry value not found";
|
||
MMSYSERR_NODRIVERCB ErrorText = "driver does not call DriverCallback";
|
||
else ErrorText = "unknown error";
|
||
end;
|
||
MessageDlg(format("Error opening wave input device (%s)",[ErrorText]), mtError, [mbOk], 0);
|
||
RX_device = FALSE;
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.stoprx;
|
||
var
|
||
Loop integer;
|
||
begin
|
||
if not RX_device then exit;
|
||
WaveInStop(WaveInHandle);
|
||
WaveInReset(WaveInHandle);
|
||
for Loop = 1 to rx_bufcount do
|
||
WaveInUnPrepareHeader(WaveInHandle, @RX_header[Loop], sizeof(TWaveHdr));
|
||
WaveInClose(WaveInHandle);
|
||
for Loop = 1 to rx_bufcount do
|
||
begin
|
||
if RX_pbuf[Loop]<>nil then
|
||
begin
|
||
FreeMem(RX_pbuf[Loop]);
|
||
RX_pbuf[Loop] = nil;
|
||
end;
|
||
end;
|
||
RX_device = FALSE;
|
||
end;
|
||
|
||
procedure TForm1.make_wave_buf(snd_ch byte; buf PChar);
|
||
const
|
||
amplitude = 22000;
|
||
var
|
||
i word;
|
||
begin
|
||
modulator(snd_ch,audio_buf[snd_ch],tx_bufsize);
|
||
if tx_status[snd_ch] = TX_NO_DATA then buf_status[snd_ch] = BUF_EMPTY;
|
||
for i = 0 to tx_bufsize-1 do
|
||
begin
|
||
case snd_ch of
|
||
1
|
||
begin
|
||
// left channel
|
||
PSmallInt(buf)^ = round(amplitude*audio_buf[snd_ch][i]);
|
||
Inc(PSmallInt(Buf));
|
||
// right channel
|
||
if SCO then PSmallInt(buf)^ = round(amplitude*audio_buf[snd_ch][i]) else PSmallInt(buf)^ = 0;
|
||
Inc(PSmallInt(Buf));
|
||
end;
|
||
2
|
||
begin
|
||
// left channel
|
||
if SCO then PSmallInt(buf)^ = round(amplitude*audio_buf[snd_ch][i]) else PSmallInt(buf)^ = 0;
|
||
Inc(PSmallInt(Buf));
|
||
// right channel
|
||
PSmallInt(buf)^ = round(amplitude*audio_buf[snd_ch][i]);
|
||
Inc(PSmallInt(Buf));
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.starttx(snd_ch byte);
|
||
var
|
||
OpenResult MMRESULT;
|
||
Loop integer;
|
||
ErrorText string;
|
||
BufferLength longint;
|
||
Begin
|
||
if snd_status[snd_ch]<>SND_IDLE then exit;
|
||
BufferLength = tx_bufsize * Channels * (BitsPerSample div 8);
|
||
with WaveFormat do
|
||
begin
|
||
wFormatTag = WAVE_FORMAT_PCM;
|
||
nChannels = Channels;
|
||
nSamplesPerSec = TX_SR;
|
||
nAvgBytesPerSec = TX_SR * Channels * (BitsPerSample div 8);
|
||
nBlockAlign = Channels * (BitsPerSample div 8);
|
||
wBitsPerSample = BitsPerSample;
|
||
cbSize = 0;
|
||
end;
|
||
OpenResult = WaveOutOpen (@WaveOutHandle[snd_ch],SND_TX_DEVICE,@WaveFormat,integer(Self.Handle),0,CALLBACK_WINDOW);
|
||
if OpenResult = MMSYSERR_NOERROR then
|
||
begin
|
||
snd_status[snd_ch] = SND_TX;
|
||
buf_status[snd_ch] = BUF_FULL;
|
||
tx_status[snd_ch] = TX_SILENCE;
|
||
tx_buf_num[snd_ch] = 0;
|
||
tx_buf_num1[snd_ch] = 0;
|
||
for Loop = 1 to tx_bufcount do
|
||
begin
|
||
GetMem(TX_pbuf[snd_ch][Loop], BufferLength);
|
||
TX_header[snd_ch][Loop].lpData = TX_pbuf[snd_ch][Loop];
|
||
TX_header[snd_ch][Loop].dwBufferLength = BufferLength;
|
||
TX_header[snd_ch][Loop].dwUser = 0;
|
||
TX_header[snd_ch][Loop].dwFlags = 0;
|
||
TX_header[snd_ch][Loop].dwLoops = 0;
|
||
OpenResult = WaveOutPrepareHeader(WaveOuthandle[snd_ch], @TX_header[snd_ch][Loop], sizeof(TWaveHdr));
|
||
if OpenResult = MMSYSERR_NOERROR then
|
||
begin
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if buf_status[snd_ch] = BUF_FULL then
|
||
begin
|
||
make_wave_buf(snd_ch,TX_pbuf[snd_ch][Loop]);
|
||
WaveOutWrite(WaveOutHandle[snd_ch],@TX_header[snd_ch][Loop],sizeof(TWaveHdr));
|
||
inc(tx_buf_num1[snd_ch]);
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
case OpenResult of
|
||
MMSYSERR_INVALHANDLE ErrorText = "device handle is invalid";
|
||
MMSYSERR_NODRIVER ErrorText = "no device driver present";
|
||
MMSYSERR_NOMEM ErrorText = "memory allocation error, could be incorrect samplerate";
|
||
else ErrorText = "unknown error";
|
||
end;
|
||
MessageDlg(format("Error adding buffer %d device (%s)",[Loop, ErrorText]), mtError, [mbOk], 0);
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
case OpenResult of
|
||
MMSYSERR_ERROR ErrorText = "unspecified error";
|
||
MMSYSERR_BADDEVICEID ErrorText = "device ID out of range";
|
||
MMSYSERR_NOTENABLED ErrorText = "driver failed enable";
|
||
MMSYSERR_ALLOCATED ErrorText = "device already allocated";
|
||
MMSYSERR_INVALHANDLE ErrorText = "device handle is invalid";
|
||
MMSYSERR_NODRIVER ErrorText = "no device driver present";
|
||
MMSYSERR_NOMEM ErrorText = "memory allocation error, could be incorrect samplerate";
|
||
MMSYSERR_NOTSUPPORTED ErrorText = "function isn""t supported";
|
||
MMSYSERR_BADERRNUM ErrorText = "error value out of range";
|
||
MMSYSERR_INVALFLAG ErrorText = "invalid flag passed";
|
||
MMSYSERR_INVALPARAM ErrorText = "invalid parameter passed";
|
||
MMSYSERR_HANDLEBUSY ErrorText = "handle being used simultaneously on another thread (eg callback)";
|
||
MMSYSERR_INVALIDALIAS ErrorText = "specified alias not found";
|
||
MMSYSERR_BADDB ErrorText = "bad registry database";
|
||
MMSYSERR_KEYNOTFOUND ErrorText = "registry key not found";
|
||
MMSYSERR_READERROR ErrorText = "registry read error";
|
||
MMSYSERR_WRITEERROR ErrorText = "registry write error";
|
||
MMSYSERR_DELETEERROR ErrorText = "registry delete error";
|
||
MMSYSERR_VALNOTFOUND ErrorText = "registry value not found";
|
||
MMSYSERR_NODRIVERCB ErrorText = "driver does not call DriverCallback";
|
||
else ErrorText = "unknown error";
|
||
end;
|
||
MessageDlg(format("Error opening wave output device (%s)",[ErrorText]), mtError, [mbOk], 0);
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.stoptx(snd_ch byte);
|
||
var
|
||
Loop integer;
|
||
begin
|
||
if snd_status[snd_ch]<>SND_TX then exit;
|
||
WaveOutReset(WaveOutHandle[snd_ch]);
|
||
for Loop = 1 to tx_bufcount do
|
||
WaveOutUnPrepareHeader(WaveOutHandle[snd_ch], @TX_header[snd_ch][Loop], sizeof(TWaveHdr));
|
||
WaveOutClose(WaveOutHandle[snd_ch]);
|
||
for Loop = 1 to tx_bufcount do
|
||
begin
|
||
if TX_pbuf[snd_ch][Loop]<>nil then
|
||
begin
|
||
FreeMem(TX_pbuf[snd_ch][Loop]);
|
||
TX_pbuf[snd_ch][Loop] = nil;
|
||
end;
|
||
end;
|
||
WaveOutHandle[snd_ch] = 0;
|
||
snd_status[snd_ch] = SND_IDLE;
|
||
end;
|
||
|
||
procedure show_grid_title;
|
||
const
|
||
title array [0..10] of string = ("MyCall","DestCall","Status","Sent pkts","Sent bytes","Rcvd pkts","Rcvd bytes","Rcvd FC","CPS TX","CPS RX","Direction");
|
||
var
|
||
i byte;
|
||
begin
|
||
for i = 0 to 10 do Form1.StringGrid1.Cells[i,0] = title[i];
|
||
end;
|
||
*/
|
||
/*
|
||
|
||
procedure disp1(src1,src2 array of single);
|
||
var
|
||
i,n word;
|
||
k,k1,amp1,amp2,amp3,amp4 single;
|
||
bm TBitMap;
|
||
begin
|
||
bm = TBitMap.Create;
|
||
bm.pixelformat = pf32bit;
|
||
//bm.pixelformat = pf24bit;
|
||
bm.Width = Form1.PaintBox2.Width;
|
||
bm.Height = Form1.PaintBox2.Height;
|
||
amp1 = 0;
|
||
amp3 = 0;
|
||
//k = 0.20;
|
||
k = 50000;
|
||
k1 = 0;
|
||
//k = 1000;
|
||
//k = 0.00001;
|
||
bm.Canvas.MoveTo(0,50);
|
||
bm.Canvas.LineTo(512,50);
|
||
n = 0;
|
||
for i = 0 to RX_Bufsize-1 do
|
||
begin
|
||
begin
|
||
amp2 = src1[i];
|
||
amp4 = src2[i];
|
||
bm.Canvas.Pen.Color = clRed;
|
||
bm.Canvas.MoveTo(n,50-round(amp1*k1));
|
||
bm.Canvas.LineTo(n+1,50-round(amp2*k1));
|
||
bm.Canvas.Pen.Color = clBlue;
|
||
bm.Canvas.MoveTo(n,50-round(amp3*k));
|
||
bm.Canvas.LineTo(n+1,50-round(amp4*k));
|
||
bm.Canvas.Pen.Color = clBlack;
|
||
inc(n);
|
||
amp1 = amp2;
|
||
amp3 = amp4;
|
||
end;
|
||
end;
|
||
Form1.PaintBox2.Canvas.Draw(0,0,bm);
|
||
bm.Free;
|
||
end;
|
||
*/
|
||
|
||
/*
|
||
|
||
procedure TForm1.wf_pointer(snd_ch byte);
|
||
var
|
||
x single;
|
||
x1,x2,y,k,pos1,pos2,pos3 word;
|
||
begin
|
||
k = 24;
|
||
x = FFTSize/RX_SampleRate;
|
||
pos1 = round((rx_freq[snd_ch]-0.5*rx_shift[snd_ch])*x)-5;
|
||
pos2 = round((rx_freq[snd_ch]+0.5*rx_shift[snd_ch])*x)-5;
|
||
pos3 = round(rx_freq[snd_ch]*x);
|
||
x1 = pos1+5;
|
||
x2 = pos2+5;
|
||
y = k+5;
|
||
with bm3.Canvas do
|
||
begin
|
||
Draw(0,20,bm[snd_ch]);
|
||
Pen.Color = clWhite;
|
||
Brush.Color = clRed;
|
||
Polygon([Point(x1+3,y),Point(x1,y-7),Point(x1-3,y),Point(x2+3,y),Point(x2,y-7),Point(x2-3,y)]);
|
||
Brush.Color = clBlue;
|
||
Polygon([Point(x1+3,y),Point(x1,y+7),Point(x1-3,y),Point(x2+3,y),Point(x2,y+7),Point(x2-3,y)]);
|
||
Polyline([Point(pos3,k+1),Point(pos3,k+9)]);
|
||
Pen.Color = clBlack;
|
||
end;
|
||
case snd_ch of
|
||
1 PaintBox1.Canvas.Draw(0,0,bm3);
|
||
2 PaintBox3.Canvas.Draw(0,0,bm3);
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.wf_Scale;
|
||
var
|
||
k single;
|
||
max_freq,x,i word;
|
||
begin
|
||
max_freq = round(RX_SampleRate*0.005);
|
||
k = 100*FFTSize/RX_SampleRate;
|
||
with bm1.Canvas do
|
||
begin
|
||
Brush.Color = clBlack;
|
||
FillRect(ClipRect);
|
||
Pen.Color = clWhite;
|
||
Font.Color = clWhite;
|
||
Font.Size = 8;
|
||
for i = 0 to max_freq do
|
||
begin
|
||
x = round(k*i);
|
||
if x<1025 then
|
||
begin
|
||
if (i mod 5) = 0 then
|
||
PolyLine([Point(x,20),Point(x,13)])
|
||
else
|
||
PolyLine([Point(x,20),Point(x,16)]);
|
||
if (i mod 10) = 0 then TextOut(x-12,1,inttostr(i*100));
|
||
end;
|
||
end;
|
||
Pen.Color = clBlack;
|
||
end;
|
||
bm3.Canvas.Draw(0,0,bm1);
|
||
end;
|
||
*/
|
||
|
||
void chk_snd_buf(float * buf, int len)
|
||
{
|
||
word i;
|
||
boolean good;
|
||
single prev_amp;
|
||
|
||
if (len < 2)
|
||
return;
|
||
|
||
good = FALSE;
|
||
i = 1;
|
||
prev_amp = buf[0];
|
||
do
|
||
{
|
||
if (buf[i++] != prev_amp)
|
||
good = TRUE;
|
||
|
||
} while (good == FALSE && i < len);
|
||
|
||
// Make noise
|
||
if (!good)
|
||
for (i = 0; i < len; i++)
|
||
buf[i] = rand();
|
||
}
|
||
|
||
#ifdef WIN32
|
||
|
||
typedef void *HANDLE;
|
||
typedef unsigned long DWORD;
|
||
|
||
#define WINAPI __stdcall
|
||
__declspec(dllimport)
|
||
DWORD
|
||
WINAPI
|
||
WaitForSingleObject(
|
||
__in HANDLE hHandle,
|
||
__in DWORD dwMilliseconds
|
||
);
|
||
|
||
|
||
|
||
|
||
#define pthread_t uintptr_t
|
||
|
||
uintptr_t _beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist);
|
||
#else
|
||
|
||
#include <pthread.h>
|
||
|
||
pthread_t _beginthread(void(*start_address)(void *), unsigned stack_size, void * arglist)
|
||
{
|
||
pthread_t thread;
|
||
|
||
if (pthread_create(&thread, NULL, (void * (*)(void *))start_address, (void*)arglist) != 0)
|
||
perror("New Thread");
|
||
|
||
return thread;
|
||
}
|
||
|
||
#endif
|
||
|
||
void runModemthread(void * param);
|
||
|
||
void runModems()
|
||
{
|
||
int snd_ch, res;
|
||
pthread_t thread[4] = { 0,0,0,0 };
|
||
|
||
for (snd_ch = 0; snd_ch < 4; snd_ch++)
|
||
{
|
||
if (soundChannel[snd_ch] == 0) // Unused channed
|
||
continue;
|
||
|
||
if (modem_mode[snd_ch] == MODE_ARDOP)
|
||
continue; // Processed above
|
||
|
||
// do we need to do this again ??
|
||
// make_core_BPF(snd_ch, rx_freq[snd_ch], bpf[snd_ch]);
|
||
|
||
if (multiCore) // Run modems in separate threads
|
||
thread[snd_ch] = _beginthread(runModemthread, 0, (void *)(size_t)snd_ch);
|
||
else
|
||
runModemthread((void *)(size_t)snd_ch);
|
||
}
|
||
|
||
if (multiCore)
|
||
{
|
||
#ifdef WIN32
|
||
if (thread[0]) WaitForSingleObject(&thread[0], 2000);
|
||
if (thread[1]) WaitForSingleObject(&thread[1], 2000);
|
||
if (thread[2]) WaitForSingleObject(&thread[2], 2000);
|
||
if (thread[3]) WaitForSingleObject(&thread[3], 2000);
|
||
#else
|
||
if (thread[0]) pthread_join(thread[0], &res);
|
||
if (thread[1]) pthread_join(thread[1], &res);
|
||
if (thread[2]) pthread_join(thread[2], &res);
|
||
if (thread[3]) pthread_join(thread[3], &res);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
Byte rcvr_idx;
|
||
|
||
void runModemthread(void * param)
|
||
{
|
||
int snd_ch = (int)(size_t)param;
|
||
|
||
// I want to run lowest to highest to simplify my display
|
||
|
||
int offset = -(RCVR[snd_ch] * rcvr_offset[snd_ch]); // lowest
|
||
int lastrx = RCVR[snd_ch] * 2;
|
||
|
||
if (soundChannel[snd_ch] == 0) // Unused channed
|
||
return;
|
||
|
||
for (rcvr_idx = 0; rcvr_idx <= lastrx; rcvr_idx++)
|
||
{
|
||
active_rx_freq[snd_ch] = rxOffset + chanOffset[snd_ch] + rx_freq[snd_ch] + offset;
|
||
offset += rcvr_offset[snd_ch];
|
||
|
||
Demodulator(snd_ch, rcvr_idx, src_buf[modemtoSoundLR[snd_ch]], rcvr_idx == lastrx, offset == 0);
|
||
}
|
||
}
|
||
|
||
// I think this processes a buffer of samples
|
||
|
||
void BufferFull(short * Samples, int nSamples) // These are Stereo Samples
|
||
{
|
||
word i, i1;
|
||
Byte snd_ch, rcvr_idx;
|
||
int buf_offset;
|
||
int Needed;
|
||
short * data1;
|
||
short * data2 = 0;
|
||
|
||
// if UDP server active send as UDP Datagram
|
||
|
||
if (UDPServ) // Extract just left
|
||
{
|
||
short Buff[1024];
|
||
|
||
i1 = 0;
|
||
|
||
for (i = 0; i < rx_bufsize; i++)
|
||
{
|
||
Buff[i] = Samples[i1];
|
||
i1 += 2;
|
||
}
|
||
|
||
sendSamplestoUDP(Buff, 512, TXPort);
|
||
}
|
||
|
||
// Do RSID processing (can we also use this for waterfall??
|
||
|
||
RSIDProcessSamples(Samples, nSamples);
|
||
|
||
// Do FFT on every 4th buffer (2048 samples)
|
||
|
||
// if in Satellite Mode look for a Tuning signal
|
||
|
||
// if (SatelliteMode)
|
||
// {
|
||
// doTuning(Samples, nSamples);
|
||
// }
|
||
|
||
for (snd_ch = 0; snd_ch < 4; snd_ch++)
|
||
{
|
||
if (soundChannel[snd_ch] == 0) // Unused channed
|
||
continue;
|
||
|
||
if (pnt_change[snd_ch])
|
||
{
|
||
make_core_BPF(snd_ch, rx_freq[snd_ch], bpf[snd_ch]);
|
||
make_core_TXBPF(snd_ch, tx_freq[snd_ch], txbpf[snd_ch]);
|
||
pnt_change[snd_ch] = FALSE;
|
||
}
|
||
|
||
}
|
||
|
||
// I don't think we should process RX if either is sending
|
||
|
||
if (snd_status[0] != SND_TX && snd_status[1] != SND_TX && snd_status[2] != SND_TX && snd_status[3] != SND_TX)
|
||
{
|
||
for (snd_ch = 0; snd_ch < 4; snd_ch++)
|
||
{
|
||
if (soundChannel[snd_ch] == 0) // Unused channed
|
||
continue;
|
||
|
||
if (modem_mode[snd_ch] == MODE_ARDOP)
|
||
{
|
||
short ardopbuff[1200];
|
||
i1 = 0;
|
||
|
||
for (i = 0; i < rx_bufsize; i++)
|
||
{
|
||
ardopbuff[i] = Samples[i1];
|
||
i1++;
|
||
i1++;
|
||
}
|
||
|
||
ARDOPProcessNewSamples(ardopbuff, nSamples);
|
||
}
|
||
}
|
||
|
||
// extract mono samples from data.
|
||
|
||
data1 = Samples;
|
||
|
||
i1 = 0;
|
||
|
||
// src_buf[0] is left data,. src_buf[1] right
|
||
|
||
// We could skip extracting other channel if only one in use - is it worth it??
|
||
|
||
if (UsingBothChannels)
|
||
{
|
||
for (i = 0; i < rx_bufsize; i++)
|
||
{
|
||
src_buf[0][i] = data1[i1];
|
||
i1++;
|
||
src_buf[1][i] = data1[i1];
|
||
i1++;
|
||
}
|
||
}
|
||
else if (UsingRight)
|
||
{
|
||
// Extract just right
|
||
|
||
i1 = 1;
|
||
|
||
for (i = 0; i < rx_bufsize; i++)
|
||
{
|
||
src_buf[1][i] = data1[i1];
|
||
i1 += 2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Extract just left
|
||
|
||
for (i = 0; i < rx_bufsize; i++)
|
||
{
|
||
src_buf[0][i] = data1[i1];
|
||
i1 += 2;
|
||
}
|
||
}
|
||
|
||
// Run modems before waterfall so fft buffer has values from before sync was detected
|
||
|
||
runModems();
|
||
|
||
// Do whichever waterfall is needed
|
||
|
||
// We need to run the waterfall FFT for the frequency guessing to work
|
||
|
||
int FirstWaterfallChan = 0;
|
||
short * ptr1 = &fft_buf[0][fftCount];
|
||
short * ptr2 = &fft_buf[1][fftCount];
|
||
|
||
int remainingSamples = rx_bufsize;
|
||
|
||
if (UsingLeft == 0)
|
||
{
|
||
FirstWaterfallChan = 1;
|
||
data1++; // to Right Samples
|
||
}
|
||
|
||
if (UsingBothChannels) // Second is always Right
|
||
data2 = &Samples[1]; // to Right Samples
|
||
|
||
|
||
// FFT size isn't necessarily a multiple of rx_bufsize, so this is a bit more complicated
|
||
// Save FFTSize samples then process. Put the unused bits back in the fft buffer
|
||
|
||
// Collect samples for both channels if needed
|
||
|
||
Needed = FFTSize - fftCount;
|
||
|
||
if (Needed <= rx_bufsize)
|
||
{
|
||
// add Needed samples to fft_buf and process. Copy rest to start of fft_buf
|
||
|
||
for (i = 0; i < Needed; i++)
|
||
{
|
||
*ptr1++ = *data1;
|
||
data1 += 2;
|
||
}
|
||
|
||
doWaterfall(FirstWaterfallChan);
|
||
|
||
if (data2)
|
||
{
|
||
for (i = 0; i < Needed; i++)
|
||
{
|
||
*ptr2++ = *data2;
|
||
data2 += 2;
|
||
}
|
||
doWaterfall(1);
|
||
}
|
||
|
||
remainingSamples = rx_bufsize - Needed;
|
||
fftCount = 0;
|
||
|
||
ptr1 = &fft_buf[0][0];
|
||
ptr2 = &fft_buf[1][0];
|
||
}
|
||
|
||
for (i = 0; i < remainingSamples; i++)
|
||
{
|
||
*ptr1++ = *data1;
|
||
data1 += 2;
|
||
}
|
||
|
||
if (data2)
|
||
{
|
||
for (i = 0; i < remainingSamples; i++)
|
||
{
|
||
*ptr2++ = *data2;
|
||
data2 += 2;
|
||
}
|
||
}
|
||
fftCount += remainingSamples;
|
||
|
||
}
|
||
|
||
|
||
if (TimerEvent == TIMER_EVENT_ON)
|
||
{
|
||
timer_event();
|
||
// timer_event2();
|
||
}
|
||
}
|
||
|
||
/*
|
||
|
||
procedure TForm1.BufferFull1(var Msg TMessage);
|
||
var
|
||
i,snd_ch byte;
|
||
begin
|
||
for snd_ch = 1 to 2 do
|
||
if pnt_change[snd_ch] then
|
||
begin
|
||
make_core_BPF(snd_ch,rx_freq[snd_ch],bpf[snd_ch]);
|
||
make_core_TXBPF(snd_ch,tx_freq[snd_ch],txbpf[snd_ch]);
|
||
pnt_change[snd_ch] = FALSE;
|
||
end;
|
||
snd_ch = 0;
|
||
for i = 1 to 2 do if msg.WParam = WaveOutHandle[i] then snd_ch = i;
|
||
if (snd_ch = 0) then exit;
|
||
if (snd_status[snd_ch]<>SND_TX) then exit;
|
||
inc(tx_buf_num[snd_ch]); if tx_buf_num[snd_ch]>tx_bufcount then tx_buf_num[snd_ch] = 1;
|
||
if (buf_status[snd_ch] = BUF_EMPTY) and (tx_buf_num[snd_ch] = tx_buf_num1[snd_ch]) then TX2RX(snd_ch);
|
||
if buf_status[snd_ch] = BUF_FULL then
|
||
beginf
|
||
make_wave_buf(snd_ch,TX_pbuf[snd_ch][tx_buf_num[snd_ch]]);
|
||
WaveOutWrite(WaveOutHandle[snd_ch],@TX_header[snd_ch][tx_buf_num[snd_ch]],sizeof(TWaveHdr));
|
||
inc(tx_buf_num1[snd_ch]); if tx_buf_num1[snd_ch]>tx_bufcount then tx_buf_num1[snd_ch] = 1;
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.TX2RX(snd_ch byte);
|
||
begin
|
||
if snd_status[snd_ch] = SND_TX then stoptx(snd_ch);
|
||
if snd_status[snd_ch] = SND_IDLE then begin pttoff(snd_ch); end;
|
||
end;
|
||
*/
|
||
|
||
|
||
// Monitor Code - from moncode.asm
|
||
|
||
|
||
#define CMDBIT 4 // CURRENT MESSAGE IS A COMMAND
|
||
#define RESP 2 // CURRENT MSG IS RESPONSE
|
||
#define VER1 1 // CURRENT MSG IS VERSION 1
|
||
|
||
|
||
#define UI 3
|
||
#define SABM 0x2F
|
||
#define DISC 0x43
|
||
#define DM 0x0F
|
||
#define UA 0x63
|
||
#define FRMR 0x87
|
||
#define RR 1
|
||
#define RNR 5
|
||
#define REJ 9
|
||
|
||
#define SREJ 0x0D
|
||
#define SABME 0x6F
|
||
#define XID 0xAF
|
||
#define TEST 0xE3
|
||
|
||
|
||
#define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE
|
||
|
||
#define NETROM_PID 0xCF
|
||
#define IP_PID 0xCC
|
||
#define ARP_PID 0xCD
|
||
|
||
#define NODES_SIG 0xFF
|
||
|
||
char FrameData[1024] = "";
|
||
|
||
char * frame_monitor(string * frame, char * code, int tx_stat)
|
||
{
|
||
char mon_frm[512];
|
||
char AGW_path[256];
|
||
string * AGW_data;
|
||
|
||
const Byte * frm = "???";
|
||
Byte * datap;
|
||
Byte _data[512] = "";
|
||
Byte * p_data = _data;
|
||
int _datalen;
|
||
|
||
char agw_port;
|
||
char CallFrom[10], CallTo[10], Digi[80];
|
||
|
||
char TR = 'R';
|
||
char codestr[64] = "";
|
||
|
||
integer i;
|
||
char time_now[32];
|
||
int len;
|
||
|
||
AGWUser * AGW;
|
||
|
||
Byte pid, nr, ns, f_type, f_id;
|
||
Byte rpt, cr, pf;
|
||
Byte path[80];
|
||
char c;
|
||
const char * p;
|
||
|
||
string * data = newString();
|
||
|
||
if (code[0] && strlen(code) < 60)
|
||
sprintf(codestr, "[%s]", code);
|
||
|
||
if (tx_stat)
|
||
TR = 'T';
|
||
|
||
decode_frame(frame->Data, frame->Length, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
|
||
|
||
datap = data->Data;
|
||
|
||
len = data->Length;
|
||
|
||
// if (pid == 0xCF)
|
||
// data = parse_NETROM(data, f_id);
|
||
// IP parsing
|
||
// else if (pid == 0xCC)
|
||
// data = parse_IP(data);
|
||
// ARP parsing
|
||
// else if (pid == 0xCD)
|
||
// data = parse_ARP(data);
|
||
//
|
||
|
||
if (len > 0)
|
||
{
|
||
for (i = 0; i < len; i++)
|
||
{
|
||
if (datap[i] > 31 || datap[i] == 13 || datap[i] == 9)
|
||
*(p_data++) = datap[i];
|
||
}
|
||
}
|
||
|
||
_datalen = p_data - _data;
|
||
|
||
if (_datalen)
|
||
{
|
||
Byte * ptr = _data;
|
||
i = 0;
|
||
|
||
// remove successive cr or cr on end while (i < _datalen)
|
||
|
||
while (i < _datalen)
|
||
{
|
||
if ((_data[i] == 13) && (_data[i + 1] == 13))
|
||
i++;
|
||
else
|
||
*(ptr++) = _data[i++];
|
||
}
|
||
|
||
if (*(ptr - 1) == 13)
|
||
ptr--;
|
||
|
||
*ptr = 0;
|
||
|
||
_datalen = ptr - _data;
|
||
}
|
||
|
||
get_monitor_path(path, CallTo, CallFrom, Digi);
|
||
|
||
if (cr)
|
||
{
|
||
c = 'C';
|
||
if (pf)
|
||
p = " P";
|
||
else p = "";
|
||
}
|
||
else
|
||
{
|
||
c = 'R';
|
||
if (pf)
|
||
p = " F";
|
||
else
|
||
p = "";
|
||
}
|
||
|
||
switch (f_id)
|
||
{
|
||
case I_I:
|
||
|
||
frm = "I";
|
||
break;
|
||
|
||
case S_RR:
|
||
|
||
frm = "RR";
|
||
break;
|
||
|
||
case S_RNR:
|
||
|
||
frm = "RNR";
|
||
break;
|
||
|
||
case S_REJ:
|
||
|
||
frm = "REJ";
|
||
break;
|
||
|
||
case S_SREJ:
|
||
|
||
frm = "SREJ";
|
||
break;
|
||
|
||
case U_SABM:
|
||
|
||
frm = "SABM";
|
||
break;
|
||
|
||
case SABME:
|
||
|
||
frm = "SABME";
|
||
break;
|
||
|
||
case U_DISC:
|
||
|
||
frm = "DISC";
|
||
break;
|
||
|
||
case U_DM:
|
||
|
||
frm = "DM";
|
||
break;
|
||
|
||
case U_UA:
|
||
|
||
frm = "UA";
|
||
break;
|
||
|
||
case U_FRMR:
|
||
|
||
frm = "FRMR";
|
||
break;
|
||
|
||
case U_UI:
|
||
|
||
frm = "UI";
|
||
}
|
||
|
||
if (Digi[0])
|
||
sprintf(AGW_path, "Fm %s To %s Via %s <%s %c%s",CallFrom, CallTo, Digi, frm, c, p);
|
||
else
|
||
sprintf(AGW_path, "Fm %s To %s <%s %c %s", CallFrom, CallTo, frm, c, p);
|
||
|
||
|
||
switch (f_type)
|
||
{
|
||
case I_FRM:
|
||
|
||
//mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' S' + inttostr(ns) + ' pid=' + dec2hex(pid) + ' Len=' + inttostr(len) + ' >' + time_now + #13 + _data + #13#13;
|
||
sprintf(mon_frm, "%s R%d S%d pid=%X Len=%d>[%s%c]%s\r%s\r", AGW_path, nr, ns, pid, len, ShortDateTime(), TR, codestr, _data);
|
||
|
||
break;
|
||
|
||
case U_FRM:
|
||
|
||
if (f_id == U_UI)
|
||
{
|
||
sprintf(mon_frm, "%s pid=%X Len=%d>[%s%c]%s\r%s\r", AGW_path, pid, len, ShortDateTime(), TR, codestr, _data); // "= AGW_path + ctrl + '>' + time_now + #13;
|
||
}
|
||
else if (f_id == U_FRMR)
|
||
{
|
||
sprintf(mon_frm, "%s>%02x %02x %02x[%s]\r", AGW_path, datap[0], datap[1], datap[2], ShortDateTime()); // "= AGW_path + ctrl + '>' + time_now + #13;
|
||
}
|
||
else
|
||
sprintf(mon_frm, "%s>[%s%c]%s\r", AGW_path, ShortDateTime(), TR, codestr); // "= AGW_path + ctrl + '>' + time_now + #13;
|
||
|
||
break;
|
||
|
||
case S_FRM:
|
||
|
||
// mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' >' + time_now + #13;
|
||
sprintf(mon_frm, "%s R%d>[%s%c]%s\r", AGW_path, nr, ShortDateTime(), TR, codestr); // "= AGW_path + ctrl + '>' + time_now + #13;
|
||
|
||
break;
|
||
|
||
}
|
||
sprintf(FrameData, "%s", mon_frm);
|
||
return FrameData;
|
||
}
|
||
|
||
|
||
/*
|
||
procedure TForm1.RX2TX(snd_ch byte);
|
||
begin
|
||
if snd_status[snd_ch] = SND_IDLE then begin ptton(snd_ch); starttx(snd_ch); end;
|
||
end;
|
||
|
||
function TForm1.frame_monitor(s,code string; tx_stat boolean) string;
|
||
var
|
||
len word;
|
||
s_tx_stat string;
|
||
time_now,s1,c,p string;
|
||
callfrom,callto,digi,path,data,frm string;
|
||
frm_body string;
|
||
pid,nr,ns,f_type,f_id byte;
|
||
rpt,cr,pf boolean;
|
||
i word;
|
||
begin
|
||
decode_frame(s,path,data,pid,nr,ns,f_type,f_id,rpt,pf,cr);
|
||
len = length(data);
|
||
// NETROM parsing
|
||
if pid = $CF then data = parse_NETROM(data,f_id);
|
||
// IP parsing
|
||
if pid = $CC then data = parse_IP(data);
|
||
// ARP parsing
|
||
if pid = $CD then data = parse_ARP(data);
|
||
//
|
||
get_monitor_path(path,CallTo,CallFrom,Digi);
|
||
if cr then
|
||
begin
|
||
c = "C";
|
||
if pf then p = " P" else p = "";
|
||
end
|
||
else
|
||
begin
|
||
c = "R";
|
||
if pf then p = " F" else p = "";
|
||
end;
|
||
frm = "UNKN";
|
||
case f_id of
|
||
I_I frm = "I";
|
||
S_RR frm = "RR";
|
||
S_RNR frm = "RNR";
|
||
S_REJ frm = "REJ";
|
||
U_SABM frm = "SABM";
|
||
U_DISC frm = "DISC";
|
||
U_DM frm = "DM";
|
||
U_UA frm = "UA";
|
||
U_FRMR frm = "FRMR";
|
||
U_UI frm = "UI";
|
||
end;
|
||
case tx_stat of
|
||
TRUE s_tx_stat = "T";
|
||
FALSE s_tx_stat = "R";
|
||
end;
|
||
s1 = "";
|
||
|
||
if code<>"" then code = " ["+code+"]";
|
||
if UTC_Time then time_now = " [UTC"+get_UTC_time+s_tx_stat+"]"
|
||
else time_now = " ["+FormatDateTime("hhmmss",now)+s_tx_stat+"]";
|
||
|
||
if digi = "" then frm_body = "Fm "+CallFrom+" To "+CallTo+" <"+frm+" "+c+p
|
||
else frm_body = "Fm "+CallFrom+" To "+CallTo+" Via "+Digi+" <"+frm+" "+c+p;
|
||
case f_type of
|
||
I_FRM frm_body = frm_body+" R"+inttostr(nr)+" S"+inttostr(ns)+" Pid = "+dec2hex(pid)+" Len = "+inttostr(len)+">"+time_now+code+#13+data;
|
||
U_FRM if f_id = U_UI then frm_body = frm_body+" Pid = "+dec2hex(pid)+" Len = "+inttostr(len)+">"+time_now+code+#13+data
|
||
else if f_id = U_FRMR then begin data = copy(data+#0#0#0,1,3); frm_body = frm_body+">"+time_now+code+#13+inttohex((byte(data[1]) shl 16) or (byte(data[2]) shl 8) or byte(data[3]),6) end
|
||
else frm_body = frm_body+">"+time_now+code;
|
||
S_FRM frm_body = frm_body+" R"+inttostr(nr)+">"+time_now+code;
|
||
end;
|
||
for i = 1 to length(frm_body) do
|
||
begin
|
||
if frm_body[i]>#31 then s1 = s1+frm_body[i];
|
||
if frm_body[i] = #13 then s1 = s1+#13#10;
|
||
if frm_body[i] = #10 then s1 = s1+"";
|
||
if frm_body[i] = #9 then s1 = s1+#9;
|
||
end;
|
||
result = s1;
|
||
end;
|
||
|
||
procedure TForm1.waterfall_init;
|
||
begin
|
||
bm[1] = TBitMap.Create;
|
||
bm[2] = TBitMap.Create;
|
||
bm1 = TBitMap.Create;
|
||
bm2 = TBitMap.Create;
|
||
bm3 = TBitMap.Create;
|
||
bm[1].pixelformat = pf32bit;
|
||
bm[2].pixelformat = pf32bit;
|
||
bm1.pixelformat = pf32bit;
|
||
bm2.pixelformat = pf32bit;
|
||
bm3.pixelformat = pf32bit;
|
||
bm[1].Height = PaintBox1.Height-20;
|
||
bm[1].Width = PaintBox1.width;
|
||
bm[2].Height = PaintBox1.Height-20;
|
||
bm[2].Width = PaintBox1.width;
|
||
bm1.Height = 20;
|
||
bm1.Width = PaintBox1.width;
|
||
bm3.Height = PaintBox1.Height;
|
||
bm3.Width = PaintBox1.width;
|
||
end;
|
||
|
||
procedure TForm1.waterfall_free;
|
||
begin
|
||
bm[1].Free;
|
||
bm[2].Free;
|
||
bm1.Free;
|
||
bm2.Free;
|
||
bm3.Free;
|
||
end;
|
||
|
||
procedure TForm1.StartAGW;
|
||
begin
|
||
try
|
||
ServerSocket1.Port = AGWPort;
|
||
ServerSocket1.Active = AGWServ;
|
||
except
|
||
ServerSocket1.Active = FALSE;
|
||
MessageDlg("AGW host port is busy!", mtWarning,[mbOk],0);
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.StartKISS;
|
||
begin
|
||
try
|
||
ServerSocket2.Port = KISSPort;
|
||
ServerSocket2.Active = KISSServ;
|
||
except
|
||
ServerSocket2.Active = FALSE;
|
||
MessageDlg("KISS port is busy!", mtWarning,[mbOk],0);
|
||
end;
|
||
end;
|
||
|
||
procedure fft_window_init;
|
||
var
|
||
mag single;
|
||
i word;
|
||
begin
|
||
mag = 2*pi/(FFTSize-1);
|
||
for i = 0 to FFTSize-1 do fft_window_arr[i] = 0.5-0.5*cos(i*mag); //hann
|
||
end;
|
||
|
||
procedure TForm1.FormCreate(Sender TObject);
|
||
begin
|
||
if hPrevInst <> 0 then begin
|
||
MessageDlg("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!", mtError, [mbOk], 0);
|
||
Application.Terminate;
|
||
end;
|
||
RS = TReedSolomon.Create(Self);
|
||
MainThreadHandle = GetCurrentThread;
|
||
form1.Caption = MODEM_CAPTION+" - Ver "+MODEM_VERSION;
|
||
cur_dir = ExtractFilePath(Application.ExeName);
|
||
fft_window_init;
|
||
detector_init;
|
||
kiss_init;
|
||
agw_init;
|
||
ax25_init;
|
||
init_raduga;
|
||
waterfall_init;
|
||
ReadIni;
|
||
show_combobox;
|
||
show_grid_title;
|
||
show_mode_panels;
|
||
show_panels;
|
||
wf_pointer(1);
|
||
wf_pointer(2);
|
||
wf_Scale;
|
||
ChangePriority;
|
||
Visible = TRUE;
|
||
StartAGW;
|
||
StartKISS;
|
||
PTTOpen;
|
||
startrx;
|
||
TimerEvent = TIMER_EVENT_OFF;
|
||
if (debugmode and DEBUG_TIMER) = 0 then create_timer1;
|
||
if MinOnStart then WindowState = wsMinimized;
|
||
end;
|
||
|
||
procedure TForm1.TrackBar1Change(Sender TObject);
|
||
begin
|
||
dcd_threshold = TrackBar1.position;
|
||
end;
|
||
*/
|
||
|
||
void Timer_Event2()
|
||
{
|
||
if (TimerStat2 == TIMER_BUSY || TimerStat2 == TIMER_OFF)
|
||
return;
|
||
|
||
TimerStat2 = TIMER_BUSY;
|
||
|
||
// show_grid();
|
||
|
||
/*
|
||
|
||
if (mod_icon_status = MOD_WAIT) then inc(icon_timer);
|
||
if icon_timer = 10 then mod_icon_status = MOD_IDLE;
|
||
if (mod_icon_status<>MOD_WAIT) and (mod_icon_status<>last_mod_icon_status) then
|
||
begin
|
||
icon_timer = 0;
|
||
case mod_icon_status of
|
||
MOD_IDLE form1.CoolTrayIcon1.IconIndex = 0;
|
||
MOD_RX begin form1.CoolTrayIcon1.IconIndex = 1; mod_icon_status = MOD_WAIT; end;
|
||
MOD_TX form1.CoolTrayIcon1.IconIndex = 2;
|
||
end;
|
||
last_mod_icon_status = mod_icon_status;
|
||
end;
|
||
//*/
|
||
|
||
TimerStat2 = TIMER_FREE;
|
||
}
|
||
|
||
/*
|
||
|
||
procedure TimeProc1(uTimerId, uMesssage UINT; dwUser, dw1, dw2 DWORD); stdcall;
|
||
begin
|
||
TimerEvent = TIMER_EVENT_ON;
|
||
end;
|
||
|
||
procedure TForm1.create_timer1;
|
||
var
|
||
TimeEpk cardinal;
|
||
begin
|
||
TimeEpk = 100;
|
||
TimerId1 = TimeSetEvent(TimeEpk,0,@TimeProc1,0,TIME_PERIODIC);
|
||
end;
|
||
|
||
procedure TForm1.free_timer1;
|
||
begin
|
||
TimerStat1 = TIMER_OFF;
|
||
timeKillEvent(TimerId1);
|
||
end;
|
||
|
||
*/
|
||
|
||
/*
|
||
|
||
|
||
procedure TForm1.PaintBox1MouseMove(Sender TObject; Shift TShiftState; X,
|
||
Y Integer);
|
||
var
|
||
low,high word;
|
||
begin
|
||
if CheckBox1.Checked then exit;
|
||
if not mouse_down[1] then Exit;
|
||
rx_freq[1] = round(x*RX_SampleRate/FFTSize);
|
||
low = round(rx_shift[1]/2+Rcvr[1]*rcvr_offset[1]+1);
|
||
high = round(rx_samplerate/2-(rx_shift[1]/2+Rcvr[1]*rcvr_offset[1]));
|
||
if (rx_freq[1]-low)<0 then rx_freq[1] = low;
|
||
if (high-rx_freq[1])<0 then rx_freq[1] = high;
|
||
tx_freq[1] = rx_freq[1];
|
||
show_freq_a;
|
||
end;
|
||
|
||
procedure TForm1.PaintBox3MouseMove(Sender TObject; Shift TShiftState; X,
|
||
Y Integer);
|
||
var
|
||
low,high word;
|
||
begin
|
||
if CheckBox1.Checked then exit;
|
||
if not mouse_down[2] then Exit;
|
||
rx_freq[2] = round(x*RX_SampleRate/FFTSize);
|
||
low = round(rx_shift[2]/2+Rcvr[2]*rcvr_offset[2]+1);
|
||
high = round(rx_samplerate/2-(rx_shift[2]/2+Rcvr[2]*rcvr_offset[2]));
|
||
if (rx_freq[2]-low)<0 then rx_freq[2] = low;
|
||
if (high-rx_freq[2])<0 then rx_freq[2] = high;
|
||
tx_freq[2] = rx_freq[2];
|
||
show_freq_b;
|
||
end;
|
||
|
||
procedure TForm1.PaintBox1MouseUp(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
begin
|
||
mouse_down[1] = FALSE;
|
||
end;
|
||
|
||
procedure TForm1.PaintBox3MouseUp(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
begin
|
||
mouse_down[2] = FALSE;
|
||
end;
|
||
|
||
procedure TForm1.PaintBox1MouseDown(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
var
|
||
low,high word;
|
||
begin
|
||
if CheckBox1.Checked then exit;
|
||
if not (ssLeft in shift) then Exit;
|
||
mouse_down[1] = TRUE;
|
||
rx_freq[1] = round(x*RX_SampleRate/FFTSize);
|
||
low = round(rx_shift[1]/2+Rcvr[1]*rcvr_offset[1]+1);
|
||
high = round(rx_samplerate/2-(rx_shift[1]/2+Rcvr[1]*rcvr_offset[1]));
|
||
if (rx_freq[1]-low)<0 then rx_freq[1] = low;
|
||
if (high-rx_freq[1])<0 then rx_freq[1] = high;
|
||
tx_freq[1] = rx_freq[1];
|
||
show_freq_a;
|
||
end;
|
||
|
||
procedure TForm1.PaintBox3MouseDown(Sender TObject; Button TMouseButton;
|
||
Shift TShiftState; X, Y Integer);
|
||
var
|
||
low,high word;
|
||
begin
|
||
if CheckBox1.Checked then exit;
|
||
if not (ssLeft in shift) then Exit;
|
||
mouse_down[2] = TRUE;
|
||
rx_freq[2] = round(x*RX_SampleRate/FFTSize);
|
||
low = round(rx_shift[2]/2+Rcvr[2]*rcvr_offset[2]+1);
|
||
high = round(rx_samplerate/2-(rx_shift[2]/2+Rcvr[2]*rcvr_offset[2]));
|
||
if (rx_freq[2]-low)<0 then rx_freq[2] = low;
|
||
if (high-rx_freq[2])<0 then rx_freq[2] = high;
|
||
tx_freq[2] = rx_freq[2];
|
||
show_freq_b;
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket1ClientRead(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
var
|
||
s string;
|
||
begin
|
||
s = Socket.ReceiveText;
|
||
AGW_explode_frame(Socket.sockethandle,s);
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket1ClientDisconnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
begin
|
||
del_incoming_mycalls_by_sock(socket.SocketHandle);
|
||
AGW_del_socket(socket.SocketHandle);
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket1ClientError(Sender TObject;
|
||
Socket TCustomWinSocket; ErrorEvent TErrorEvent;
|
||
var ErrorCode Integer);
|
||
begin
|
||
del_incoming_mycalls_by_sock(socket.SocketHandle);
|
||
AGW_del_socket(socket.SocketHandle);
|
||
ErrorCode = 0;
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket1ClientConnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
begin
|
||
agw_add_socket(Socket.sockethandle);
|
||
end;
|
||
|
||
procedure TForm1.OutputVolume1Click(Sender TObject);
|
||
var
|
||
s string;
|
||
begin
|
||
s = "SndVol32.exe -D"+inttostr(SND_TX_DEVICE);
|
||
WinExec(pchar(s),SW_SHOWNORMAL);
|
||
end;
|
||
|
||
procedure TForm1.InputVolume1Click(Sender TObject);
|
||
var
|
||
s string;
|
||
begin
|
||
s = "SndVol32.exe -R -D"+inttostr(SND_RX_DEVICE);
|
||
WinExec(pchar(s),SW_SHOWNORMAL);
|
||
end;
|
||
|
||
procedure TForm1.CoolTrayIcon1Click(Sender TObject);
|
||
begin
|
||
CoolTrayIcon1.ShowMainForm;
|
||
end;
|
||
|
||
procedure TForm1.CoolTrayIcon1Cycle(Sender TObject; NextIndex Integer);
|
||
begin
|
||
CoolTrayIcon1.IconIndex = 2;
|
||
CoolTrayIcon1.CycleIcons = FALSE;
|
||
end;
|
||
|
||
procedure TForm1.ABout1Click(Sender TObject);
|
||
begin
|
||
Form2.ShowModal;
|
||
end;
|
||
|
||
procedure TForm1.put_frame(snd_ch byte; frame,code string; tx_stat,excluded boolean);
|
||
var
|
||
s string;
|
||
begin
|
||
if RxRichedit1.Focused then Windows.SetFocus(0);
|
||
if code = "NON-AX25" then
|
||
s = inttostr(snd_ch)+" <NON-AX25 frame Len = "+inttostr(length(frame)-2)+"> ["+FormatDateTime("hhmmss",now)+"R]"
|
||
else
|
||
s = inttostr(snd_ch)+""+frame_monitor(frame,code,tx_stat);
|
||
//RxRichedit1.Lines.BeginUpdate;
|
||
RxRichedit1.SelStart = length(RxRichedit1.text);
|
||
RxRichEdit1.SelLength = length(s);
|
||
case tx_stat of
|
||
TRUE RxRichEdit1.SelAttributes.Color = clMaroon;
|
||
FALSE RxRichEdit1.SelAttributes.Color = clBlack;
|
||
end;
|
||
if excluded then RxRichEdit1.SelAttributes.Color = clGreen;
|
||
RxRichedit1.SelText = s+#10;
|
||
if RxRichedit1.Lines.Count>nr_monitor_lines then
|
||
repeat
|
||
RxRichedit1.Lines.Delete(0);
|
||
until RxRichedit1.Lines.Count = nr_monitor_lines;
|
||
RxRichedit1.HideSelection = FALSE;
|
||
RxRichedit1.SelStart = length(RxRichedit1.text);
|
||
RxRichedit1.SelLength = 0;
|
||
RxRichedit1.HideSelection = TRUE;
|
||
//RxRichedit1.Lines.EndUpdate;
|
||
end;
|
||
|
||
procedure TForm1.show_mode_panels;
|
||
begin
|
||
panel8.Align = alNone;
|
||
panel6.Align = alNone;
|
||
if dualchan then panel6.Visible = TRUE else panel6.Visible = FALSE;
|
||
panel8.Align = alLeft;
|
||
panel6.Align = alLeft;
|
||
end;
|
||
|
||
procedure TForm1.show_panels;
|
||
var
|
||
i byte;
|
||
begin
|
||
panel1.Align = alNone;
|
||
panel2.Align = alNone;
|
||
panel3.Align = alNone;
|
||
panel4.Align = alNone;
|
||
panel5.Align = alNone;
|
||
for i = 1 to 5 do
|
||
case i of
|
||
1 panel1.Visible = panels[i];
|
||
2 panel5.Visible = panels[i];
|
||
3 panel3.Visible = panels[i];
|
||
4 panel4.Visible = panels[i];
|
||
5 panel2.Visible = panels[i];
|
||
end;
|
||
panel1.Align = alBottom;
|
||
panel5.Align = alBottom;
|
||
panel3.Align = alBottom;
|
||
panel2.Align = alTop;
|
||
panel4.Align = alClient;
|
||
end;
|
||
|
||
procedure TForm1.Secondwaterfall1Click(Sender TObject);
|
||
begin
|
||
case Secondwaterfall1.Checked of
|
||
TRUE Secondwaterfall1.Checked = FALSE;
|
||
FALSE Secondwaterfall1.Checked = TRUE;
|
||
end;
|
||
panels[1] = Secondwaterfall1.Checked;
|
||
show_panels;
|
||
end;
|
||
|
||
|
||
|
||
procedure TForm1.Firstwaterfall1Click(Sender TObject);
|
||
begin
|
||
case Firstwaterfall1.Checked of
|
||
TRUE Firstwaterfall1.Checked = FALSE;
|
||
FALSE Firstwaterfall1.Checked = TRUE;
|
||
end;
|
||
panels[2] = Firstwaterfall1.Checked;
|
||
show_panels;
|
||
end;
|
||
|
||
procedure TForm1.Statustable1Click(Sender TObject);
|
||
begin
|
||
case Statustable1.Checked of
|
||
TRUE Statustable1.Checked = FALSE;
|
||
FALSE Statustable1.Checked = TRUE;
|
||
end;
|
||
panels[3] = Statustable1.Checked;
|
||
show_panels;
|
||
end;
|
||
|
||
procedure TForm1.Monitor1Click(Sender TObject);
|
||
begin
|
||
case Monitor1.Checked of
|
||
TRUE Monitor1.Checked = FALSE;
|
||
FALSE Monitor1.Checked = TRUE;
|
||
end;
|
||
panels[4] = Monitor1.Checked;
|
||
show_panels;
|
||
end;
|
||
|
||
procedure TForm1.Devices1Click(Sender TObject);
|
||
begin
|
||
if (ptt = "EXT") or (ptt = "CAT") then Form3.Button3.Enabled = TRUE else Form3.Button3.Enabled = FALSE;
|
||
Form3.GetDeviceInfo;
|
||
form3.ShowModal;
|
||
end;
|
||
|
||
procedure TForm1.FormPaint(Sender TObject);
|
||
begin
|
||
RxRichedit1.HideSelection = FALSE;
|
||
RxRichedit1.SelStart = length(RxRichedit1.text);
|
||
RxRichedit1.SelLength = 0;
|
||
RxRichedit1.HideSelection = TRUE;
|
||
end;
|
||
|
||
procedure TForm1.Filters1Click(Sender TObject);
|
||
begin
|
||
Form5.Show_modem_settings;
|
||
end;
|
||
|
||
procedure TForm1.Clearmonitor1Click(Sender TObject);
|
||
begin
|
||
RxRichEdit1.Clear;
|
||
frame_count = 0;
|
||
single_frame_count = 0;
|
||
end;
|
||
|
||
procedure TForm1.Copytext1Click(Sender TObject);
|
||
begin
|
||
RxRichEdit1.CopyToClipboard;
|
||
end;
|
||
|
||
procedure TForm1.ApplicationEvents1Minimize(Sender TObject);
|
||
begin
|
||
if stop_wf then w_state = WIN_MINIMIZED;
|
||
end;
|
||
|
||
procedure TForm1.ApplicationEvents1Restore(Sender TObject);
|
||
begin
|
||
w_state = WIN_MAXIMIZED;
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket2ClientConnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
begin
|
||
KISS_add_stream(socket.sockethandle);
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket2ClientDisconnect(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
begin
|
||
KISS_del_stream(socket.sockethandle);
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket2ClientError(Sender TObject;
|
||
Socket TCustomWinSocket; ErrorEvent TErrorEvent;
|
||
var ErrorCode Integer);
|
||
begin
|
||
KISS_del_stream(socket.sockethandle);
|
||
ErrorCode = 0;
|
||
end;
|
||
|
||
procedure TForm1.ServerSocket2ClientRead(Sender TObject;
|
||
Socket TCustomWinSocket);
|
||
var
|
||
data string;
|
||
begin
|
||
data = socket.ReceiveText;
|
||
KISS_on_data_in(socket.sockethandle,data);
|
||
end;
|
||
|
||
procedure TForm1.Font1Click(Sender TObject);
|
||
begin
|
||
FontDialog1.Font = RXRichEdit1.Font;
|
||
if FontDialog1.Execute then
|
||
begin
|
||
RXRichEdit1.SelStart = 0;
|
||
RXRichEdit1.SelLength = Length(RXRichEdit1.Text);
|
||
RXRichEdit1.SelAttributes.Size = FontDialog1.Font.Size;
|
||
RXRichEdit1.SelAttributes.Name = FontDialog1.Font.Name;
|
||
RXRichEdit1.Font.Size = FontDialog1.Font.Size;
|
||
RXRichEdit1.Font.Name = FontDialog1.Font.Name;
|
||
WriteIni;
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.Calibration1Click(Sender TObject);
|
||
begin
|
||
Form6.ShowModal;
|
||
end;
|
||
|
||
procedure TForm1.ComboBox1Change(Sender TObject);
|
||
begin
|
||
Speed[1] = get_idx_by_name(ComboBox1.Text);
|
||
init_speed(1);
|
||
windows.setfocus(0);
|
||
end;
|
||
|
||
procedure TForm1.ComboBox1KeyDown(Sender TObject; var Key Word;
|
||
Shift TShiftState);
|
||
begin
|
||
key = 0;
|
||
windows.SetFocus(0);
|
||
end;
|
||
|
||
procedure TForm1.ComboBox1KeyPress(Sender TObject; var Key Char);
|
||
begin
|
||
key = #0;
|
||
windows.SetFocus(0);
|
||
end;
|
||
|
||
procedure TForm1.ComboBox2Change(Sender TObject);
|
||
begin
|
||
Speed[2] = get_idx_by_name(ComboBox2.Text);
|
||
init_speed(2);
|
||
windows.setfocus(0);
|
||
end;
|
||
|
||
procedure TForm1.FormDestroy(Sender TObject);
|
||
var
|
||
snd_ch byte;
|
||
begin
|
||
stoprx;
|
||
for snd_ch = 1 to 2 do if snd_status[snd_ch] = SND_TX then stoptx(snd_ch);
|
||
if (debugmode and DEBUG_TIMER) = 0 then free_timer1;
|
||
TimerStat2 = TIMER_OFF;
|
||
PTTClose;
|
||
ax25_free;
|
||
agw_free;
|
||
kiss_free;
|
||
detector_free;
|
||
RS.Free;
|
||
waterfall_free;
|
||
WriteIni;
|
||
end;
|
||
|
||
end.
|
||
*/ |