private void WriteZ9Message(ZeoMessage zeoMessage, Z9DataType dataType) { short[] lengths = new short[] { 4, 1 }; if (this.binFile != null && this.binFile.CanWrite == true) { byte[] bytes = new byte[] { (byte)'Z', (byte)'9' }; this.binFile.Write(bytes, 0, bytes.Length); this.WriteInt16(lengths[(int)dataType]); this.WriteInt32(zeoMessage.ZeoTimestamp); this.binFile.WriteByte((byte)dataType); switch (dataType) { case Z9DataType.SoundAlarmVolume: { this.WriteInt32(zeoMessage.SoundAlarmVolume); break; } case Z9DataType.SoundAlarmEnabled: { this.binFile.WriteByte(1); break; } } } }
private void ReadZ9Message() { this.ReadNBytes(2); int length = this.buffer[0] | this.buffer[1] << 8; // ZeoTimestamp is used as an index to update ZeoMessage in the list this.ReadNBytes(4); uint zeoTimestamp = (uint)this.GetInt32(); ZeoMessage zeoMessage = this.GetZeoMessage(zeoTimestamp); Z9DataType dataType = (Z9DataType)this.ReadByte(); this.ReadNBytes(length); switch (dataType) { case Z9DataType.SoundAlarmVolume: zeoMessage.SoundAlarmVolume = this.GetInt32(); break; case Z9DataType.SoundAlarmEnabled: this.SoundAlarmEnabled = this.buffer[0] != 0; break; } }
public ChannelData[] ReadEegFromLastPosition(ref int lastPosition, int len) { this.rwLock.AcquireReaderLock(Timeout.Infinite); ChannelData[] eegValues = new ChannelData[len]; for (int i = 0; i < len; i++) { eegValues[i] = new ChannelData(1); } int count = (len / ZeoMessage.SamplesPerMessage) + 1; for (int i = lastPosition, j = 0; i < (lastPosition + count) && i < this.zeoMessages.Count; i++) { ZeoMessage zeoMessage = this.zeoMessages[i]; for (int k = 0; j < len && k < ZeoMessage.SamplesPerMessage; j++, k++) { if (zeoMessage.Waveform != null) { eegValues[j].Values[0] = zeoMessage.Waveform[k]; } else { eegValues[j].Values[0] = 0; } } } if (this.LiveStream) { lastPosition = ((this.Length * ZeoMessage.SamplesPerMessage) - len) / ZeoMessage.SamplesPerMessage; if (lastPosition < 0) { lastPosition = 0; } } ChannelData[] filteredValues = this.Filter50Hz(eegValues); for (int i = 0; i < len; i++) { eegValues[i] = filteredValues[i]; } this.rwLock.ReleaseLock(); return(eegValues); }
public void ReadStageDataFromLastPosition(ref int stage) { this.rwLock.AcquireReaderLock(Timeout.Infinite); for (int i = this.zeoMessages.Count - 1; i > 0; i--) { ZeoMessage zeoMessage = this.zeoMessages[i]; if (zeoMessage.SleepStage != null) { if (zeoMessage.SleepStage != ZeoSleepStage.Undefined & zeoMessage.SleepStage != ZeoSleepStage.Undefined0) { stage = -(int)zeoMessage.SleepStage; break; } } } this.rwLock.ReleaseLock(); }
public void OpenFileStream(string fileName) { this.fileName = fileName; this.binFile = new FileStream(this.fileName, FileMode.Open); this.VerifyVersionString(); try { while (true) { ZeoMessage zeoMessage = this.ReadMessage(); if (zeoMessage != null && zeoMessage.Waveform != null) { break; } } while (true) { ZeoMessage zeoMessage = this.ReadMessage(); if (zeoMessage != null) { this.zeoMessages.Add(zeoMessage); if (zeoMessage.Event == ZeoEvent.HeadbandDocked) { break; } } } } catch (IOException) { } finally { if (this.binFile != null) { this.binFile.Close(); this.binFile = null; } } }
public ChannelData[] ReadFrequencyDataFromLastPosition(ref int lastPosition, int len) { this.rwLock.AcquireReaderLock(Timeout.Infinite); ChannelData[] freqData = new ChannelData[len]; for (int i = lastPosition, j = 0; i < (lastPosition + len) && i < this.zeoMessages.Count; i++, j++) { ZeoMessage zeoMessage = this.zeoMessages[i]; freqData[j] = new ChannelData(ZeoMessage.FrequencyBinsLength + 2); if (zeoMessage.FrequencyBins != null) { int k = 0; for (k = 0; k < zeoMessage.FrequencyBins.Length; k++) { freqData[j].Values[k] = zeoMessage.FrequencyBins[k]; } freqData[j].Values[k] = zeoMessage.Impedance ?? 0; } else { freqData[j].Values[freqData[j].Values.Length - 2] = zeoMessage.Impedance ?? 0; } freqData[j].Values[freqData[j].Values.Length - 1] = zeoMessage.SoundAlarmVolume; } if (this.LiveStream) { lastPosition = this.Length - len; if (lastPosition < 0) { lastPosition = 0; } } this.rwLock.ReleaseLock(); return(freqData); }
public ChannelData[] ReadStageDataFromLastPosition(ref int lastPosition, int len) { this.rwLock.AcquireReaderLock(Timeout.Infinite); ChannelData[] stageData = new ChannelData[len]; for (int i = lastPosition, j = 0; j < len && i < this.zeoMessages.Count; i++) { ZeoMessage zeoMessage = this.zeoMessages[i]; stageData[j] = new ChannelData(2); if (zeoMessage.SleepStage != null) { stageData[j].Values[0] = -(int)zeoMessage.SleepStage; stageData[j].Values[1] = zeoMessage.SoundAlarmVolume; j++; } } for (int i = 0; i < len; i++) { if (stageData[i] == null) { stageData[i] = new ChannelData(2); stageData[i].Values[0] = -5; stageData[i].Values[1] = ZeoMessage.MinSoundVolume; } else if (stageData[i].Values[0] == 0) { stageData[i].Values[0] = -5; stageData[i].Values[1] = ZeoMessage.MinSoundVolume; } } this.rwLock.ReleaseLock(); return(stageData); }
public ZeoMessage ProcessZeoMessage(ZeoMessage zeoMessage) { if (string.IsNullOrEmpty(this.fromTime) == false && DateTime.Now.ToString("HH:mm") == this.fromTime) { this.AlarmEnabled = true; } if (string.IsNullOrEmpty(this.toTime) == false && DateTime.Now.ToString("HH:mm") == this.toTime) { this.AlarmEnabled = false; // This will stop the alarm this.AlarmStarted = false; } if (this.AlarmStarted == true && this.audio.Playing == false) { // Called from SettingsForm // TODO: Improve the design here this.StartAlarm(); return null; } if (this.AlarmStarted == true || this.audio.Playing == true) { this.SetAudioVolume(); zeoMessage.SoundAlarmVolume = this.audio.Volume; return zeoMessage; } if (this.AlarmEnabled == false) { return null; } if (zeoMessage.SleepStage != null) { this.sleepStages.Add(zeoMessage.SleepStage.Value); } int count = this.sleepStages.Count - 1; bool startAlarm = true; foreach (List<AlarmState> alarmCue in this.alarmCues) { int i = count; startAlarm = true; foreach (AlarmState state in alarmCue) { int end = i - state.Count; if (end < -1 || startAlarm == false) { startAlarm = false; break; } for (; i >= 0 && i > end; i--) { if (state.SleepStage == ZeoSleepStage.Sleep && (this.sleepStages[i] != ZeoSleepStage.REM && this.sleepStages[i] != ZeoSleepStage.Light && this.sleepStages[i] != ZeoSleepStage.Deep)) { startAlarm = false; break; } else if (state.SleepStage != ZeoSleepStage.Sleep && this.sleepStages[i] != state.SleepStage) { startAlarm = false; break; } } } if (startAlarm == true) { break; } } if (startAlarm == true) { this.StartAlarm(); } return null; }
private ZeoDataType ReadA4Message(ZeoMessage zeoMessage) { byte checkSum = this.ReadByte(); this.ReadNBytes(2); int length = this.buffer[0] | this.buffer[1] << 8; this.ReadNBytes(2); int lengthN = this.buffer[0] | this.buffer[1] << 8; if ((short)length != (short)(~lengthN)) { // TODO: log error return(ZeoDataType.Error); } byte unixT = this.ReadByte(); this.ReadNBytes(2); float subsecondT = (this.buffer[0] | this.buffer[1] << 8) / 65535.0f; byte sequence = this.ReadByte(); ZeoDataType dataType = (ZeoDataType)this.ReadByte(); this.ReadNBytes(length - 1); switch (dataType) { case ZeoDataType.FrequencyBins: short[] shorts = new short[7]; Buffer.BlockCopy(this.buffer, 0, shorts, 0, 14); float[] floats = new float[7]; for (int k = 0; k < 7; k++) { floats[k] = (shorts[k] / 32767.0f) * 100.0f; } zeoMessage.FrequencyBins = floats; break; case ZeoDataType.Waveform: shorts = new short[128]; Buffer.BlockCopy(this.buffer, 0, shorts, 0, 256); floats = new float[128]; for (int k = 0; k < 128; k++) { floats[k] = (shorts[k] / 32767.0f) * 315.0f; } zeoMessage.Waveform = floats; zeoMessage.Second = unixT + subsecondT; // 128 16-bit samples per ~1.005 sec break; case ZeoDataType.ZeoTimestamp: zeoMessage.ZeoTimestamp = this.GetInt32(); break; case ZeoDataType.Event: zeoMessage.Event = (ZeoEvent)this.GetInt32(); break; case ZeoDataType.Version: break; case ZeoDataType.SQI: zeoMessage.SQI = this.GetInt32(); break; case ZeoDataType.BadSignal: zeoMessage.BadSignal = this.GetInt32() == 0 ? false : true; break; case ZeoDataType.Impedance: zeoMessage.Impedance = this.GetImpedance(); break; case ZeoDataType.SleepStage: zeoMessage.SleepStage = (ZeoSleepStage)this.GetInt32(); break; case ZeoDataType.SliceEnd: break; default: return(ZeoDataType.Error); } return(dataType); }
private ZeoMessage ReadMessage() { ZeoMessage zeoMessage = new ZeoMessage(); // A4 are standard Zeo messages bool isA4 = false; // Z9 are additional messages from ZeoScope bool isZ9 = false; byte header = 0; for (int j = 0; j < 20; j++) { int i; for (i = 0; i < 500; i++) { if (header == 'A') { header = this.ReadByte(); if (header == '4') { isA4 = true; break; } else { continue; } } else if (header == 'Z') { header = this.ReadByte(); if (header == '9') { isZ9 = true; break; } else { continue; } } header = this.ReadByte(); } if (i != 1) { // TODO: log error } if (isA4 == true) { ZeoDataType dataType = this.ReadA4Message(zeoMessage); if (dataType == ZeoDataType.SliceEnd) { return(zeoMessage); } else if (dataType == ZeoDataType.Error) { return(null); } } else if (isZ9 == true) { this.ReadZ9Message(); return(null); } } return(null); }
private void ReadSerialStream() { Thread.CurrentThread.Name = "ReadSerialStream"; this.writeEnabled = false; while (this.exitWorkerEvent.WaitOne(0, true) == false) { try { if (this.writeEnabled == false) { ZeoMessage zeoMessage = this.ReadMessage(); if (zeoMessage.Waveform != null) { this.writeEnabled = true; } } if (this.writeEnabled == true) { ZeoMessage zeoMessage = this.ReadMessage(); if (zeoMessage != null) { this.rwLock.AcquireWriterLock(Timeout.Infinite); this.zeoMessages.Add(zeoMessage); this.rwLock.ReleaseLock(); if (this.soundAlarm != null) { ZeoMessage zm = this.soundAlarm.ProcessZeoMessage(zeoMessage); if (zm != null) { this.WriteZ9Message(zm, Z9DataType.SoundAlarmVolume); } } if (zeoMessage.Event == ZeoEvent.HeadbandDocked) { if (this.HeadbandDocked != null) { this.HeadbandDocked(this, null); } this.binFile.Flush(); break; } } } } catch (TimeoutException) { // Port Timeout } catch (InvalidOperationException) { // Port closed } catch (NullReferenceException) { // Port disposed } catch (IOException) { } } this.LiveStream = false; }
private ZeoMessage ReadMessage() { ZeoMessage zeoMessage = new ZeoMessage(); // A4 are standard Zeo messages bool isA4 = false; // Z9 are additional messages from ZeoScope bool isZ9 = false; byte header = 0; for (int j = 0; j < 20; j++) { int i; for (i = 0; i < 500; i++) { if (header == 'A') { header = this.ReadByte(); if (header == '4') { isA4 = true; break; } else { continue; } } else if (header == 'Z') { header = this.ReadByte(); if (header == '9') { isZ9 = true; break; } else { continue; } } header = this.ReadByte(); } if (i != 1) { // TODO: log error } if (isA4 == true) { ZeoDataType dataType = this.ReadA4Message(zeoMessage); if (dataType == ZeoDataType.SliceEnd) { return zeoMessage; } else if (dataType == ZeoDataType.Error) { return null; } } else if (isZ9 == true) { this.ReadZ9Message(); return null; } } return null; }
private ZeoDataType ReadA4Message(ZeoMessage zeoMessage) { byte checkSum = this.ReadByte(); this.ReadNBytes(2); int length = this.buffer[0] | this.buffer[1] << 8; this.ReadNBytes(2); int lengthN = this.buffer[0] | this.buffer[1] << 8; if ((short)length != (short)(~lengthN)) { // TODO: log error return ZeoDataType.Error; } byte unixT = this.ReadByte(); this.ReadNBytes(2); float subsecondT = (this.buffer[0] | this.buffer[1] << 8) / 65535.0f; byte sequence = this.ReadByte(); ZeoDataType dataType = (ZeoDataType)this.ReadByte(); this.ReadNBytes(length - 1); switch (dataType) { case ZeoDataType.FrequencyBins: short[] shorts = new short[7]; Buffer.BlockCopy(this.buffer, 0, shorts, 0, 14); float[] floats = new float[7]; for (int k = 0; k < 7; k++) { floats[k] = (shorts[k] / 32767.0f) * 100.0f; } zeoMessage.FrequencyBins = floats; break; case ZeoDataType.Waveform: shorts = new short[128]; Buffer.BlockCopy(this.buffer, 0, shorts, 0, 256); floats = new float[128]; for (int k = 0; k < 128; k++) { floats[k] = (shorts[k] / 32767.0f) * 315.0f; } zeoMessage.Waveform = floats; zeoMessage.Second = unixT + subsecondT; // 128 16-bit samples per ~1.005 sec break; case ZeoDataType.ZeoTimestamp: zeoMessage.ZeoTimestamp = this.GetInt32(); break; case ZeoDataType.Event: zeoMessage.Event = (ZeoEvent)this.GetInt32(); break; case ZeoDataType.Version: break; case ZeoDataType.SQI: zeoMessage.SQI = this.GetInt32(); break; case ZeoDataType.BadSignal: zeoMessage.BadSignal = this.GetInt32() == 0 ? false : true; break; case ZeoDataType.Impedance: zeoMessage.Impedance = this.GetImpedance(); break; case ZeoDataType.SleepStage: zeoMessage.SleepStage = (ZeoSleepStage)this.GetInt32(); break; case ZeoDataType.SliceEnd: break; default: return ZeoDataType.Error; } return dataType; }
public ZeoMessage ProcessZeoMessage(ZeoMessage zeoMessage) { if (string.IsNullOrEmpty(this.fromTime) == false && DateTime.Now.ToString("HH:mm") == this.fromTime) { this.AlarmEnabled = true; } if (string.IsNullOrEmpty(this.toTime) == false && DateTime.Now.ToString("HH:mm") == this.toTime) { this.AlarmEnabled = false; // This will stop the alarm this.AlarmStarted = false; } if (this.AlarmStarted == true && this.audio.Playing == false) { // Called from SettingsForm // TODO: Improve the design here this.StartAlarm(); return(null); } if (this.AlarmStarted == true || this.audio.Playing == true) { this.SetAudioVolume(); zeoMessage.SoundAlarmVolume = this.audio.Volume; return(zeoMessage); } if (this.AlarmEnabled == false) { return(null); } if (zeoMessage.SleepStage != null) { this.sleepStages.Add(zeoMessage.SleepStage.Value); } int count = this.sleepStages.Count - 1; bool startAlarm = true; foreach (List <AlarmState> alarmCue in this.alarmCues) { int i = count; startAlarm = true; foreach (AlarmState state in alarmCue) { int end = i - state.Count; if (end < -1 || startAlarm == false) { startAlarm = false; break; } for (; i >= 0 && i > end; i--) { if (state.SleepStage == ZeoSleepStage.Sleep && (this.sleepStages[i] != ZeoSleepStage.REM && this.sleepStages[i] != ZeoSleepStage.Light && this.sleepStages[i] != ZeoSleepStage.Deep)) { startAlarm = false; break; } else if (state.SleepStage != ZeoSleepStage.Sleep && this.sleepStages[i] != state.SleepStage) { startAlarm = false; break; } } } if (startAlarm == true) { break; } } if (startAlarm == true) { this.StartAlarm(); } return(null); }