9
9
using System . Text ;
10
10
using System . Threading ;
11
11
using System . Threading . Tasks ;
12
+ using System . Windows . Data ;
13
+ using System . Windows . Input ;
12
14
13
- namespace fakehermes
15
+ namespace patroclus
14
16
{
15
17
public class FakeHermes : BindableBase
16
18
{
17
19
private UdpClient client ;
20
+ private Thread handleCommsThread ;
21
+
18
22
public int port { get ; set ; } //Port for the Client to use
19
23
20
- System . Windows . Threading . DispatcherTimer timer = new System . Windows . Threading . DispatcherTimer ( ) ;
21
24
ConcurrentQueue < receivedPacket > msgQueue = new ConcurrentQueue < receivedPacket > ( ) ;
22
25
23
26
IPEndPoint ClientIpEndPoint ;
@@ -36,6 +39,18 @@ public class FakeHermes : BindableBase
36
39
37
40
private static int [ ] bandwidths = { 48000 , 96000 , 192000 , 384000 } ;
38
41
42
+ public FakeHermes ( )
43
+ {
44
+ BindingOperations . CollectionRegistering += BindingOperations_CollectionRegistering ;
45
+
46
+ }
47
+
48
+ void BindingOperations_CollectionRegistering ( object sender , CollectionRegisteringEventArgs e )
49
+ {
50
+ BindingOperations . EnableCollectionSynchronization ( receivers , _receiversLock ) ;
51
+ }
52
+ private object _receiversLock = new object ( ) ;
53
+
39
54
private ObservableCollection < receiver > _receivers = new ObservableCollection < receiver > ( ) ;
40
55
public ObservableCollection < receiver > receivers
41
56
{
@@ -99,71 +114,73 @@ public void start()
99
114
client . Client . IOControl ( SIO_UDP_CONNRESET , inValue , outValue ) ;
100
115
101
116
client . BeginReceive ( new AsyncCallback ( incomming ) , null ) ;
102
-
103
- timer . Interval = TimeSpan . FromMilliseconds ( 10 ) ;
104
- timer . Tick += new EventHandler ( timer_Tick ) ;
105
- timer . Start ( ) ;
117
+
118
+ handleCommsThread = new Thread ( handleComms ) ;
119
+ handleCommsThread . IsBackground = true ;
120
+ handleCommsThread . Start ( ) ;
106
121
107
122
}
108
123
109
124
long actualPacketCount = 0 ;
110
- void timer_Tick ( object sender , EventArgs e )
125
+ void handleComms ( )
111
126
{
112
- //deal with any udp packets in main thread
113
- while ( ! msgQueue . IsEmpty )
114
- {
115
- receivedPacket packet ;
116
- if ( msgQueue . TryDequeue ( out packet ) ) handlePacket ( packet ) ;
117
- }
118
- //send any output
119
- if ( running )
127
+ while ( true )
120
128
{
121
- adc1clip = false ;
122
- int channels = receivers . Count ( ) ;
123
- int stride = channels * 6 + 2 ;
124
- int nSamples = ( 512 - 8 ) / stride ;
125
- double timeStep = 1.0 / bandwidth ;
126
-
129
+ while ( ! msgQueue . IsEmpty )
130
+ {
131
+ receivedPacket packet ;
132
+ if ( msgQueue . TryDequeue ( out packet ) ) handlePacket ( packet ) ;
133
+ }
134
+ //send any output
135
+ if ( running )
136
+ {
137
+ adc1clip = false ;
138
+ int channels = receivers . Count ( ) ;
139
+ int stride = channels * 6 + 2 ;
140
+ int nSamples = ( 512 - 8 ) / stride ;
141
+ double timeStep = 1.0 / bandwidth ;
127
142
128
- //calculate number of packets to maintain sync
129
- DateTime now = DateTime . Now ;
130
- long totalTime = ( long ) ( now - startTime ) . TotalMilliseconds ;
131
- long nPacketsCalculated = bandwidth / ( nSamples * 2 ) * totalTime / 1000 ;
132
143
133
- long packetsToSend = nPacketsCalculated - actualPacketCount ;
144
+ //calculate number of packets to maintain sync
145
+ DateTime now = DateTime . Now ;
146
+ long totalTime = ( long ) ( now - startTime ) . TotalMilliseconds ;
147
+ long nPacketsCalculated = bandwidth / ( nSamples * 2 ) * totalTime / 1000 ;
134
148
135
- databuf [ 0 ] = 0xef ;
136
- databuf [ 1 ] = 0xfe ;
137
- databuf [ 2 ] = 0x01 ;
149
+ long packetsToSend = nPacketsCalculated - actualPacketCount ;
138
150
139
- databuf [ 3 ] = 0x06 ;
151
+ databuf [ 0 ] = 0xef ;
152
+ databuf [ 1 ] = 0xfe ;
153
+ databuf [ 2 ] = 0x01 ;
140
154
141
- for ( int i = 0 ; i < packetsToSend ; i ++ )
142
- {
143
- databuf [ 4 ] = ( byte ) ( seqNo >> 24 ) ;
144
- databuf [ 5 ] = ( byte ) ( ( seqNo >> 16 ) & 0xff ) ;
145
- databuf [ 6 ] = ( byte ) ( ( seqNo >> 8 ) & 0xff ) ;
146
- databuf [ 7 ] = ( byte ) ( seqNo & 0xff ) ;
155
+ databuf [ 3 ] = 0x06 ;
147
156
148
- int bufStart = 8 ;
149
- for ( int block = 0 ; block < 2 ; block ++ )
157
+ for ( int i = 0 ; i < packetsToSend ; i ++ )
150
158
{
151
- for ( int c = 0 ; c < channels ; c ++ )
159
+ databuf [ 4 ] = ( byte ) ( seqNo >> 24 ) ;
160
+ databuf [ 5 ] = ( byte ) ( ( seqNo >> 16 ) & 0xff ) ;
161
+ databuf [ 6 ] = ( byte ) ( ( seqNo >> 8 ) & 0xff ) ;
162
+ databuf [ 7 ] = ( byte ) ( seqNo & 0xff ) ;
163
+
164
+ int bufStart = 8 ;
165
+ for ( int block = 0 ; block < 2 ; block ++ )
152
166
{
153
- GenerateSignal ( databuf , bufStart + 8 + c * 6 , stride , nSamples , timebase , timeStep , receivers [ c ] ) ;
167
+ for ( int c = 0 ; c < channels ; c ++ )
168
+ {
169
+ GenerateSignal ( databuf , bufStart + 8 + c * 6 , stride , nSamples , timebase , timeStep , receivers [ c ] ) ;
170
+ }
171
+ GenerateComandControl ( databuf , bufStart , 0 ) ;
172
+ timebase += nSamples * timeStep ;
173
+ bufStart += 512 ;
154
174
}
155
- GenerateComandControl ( databuf , bufStart , 0 ) ;
156
- timebase += nSamples * timeStep ;
157
- bufStart += 512 ;
175
+
176
+ client . Send ( databuf , databuf . Length , ClientIpEndPoint ) ;
177
+ seqNo ++ ;
178
+ actualPacketCount ++ ;
179
+ packetsSent ++ ;
158
180
}
159
-
160
- client . Send ( databuf , databuf . Length , ClientIpEndPoint ) ;
161
- seqNo ++ ;
162
- actualPacketCount ++ ;
163
- packetsSent ++ ;
164
181
}
182
+ Thread . Sleep ( 5 ) ;
165
183
}
166
-
167
184
}
168
185
void GenerateComandControl ( byte [ ] databuf , int startOffset , int seq )
169
186
{
@@ -181,33 +198,29 @@ void GenerateComandControl(byte[] databuf, int startOffset, int seq)
181
198
}
182
199
void GenerateSignal ( byte [ ] outputbuf , int startOffset , int stride , int nSamples , double timebase , double timestep , receiver rx )
183
200
{
184
- //todo handle multiple generators automatically
185
-
186
- int f1 = rx . vfo - rx . generators [ 0 ] . frequency ;
187
- int f2 = rx . vfo - rx . generators [ 1 ] . frequency ;
201
+ double [ ] mixbuf = new double [ nSamples * 2 ] ; //auto cleared to 0
202
+ // combine all signal generatiors
203
+ rx . GenerateSignal ( mixbuf , nSamples , timebase , timestep ) ;
204
+ //convert to formatted 24 bit
205
+ int idx = 0 ;
188
206
for ( int i = 0 ; i < nSamples * stride ; i += stride )
189
207
{
190
- double angle1 = f1 * 2 * Math . PI * timebase ;
191
- double angle2 = f2 * 2 * Math . PI * timebase ;
192
-
193
- double amp = Math . Round ( Math . Sin ( angle1 ) * rx . generators [ 0 ] . damplitude + Math . Sin ( angle2 ) * rx . generators [ 1 ] . damplitude ) ;
194
- int iamp = ( int ) amp ;
195
- if ( iamp > max24int )
208
+ int iamp = ( int ) Math . Round ( mixbuf [ idx ++ ] * 0x7fffff ) ;
209
+ if ( iamp > max24int )
196
210
{
197
211
iamp = max24int ;
198
212
adc1clip = true ;
199
213
}
200
- else if ( iamp < min24int )
214
+ else if ( iamp < min24int )
201
215
{
202
216
iamp = min24int ;
203
217
adc1clip = true ;
204
218
}
205
219
databuf [ startOffset + i ] = ( byte ) ( iamp >> 16 ) ;
206
220
databuf [ startOffset + i + 1 ] = ( byte ) ( ( iamp >> 8 ) & 0xff ) ;
207
- databuf [ startOffset + i + 2 ] = ( byte ) ( ( iamp ) & 0xff ) ;
208
-
209
- amp = Math . Round ( - Math . Cos ( angle1 ) * rx . generators [ 0 ] . damplitude - Math . Cos ( angle2 ) * rx . generators [ 1 ] . damplitude ) ;
210
- iamp = ( int ) amp ;
221
+ databuf [ startOffset + i + 2 ] = ( byte ) ( ( iamp ) & 0xff ) ;
222
+
223
+ iamp = ( int ) Math . Round ( mixbuf [ idx ++ ] * 0x7fffff ) ;
211
224
212
225
if ( iamp > max24int )
213
226
{
@@ -219,14 +232,13 @@ void GenerateSignal(byte[] outputbuf, int startOffset, int stride, int nSamples,
219
232
iamp = min24int ;
220
233
adc1clip = true ;
221
234
}
222
-
235
+
223
236
databuf [ startOffset + i + 3 ] = ( byte ) ( iamp >> 16 ) ;
224
237
databuf [ startOffset + i + 4 ] = ( byte ) ( ( iamp >> 8 ) & 0xff ) ;
225
238
databuf [ startOffset + i + 5 ] = ( byte ) ( iamp & 0xff ) ;
226
-
227
- timebase += timestep ;
228
-
229
239
}
240
+ timebase += nSamples * timestep ;
241
+
230
242
}
231
243
private void incomming ( IAsyncResult res )
232
244
{
@@ -332,8 +344,15 @@ public void handleCommandControl(byte c0,byte c1, byte c2, byte c3, byte c4)
332
344
int nReceivers = ( ( c4 >> 3 ) & 0x07 ) + 1 ;
333
345
if ( nReceivers != receivers . Count )
334
346
{
335
- while ( receivers . Count > nReceivers ) receivers . Remove ( receivers . Last ( ) ) ;
336
- while ( receivers . Count < nReceivers ) receivers . Add ( new receiver ( "RX" + ( receivers . Count + 1 ) ) ) ;
347
+ lock ( _receiversLock )
348
+ {
349
+ while ( receivers . Count > nReceivers ) receivers . Remove ( receivers . Last ( ) ) ;
350
+ while ( receivers . Count < nReceivers ) receivers . Add ( new receiver ( "RX" + ( receivers . Count + 1 ) ) ) ;
351
+ }
352
+ // while (receivers.Count > nReceivers) receivers.DoOperation(currentItems => currentItems.Remove(currentItems.Last()));
353
+ // while (receivers.Count < nReceivers) receivers.DoOperation(currentItems => currentItems.Add(new receiver("RX" + (currentItems.Count + 1))));
354
+
355
+
337
356
resetTransmission ( ) ;
338
357
}
339
358
break ;
@@ -342,8 +361,8 @@ public void handleCommandControl(byte c0,byte c1, byte c2, byte c3, byte c4)
342
361
if ( ! duplex )
343
362
{
344
363
receivers [ 0 ] . vfo = txNCO ;
345
- if ( receivers [ 0 ] . generators [ 0 ] . frequency == 0 ) receivers [ 0 ] . generators [ 0 ] . frequency = receivers [ 0 ] . vfo ;
346
- if ( receivers [ 0 ] . generators [ 1 ] . frequency == 0 ) receivers [ 0 ] . generators [ 1 ] . frequency = receivers [ 0 ] . vfo + 10000 ;
364
+ receivers [ 0 ] . generators [ 0 ] . SetDefaults ( receivers [ 0 ] . vfo ) ;
365
+ receivers [ 0 ] . generators [ 1 ] . SetDefaults ( receivers [ 0 ] . vfo + 10000 ) ;
347
366
348
367
}
349
368
break ;
@@ -357,8 +376,8 @@ public void handleCommandControl(byte c0,byte c1, byte c2, byte c3, byte c4)
357
376
if ( receivers != null && receivers . Count > rxIdx )
358
377
{
359
378
receivers [ rxIdx ] . vfo = ( ( ( int ) c1 ) << 24 ) + ( ( ( int ) c2 ) << 16 ) + ( ( ( int ) c3 ) << 8 ) + ( int ) c4 ;
360
- if ( receivers [ rxIdx ] . generators [ 0 ] . frequency == 0 ) receivers [ rxIdx ] . generators [ 0 ] . frequency = receivers [ rxIdx ] . vfo ;
361
- if ( receivers [ rxIdx ] . generators [ 1 ] . frequency == 0 ) receivers [ rxIdx ] . generators [ 1 ] . frequency = receivers [ rxIdx ] . vfo + 10000 ;
379
+ receivers [ 0 ] . generators [ 0 ] . SetDefaults ( receivers [ 0 ] . vfo ) ;
380
+ receivers [ 0 ] . generators [ 1 ] . SetDefaults ( receivers [ 0 ] . vfo + 10000 ) ;
362
381
}
363
382
break ;
364
383
// default: Console.WriteLine(string.Format("Unhandled Control message {0}\t{1}\t{2}\t{3}\t{4}", c0, c1, c2, c3, c4)); break;
@@ -367,58 +386,8 @@ public void handleCommandControl(byte c0,byte c1, byte c2, byte c3, byte c4)
367
386
}
368
387
369
388
}
370
- public class receiver : BindableBase
371
- {
372
- public receiver ( string name )
373
- {
374
- this . name = name ;
375
- generators . Add ( new sineWave ( ) ) ;
376
- generators . Add ( new sineWave ( ) ) ;
377
- }
378
- private int _vfo ;
379
- public int vfo
380
- {
381
- get { return _vfo ; }
382
- set { SetProperty ( ref _vfo , value ) ; }
383
- }
384
- private string _name ;
385
- public string name
386
- {
387
- get { return _name ; }
388
- set { SetProperty ( ref _name , value ) ; }
389
- }
390
- ObservableCollection < sineWave > _generators = new ObservableCollection < sineWave > ( ) ;
391
- public ObservableCollection < sineWave > generators
392
- {
393
- get { return _generators ; }
394
- set { SetProperty ( ref _generators , value ) ; }
395
- }
396
- }
397
- public class sineWave : BindableBase
398
- {
399
- public sineWave ( )
400
- {
401
- amplitude = - 10 ;
402
- }
403
- private int _frequency = 0 ;
404
- public double damplitude = 0.0 ;
405
- public int frequency
406
- {
407
- get { return _frequency ; }
408
- set { SetProperty ( ref _frequency , value ) ; }
409
- }
410
- private int _amplitude = 0 ;
411
- public int amplitude
412
- {
413
- get { return _amplitude ; }
414
- set
415
- {
416
- damplitude = 0x7fffff / Math . Pow ( Math . Sqrt ( 10 ) , - ( double ) value / 10 ) ;
417
- SetProperty ( ref _amplitude , value ) ;
418
- }
419
- }
420
-
421
- }
389
+
390
+
422
391
public class receivedPacket
423
392
{
424
393
public IPEndPoint endPoint { get ; set ; }
0 commit comments