public void Process() { OVRPlugin.HapticsState controllerHapticsState = OVRPlugin.GetControllerHapticsState(this.m_controller); float num = Time.realtimeSinceStartup - this.m_prevSamplesQueuedTime; if (this.m_prevSamplesQueued > 0) { int num2 = this.m_prevSamplesQueued - (int)(num * (float)OVRHaptics.Config.SampleRateHz + 0.5f); if (num2 < 0) { num2 = 0; } if (controllerHapticsState.SamplesQueued - num2 == 0) { this.m_numPredictionHits++; } else { this.m_numPredictionMisses++; } if (num2 > 0 && controllerHapticsState.SamplesQueued == 0) { this.m_numUnderruns++; } this.m_prevSamplesQueued = controllerHapticsState.SamplesQueued; this.m_prevSamplesQueuedTime = Time.realtimeSinceStartup; } int num3 = OVRHaptics.Config.OptimalBufferSamplesCount; if (this.m_lowLatencyMode) { float num4 = 1000f / (float)OVRHaptics.Config.SampleRateHz; float num5 = num * 1000f; int num6 = (int)Mathf.Ceil(num5 / num4); int num7 = OVRHaptics.Config.MinimumSafeSamplesQueued + num6; if (num7 < num3) { num3 = num7; } } if (controllerHapticsState.SamplesQueued > num3) { return; } if (num3 > OVRHaptics.Config.MaximumBufferSamplesCount) { num3 = OVRHaptics.Config.MaximumBufferSamplesCount; } if (num3 > controllerHapticsState.SamplesAvailable) { num3 = controllerHapticsState.SamplesAvailable; } int num8 = 0; int num9 = 0; while (num8 < num3 && num9 < this.m_pendingClips.Count) { int num10 = num3 - num8; int num11 = this.m_pendingClips[num9].Clip.Count - this.m_pendingClips[num9].ReadCount; if (num10 > num11) { num10 = num11; } if (num10 > 0) { int length = num10 * OVRHaptics.Config.SampleSizeInBytes; int byteOffset = num8 * OVRHaptics.Config.SampleSizeInBytes; int startIndex = this.m_pendingClips[num9].ReadCount * OVRHaptics.Config.SampleSizeInBytes; Marshal.Copy(this.m_pendingClips[num9].Clip.Samples, startIndex, this.m_nativeBuffer.GetPointer(byteOffset), length); this.m_pendingClips[num9].ReadCount += num10; num8 += num10; } num9++; } int num12 = this.m_pendingClips.Count - 1; while (num12 >= 0 && this.m_pendingClips.Count > 0) { if (this.m_pendingClips[num12].ReadCount >= this.m_pendingClips[num12].Clip.Count) { this.m_pendingClips.RemoveAt(num12); } num12--; } int num13 = num3 - (controllerHapticsState.SamplesQueued + num8); if (num13 < OVRHaptics.Config.MinimumBufferSamplesCount - num8) { num13 = OVRHaptics.Config.MinimumBufferSamplesCount - num8; } if (num13 > controllerHapticsState.SamplesAvailable) { num13 = controllerHapticsState.SamplesAvailable; } if (num13 > 0) { int length2 = num13 * OVRHaptics.Config.SampleSizeInBytes; int byteOffset2 = num8 * OVRHaptics.Config.SampleSizeInBytes; int startIndex2 = 0; Marshal.Copy(this.m_paddingClip.Samples, startIndex2, this.m_nativeBuffer.GetPointer(byteOffset2), length2); num8 += num13; } if (num8 > 0) { OVRPlugin.HapticsBuffer hapticsBuffer; hapticsBuffer.Samples = this.m_nativeBuffer.GetPointer(0); hapticsBuffer.SamplesCount = num8; OVRPlugin.SetControllerHaptics(this.m_controller, hapticsBuffer); this.m_prevSamplesQueued = OVRPlugin.GetControllerHapticsState(this.m_controller).SamplesQueued; this.m_prevSamplesQueuedTime = Time.realtimeSinceStartup; } }
/// <summary> /// The system calls this each frame to update haptics playback. /// </summary> public void Process() { var hapticsState = OVRPlugin.GetControllerHapticsState(m_controller); float elapsedTime = Time.realtimeSinceStartup - m_prevSamplesQueuedTime; if (m_prevSamplesQueued > 0) { int expectedSamples = m_prevSamplesQueued - (int)(elapsedTime * OVRHaptics.Config.SampleRateHz + 0.5f); if (expectedSamples < 0) { expectedSamples = 0; } if ((hapticsState.SamplesQueued - expectedSamples) == 0) { m_numPredictionHits++; } else { m_numPredictionMisses++; } //Debug.Log(hapticsState.SamplesAvailable + "a " + hapticsState.SamplesQueued + "q " + expectedSamples + "e " //+ "Prediction Accuracy: " + m_numPredictionHits / (float)(m_numPredictionMisses + m_numPredictionHits)); if ((expectedSamples > 0) && (hapticsState.SamplesQueued == 0)) { m_numUnderruns++; //Debug.LogError("Samples Underrun (" + m_controller + " #" + m_numUnderruns + ") -" // + " Expected: " + expectedSamples // + " Actual: " + hapticsState.SamplesQueued); } m_prevSamplesQueued = hapticsState.SamplesQueued; m_prevSamplesQueuedTime = Time.realtimeSinceStartup; } int desiredSamplesCount = OVRHaptics.Config.OptimalBufferSamplesCount; if (m_lowLatencyMode) { float sampleRateMs = 1000.0f / (float)OVRHaptics.Config.SampleRateHz; float elapsedMs = elapsedTime * 1000.0f; int samplesNeededPerFrame = (int)Mathf.Ceil(elapsedMs / sampleRateMs); int lowLatencySamplesCount = OVRHaptics.Config.MinimumSafeSamplesQueued + samplesNeededPerFrame; if (lowLatencySamplesCount < desiredSamplesCount) { desiredSamplesCount = lowLatencySamplesCount; } } if (hapticsState.SamplesQueued > desiredSamplesCount) { return; } if (desiredSamplesCount > OVRHaptics.Config.MaximumBufferSamplesCount) { desiredSamplesCount = OVRHaptics.Config.MaximumBufferSamplesCount; } if (desiredSamplesCount > hapticsState.SamplesAvailable) { desiredSamplesCount = hapticsState.SamplesAvailable; } int acquiredSamplesCount = 0; int clipIndex = 0; while (acquiredSamplesCount < desiredSamplesCount && clipIndex < m_pendingClips.Count) { int numSamplesToCopy = desiredSamplesCount - acquiredSamplesCount; int remainingSamplesInClip = m_pendingClips[clipIndex].Clip.Count - m_pendingClips[clipIndex].ReadCount; if (numSamplesToCopy > remainingSamplesInClip) { numSamplesToCopy = remainingSamplesInClip; } if (numSamplesToCopy > 0) { int numBytes = numSamplesToCopy * OVRHaptics.Config.SampleSizeInBytes; int dstOffset = acquiredSamplesCount * OVRHaptics.Config.SampleSizeInBytes; int srcOffset = m_pendingClips[clipIndex].ReadCount * OVRHaptics.Config.SampleSizeInBytes; Marshal.Copy(m_pendingClips[clipIndex].Clip.Samples, srcOffset, m_nativeBuffer.GetPointer(dstOffset), numBytes); m_pendingClips[clipIndex].ReadCount += numSamplesToCopy; acquiredSamplesCount += numSamplesToCopy; } clipIndex++; } for (int i = m_pendingClips.Count - 1; i >= 0 && m_pendingClips.Count > 0; i--) { if (m_pendingClips[i].ReadCount >= m_pendingClips[i].Clip.Count) { m_pendingClips.RemoveAt(i); } } int desiredPadding = desiredSamplesCount - (hapticsState.SamplesQueued + acquiredSamplesCount); if (desiredPadding < (OVRHaptics.Config.MinimumBufferSamplesCount - acquiredSamplesCount)) { desiredPadding = (OVRHaptics.Config.MinimumBufferSamplesCount - acquiredSamplesCount); } if (desiredPadding > hapticsState.SamplesAvailable) { desiredPadding = hapticsState.SamplesAvailable; } if (desiredPadding > 0) { int numBytes = desiredPadding * OVRHaptics.Config.SampleSizeInBytes; int dstOffset = acquiredSamplesCount * OVRHaptics.Config.SampleSizeInBytes; int srcOffset = 0; Marshal.Copy(m_paddingClip.Samples, srcOffset, m_nativeBuffer.GetPointer(dstOffset), numBytes); acquiredSamplesCount += desiredPadding; } if (acquiredSamplesCount > 0) { OVRPlugin.HapticsBuffer hapticsBuffer; hapticsBuffer.Samples = m_nativeBuffer.GetPointer(); hapticsBuffer.SamplesCount = acquiredSamplesCount; OVRPlugin.SetControllerHaptics(m_controller, hapticsBuffer); hapticsState = OVRPlugin.GetControllerHapticsState(m_controller); m_prevSamplesQueued = hapticsState.SamplesQueued; m_prevSamplesQueuedTime = Time.realtimeSinceStartup; } }