Exemple #1
0
        /// <summary>
        /// Pause the audio
        /// </summary>
        public void Pause()
        {
            if (m_PlaybackState != PlaybackState.Playing)
            {
                return;
            }

            MmResult result;

            m_PlaybackState = PlaybackState.Paused; // set this here to avoid a deadlock problem with some drivers
            lock (WaveOutLock)
                result = WaveInterop.waveOutPause(DeviceHandle);

            if (result != MmResult.NoError)
            {
                throw new MmException(result, nameof(WaveInterop.waveOutPause));
            }
        }
Exemple #2
0
        /// <summary>
        /// Resume playing after a pause from the same position
        /// </summary>
        private void Resume()
        {
            if (m_PlaybackState != PlaybackState.Paused)
            {
                return;
            }

            MmResult result;

            lock (WaveOutLock)
                result = WaveInterop.waveOutRestart(DeviceHandle);

            if (result != MmResult.NoError)
            {
                throw new MmException(result, nameof(WaveInterop.waveOutRestart));
            }

            m_PlaybackState = PlaybackState.Playing;
        }
        private GCHandle hThis;   // for the user callback

        /// <summary>
        /// creates a new wavebuffer
        /// </summary>
        /// <param name="hWaveOut">WaveOut device to write to</param>
        /// <param name="bufferSize">Buffer size in bytes</param>
        /// <param name="bufferFillStream">Stream to provide more data</param>
        /// <param name="waveOutLock">Lock to protect WaveOut API's from being called on >1 thread</param>
        public WaveOutBuffer(IntPtr hWaveOut, Int32 bufferSize, IWaveProvider bufferFillStream, object waveOutLock)
        {
            this.bufferSize  = bufferSize;
            buffer           = new byte[bufferSize];
            hBuffer          = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            this.hWaveOut    = hWaveOut;
            waveStream       = bufferFillStream;
            this.waveOutLock = waveOutLock;

            header              = new WaveHeader();
            hHeader             = GCHandle.Alloc(header, GCHandleType.Pinned);
            header.dataBuffer   = hBuffer.AddrOfPinnedObject();
            header.bufferLength = bufferSize;
            header.loops        = 1;
            hThis           = GCHandle.Alloc(this);
            header.userData = (IntPtr)hThis;
            lock (waveOutLock)
            {
                MmException.Try(WaveInterop.waveOutPrepareHeader(hWaveOut, header, Marshal.SizeOf(header)), "waveOutPrepareHeader");
            }
        }
Exemple #4
0
        /// <summary>
        /// Initializes the specified wave provider.
        /// </summary>
        /// <param name="waveProvider">The wave provider.</param>
        /// <exception cref="System.InvalidOperationException">Can't re-initialize during playback</exception>
        public void Init(IWaveProvider waveProvider)
        {
            if (m_PlaybackState != PlaybackState.Stopped)
            {
                throw new InvalidOperationException("Can't re-initialize during playback");
            }

            if (DeviceHandle != 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();
            }

            CallbackEvent = new AutoResetEvent(false);

            WaveStream = waveProvider;
            var bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);

            MmResult result;

            lock (WaveOutLock)
            {
                result = WaveInterop.waveOutOpenWindow(out DeviceHandle, (IntPtr)DeviceNumber, WaveStream.WaveFormat,
                                                       CallbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent);
            }

            MmException.Try(result, nameof(WaveInterop.waveOutOpen));

            Buffers         = new WaveOutBuffer[NumberOfBuffers];
            m_PlaybackState = PlaybackState.Stopped;
            for (var n = 0; n < NumberOfBuffers; n++)
            {
                Buffers[n] = new WaveOutBuffer(DeviceHandle, bufferSize, WaveStream, WaveOutLock);
            }
        }
Exemple #5
0
        /// <summary>
        /// Stop and reset the WaveOut device
        /// </summary>
        public void Stop()
        {
            if (m_PlaybackState != PlaybackState.Stopped)
            {
                return;
            }

            // in the call to waveOutReset with function callbacks
            // some drivers will block here until OnDone is called
            // for every buffer
            m_PlaybackState = PlaybackState.Stopped; // set this here to avoid a problem with some drivers whereby
            MmResult result;

            lock (WaveOutLock)
                result = WaveInterop.waveOutReset(DeviceHandle);

            if (result != MmResult.NoError)
            {
                throw new MmException(result, nameof(WaveInterop.waveOutReset));
            }

            CallbackEvent.Set(); // give the thread a kick, make sure we exit
        }