예제 #1
0
        private void PlaybackProc(object o)
        {
            var waitHandle = o as EventWaitHandle;

            WaitHandle[] waitHandles = null;

            Exception exception = null;

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

                _primaryBuffer.Play(DSBPlayFlags.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 WaitHandle[] { waitHandleNull, waitHandle0, waitHandleEnd };

                _directSoundNotify = _secondaryBuffer.QueryInterface <DirectSoundNotify>();
                DSBPositionNotify[] positionNotifies =
                {
                    new DSBPositionNotify
                    {
                        Offset            = DSBPositionNotify.OffsetZero,
                        EventNotifyHandle = waitHandleNull.SafeWaitHandle.DangerousGetHandle()
                    },
                    new DSBPositionNotify
                    {
                        Offset            = (int)_source.WaveFormat.MillisecondsToBytes(_latency),
                        EventNotifyHandle = waitHandle0.SafeWaitHandle.DangerousGetHandle()
                    },
                    new DSBPositionNotify
                    {
                        Offset            = DSBPositionNotify.OffsetStop,
                        EventNotifyHandle = 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.Looping); //default flags: looping

                _playbackState = PlaybackState.Playing;

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


                while (PlaybackState != 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 = PlaybackState.Stopped;
                        }
                    }
                    else
                    {
                        _playbackState = PlaybackState.Stopped;
                    }
                }

                /*}
                 * else
                 * {
                 *  _playbackState = SoundOut.PlaybackState.Stopped;
                 * }*/
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            finally
            {
                if (_directSoundNotify != null)
                {
                    _directSoundNotify.Dispose();
                    _directSoundNotify = null;
                }
                if (_secondaryBuffer != null)
                {
                    _secondaryBuffer.Stop();
                }
                if (_primaryBuffer != null)
                {
                    _primaryBuffer.Stop();
                }

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

                RaiseStopped(exception);
            }
        }