public int CalculateSamplesNeeded() { long currentWriteTime = Stopwatch.GetTimestamp(); bool isInitializing = _lastWriteTime == 0; bool detectedUnderrun = false; if (!isInitializing) { double elapsedSeconds = (currentWriteTime - _lastWriteTime) / (double)Stopwatch.Frequency; // Due to rounding errors this doesn't work well in audio throttle mode unless enough time has passed if (elapsedSeconds >= 0.001) { _remainingSamples -= (int)Math.Round(elapsedSeconds * _sound.SampleRate); if (_remainingSamples < 0) { _remainingSamples = 0; detectedUnderrun = true; } _lastWriteTime = currentWriteTime; } } else { _lastWriteTime = currentWriteTime; } int samplesNeeded = BufferSizeSamples - _remainingSamples; if (isInitializing || detectedUnderrun) { _sound.HandleInitializationOrUnderrun(detectedUnderrun, ref samplesNeeded); } return(samplesNeeded); }
public int CalculateSamplesNeeded() { int samplesNeeded = 0; if (IsPlaying) { try { long currentWriteTime = Stopwatch.GetTimestamp(); int playCursor = _deviceBuffer.CurrentPlayPosition; int writeCursor = _deviceBuffer.CurrentWritePosition; bool isInitializing = _actualWriteOffsetBytes == -1; bool detectedUnderrun = false; if (!isInitializing) { double elapsedSeconds = (currentWriteTime - _lastWriteTime) / (double)Stopwatch.Frequency; double bufferSizeSeconds = (double)BufferSizeSamples / _sound.SampleRate; int cursorDelta = CircularDistance(_lastWriteCursor, writeCursor, BufferSizeBytes); cursorDelta += BufferSizeBytes * (int)Math.Round((elapsedSeconds - (cursorDelta / (double)(_sound.SampleRate * _sound.BlockAlign))) / bufferSizeSeconds); _filledBufferSizeBytes -= cursorDelta; detectedUnderrun = _filledBufferSizeBytes < 0; } if (isInitializing || detectedUnderrun) { _actualWriteOffsetBytes = writeCursor; _filledBufferSizeBytes = 0; } samplesNeeded = CircularDistance(_actualWriteOffsetBytes, playCursor, BufferSizeBytes) / _sound.BlockAlign; if (isInitializing || detectedUnderrun) { _sound.HandleInitializationOrUnderrun(detectedUnderrun, ref samplesNeeded); } _lastWriteTime = currentWriteTime; _lastWriteCursor = writeCursor; } catch (DirectSoundException) { samplesNeeded = 0; } } return(samplesNeeded); }