forked from VE3NEA/MorseRunner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DxStn.pas
161 lines (124 loc) · 3.84 KB
/
DxStn.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//------------------------------------------------------------------------------
//This Source Code Form is subject to the terms of the Mozilla Public
//License, v. 2.0. If a copy of the MPL was not distributed with this
//file, You can obtain one at http://mozilla.org/MPL/2.0/.
//------------------------------------------------------------------------------
unit DxStn;
interface
uses
SysUtils, Classes, Station, RndFunc, Ini, CallLst, Qsb, DxOper, Log, SndTypes;
type
TDxStation = class(TStation)
private
Qsb: TQsb;
public
Oper: TDxOperator;
constructor CreateStation;
destructor Destroy; override;
procedure ProcessEvent(AEvent: TStationEvent); override;
procedure DataToLastQso;
function GetBlock: TSingleArray; override;
end;
implementation
uses
Contest;
{ TDxStation }
constructor TDxStation.CreateStation;
begin
inherited Create(nil);
HisCall := Ini.Call;
MyCall := PickCall;
Oper := TDxOperator.Create;
Oper.Call := MyCall;
Oper.Skills := 1 + Random(3); //1..3
Oper.SetState(osNeedPrevEnd);
NrWithError := Ini.Lids and (Random < 0.1);
Wpm := Oper.GetWpm;
NR := Oper.GetNR;
if Ini.Lids and (Random < 0.03)
then RST := 559 + 10*Random(4)
else RST := 599;
Qsb := TQsb.Create;
Qsb.Bandwidth := 0.1 + Random / 2;
if Ini.Flutter and (Random < 0.3) then Qsb.Bandwidth := 3 + Random * 30;
Amplitude := 9000 + 18000 * (1 + RndUShaped);
Pitch := Round(RndGaussLim(0, 300));
//the MeSent event will follow immediately
TimeOut := NEVER;
State := stCopying;
end;
destructor TDxStation.Destroy;
begin
Oper.Free;
Qsb.Free;
inherited;
end;
procedure TDxStation.ProcessEvent(AEvent: TStationEvent);
var
i: integer;
begin
if Oper.State = osDone then Exit;
case AEvent of
evMsgSent:
//we finished sending and started listening
if Tst.Me.State = stSending
then TimeOut := NEVER
else TimeOut := Oper.GetReplyTimeout;
evTimeout:
begin
//he did not reply, quit or try again
if State = stListening then
begin
Oper.MsgReceived([msgNone]);
if Oper.State = osFailed then begin Free; Exit; end;
State := stPreparingToSend;
end;
//preparations to send are done, now send
if State = stPreparingToSend then
for i:=1 to Oper.RepeatCnt do SendMsg(Oper.GetReply)
end;
evMeFinished: //he finished sending
//we notice the message only if we are not sending ourselves
if State <> stSending then
begin
//interpret the message
case State of
stCopying:
Oper.MsgReceived(Tst.Me.Msg);
stListening, stPreparingToSend:
//these messages can be copied even if partially received
if (msgCQ in Tst.Me.Msg) or (msgTU in Tst.Me.Msg) or (msgNil in Tst.Me.Msg)
then Oper.MsgReceived(Tst.Me.Msg)
else Oper.MsgReceived([msgGarbage]);
end;
//react to the message
if Oper.State = osFailed
then begin Free; Exit; end //give up
else TimeOut := Oper.GetSendDelay; //reply or switch to standby
State := stPreparingToSend;
end;
evMeStarted:
//If we are not sending, we can start copying
//Cancel timeout, he is replying
begin
if State <> stSending then State := stCopying;
TimeOut := NEVER;
end;
end;
end;
procedure TDxStation.DataToLastQso;
begin
with QsoList[High(QsoList)] do
begin
TrueCall := Self.MyCall;
TrueRst := Self.Rst;
TrueNR := Self.NR;
end;
Free;
end;
function TDxStation.GetBlock: TSingleArray;
begin
Result := inherited GetBlock;
if Ini.Qsb then Qsb.ApplyTo(Result);
end;
end.