Esempio n. 1
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">WaveProvider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            if (playbackState != PlaybackState.Stopped)
            {
                throw new InvalidOperationException("Can't re-initialize during playback");
            }
            if (hWaveOut != IntPtr.Zero)
            {
                // normally we don't allow calling Init twice, but as experiment, see if we can clean up and go again
                // try to allow reuse of this waveOut device
                // n.b. risky if Playback thread has not exited
                DisposeBuffers();
                CloseWaveOut();
            }

            this.callbackEvent = new AutoResetEvent(false);

            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);

            MmResult result;

            lock (waveOutLock)
            {
                result = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent);
            }
            MmException.Try(result, "waveOutOpen");

            buffers       = new WaveOutBuffer[NumberOfBuffers];
            playbackState = PlaybackState.Stopped;
            for (int n = 0; n < NumberOfBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">Wave provider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            if (Thread.CurrentThread.ManagedThreadId != waveOutThread.ManagedThreadId)
            {
                lock (actionQueue)
                {
                    actionQueue.Enqueue(new WaveOutAction(WaveOutFunction.Init, waveStream));
                    workAvailable.Set();
                }
                return;
            }

            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize(desiredLatency);  //waveStream.GetReadSize((desiredLatency + 2) / 3);

            this.numBuffers = 3;

            MmException.Try(WaveInterop.waveOutOpen(out hWaveOut, (IntPtr)devNumber, waveStream.WaveFormat, callback, IntPtr.Zero, WaveInterop.CallbackFunction), "waveOutOpen");

            buffers       = new WaveOutBuffer[numBuffers];
            playbackState = PlaybackState.Stopped;
            object waveOutLock = new object();

            for (int n = 0; n < numBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }
Esempio n. 3
0
 private void Callback(IntPtr hWaveOut, WaveInterop.WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved)
 {
     if (uMsg == WaveInterop.WaveMessage.WaveOutDone)
     {
         WaveOutBuffer waveOutBuffer = (WaveOutBuffer)((GCHandle)wavhdr.userData).Target;
         Interlocked.Decrement(ref this.queuedBuffers);
         Exception e = null;
         if (this.PlaybackState == PlaybackState.Playing)
         {
             lock (this.waveOutLock)
             {
                 try
                 {
                     if (waveOutBuffer.OnDone())
                     {
                         Interlocked.Increment(ref this.queuedBuffers);
                     }
                 }
                 catch (Exception ex)
                 {
                     e = ex;
                 }
             }
         }
         if (this.queuedBuffers == 0)
         {
             if (this.callbackInfo.Strategy == WaveCallbackStrategy.FunctionCallback && this.playbackState == PlaybackState.Stopped)
             {
                 return;
             }
             this.playbackState = PlaybackState.Stopped;
             this.RaisePlaybackStoppedEvent(e);
         }
     }
 }
Esempio n. 4
0
 private void OnBufferDone(WaveOutBuffer buffer)
 {
     if (playbackState == PlaybackState.Playing)
     {
         if (!buffer.OnDone())
         {
             playbackState = PlaybackState.Stopped;
             RaisePlaybackStopped();
         }
     }
 }
Esempio n. 5
0
 // made non-static so that playing can be stopped here
 private void Callback(IntPtr hWaveOut, WaveInterop.WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved)
 {
     if (uMsg == WaveInterop.WaveMessage.WaveOutDone)
     {
         GCHandle      hBuffer = (GCHandle)wavhdr.userData;
         WaveOutBuffer buffer  = (WaveOutBuffer)hBuffer.Target;
         Interlocked.Decrement(ref queuedBuffers);
         Exception exception = null;
         // check that we're not here through pressing stop
         if (PlaybackState == PlaybackState.Playing)
         {
             // to avoid deadlocks in Function callback mode,
             // we lock round this whole thing, which will include the
             // reading from the stream.
             // this protects us from calling waveOutReset on another
             // thread while a WaveOutWrite is in progress
             lock (waveOutLock)
             {
                 try
                 {
                     if (buffer.OnDone())
                     {
                         Interlocked.Increment(ref queuedBuffers);
                     }
                 }
                 catch (Exception e)
                 {
                     // one likely cause is soundcard being unplugged
                     NAudioLogger.Instance.LogError(e.Message);
                     exception = e;
                 }
             }
         }
         if (queuedBuffers == 0)
         {
             if (callbackInfo.Strategy == WaveCallbackStrategy.FunctionCallback && playbackState == Wave.PlaybackState.Stopped)
             {
                 // the user has pressed stop
                 // DO NOT raise the playback stopped event from here
                 // since on the main thread we are still in the waveOutReset function
                 // Playback stopped will be raised elsewhere
             }
             else
             {
                 playbackState = PlaybackState.Stopped; // set explicitly for when we reach the end of the audio
                 RaisePlaybackStoppedEvent(exception);
             }
         }
     }
 }
Esempio n. 6
0
        // made non-static so that playing can be stopped here
        private void Callback(IntPtr hWaveOut, WaveInterop.WaveMessage uMsg, IntPtr dwUser, WaveHeader wavhdr, IntPtr dwReserved)
        {
            if (uMsg == WaveInterop.WaveMessage.WaveOutDone)
            {
                // check that we're not here through pressing stop
                GCHandle      hBuffer = (GCHandle)wavhdr.userData;
                WaveOutBuffer buffer  = (WaveOutBuffer)hBuffer.Target;

                lock (actionQueue)
                {
                    actionQueue.Enqueue(new WaveOutAction(WaveOutFunction.BufferDone, buffer));
                    workAvailable.Set();
                }

                // n.b. this was wrapped in an exception handler, but bug should be fixed now
            }
        }
Esempio n. 7
0
        // made non-static so that playing can be stopped here
        private void Callback(IntPtr hWaveOut, WaveInterop.WaveMessage uMsg, Int32 dwUser, WaveHeader wavhdr, int dwReserved)
        {
            if (uMsg == WaveInterop.WaveMessage.WaveOutDone)
            {
                GCHandle      hBuffer = (GCHandle)wavhdr.userData;
                WaveOutBuffer buffer  = (WaveOutBuffer)hBuffer.Target;
                // check that we're not here through pressing stop
                if (PlaybackState == PlaybackState.Playing)
                {
                    if (!buffer.OnDone())
                    {
                        playbackState = PlaybackState.Stopped;
                        RaisePlaybackStoppedEvent();
                    }
                }

                // n.b. this was wrapped in an exception handler, but bug should be fixed now
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">WaveProvider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);            

            MmResult result;
            lock (waveOutLock)
            {
                result = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent);
            }
            MmException.Try(result, "waveOutOpen");

            buffers = new WaveOutBuffer[NumberOfBuffers];
            playbackState = PlaybackState.Stopped;
            for (int n = 0; n < NumberOfBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">WaveProvider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);

            MmResult result;

            lock (waveOutLock)
            {
                result = callbackInfo.WaveOutOpen(out hWaveOut, DeviceNumber, waveStream.WaveFormat, callback);
            }
            MmException.Try(result, "waveOutOpen");

            buffers       = new WaveOutBuffer[NumberOfBuffers];
            playbackState = PlaybackState.Stopped;
            for (int n = 0; n < NumberOfBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">WaveProvider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);

            MmResult result;

            lock (waveOutLock)
            {
                result = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent);
            }
            MmException.Try(result, "waveOutOpen");

            buffers       = new WaveOutBuffer[NumberOfBuffers];
            playbackState = PlaybackState.Stopped;
            for (int n = 0; n < NumberOfBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }
Esempio n. 11
0
        // made non-static so that playing can be stopped here
        private void Callback(IntPtr hWaveOut, WaveInterop.WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved)
        {
            if (uMsg == WaveInterop.WaveMessage.WaveOutDone)
            {
                GCHandle      hBuffer = (GCHandle)wavhdr.userData;
                WaveOutBuffer buffer  = (WaveOutBuffer)hBuffer.Target;
                Interlocked.Decrement(ref queuedBuffers);
                // check that we're not here through pressing stop
                if (PlaybackState == PlaybackState.Playing)
                {
                    // to avoid deadlocks in Function callback mode,
                    // we lock round this whole thing, which will include the
                    // reading from the stream.
                    // this protects us from calling waveOutReset on another
                    // thread while a WaveOutWrite is in progress
                    lock (waveOutLock)
                    {
                        if (buffer.OnDone())
                        {
                            Interlocked.Increment(ref queuedBuffers);
                        }
                    }
                }
                if (queuedBuffers == 0)
                {
                    if (callbackInfo.Strategy == WaveCallbackStrategy.FunctionCallback && playbackState == Wave.PlaybackState.Stopped)
                    {
                        // the user has pressed stop
                        // DO NOT raise the playback stopped event from here
                        // since on the main thread we are still in the waveOutReset function
                        // Playback stopped will be raised elsewhere
                    }
                    else
                    {
                        RaisePlaybackStoppedEvent();
                    }
                }

                // n.b. this was wrapped in an exception handler, but bug should be fixed now
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">WaveProvider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            if (playbackState != PlaybackState.Stopped)
            {
                throw new InvalidOperationException("Can't re-initialize during playback");
            }
            if (hWaveOut != IntPtr.Zero)
            {
                // normally we don't allow calling Init twice, but as experiment, see if we can clean up and go again
                // try to allow reuse of this waveOut device
                // n.b. risky if Playback thread has not exited
                DisposeBuffers();
                CloseWaveOut();
            }

            this.callbackEvent = new AutoResetEvent(false);

            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);            

            MmResult result;
            lock (waveOutLock)
            {
                result = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent);
            }
            MmException.Try(result, "waveOutOpen");

            buffers = new WaveOutBuffer[NumberOfBuffers];
            playbackState = PlaybackState.Stopped;
            for (int n = 0; n < NumberOfBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }
Esempio n. 13
0
 private void OnBufferDone(WaveOutBuffer buffer)
 {
     if (playbackState == PlaybackState.Playing)
     {
         if (!buffer.OnDone())
         {
             playbackState = PlaybackState.Stopped;
             RaisePlaybackStopped();
         }
     }
 }
Esempio n. 14
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">Wave provider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            if(Thread.CurrentThread.ManagedThreadId != waveOutThread.ManagedThreadId)
            {
                lock(actionQueue)
                {
                    actionQueue.Enqueue(new WaveOutAction(WaveOutFunction.Init,waveStream));
                    workAvailable.Set();
                }
                return;
            }

            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize(desiredLatency);  //waveStream.GetReadSize((desiredLatency + 2) / 3);
            this.numBuffers = 3;

            MmException.Try(WaveInterop.waveOutOpen(out hWaveOut, devNumber, waveStream.WaveFormat, callback, 0, WaveInterop.CallbackFunction), "waveOutOpen");

            buffers = new WaveOutBuffer[numBuffers];
            playbackState = PlaybackState.Stopped;
            object waveOutLock = new object();
            for (int n = 0; n < numBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">WaveProvider to play</param>
        public void Init(IWaveProvider waveProvider)
        {
            this.waveStream = waveProvider;
            int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);

            MmResult result;
            lock (waveOutLock)
            {
                result = callbackInfo.WaveOutOpen(out hWaveOut, DeviceNumber, waveStream.WaveFormat, callback);
            }
            MmException.Try(result, "waveOutOpen");

            buffers = new WaveOutBuffer[NumberOfBuffers];
            playbackState = PlaybackState.Stopped;
            for (int n = 0; n < NumberOfBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
        }