private async Task LSLPushChunk(MuseSample sample) { ValueSet message = new ValueSet { { LSLBridge.Constants.LSL_MESSAGE_STREAM_NAME, EEGStreamName } }; // Can only send 1D array with garbage AppService :S - inlined as channel1sample1,channel1sample2,channel1sample3...channel2sample1,channel2sample2... if (streamInfo.ChannelDataType == LSLBridgeDataType.DOUBLE) { double[] data = new double[Constants.MUSE_SAMPLE_COUNT * channelCount]; for (int i = 0; i < channelCount; i++) { var channelData = sample.ChannelData[channelUUIDs[i]]; // Maintains muse-lsl.py ordering. for (int j = 0; j < Constants.MUSE_SAMPLE_COUNT; j++) { data[(i * Constants.MUSE_SAMPLE_COUNT) + j] = channelData[j]; } } message.Add(LSLBridge.Constants.LSL_MESSAGE_CHUNK_DATA, data); } // Default to float. else if (streamInfo.ChannelDataType == LSLBridgeDataType.FLOAT) { float[] data = new float[Constants.MUSE_SAMPLE_COUNT * channelCount]; for (int i = 0; i < channelCount; i++) { var channelData = sample.ChannelData[channelUUIDs[i]]; // Maintains muse-lsl.py ordering. for (int j = 0; j < Constants.MUSE_SAMPLE_COUNT; j++) { data[(i * Constants.MUSE_SAMPLE_COUNT) + j] = (float)channelData[j]; } } message.Add(LSLBridge.Constants.LSL_MESSAGE_CHUNK_DATA, data); } else { throw new InvalidOperationException("Can't push LSL chunk - unsupported stream data type. Must use float32 or double64."); } message.Add(LSLBridge.Constants.LSL_MESSAGE_CHUNK_TIMESTAMPS, sample.Timestamps); message.Add(LSLBridge.Constants.LSL_MESSAGE_CHUNK_TIMESTAMPS2, sample.Timestamps2); await AppServiceManager.SendMessageAsync(LSLBridge.Constants.LSL_MESSAGE_TYPE_SEND_CHUNK, message); }
private async void Channel_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) { if (isStreaming) { string bits = GetBits(args.CharacteristicValue); ushort museTimestamp = PacketConversion.ToUInt16(bits, 0); // Zero bit offset, since first 16 bits represent Muse timestamp. MuseSample sample; lock (sampleBuffer) { if (!sampleBuffer.ContainsKey(museTimestamp)) { sample = new MuseSample(); sampleBuffer.Add(museTimestamp, sample); sample.BaseTimestamp = TimestampFormat.GetNow(); // This is the real timestamp, not the Muse timestamp which we use to group channel data. sample.BasetimeStamp2 = TimestampFormat.GetType() != TimestampFormat2.GetType() ? TimestampFormat2.GetNow() // This is the real timestamp (format 2), not the Muse timestamp which we use to group channel data. : sample.BasetimeStamp2 = sample.BaseTimestamp; // Ensures they are equal if using same timestamp format. } else { sample = sampleBuffer[museTimestamp]; } // Get time samples. sample.ChannelData[sender.Uuid] = GetTimeSamples(bits); } // If we have all 5 channels, we can push the 12 samples for each channel. if (sample.ChannelData.Count == channelCount) { await LSLPushChunk(sample); lock (sampleBuffer) sampleBuffer.Remove(museTimestamp); } } }