Beispiel #1
0
 internal MmResult WaveOutOpen(out IntPtr waveOutHandle, int deviceNumber, WaveFormat waveFormat, WaveInterop.WaveCallback callback)
 {
     MmResult result;
     if (Strategy == WaveCallbackStrategy.FunctionCallback)
     {
         result = WaveInterop.waveOutOpen(out waveOutHandle, (IntPtr)deviceNumber, waveFormat, callback, IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackFunction);
     }
     else
     {
         result = WaveInterop.waveOutOpenWindow(out waveOutHandle, (IntPtr)deviceNumber, waveFormat, this.Handle, IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackWindow);
     }
     return result;
 }
Beispiel #2
0
 internal void Connect(WaveInterop.WaveCallback callback)
 {
     if (Strategy == WaveCallbackStrategy.NewWindow)
     {
         waveOutWindow = new WaveWindow(callback);
         waveOutWindow.CreateControl();
         this.Handle = waveOutWindow.Handle;
     }
     else if (Strategy == WaveCallbackStrategy.ExistingWindow)
     {
         waveOutWindowNative = new WaveWindowNative(callback);
         waveOutWindowNative.AssignHandle(this.Handle);
     }
 }
Beispiel #3
0
        private GCHandle hThis;   // for the user callback

        /// <summary>
        /// creates a new wavebuffer
        /// </summary>
        /// <param name="waveInHandle">WaveIn device to write to</param>
        /// <param name="bufferSize">Buffer size in bytes</param>
        public WaveInBuffer(IntPtr waveInHandle, Int32 bufferSize)
        {
            this.bufferSize   = bufferSize;
            this.buffer       = new byte[bufferSize];
            this.hBuffer      = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            this.waveInHandle = waveInHandle;

            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;

            MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader");
            //MmException.Try(WaveInterop.waveInAddBuffer(waveInHandle, header, Marshal.SizeOf(header)), "waveInAddBuffer");
        }
Beispiel #4
0
 private void CloseWaveInDevice()
 {
     if (waveInHandle == IntPtr.Zero)
     {
         return;
     }
     // Some drivers need the reset to properly release buffers
     WaveInterop.waveInReset(waveInHandle);
     if (buffers != null)
     {
         for (int n = 0; n < buffers.Length; n++)
         {
             buffers[n].Dispose();
         }
         buffers = null;
     }
     WaveInterop.waveInClose(waveInHandle);
     waveInHandle = IntPtr.Zero;
 }
Beispiel #5
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
     }
 }
Beispiel #6
0
        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;
            this.buffer      = new byte[bufferSize];
            this.hBuffer     = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            this.hWaveOut    = hWaveOut;
            this.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");
            }
        }
Beispiel #7
0
 /// <summary>
 /// Stop recording
 /// </summary>
 public void StopRecording()
 {
     if (recording)
     {
         recording = false;
         MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop");
         // report the last buffers, sometimes more than one, so taking care to report them in the right order
         for (int n = 0; n < buffers.Length; n++)
         {
             int index  = (n + lastReturnedBufferIndex + 1) % buffers.Length;
             var buffer = buffers[index];
             if (buffer.Done)
             {
                 RaiseDataAvailable(buffer);
             }
         }
         RaiseRecordingStopped(null);
     }
     //MmException.Try(WaveInterop.waveInReset(waveInHandle), "waveInReset");
     // Don't actually close yet so we get the last buffer
 }
Beispiel #8
0
        internal static void SetWaveOutVolume(float value, IntPtr hWaveOut, object lockObject)
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0");
            }
            if (value > 1)
            {
                throw new ArgumentOutOfRangeException("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");
        }
Beispiel #9
0
 /// <summary>
 /// Called when we get a new buffer of recorded data
 /// </summary>
 private void Callback(IntPtr waveInHandle, WaveInterop.WaveMessage message, IntPtr userData, WaveHeader waveHeader, IntPtr reserved)
 {
     if (message == WaveInterop.WaveMessage.WaveInData)
     {
         if (recording)
         {
             var hBuffer = (GCHandle)waveHeader.userData;
             var buffer = (WaveInBuffer)hBuffer.Target;
             if (buffer == null) return;
         
             lastReturnedBufferIndex = Array.IndexOf(buffers, buffer);
             RaiseDataAvailable(buffer);
             try
             {
                 buffer.Reuse();
             }
             catch (Exception e)
             {
                 recording = false;
                 RaiseRecordingStopped(e);
             }
         }
         
     }
 }
Beispiel #10
0
 /// <summary>
 /// Stop recording
 /// </summary>
 public void StopRecording()
 {
     recording = false;
     this.callbackEvent.Set(); // signal the thread to exit
     MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop");
 }
Beispiel #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);
         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
                     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);
             }
         }
     }
 }