Example #1
0
        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);
        }