Skip to content

Commit 1d57505

Browse files
committed
Update Cyton Digital networking output to send integers
1 parent 5a73373 commit 1d57505

4 files changed

Lines changed: 130 additions & 54 deletions

File tree

Networking-Test-Kit/LSL/lslStreamTest_3Streams.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,21 @@ def testLSLSamplingRates():
3535
if i == 0:
3636
chunk, timestamps = inlet.pull_chunk()
3737
if timestamps:
38+
print("Stream 1 Chunk: ", chunk)
3839
for sample in chunk:
39-
if sample:
40-
num_samples_1 += 1
41-
#print(sample)
40+
num_samples_1 += 1
4241
elif i == 1:
4342
chunk, timestamps_2 = inlet_2.pull_chunk()
4443
if timestamps_2:
44+
print("Stream 2 Chunk: ", chunk)
4545
for sample in chunk:
4646
num_samples_2 += 1
47-
#print(sample)
4847
elif i == 2:
4948
chunk, timestamps_3 = inlet_3.pull_chunk()
5049
if timestamps_3:
50+
print("Stream 3 Chunk: ", chunk)
5151
for sample in chunk:
5252
num_samples_3 += 1
53-
#print(sample)
5453
#print("Stream", i + 1, " == ", chunk)
5554
print( "Stream 1 Sampling Rate == ", num_samples_1 / duration_seconds, " | Type : EEG")
5655
print( "Stream 2 Sampling Rate == ", num_samples_2 / duration_seconds, " | Type : AUX")
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Example program to show how to read a multi-channel time series from LSL."""
2+
import time
3+
from pylsl import StreamInlet, resolve_stream
4+
from time import sleep
5+
6+
# first resolve an EEG stream on the lab network
7+
print("looking for an EEG stream...")
8+
streams = resolve_stream('type', 'EEG')
9+
10+
# create a new inlet to read from the stream
11+
inlet = StreamInlet(streams[0])
12+
duration = 10
13+
14+
sleep(1)
15+
16+
def testLSLSamplingRate():
17+
start = time.time()
18+
totalNumSamples = 0
19+
validSamples = 0
20+
numChunks = 0
21+
print( "Testing Sampling Rates..." )
22+
23+
while time.time() <= start + duration:
24+
# get chunks of samples
25+
chunk, timestamp = inlet.pull_chunk()
26+
if timestamp:
27+
print("\nNew chunk! Chunk size == {}".format(len(chunk)) )
28+
numChunks += 1
29+
totalNumSamples += len(chunk)
30+
print(chunk, timestamp)
31+
for sample in chunk:
32+
#print(sample)
33+
validSamples += 1
34+
35+
print( "Number of Chunks and Samples == {} , {}".format(numChunks, totalNumSamples) )
36+
print( "Average Number of Samples per Chunk == {}".format(totalNumSamples / numChunks) )
37+
print( "Valid Chunks and Duration == {} / {}".format(numChunks, duration) )
38+
print( "Average Sampling Rate == {}".format(numChunks / duration) )
39+
40+
41+
testLSLSamplingRate()

OpenBCI_GUI/NetworkStreamOut.pde

Lines changed: 67 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ class NetworkStreamOut extends Thread {
1414

1515
public Boolean isStreaming;
1616
private int start;
17-
private float[] dataToSend;
1817
private double[][] previousFrameData;
1918

2019
private int samplesSent = 0;
@@ -173,7 +172,6 @@ class NetworkStreamOut extends Thread {
173172

174173
private void updateNumChan() {
175174
numExgChannels = currentBoard.getNumEXGChannels();
176-
dataToSend = new float[numExgChannels * nPointsPerUpdate];
177175
// Bug #638: ArrayOutOfBoundsException was thrown if
178176
// nPointsPerUpdate was larger than 10, as start was
179177
// set to dataProcessingFilteredBuffer[0].length - 10.
@@ -194,6 +192,27 @@ class NetworkStreamOut extends Thread {
194192
return w_networking.newMarkerDataToSend.compareAndSet(true, false);
195193
}
196194

195+
if (this.dataType.equals("Accel/Aux")) {
196+
if (currentBoard instanceof AccelerometerCapableBoard) {
197+
AccelerometerCapableBoard accelBoard = (AccelerometerCapableBoard) currentBoard;
198+
if (accelBoard.isAccelerometerActive()) {
199+
return w_networking.newAccelDataToSend.compareAndSet(true, false);
200+
}
201+
}
202+
if (currentBoard instanceof AnalogCapableBoard) {
203+
AnalogCapableBoard analogBoard = (AnalogCapableBoard) currentBoard;
204+
if (analogBoard.isAnalogActive()) {
205+
return w_networking.newAnalogDataToSend.compareAndSet(true, false);
206+
}
207+
}
208+
if (currentBoard instanceof DigitalCapableBoard) {
209+
DigitalCapableBoard digitalBoard = (DigitalCapableBoard) currentBoard;
210+
if (digitalBoard.isDigitalActive()) {
211+
return w_networking.newDigitalDataToSend.compareAndSet(true, false);
212+
}
213+
}
214+
}
215+
197216
if (w_networking.networkingFrameLocks[this.streamNumber].compareAndSet(true, false)) {
198217
return true;
199218
} else {
@@ -325,15 +344,15 @@ class NetworkStreamOut extends Thread {
325344
} else if (this.protocol.equals("LSL")) {
326345
int numChannels = newDataFromBuffer.length;
327346
int numSamples = newDataFromBuffer[0].length;
328-
float[] _dataToSend = new float[numChannels * numSamples];
347+
float[] dataToSend = new float[numChannels * numSamples];
329348
for (int sample = 0; sample < numSamples; sample++) {
330349
for (int channel = 0; channel < numChannels; channel++) {
331-
_dataToSend[channel + sample * numChannels] = newDataFromBuffer[channel][sample];
350+
dataToSend[channel + sample * numChannels] = newDataFromBuffer[channel][sample];
332351
}
333352
}
334353
// From LSLLink Library: The time stamps of other samples are automatically
335354
// derived based on the sampling rate of the stream.
336-
outlet_data.push_chunk(_dataToSend);
355+
outlet_data.push_chunk(dataToSend);
337356

338357
} else if (this.protocol.equals("Serial")) {
339358

@@ -441,15 +460,15 @@ class NetworkStreamOut extends Thread {
441460
println(e.getMessage());
442461
}
443462
} else if (this.protocol.equals("LSL")) {
444-
float[] _dataToSend = new float[numExgChannels * 125];
463+
float[] dataToSend = new float[numExgChannels * 125];
445464
for (int i = 0; i < numExgChannels; i++) {
446465
for (int j = 0; j < 125; j++) {
447-
_dataToSend[j + 125 * i] = fftBuff[i].getBand(j);
466+
dataToSend[j + 125 * i] = fftBuff[i].getBand(j);
448467
}
449468
}
450469
// From LSLLink Library: The time stamps of other samples are automatically
451470
// derived based on the sampling rate of the stream.
452-
outlet_data.push_chunk(_dataToSend);
471+
outlet_data.push_chunk(dataToSend);
453472
} else if (this.protocol.equals("Serial")) {
454473
///////////////////////////////// THIS OUTPUT IS DISABLED
455474
// Send FFT Data over Serial ...
@@ -469,13 +488,13 @@ class NetworkStreamOut extends Thread {
469488
private void sendPowerBandData() {
470489
// UNFILTERED & FILTERED ... influenced globally by the FFT filters dropdown
471490
// just like the FFT data
472-
int numBandPower = 5; // DELTA, THETA, ALPHA, BETA, GAMMA
491+
final int NUM_BAND_POWERS = 5; // DELTA, THETA, ALPHA, BETA, GAMMA
473492

474493
if (this.protocol.equals("OSC")) {
475494
for (int i = 0; i < numExgChannels; i++) {
476495
msg.clearArguments();
477496
msg.setAddrPattern(baseOscAddress + "/band-power/" + i);
478-
for (int j = 0; j < numBandPower; j++) {
497+
for (int j = 0; j < NUM_BAND_POWERS; j++) {
479498
msg.add(dataProcessing.avgPowerInBins[i][j]); // [CHAN][BAND]
480499
}
481500
try {
@@ -488,9 +507,9 @@ class NetworkStreamOut extends Thread {
488507
// DELTA, THETA, ALPHA, BETA, GAMMA
489508
String outputter = "{\"type\":\"bandPower\",\"data\":[[";
490509
for (int i = 0; i < numExgChannels; i++) {
491-
for (int j = 0; j < numBandPower; j++) {
510+
for (int j = 0; j < NUM_BAND_POWERS; j++) {
492511
outputter += str(dataProcessing.avgPowerInBins[i][j]); // [CHAN][BAND]
493-
if (j != numBandPower - 1) {
512+
if (j != NUM_BAND_POWERS - 1) {
494513
outputter += ",";
495514
}
496515
}
@@ -505,23 +524,29 @@ class NetworkStreamOut extends Thread {
505524
} catch (Exception e) {
506525
println(e.getMessage());
507526
}
527+
508528
} else if (this.protocol.equals("LSL")) {
529+
509530
// DELTA, THETA, ALPHA, BETA, GAMMA
510-
float[] avgPowerLSL = new float[numExgChannels * numBandPower];
511-
for (int i = 0; i < numExgChannels; i++) {
512-
for (int j = 0; j < numBandPower; j++) {
513-
avgPowerLSL[j + numBandPower * i] = dataProcessing.avgPowerInBins[i][j];
531+
int numChannels = numExgChannels;
532+
float[] dataToSend = new float[numChannels * NUM_BAND_POWERS];
533+
for (int band = 0; band < NUM_BAND_POWERS; band++) {
534+
for (int channel = 0; channel < numChannels; channel++) {
535+
dataToSend[channel + band * numChannels] = dataProcessing.avgPowerInBins[channel][band];
514536
}
515537
}
516-
outlet_data.push_chunk(avgPowerLSL);
538+
double unixTime = System.currentTimeMillis() / 1000d;
539+
//println(unixTime);
540+
outlet_data.push_chunk(dataToSend, unixTime, true);
541+
517542
} else if (this.protocol.equals("Serial")) {
518543
for (int i = 0; i < numExgChannels; i++) {
519544
serialMessage = "[" + (i + 1) + ","; // clear message
520-
for (int j = 0; j < numBandPower; j++) {
545+
for (int j = 0; j < NUM_BAND_POWERS; j++) {
521546
float power_band = dataProcessing.avgPowerInBins[i][j];
522547
String power_band_3dec = threeDecimalPlaces.format(power_band);
523548
serialMessage += power_band_3dec;
524-
if (j < numBandPower - 1) {
549+
if (j < NUM_BAND_POWERS - 1) {
525550
serialMessage += ","; // add a comma to serialMessage to separate chan values, as long as it
526551
// isn't last value...
527552
}
@@ -541,12 +566,12 @@ class NetworkStreamOut extends Thread {
541566
// UNFILTERED & FILTERED ... influenced globally by the FFT filters dropdown ...
542567
// just like the FFT data
543568
// Band Power order: DELTA, THETA, ALPHA, BETA, GAMMA
544-
int numBandPower = 5;
569+
final int NUM_BAND_POWERS = 5;
545570

546571
if (this.protocol.equals("OSC")) {
547572

548573
msg.clearArguments();
549-
for (int i = 0; i < numBandPower; i++) {
574+
for (int i = 0; i < NUM_BAND_POWERS; i++) {
550575
msg.setAddrPattern(baseOscAddress + "/average-band-power/" + i);
551576
msg.add(w_bandPower.getNormalizedBPSelectedChannels()[i]); // [CHAN][BAND]
552577
try {
@@ -559,9 +584,9 @@ class NetworkStreamOut extends Thread {
559584
} else if (this.protocol.equals("UDP")) {
560585

561586
StringBuilder outputter = new StringBuilder("{\"type\":\"averageBandPower\",\"data\":[");
562-
for (int i = 0; i < numBandPower; i++) {
587+
for (int i = 0; i < NUM_BAND_POWERS; i++) {
563588
outputter.append(str(w_bandPower.getNormalizedBPSelectedChannels()[i]));
564-
if (i != numBandPower - 1) {
589+
if (i != NUM_BAND_POWERS - 1) {
565590
outputter.append(",");
566591
} else {
567592
outputter.append("]}\r\n");
@@ -582,11 +607,11 @@ class NetworkStreamOut extends Thread {
582607
} else if (this.protocol.equals("Serial")) {
583608

584609
serialMessage = "[";
585-
for (int i = 0; i < numBandPower; i++) {
610+
for (int i = 0; i < NUM_BAND_POWERS; i++) {
586611
float power_band = w_bandPower.getNormalizedBPSelectedChannels()[i];
587612
String power_band_3dec = threeDecimalPlaces.format(power_band);
588613
serialMessage += power_band_3dec;
589-
if (i < numBandPower - 1) {
614+
if (i < NUM_BAND_POWERS - 1) {
590615
// add a comma to serialMessage to separate chan values, as long as it isn't last value...
591616
serialMessage += ",";
592617
}
@@ -631,6 +656,7 @@ class NetworkStreamOut extends Thread {
631656
println(e.getMessage());
632657
}
633658
} else if (this.protocol.equals("LSL")) {
659+
float[] dataToSend = new float[numExgChannels];
634660
for (int i = 0; i < numExgChannels; i++) {
635661
dataToSend[i] = emgSettingsValues.getOutputNormalized(i);
636662
}
@@ -711,13 +737,13 @@ class NetworkStreamOut extends Thread {
711737

712738
int numChannels = NUM_ACCEL_DIMS;
713739
int numSamples = w_networking.accelDataBufferToSend[0].length;
714-
float[] _dataToSend = new float[numChannels * numSamples];
740+
float[] dataToSend = new float[numChannels * numSamples];
715741
for (int sample = 0; sample < numSamples; sample++) {
716742
for (int channel = 0; channel < numChannels; channel++) {
717-
_dataToSend[channel + sample * numChannels] = w_networking.accelDataBufferToSend[channel][sample];
743+
dataToSend[channel + sample * numChannels] = w_networking.accelDataBufferToSend[channel][sample];
718744
}
719745
}
720-
outlet_data.push_sample(_dataToSend);
746+
outlet_data.push_chunk(dataToSend);
721747

722748
} else if (this.protocol.equals("Serial")) {
723749

@@ -798,13 +824,13 @@ class NetworkStreamOut extends Thread {
798824

799825
int numChannels = NUM_ANALOG_READS;
800826
int numSamples = w_networking.analogDataBufferToSend[0].length;
801-
float[] _dataToSend = new float[numChannels * numSamples];
827+
float[] dataToSend = new float[numChannels * numSamples];
802828
for (int sample = 0; sample < numSamples; sample++) {
803829
for (int channel = 0; channel < numChannels; channel++) {
804-
_dataToSend[channel + sample * numChannels] = w_networking.analogDataBufferToSend[channel][sample];
830+
dataToSend[channel + sample * numChannels] = w_networking.analogDataBufferToSend[channel][sample];
805831
}
806832
}
807-
outlet_data.push_sample(_dataToSend);
833+
outlet_data.push_chunk(dataToSend);
808834

809835
} else if (this.protocol.equals("Serial")) {
810836

@@ -862,7 +888,7 @@ class NetworkStreamOut extends Thread {
862888
for (int i = 0; i < NUM_DIGITAL_READS; i++) {
863889
output.append("[");
864890
for (int j = 0; j < w_networking.digitalDataBufferToSend[i].length; j++) {
865-
double digitalData = w_networking.digitalDataBufferToSend[i][j];
891+
int digitalData = w_networking.digitalDataBufferToSend[i][j];
866892
String digitalDataFormatted = String.format("%d", digitalData);
867893
output.append(digitalDataFormatted);
868894
if (j != w_networking.digitalDataBufferToSend[i].length - 1) {
@@ -885,13 +911,13 @@ class NetworkStreamOut extends Thread {
885911

886912
int numChannels = NUM_DIGITAL_READS;
887913
int numSamples = w_networking.digitalDataBufferToSend[0].length;
888-
float[] _dataToSend = new float[numChannels * numSamples];
914+
float[] dataToSend = new float[numChannels * numSamples];
889915
for (int sample = 0; sample < numSamples; sample++) {
890916
for (int channel = 0; channel < numChannels; channel++) {
891-
_dataToSend[channel + sample * numChannels] = w_networking.digitalDataBufferToSend[channel][sample];
917+
dataToSend[channel + sample * numChannels] = w_networking.digitalDataBufferToSend[channel][sample];
892918
}
893919
}
894-
outlet_data.push_sample(_dataToSend);
920+
outlet_data.push_chunk(dataToSend);
895921

896922
} else if (this.protocol.equals("Serial")) {
897923

@@ -900,7 +926,7 @@ class NetworkStreamOut extends Thread {
900926
for (int i = 0; i < NUM_DIGITAL_READS; i++) {
901927
serialMessage.append("[");
902928
for (int j = 0; j < w_networking.digitalDataBufferToSend[i].length; j++) {
903-
double digitalData = w_networking.digitalDataBufferToSend[i][j];
929+
int digitalData = w_networking.digitalDataBufferToSend[i][j];
904930
String digitalDataFormatted = String.format("%d", digitalData);
905931
serialMessage.append(digitalDataFormatted);
906932
if (j != w_networking.digitalDataBufferToSend[i].length - 1) {
@@ -961,12 +987,12 @@ class NetworkStreamOut extends Thread {
961987

962988
} else if (this.protocol.equals("LSL")) {
963989

964-
float[] _dataToSend = new float[2];
965-
_dataToSend[0] = w_pulsesensor.getBPM();
966-
_dataToSend[1] = w_pulsesensor.getIBI();
990+
float[] dataToSend = new float[2];
991+
dataToSend[0] = w_pulsesensor.getBPM();
992+
dataToSend[1] = w_pulsesensor.getIBI();
967993
// From LSLLink Library: The time stamps of other samples are automatically
968994
// derived based on the sampling rate of the stream.
969-
outlet_data.push_chunk(_dataToSend);
995+
outlet_data.push_sample(dataToSend);
970996

971997
} else if (this.protocol.equals("Serial")) {
972998

@@ -1019,6 +1045,7 @@ class NetworkStreamOut extends Thread {
10191045
println(e.getMessage());
10201046
}
10211047
} else if (this.protocol.equals("LSL")) {
1048+
float[] dataToSend = new float[emgJoystickXY.length];
10221049
for (int i = 0; i < emgJoystickXY.length; i++) {
10231050
dataToSend[i] = emgJoystickXY[i];
10241051
}

0 commit comments

Comments
 (0)