Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
                }
            }
        }