Exemple #1
0
        private GCHandle hHeader; // we need to pin the header structure

        /// <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;
            bufferPtr       = Marshal.AllocHGlobal(bufferSize);

            this.hWaveOut    = hWaveOut;
            waveStream       = bufferFillStream;
            this.waveOutLock = waveOutLock;

            header              = new WaveHeader();
            hHeader             = GCHandle.Alloc(header, GCHandleType.Pinned);
            header.dataBuffer   = bufferPtr;
            header.bufferLength = bufferSize;
            header.loops        = 1;
            lock (waveOutLock)
            {
                MmException.Try(WaveInterop.waveOutPrepareHeader(hWaveOut, header, Marshal.SizeOf(header)), "waveOutPrepareHeader");
            }
        }
Exemple #2
0
 /// <summary>
 /// Releases resources held by this WaveBuffer
 /// </summary>
 protected void Dispose(bool disposing)
 {
     if (disposing)
     {
         // free managed resources
     }
     // free unmanaged resources
     if (hHeader.IsAllocated)
     {
         hHeader.Free();
     }
     if (hWaveOut != IntPtr.Zero)
     {
         lock (waveOutLock)
         {
             WaveInterop.waveOutUnprepareHeader(hWaveOut, header, Marshal.SizeOf(header));
         }
         hWaveOut = IntPtr.Zero;
     }
 }
Exemple #3
0
 /// <summary>
 /// Stop and reset the WaveOut device
 /// </summary>
 public void Stop()
 {
     if (playbackState != PlaybackState.Stopped)
     {
         // in the call to waveOutReset with function callbacks
         // some drivers will block here until OnDone is called
         // for every buffer
         playbackState = PlaybackState.Stopped; // set this here to avoid a problem with some drivers whereby
         MmResult result;
         lock (waveOutLock)
         {
             result = WaveInterop.waveOutReset(hWaveOut);
         }
         if (result != MmResult.NoError)
         {
             throw new MmException(result, "waveOutReset");
         }
         callbackEvent.Set(); // give the thread a kick, make sure we exit
     }
 }
Exemple #4
0
        internal static void SetWaveOutVolume(float value, IntPtr hWaveOut, object lockObject)
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(value), "Volume must be between 0.0 and 1.0");
            }
            if (value > 1)
            {
                throw new ArgumentOutOfRangeException(nameof(value), "Volume must be between 0.0 and 1.0");
            }
            float left  = value;
            float right = value;

            int      stereoVolume = (int)(left * 0xFFFF) + ((int)(right * 0xFFFF) << 16);
            MmResult result;

            lock (lockObject)
            {
                result = WaveInterop.waveOutSetVolume(hWaveOut, stereoVolume);
            }
            MmException.Try(result, "waveOutSetVolume");
        }
Exemple #5
0
        /// <summary>
        /// Initialises the WaveOut device
        /// </summary>
        /// <param name="waveProvider">WaveProvider to play</param>
        public Task InitAsync(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();
            }

            callbackEvent = new AutoResetEvent(false);

            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 (var n = 0; n < NumberOfBuffers; n++)
            {
                buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
            }
            return(Task.CompletedTask);
        }