示例#1
0
        private void PlaybackProc(object o)
        {
            EventWaitHandle waitHandle = o as EventWaitHandle;
            EventWaitHandle[] waitHandles = null;

            try
            {
                //004
                //bool flag = true;
                int bufferSize = _secondaryBuffer.BufferCaps.dwBufferBytes;
                int latencyBytes = (int)_source.WaveFormat.MillisecondsToBytes(_latency);
                byte[] buffer = new byte[bufferSize];

                _primaryBuffer.Play(DSBPlayFlags.DSBPLAY_LOOPING); //default flags: looping

                //003
                /*if (flag) //could refill buffer
                {*/
                    /*
                     * Setup notify
                     */
                    var waitHandleNull = new EventWaitHandle(false, EventResetMode.AutoReset);
                    var waitHandle0 = new EventWaitHandle(false, EventResetMode.AutoReset);
                    var waitHandleEnd = new EventWaitHandle(false, EventResetMode.AutoReset);

                    waitHandles = new EventWaitHandle[]{ waitHandleNull, waitHandle0, waitHandleEnd };

                    _directSoundNotify = _secondaryBuffer.QueryInterface<DirectSoundNotify>();
                    DSBPositionNotify[] positionNotifies =
                    {
                        new DSBPositionNotify()
                        {
                            dwOffset = DSBPositionNotify.OffsetZero,
                            hEventNotify = waitHandleNull.SafeWaitHandle.DangerousGetHandle()
                        },
                        new DSBPositionNotify()
                        {
                            dwOffset = (uint)_source.WaveFormat.MillisecondsToBytes(_latency),
                            hEventNotify = waitHandle0.SafeWaitHandle.DangerousGetHandle()
                        },
                        new DSBPositionNotify()
                        {
                            dwOffset = DSBPositionNotify.OffsetEnd,
                            hEventNotify = waitHandleEnd.SafeWaitHandle.DangerousGetHandle()
                        }
                    };
                    _directSoundNotify.SetNotificationPositions(positionNotifies);
                    int waitHandleTimeout = waitHandles.Length * _latency;

                    //001
                    /*if (PlaybackState == SoundOut.PlaybackState.Stopped)
                    {
                        _secondaryBuffer.SetCurrentPosition(0);
                        flag = RefillBuffer(buffer, 0, bufferSize);
                    }*/
                    //002
                    _secondaryBuffer.SetCurrentPosition(0);

                    _secondaryBuffer.Play(DSBPlayFlags.DSBPLAY_LOOPING); //default flags: looping

                    _playbackState = SoundOut.PlaybackState.Playing;

                    if (waitHandle != null)
                        waitHandle.Set();

                    while (PlaybackState != SoundOut.PlaybackState.Stopped)
                    {
                        int waitHandleIndex = WaitHandle.WaitAny(waitHandles, waitHandleTimeout, true);
                        bool isTimeOut = waitHandleIndex == WaitHandle.WaitTimeout;

                        //dsound stopped
                        //case of end of buffer or Stop() called: http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.dsbpositionnotify(v=vs.85).aspx
                        bool isBufferStopped = waitHandleIndex == (waitHandles.Length - 1);

                        int sampleOffset = (waitHandleIndex == 0 ? 1 : 0) * latencyBytes;
                        //bug: sampleOffset = count

                        if (isTimeOut == false && isBufferStopped == false)
                        {
                            /*
                             * Refill the buffer
                             */
                            if (RefillBuffer(buffer, sampleOffset, latencyBytes) == false)
                            {
                                _playbackState = SoundOut.PlaybackState.Stopped;
                            }
                        }
                        else
                        {
                            _playbackState = SoundOut.PlaybackState.Stopped;
                        }
                    }
                /*}
                else
                {
                    _playbackState = SoundOut.PlaybackState.Stopped;
                }*/
            }
            finally
            {
                if (_directSoundNotify != null)
                {
                    _directSoundNotify.Dispose();
                    _directSoundNotify = null;
                }
                if (_secondaryBuffer != null)
                {
                    _secondaryBuffer.Stop();
                }
                if (_primaryBuffer != null)
                {
                    _primaryBuffer.Stop();
                }

                if (waitHandles != null)
                {
                    foreach (var wh in waitHandles)
                    {
                        wh.Close();
                    }
                }

                RaiseStopped();
            }
        }
示例#2
0
        private void CleanupRessources()
        {
            if (_directSoundNotify != null)
            {
                _directSoundNotify.Dispose();
                _directSoundNotify = null;
            }
            if (_secondaryBuffer != null)
            {
                _secondaryBuffer.Stop();
                _secondaryBuffer.Dispose();
                _secondaryBuffer = null;
            }
            if (_primaryBuffer != null)
            {
                _primaryBuffer.Stop();
                _primaryBuffer.Dispose();
                _primaryBuffer = null;
            }

            if (_directSound != null)
            {
                _directSound.Dispose();
                _directSound = null;
            }

            //_isInitialized = false;
        }