/// <summary> /// Override this method to implement whatever should happen with the samples... /// IMPORTANT: Avoid heavy processing logic within this method, update a state and use /// coroutines for more complexe processing tasks to distribute processing time over /// several frames /// </summary> /// <param name="newSample"></param> /// <param name="timeStamp"></param> protected override void Process(float[] newSample, double timeStamp) { //TODO: Use the timestamp from the sensor, which is in nanoseconds. EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), newSample[0]); LoggerController.instance.WriteLine(LogName.VariableRrInterval, ExciteOMeterManager.GetTimestampString() + "," + ExciteOMeterManager.ConvertFloatToString(newSample[0])); }
void TimeBasedCalculation() { // New window time is the original window time minus overlapping window. Set elapsed time in proportional position. elapsedWindowTime = windowTime * overlappingFraction; // Check that data is available if (timestamps.Count == 0 && dataBuffer.Count == 0) { ExciteOMeterManager.LogInFile("No incoming data " + incomingDataType.ToString() + " was found to calculate feature " + outputDataType.ToString()); return; } // Calculate feature featureValue = CalculateFeature(timestamps.ToArray(), dataBuffer.ToArray()); // Send events and log in file ExciteOMeterManager.DebugLog("A new feature was calculated in " + outputDataType.ToString() + ": " + timestamps[timestamps.Count - 1] + ", " + featureValue.ToString()); EoM_Events.Send_OnDataReceived(outputDataType, timestamps[timestamps.Count - 1], featureValue); LoggerController.instance.WriteLine(logIdentifier, timestamps[timestamps.Count - 1] + "," + featureValue.ToString()); // Rearrange overlap in signal // Overlap should not be greater than 95%, because it would generate very often feature calculations that might affect performance. int elementsToDelete = (int)(Mathf.Clamp(1.0f - (overlappingFraction), 0f, 0.95f) * dataBuffer.Count); timestamps.RemoveRange(0, elementsToDelete); dataBuffer.RemoveRange(0, elementsToDelete); }
// JUST CALLED BY ExciteOMeterManager WHEN POST-PROCESSING IS FINISHED. public void FinalStopLogSession() { // Logging is finished currentlyLogging = false; ExciteOMeterManager.SetCurrentlyRecordingVariable(false); // Notify everyone before closing logs. // Specially for feature calculation that matches length of input data before log is closed. EoM_Events.Send_OnLoggingStateChanged(currentlyLogging); // STOP LOGGING SetLoggingState(false); CloseLogFiles(); // Create JSON SessionVariablesController.instance.StopCurrentSession(); if (recordingScreenshots) { ScreenRecorder.instance.StopScreenRecorder(); } // Allow custom events from the end user ExciteOMeterManager.instance.OnStopSessionLog.Invoke(); }
/// <summary> /// Override this method to implement whatever should happen with the samples... /// IMPORTANT: Avoid heavy processing logic within this method, update a state and use /// coroutines for more complexe processing tasks to distribute processing time over /// several frames /// </summary> /// <param name="newSample"></param> /// <param name="timeStamp"></param> protected void Process2(int numSamples, int[,] newSamples, double[] timeStamps) //protected override void Process(int numSamples, int[,] newSamples, double[] timeStamps) { ExciteOMeterManager.DebugLog("ECG NumSamples: " + numSamples); // pull as long samples are available for (int i = 0; i < numSamples; i++) { if (newSamples[0, i] > 1.0e7) // Check values with bad parsing { ExciteOMeterManager.DebugLog("Error parsing value: " + BitConverter.ToString(BitConverter.GetBytes(newSamples[0, i])) + ", " + newSamples[0, i].ToString("F2")); continue; } else { EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), newSamples[0, i]); LoggerController.instance.WriteLine(LogName.VariableRawECG, newSamples[0, i].ToString("F0") + "," + newSamples[0, i].ToString("F0")); } } // Debug.Log($"Receiving from stream {StreamName}, first sample {newSample[0]}"); //TODO: The event only sends float[], all samples need to be parsed to float // EoM_Events.Send_OnDataReceived(VariableType, new float[1]{(float) newSample[0]}); //LoggerController.instance.WriteLine(LogName.VariableRawECG, timestamp.ToString("F0") + "," + newSample[0].ToString("F0")); }
/// <summary> /// Calculate feature value from a unidimensional sample-based feature /// </summary> void SampleBasedCalculation() { // Check that data is available if (timestamps.Count == 0 && dataBuffer.Count == 0) { // ExciteOMeterManager.DebugLog("No timestamps or data were found to calculate features"); ExciteOMeterManager.LogInFile("No incoming data " + incomingDataType.ToString() + " was found to calculate feature " + outputDataType.ToString()); return; } // Calculate feature featureValue = CalculateFeature(timestamps.ToArray(), dataBuffer.ToArray()); // Calculate offset of timestamp that corresponds to the calculated feature (# displacements to the left in timestamps) // Examples: Assume `sampleBuffer=5` // If `offsetSamplesTimestamp=0`, t for calculated feature is [t-4,t-3,...,t] // If `offsetSamplesTimestamp=3`, t for calculated feature is [t-1,t,t+1,t+2,t+3] indexOffsetForTimestamp = sampleBuffer - offsetSamplesTimestamp - 1; // Send events and log in file ExciteOMeterManager.DebugLog("A new feature was calculated in " + outputDataType.ToString() + ": " + timestamps[indexOffsetForTimestamp] + ", " + featureValue.ToString()); // Flag to know if it is the first calculation of the feature. // If so, the new feature has to match all the timestamps existing before the first timestamp of the feature. if (matchLengthOfInputSignal) { if (isFirstCalculatedFeature) { isFirstCalculatedFeature = false; idxStartRepeating = 0; // No previous data in array, repeat from beginning of input timestamps. } else { // CASE: Match length and buffer already contains data from previous window // Based on overlap and offset, the position where to start repeating timestamps is the following formula. idxStartRepeating = overlappingSamples - offsetSamplesTimestamp; } // Fill the previous timestamps of the input signal with the same value of this feature. for (int i = idxStartRepeating; i <= indexOffsetForTimestamp; i++) { // Write in files to collect data corresponding to EoM_Events.Send_OnDataReceived(outputDataType, timestamps[i], featureValue); LoggerController.instance.WriteLine(logIdentifier, ExciteOMeterManager.ConvertFloatToString(timestamps[i]) + "," + ExciteOMeterManager.ConvertFloatToString(featureValue)); } } else { Debug.LogWarning("Error calculating feature. Matching sampling error: logIdentifier" + logIdentifier.ToString()); //// CASE: DO NOT MATCH LENGTH OF INPUT SIGNAL, BUT USE TIMESTAMP DIFFERENT THAN LAST SAMPLE //EoM_Events.Send_OnDataReceived(outputDataType, timestamps[indexOffsetForTimestamp], featureValue); //LoggerController.instance.WriteLine(logIdentifier, ExciteOMeterManager.ConvertFloatToString(timestamps[indexOffsetForTimestamp]) + "," + ExciteOMeterManager.ConvertFloatToString(featureValue)); } // Rearrange overlap in signal elementsToDelete = sampleBuffer - overlappingSamples; timestamps.RemoveRange(0, elementsToDelete); dataBuffer.RemoveRange(0, elementsToDelete); }
/// <summary> /// Override this method to implement whatever should happen with the samples... /// IMPORTANT: Avoid heavy processing logic within this method, update a state and use /// coroutines for more complexe processing tasks to distribute processing time over /// several frames /// </summary> /// <param name="newSample"></param> /// <param name="timeStamp"></param> protected override void Process(short[] newSample, double timeStamp) { //TODO: The event only sends float[], all samples need to be parsed to float EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), (float)newSample[0]); LoggerController.instance.WriteLine(LogName.VariableHeartRate, ExciteOMeterManager.GetTimestampString() + "," + ExciteOMeterManager.ConvertFloatToString(newSample[0], 0)); }
void PostProcessing() { if (isSampleBasedFeature && matchLengthOfInputSignal) { // CASE: Match length of input signal, recording has finished but input signal is larger than features. // This saves in the log the number of lines remaining to match the length of the input. idxStartRepeating = isFirstCalculatedFeature? 0 : (overlappingSamples - offsetSamplesTimestamp); for (int i = idxStartRepeating; i < timestamps.Count; i++) { // Write in files to collect data corresponding to EoM_Events.Send_OnDataReceived(outputDataType, timestamps[i], featureValue); LoggerController.instance.WriteLine(logIdentifier, timestamps[i] + "," + featureValue.ToString()); } } ////////////// POSTPROCESSING // Postprocessing control instancesFinishedPostprocessing++; if (instancesFinishedPostprocessing == numInstances) { // All feature extraction have finished postprocessing ExciteOMeterManager.instance.PostProcessingExciteOMeterLevel(); // Reset instancesFinishedPostprocessing = 0; } }
protected virtual void OnStreamAvailable() { EoM_Events.Send_OnStreamConnected(VariableType); // decide what happens when the stream gets available pullSamplesContinuously = true; }
/// <summary> /// Override this method to implement whatever should happen with the samples... /// IMPORTANT: Avoid heavy processing logic within this method, update a state and use /// coroutines for more complexe processing tasks to distribute processing time over /// several frames /// </summary> /// <param name="newSample"></param> /// <param name="timeStamp"></param> protected override void Process(short[] newSample, double timeStamp) { //TODO: The event only sends float[], all samples need to be parsed to float EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), (float)newSample[0]); Debug.Log("hello from the OG Script"); LoggerController.instance.WriteLine(LogName.VariableHeartRate, ExciteOMeterManager.GetTimestamp().ToString("F6") + "," + newSample[0].ToString("F0")); Debug.Log(newSample); }
// Update is called once per frame void Update() { if (!active) { return; } // Timer control elapsedTime += Time.deltaTime; // Emulate connection disconnection HR if (sendHR && !previousSendHR) { EoM_Events.Send_OnStreamConnected(DataType.HeartRate); } else if (!sendHR && previousSendHR) { EoM_Events.Send_OnStreamDisconnected(DataType.HeartRate); } // Emulate connection disconnection RRi if (sendRrI && !previousSendRRi) { EoM_Events.Send_OnStreamConnected(DataType.RRInterval); } else if (!sendRrI && previousSendRRi) { EoM_Events.Send_OnStreamDisconnected(DataType.RRInterval); } // Send data each "sendingPeriod" if (elapsedTime >= sendingPeriod) { // Reset timer for next event elapsedTime = 0.0f; // Calculate new random values randomVariation = Random.Range(-variance, variance); // Setup new random values. If HR increases, RRi should decrease. HR += HR * randomVariation; RRi -= RRi * randomVariation * Random.Range(1.0f, 3.0f); // Send events float HRf = (float)Mathf.RoundToInt(HR); EoM_Events.Send_OnDataReceived(DataType.HeartRate, ExciteOMeterManager.GetTimestamp(), HRf); LoggerController.instance.WriteLine(LogName.VariableHeartRate, ExciteOMeterManager.GetTimestamp().ToString("F6") + "," + HR.ToString("F0")); EoM_Events.Send_OnDataReceived(DataType.RRInterval, ExciteOMeterManager.GetTimestamp(), RRi); LoggerController.instance.WriteLine(LogName.VariableRrInterval, ExciteOMeterManager.GetTimestamp().ToString("F6") + "," + RRi.ToString("F3")); } // To detect changes in runtime previousSendHR = sendHR; previousSendRRi = sendRrI; }
public void StopLogSession() { if (currentlyLogging) { // NOTE: The final stop is given in `FinalStopLogSession` // by ExciteOMeterManager when EoM level is calculated // This is executed between the stop session and allowing control from the user. EoM_Events.Send_OnPostProcessingStarted(); } }
public void StopLogSession() { if (currentlyLogging) { // NOTE: The final stop is given in `FinalStopLogSession` // by ExciteOMeterManager when EoM level is calculated // This is a type of pre-stop session EoM_Events.Send_OnPostProcessingStarted(); } }
////// MARKERS UI public void CreateManualMarker(string defaultText, MarkerLabel markerLabel = MarkerLabel.CUSTOM_MARKER) { EoM_Events.Send_OnStringReceived(DataType.ManualMarkers, ExciteOMeterManager.GetTimestamp(), defaultText); LogMessageUI.instance.WriteConsoleText("New custom marker at " + ExciteOMeterManager.GetTimestampString(2) + " with message " + defaultText); GameObject go = Instantiate(instanceMarkerPrefab, markersParent); CustomMarkerScriptUI script = go.GetComponent <CustomMarkerScriptUI>(); script.Setup(ExciteOMeterManager.GetTimestamp(), defaultText, markerLabel); // sessionMarkers.Add(script); // Used to keep record of existing session markers LoggerController.instance.SaveScreenshot(); }
IEnumerator SendDataEventsMovement(float timestamp) { if (transformArray.Length != typesTransformArray.Length) { Debug.LogError("The movement arrays are not the same length"); } for (int i = 0; i < transformArray.Length; i++) { EoM_Events.Send_OnDataReceived(typesTransformArray[i], timestamp, transformArray[i]); yield return(null); } }
// In case it is inheriting from InletIntSample instead of InletIntChunk // protected void Process2(int[] newSample, double timestamp) protected override void Process(int[] newSample, double timestamp) { // Debug.Log($"Receiving from stream {StreamName}, first sample {newSample[0]}"); //TODO: The event only sends float[], all samples need to be parsed to float if (newSample[0] > 1.0e7) // Check values with bad parsing { Debug.Log("Error parsing value ECG: " + BitConverter.ToString(BitConverter.GetBytes(newSample[0])) + ", " + newSample[0].ToString("F2")); } else { EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), newSample[0]); LoggerController.instance.WriteLine(LogName.VariableRawECG, timestamp.ToString("F0") + "," + newSample[0].ToString("F0")); } }
public bool SaveScreenshot() { if (!recordingScreenshots) { return(false); } string screenshot_filepath = ScreenRecorder.instance.CaptureScreenshot(); if (screenshot_filepath == null) { return(false); } // Screenshot was successful EoM_Events.Send_OnStringReceived(DataType.Screenshots, ExciteOMeterManager.GetTimestamp(), screenshot_filepath, MarkerLabel.NONE); return(true); }
/// <summary> /// Override this method to implement whatever should happen with the samples... /// IMPORTANT: Avoid heavy processing logic within this method, update a state and use /// coroutines for more complexe processing tasks to distribute processing time over /// several frames /// </summary> /// <param name="newSample"></param> /// <param name="timeStamp"></param> protected override void Process(int[] newSample, double timestamp) { //Assuming that a sample contains at least 3 values for x,y,z // Debug.Log($"Receiving from stream {StreamName}, first sample {newSample[0]}"); if (newSample[0] > 1.0e7) // Check values with bad parsing { ExciteOMeterManager.DebugLog("Error parsing value ACC: " + BitConverter.ToString(BitConverter.GetBytes(newSample[0])) + ", " + newSample[0].ToString("F2")); } else { //EoM_Events.Send_OnDataReceived(VariableType, new float[3]{(float) newSample[0], (float) newSample[1], (float) newSample[2]}); // TODO: The event for ACC should be a different delegate receiving float[] instead of single float. EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), (float)newSample[0]); EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), (float)newSample[1]); EoM_Events.Send_OnDataReceived(VariableType, ExciteOMeterManager.GetTimestamp(), (float)newSample[2]); LoggerController.instance.WriteLine(LogName.VariableRawACC, timestamp.ToString("F2") + "," + newSample[0].ToString("F0") + "," + newSample[1].ToString("F0") + "," + newSample[2].ToString("F0")); } }
public void StartLogSession() { if (!currentlyLogging) { // Allow custom events from the end user ExciteOMeterManager.instance.OnStartSessionLog.Invoke(); currentlyLogging = true; ExciteOMeterManager.SetCurrentlyRecordingVariable(true); // START LOGGING SetLoggingState(true); // Creates directory and files for CSV logging SetupNewLog(); // Setups a JSON file to be saved in the same directory SessionVariablesController.instance.SetupNewSession(thisLogPath); // SEND EoM Event EoM_Events.Send_OnLoggingStateChanged(currentlyLogging); } }
////////////// MULTIDIMENSIONAL FEATURES /// <summary> /// Calculate features from a MULTIDIMENSIONAL sample-based feature /// </summary> void SampleBasedCalculationArray() { // Check that data is available if (timestamps.Count == 0 && dataBufferArray.Count == 0) { // ExciteOMeterManager.DebugLog("No timestamps or data were found to calculate features"); ExciteOMeterManager.LogInFile("No incoming data " + incomingDataType.ToString() + " was found to calculate feature " + outputDataType.ToString()); return; } // Calculate feature featureArray = CalculateFeatureArray(timestamps.ToArray(), dataBufferArray.ToArray()); // Calculate offset of timestamp that corresponds to the calculated feature (# displacements to the left in timestamps) // Examples: Assume `sampleBuffer=5` // If `offsetSamplesTimestamp=0`, t for calculated feature is [t-4,t-3,...,t] // If `offsetSamplesTimestamp=3`, t for calculated feature is [t-1,t,t+1,t+2,t+3] indexOffsetForTimestamp = sampleBuffer - offsetSamplesTimestamp - 1; // Send events and log in file ExciteOMeterManager.DebugLog("A new feature was calculated in " + outputDataType.ToString() + ": " + timestamps[indexOffsetForTimestamp] + ", Length: " + featureArray.Length.ToString()); // Flag to know if it is the first calculation of the feature. // If so, the new feature has to match all the timestamps existing before the first timestamp of the feature. if (matchLengthOfInputSignal) { if (isFirstCalculatedFeature) { isFirstCalculatedFeature = false; idxStartRepeating = 0; // No previous data in array, repeat from beginning of input timestamps. } else { // CASE: Match length and buffer already contains data from previous window // Based on overlap and offset, the position where to start repeating timestamps is the following formula. idxStartRepeating = overlappingSamples - offsetSamplesTimestamp; } // Get the DataType for each of the features that are calculated DataType[] featureDataTypes = Constants.SubsetOfFeaturesTransformDataTypes(logIdentifier); // Fill the previous timestamps of the input signal with the same value of this feature. for (int i = idxStartRepeating; i <= indexOffsetForTimestamp; i++) { // Write in files to collect data corresponding to // Create string to save in CSV string featureArrayText = ""; foreach (float v in featureArray) { featureArrayText += "," + ExciteOMeterManager.ConvertFloatToString(v, 4); } bool logIsWriting = LoggerController.instance.WriteLine(logIdentifier, ExciteOMeterManager.ConvertFloatToString(timestamps[i]) + featureArrayText); if (!logIsWriting) { Debug.LogWarning("Error writing movement data. Please setup LoggerController with a file with LogID is" + logIdentifier.ToString()); } //// --------- TODO //// Send an event with the multidimensional data for the receivers taht can handle multidimensionality //EoM_Events.Send_OnDataArrayReceived(outputDataType, timestamps[i], featureArray); //// Visualizer is designed to analyze unidimensional data, therefore multidimensional needs to be sent one by one to the system //StartCoroutine(SendDataEventsMovement(ExciteOMeterManager.GetTimestamp())); // BUG: Sending events from the coroutine does not seem to be received... // --------- // If the above works, delete the remaining code!! ---------------------- if (featureDataTypes.Length != featureArray.Length) { Debug.LogError("Mismatch between the calculated array of features and the expected, in feature with logIdentifier" + logIdentifier); return; } for (int j = 0; j < featureArray.Length; j++) { EoM_Events.Send_OnDataReceived(featureDataTypes[j], timestamps[i], featureArray[j]); } /// -------------------------------------------------------- } } else { // CASE: DO NOT MATCH LENGTH OF INPUT SIGNAL, BUT USE TIMESTAMP DIFFERENT THAN LAST SAMPLE EoM_Events.Send_OnDataReceived(outputDataType, timestamps[indexOffsetForTimestamp], featureValue); LoggerController.instance.WriteLine(logIdentifier, ExciteOMeterManager.ConvertFloatToString(timestamps[indexOffsetForTimestamp]) + "," + ExciteOMeterManager.ConvertFloatToString(featureValue)); } // Rearrange overlap in signal elementsToDelete = sampleBuffer - overlappingSamples; timestamps.RemoveRange(0, elementsToDelete); dataBufferArray.RemoveRange(0, elementsToDelete); }
public void FixedUpdate() { if (isConfigured && ExciteOMeterManager.currentlyRecordingSession) { // Timer control elapsedTime += Time.fixedDeltaTime; // Send data each "sendingPeriod" if (elapsedTime >= sendingPeriod) { // Reset timer for next event elapsedTime = 0.0f; // Define array transformArray[0] = objectToTrack.position.x; transformArray[1] = objectToTrack.position.y; transformArray[2] = objectToTrack.position.z; transformArray[3] = objectToTrack.localRotation.w; // Quaternion without axis. transformArray[4] = objectToTrack.localRotation.x; // Q in the axis i transformArray[5] = objectToTrack.localRotation.y; // Q in the axis j transformArray[6] = objectToTrack.localRotation.z; // Q in the axis k transformArray[7] = objectToTrack.localEulerAngles.x; // Pitch (up-down) transformArray[8] = objectToTrack.localEulerAngles.y; // Yaw (left-right) transformArray[9] = objectToTrack.localEulerAngles.z; // Roll (towards shoulders) // Create string to save in CSV transformArrayText = ""; foreach (float v in transformArray) { transformArrayText += "," + ExciteOMeterManager.ConvertFloatToString(v, 4); } logIsWriting = LoggerController.instance.WriteLine(logToWrite, ExciteOMeterManager.GetTimestampString() + transformArrayText); if (!logIsWriting) { Debug.LogWarning("Error writing movement data. Please setup LoggerController with a file with LogID is" + logToWrite.ToString()); } //Debug.Log("Sending Movement from " + gameObject.name + " > " + transformArrayText); // Send an event with the multidimensional data for the receivers taht can handle multidimensionality EoM_Events.Send_OnDataArrayReceived(DataType.Headset_array, ExciteOMeterManager.GetTimestamp(), transformArray); // Send values individually, because they need to be stored in the .json file as unidimensional data, so that they can be visualized // --------- TODO //// Visualizer is designed to analyze unidimensional data, therefore multidimensional needs to be sent one by one to the system //StartCoroutine(SendDataEventsMovement(ExciteOMeterManager.GetTimestamp())); // BUG: Sending events from the coroutine does not seem to be received... // --------- // If the above works, delete the remaining code!! ---------------------- if (transformArray.Length != typesTransformArray.Length) { Debug.LogError("The movement arrays are not the same length"); } for (int i = 0; i < transformArray.Length; i++) { EoM_Events.Send_OnDataReceived(typesTransformArray[i], ExciteOMeterManager.GetTimestamp(), transformArray[i]); } /// -------------------------------------------------------- } } }
public void SendAutomaticMarker2() { EoM_Events.Send_OnStringReceived(DataType.AutomaticMarkers, ExciteOMeterManager.GetTimestamp(), "RMSSD > 3*SD", MarkerLabel.ABNORMAL_RMSSD); LoggerController.instance.SaveScreenshot(); }
public void SetCustomRange() { Debug.Log("Custom range"); EoM_Events.Send_SetTimelineRange(UnityEngine.Random.Range(0, 30), UnityEngine.Random.Range(60, 180)); }
IEnumerator StartDelayed() { yield return(new WaitForEndOfFrame()); EoM_Events.Send_TimelineRedraw(); }
// Update is called once per frame void Update() { //// OLD INPUT SYSTEM if (kb[Key.U].wasPressedThisFrame) { // Update values and whole timeline Debug.Log("Updating Timeline"); EoM_Events.Send_TimelineRedraw(); } if (kb[Key.C].wasPressedThisFrame) { // Update values and whole timeline Debug.Log("Custom range"); EoM_Events.Send_SetTimelineRange(10, 90); } if (kb[Key.J].wasPressedThisFrame) { // Update values and whole timeline float value = 3f; Debug.Log("Value:" + value); int intvalue = Convert.ToInt32(value); Debug.Log("Int Value:" + intvalue); MarkerLabel mlabel = (MarkerLabel)intvalue; Debug.Log("label:" + mlabel); Color labelC = ExciteOMeter.Vizualisation.VisualStyle.InstantMarkersColorTable[mlabel]; Debug.Log("Color: " + labelC); } if (kb[Key.S].wasPressedThisFrame) { // Update values and whole timeline Debug.Log("Set range"); EoM_Events.Send_SetTimelineRange(0, 300); } if (kb[Key.T].wasPressedThisFrame) { // Update values and whole timeline // float newTimestamp = UnityEngine.Random.Range(0f,200f); float newTimestamp = 60f; Debug.Log("newTimestamp:" + newTimestamp + " = " + TimeLineHelpers.GetTimeFormat(newTimestamp, true)); EoM_Events.Send_SetTimeMarker(newTimestamp); } if (kb[Key.D].wasPressedThisFrame) { OfflineAnalysisManager.instance.GenerateDataTypeListMenu(); } if (kb[Key.G].wasPressedThisFrame) { int findindex = ExciteOMeter.Vizualisation.OfflineAnalysisManager.instance.sessions.FindLastIndex(x => x.isLoaded == true); ExciteOMeter.Vizualisation.Timeline.instance.AddLineGraph(ExciteOMeter.Vizualisation.OfflineAnalysisManager.instance.sessions[findindex], DataType.HeartRate); } if (kb[Key.A].wasPressedThisFrame) { int findindex = ExciteOMeter.Vizualisation.OfflineAnalysisManager.instance.sessions.FindLastIndex(x => x.isLoaded == true); ExciteOMeter.Vizualisation.Timeline.instance.AddMarkerGraph(ExciteOMeter.Vizualisation.OfflineAnalysisManager.instance.sessions[findindex], DataType.AutomaticMarkers); } }
protected virtual void OnStreamLost() { // decide what happens when the stream gets lost pullSamplesContinuously = false; EoM_Events.Send_OnStreamDisconnected(VariableType); }