Esempio n. 1
0
        /// <summary>
        /// Called when we get a new buffer of recorded data
        /// </summary>
        private void Callback(IntPtr waveInHandle, WaveInterop.WaveMessage message, int userData, WaveHeader waveHeader, int reserved)
        {
            if (message == WaveInterop.WaveMessage.WaveInData)
            {
                GCHandle hBuffer = (GCHandle)waveHeader.userData;
                WaveInBuffer buffer = (WaveInBuffer)hBuffer.Target;

                length += buffer.BytesRecorded;
                if (DataAvailable != null)
                {
                    DataAvailable(this, new WaveInEventArgs(buffer.Data, buffer.BytesRecorded));
                }
                if (recording)
                {
                    buffer.Reuse();
                }
                else
                {
                    if (RecordingStopped != null)
                    {
                        RecordingStopped(this, EventArgs.Empty);
                    }
                }
            }
        }
Esempio n. 2
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, deviceNumber, waveFormat, callback, 0, WaveInterop.CallbackFunction);
     }
     else
     {
         result = WaveInterop.waveOutOpenWindow(out waveOutHandle, deviceNumber, waveFormat, this.Handle, 0, WaveInterop.CallbackWindow);
     }
     return result;
 }
Esempio n. 3
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);
     }
 }
Esempio n. 4
0
 /// <summary>
 /// Stop and reset the WaveOut device
 /// </summary>
 public void Stop()
 {
     if (playbackState != PlaybackState.Stopped)
     {
         MmResult result;
         playbackState = PlaybackState.Stopped; // set this here to avoid a problem with some drivers whereby
         // in the call to waveOutReset they don't return until an OnDone is called
         lock (waveOutLock)
         {
             result = WaveInterop.waveOutReset(hWaveOut);
         }
         if (result != MmResult.NoError)
         {
             throw new MmException(result, "waveOutReset");
         }
     }
 }
Esempio n. 5
0
        public long GetPosition()
        {
            long result;

            lock (this.waveOutLock)
            {
                MmTime mmTime = default(MmTime);
                mmTime.wType = 4u;
                MmException.Try(WaveInterop.waveOutGetPosition(this.hWaveOut, out mmTime, Marshal.SizeOf(mmTime)), "waveOutGetPosition");
                if (mmTime.wType != 4u)
                {
                    throw new Exception(string.Format("waveOutGetPosition: wType -> Expected {0}, Received {1}", 4, mmTime.wType));
                }
                result = (long)((ulong)mmTime.cb);
            }
            return(result);
        }
Esempio n. 6
0
 public void Stop()
 {
     if (this.playbackState != PlaybackState.Stopped)
     {
         this.playbackState = PlaybackState.Stopped;
         MmResult mmResult;
         lock (this.waveOutLock)
         {
             mmResult = WaveInterop.waveOutReset(this.hWaveOut);
         }
         if (mmResult != MmResult.NoError)
         {
             throw new MmException(mmResult, "waveOutReset");
         }
         this.callbackEvent.Set();
     }
 }
Esempio n. 7
0
        /// <summary>
        /// Pause the audio
        /// </summary>
        public void Pause()
        {
            if (playbackState == PlaybackState.Playing)
            {
                playbackState = PlaybackState.Paused; // set this here to avoid a deadlock problem with some drivers

                MmResult result;
                lock (waveOutLock)
                {
                    result = WaveInterop.waveOutPause(hWaveOut);
                }
                if (result != MmResult.NoError)
                {
                    throw new MmException(result, "waveOutPause");
                }
            }
        }
Esempio n. 8
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");
        }
Esempio n. 9
0
        private void Exit()
        {
            if (hWaveOut != IntPtr.Zero)
            {
                Stop();
                WaveInterop.waveOutClose(hWaveOut);
                hWaveOut = IntPtr.Zero;
            }

            if (buffers != null)
            {
                for (int n = 0; n < numBuffers; n++)
                {
                    buffers[n].Dispose();
                }
                buffers = null;
            }
        }
Esempio n. 10
0
 private void CloseWaveInDevice()
 {
     if (this.waveInHandle == IntPtr.Zero)
     {
         return;
     }
     WaveInterop.waveInReset(this.waveInHandle);
     if (this.buffers != null)
     {
         for (int i = 0; i < this.buffers.Length; i++)
         {
             this.buffers[i].Dispose();
         }
         this.buffers = null;
     }
     WaveInterop.waveInClose(this.waveInHandle);
     this.waveInHandle = IntPtr.Zero;
 }
Esempio n. 11
0
 public void StopRecording()
 {
     if (this.recording)
     {
         this.recording = false;
         MmException.Try(WaveInterop.waveInStop(this.waveInHandle), "waveInStop");
         for (int i = 0; i < this.buffers.Length; i++)
         {
             int          num          = (i + this.lastReturnedBufferIndex + 1) % this.buffers.Length;
             WaveInBuffer waveInBuffer = this.buffers[num];
             if (waveInBuffer.Done)
             {
                 this.RaiseDataAvailable(waveInBuffer);
             }
         }
         this.RaiseRecordingStopped(null);
     }
 }
        /// <summary>
        /// Gets the current position in bytes from the wave output device.
        /// (n.b. this is not the same thing as the position within your reader
        /// stream - it calls directly into waveOutGetPosition)
        /// </summary>
        /// <returns>Position in bytes</returns>
        public long GetPosition()
        {
            lock (waveOutLock)
            {
                var mmTime = new MmTime();
                mmTime.wType =
                    MmTime.TIME_BYTES; // request results in bytes, TODO: perhaps make this a little more flexible and support the other types?
                MmException.Try(WaveInterop.waveOutGetPosition(hWaveOut, out mmTime, Marshal.SizeOf(mmTime)),
                                "waveOutGetPosition");

                if (mmTime.wType != MmTime.TIME_BYTES)
                {
                    throw new Exception(string.Format("waveOutGetPosition: wType -> Expected {0}, Received {1}",
                                                      MmTime.TIME_BYTES, mmTime.wType));
                }

                return(mmTime.cb);
            }
        }
Esempio n. 13
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;
 }
Esempio n. 14
0
        internal static void SetWaveOutVolume(float value, IntPtr hWaveOut, object lockObject)
        {
            if (value < 0f)
            {
                throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0");
            }
            if (value > 1f)
            {
                throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0");
            }
            int      dwVolume = (int)(value * 65535f) + ((int)(value * 65535f) << 16);
            MmResult result;

            lock (lockObject)
            {
                result = WaveInterop.waveOutSetVolume(hWaveOut, dwVolume);
            }
            MmException.Try(result, "waveOutSetVolume");
        }
Esempio n. 15
0
 public void Stop()
 {
     if (this.playbackState != PlaybackState.Stopped)
     {
         this.playbackState = PlaybackState.Stopped;
         MmResult mmResult;
         lock (this.waveOutLock)
         {
             mmResult = WaveInterop.waveOutReset(this.hWaveOut);
         }
         if (mmResult != MmResult.NoError)
         {
             throw new MmException(mmResult, "waveOutReset");
         }
         if (this.callbackInfo.Strategy == WaveCallbackStrategy.FunctionCallback)
         {
             this.RaisePlaybackStoppedEvent(null);
         }
     }
 }
Esempio n. 16
0
        /// <summary>
        /// Resume playing after a pause from the same position
        /// </summary>
        public void Resume()
        {
            if (Thread.CurrentThread.ManagedThreadId != waveOutThread.ManagedThreadId)
            {
                lock (actionQueue)
                {
                    actionQueue.Enqueue(new WaveOutAction(WaveOutFunction.Resume, null));
                    workAvailable.Set();
                }
                return;
            }

            MmResult result = WaveInterop.waveOutRestart(hWaveOut);

            if (result != MmResult.NoError)
            {
                throw new MmException(result, "waveOutRestart");
            }
            playbackState = PlaybackState.Playing;
        }
Esempio n. 17
0
 /// <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 &gt;1 thread</param>
 // Token: 0x06000BCD RID: 3021 RVA: 0x00023868 File Offset: 0x00021A68
 public WaveOutBuffer(IntPtr hWaveOut, int bufferSize, IWaveProvider bufferFillStream, object waveOutLock)
 {
     this.bufferSize          = bufferSize;
     this.buffer              = new byte[bufferSize];
     this.hBuffer             = GCHandle.Alloc(this.buffer, GCHandleType.Pinned);
     this.hWaveOut            = hWaveOut;
     this.waveStream          = bufferFillStream;
     this.waveOutLock         = waveOutLock;
     this.header              = new WaveHeader();
     this.hHeader             = GCHandle.Alloc(this.header, GCHandleType.Pinned);
     this.header.dataBuffer   = this.hBuffer.AddrOfPinnedObject();
     this.header.bufferLength = bufferSize;
     this.header.loops        = 1;
     this.hThis           = GCHandle.Alloc(this);
     this.header.userData = (IntPtr)this.hThis;
     lock (waveOutLock)
     {
         MmException.Try(WaveInterop.waveOutPrepareHeader(hWaveOut, this.header, Marshal.SizeOf(this.header)), "waveOutPrepareHeader");
     }
 }
Esempio n. 18
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
     }
 }
Esempio n. 19
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. 20
0
 /// <summary>
 /// Releases resources held by this WaveBuffer
 /// </summary>
 // Token: 0x06000BA8 RID: 2984 RVA: 0x00022E9C File Offset: 0x0002109C
 protected void Dispose(bool disposing)
 {
     if (this.waveInHandle != IntPtr.Zero)
     {
         WaveInterop.waveInUnprepareHeader(this.waveInHandle, this.header, Marshal.SizeOf(this.header));
         this.waveInHandle = IntPtr.Zero;
     }
     if (this.hHeader.IsAllocated)
     {
         this.hHeader.Free();
     }
     if (this.hBuffer.IsAllocated)
     {
         this.hBuffer.Free();
     }
     if (this.hThis.IsAllocated)
     {
         this.hThis.Free();
     }
 }
Esempio n. 21
0
        /// <summary>
        /// Stop and reset the WaveOut device
        /// </summary>
        public void Stop()
        {
            if (Thread.CurrentThread.ManagedThreadId != waveOutThread.ManagedThreadId)
            {
                lock (actionQueue)
                {
                    actionQueue.Enqueue(new WaveOutAction(WaveOutFunction.Stop, null));
                    workAvailable.Set();
                }
                return;
            }

            playbackState = PlaybackState.Stopped;
            buffersQueued = false;
            MmResult result = WaveInterop.waveOutReset(hWaveOut);

            if (result != MmResult.NoError)
            {
                throw new MmException(result, "waveOutReset");
            }
        }
 /// <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
 }
        /// <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();
            }

            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);
            }
        }
Esempio n. 24
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");
        }
Esempio n. 25
0
 protected void Dispose(bool disposing)
 {
     this.Stop();
     if (disposing && this.buffers != null)
     {
         for (int i = 0; i < this.buffers.Length; i++)
         {
             if (this.buffers[i] != null)
             {
                 this.buffers[i].Dispose();
             }
         }
         this.buffers = null;
     }
     lock (this.waveOutLock)
     {
         WaveInterop.waveOutClose(this.hWaveOut);
     }
     if (disposing)
     {
         this.callbackInfo.Disconnect();
     }
 }
Esempio n. 26
0
 /// <summary>
 /// Releases resources held by this WaveBuffer
 /// </summary>
 // Token: 0x06000BD0 RID: 3024 RVA: 0x000239A8 File Offset: 0x00021BA8
 protected void Dispose(bool disposing)
 {
     if (this.hHeader.IsAllocated)
     {
         this.hHeader.Free();
     }
     if (this.hBuffer.IsAllocated)
     {
         this.hBuffer.Free();
     }
     if (this.hThis.IsAllocated)
     {
         this.hThis.Free();
     }
     if (this.hWaveOut != IntPtr.Zero)
     {
         lock (this.waveOutLock)
         {
             WaveInterop.waveOutUnprepareHeader(this.hWaveOut, this.header, Marshal.SizeOf(this.header));
         }
         this.hWaveOut = IntPtr.Zero;
     }
 }
Esempio n. 27
0
        //BPCM added
        internal static void SetWaveOutRate(float value, IntPtr hWaveOut, object lockObject)
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException("value", "Rate must be between 0.0 and 4.0");
            }
            if (value > 4)
            {
                throw new ArgumentOutOfRangeException("value", "Rate must be between 0.0 and 4.0");
            }
            ushort hi = (ushort)Math.Floor(value);
            ushort lo = (ushort)Math.Round(0xFFFF * (value - Math.Floor(value)), 0);

            int rateValue = lo + (hi << 16);
            //Debug.WriteLine("lo=" + lo.ToString() + " hi=" + hi.ToString() + " rateValue=" + rateValue.ToString("X"));
            MmResult result;

            lock (lockObject)
            {
                result = WaveInterop.waveOutSetPlaybackRate(hWaveOut, rateValue);
            }
            MmException.Try(result, "waveOutSetPlaybackRate");
        }
Esempio n. 28
0
        /// <summary>
        /// Creates a cue list from the cue RIFF chunk and the list RIFF chunk
        /// </summary>
        /// <param name="cueChunkData">The data contained in the cue chunk</param>
        /// <param name="listChunkData">The data contained in the list chunk</param>
        internal CueList(byte[] cueChunkData, byte[] listChunkData)
        {
            int cueCount = BitConverter.ToInt32(cueChunkData, 0);
            Dictionary <int, int> cueIndex = new Dictionary <int, int>();

            int[] positions = new int[cueCount];
            int   cue       = 0;

            for (int p = 4; cueChunkData.Length - p >= 24; p += 24, cue++)
            {
                cueIndex[BitConverter.ToInt32(cueChunkData, p)] = cue;
                positions[cue] = BitConverter.ToInt32(cueChunkData, p + 20);
            }

            string[] labels      = new string[cueCount];
            int      labelLength = 0;
            int      cueID       = 0;

            Int32 labelChunkID = WaveInterop.mmioStringToFOURCC("labl", 0);

            for (int p = 4; listChunkData.Length - p >= 16; p += labelLength + labelLength % 2 + 12)
            {
                if (BitConverter.ToInt32(listChunkData, p) == labelChunkID)
                {
                    labelLength = BitConverter.ToInt32(listChunkData, p + 4) - 4;
                    cueID       = BitConverter.ToInt32(listChunkData, p + 8);
                    cue         = cueIndex[cueID];
                    labels[cue] = Encoding.Default.GetString(listChunkData, p + 12, labelLength - 1);
                }
            }

            for (int i = 0; i < cueCount; i++)
            {
                cues.Add(new Cue(positions[i], labels[i]));
            }
        }
Esempio n. 29
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. 30
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)
     {
         GCHandle hBuffer = (GCHandle)waveHeader.userData;
         WaveInBuffer buffer = (WaveInBuffer)hBuffer.Target;
         Exception exception = null;
         if (DataAvailable != null)
         {
             DataAvailable(this, new WaveInEventArgs(buffer.Data, buffer.BytesRecorded));
         }
         if (recording)
         {
             try
             {
                 buffer.Reuse();
             }
             catch (Exception e)
             {
                 recording = false;
                 exception = e;
             }
         }
         
         if (!recording)
         {
             RaiseRecordingStopped(exception);
         }
     }
 }
        /// <summary>
        /// Reads the header part of a WAV file from a stream
        /// </summary>
        /// <param name="stream">The stream, positioned at the start of audio data</param>
        /// <param name="format">The format found</param>
        /// <param name="dataChunkPosition">The position of the data chunk</param>
        /// <param name="dataChunkLength">The length of the data chunk</param>
        /// <param name="chunks">Additional chunks found</param>
        public static void ReadWaveHeader(Stream stream, out WaveFormat format, out long dataChunkPosition, out int dataChunkLength, List <RiffChunk> chunks)
        {
            dataChunkPosition = -1;
            format            = null;
            BinaryReader br = new BinaryReader(stream);

            if (br.ReadInt32() != WaveInterop.mmioStringToFOURCC("RIFF", 0))
            {
                throw new FormatException("Not a WAVE file - no RIFF header");
            }
            uint fileSize = br.ReadUInt32(); // read the file size (minus 8 bytes)

            if (br.ReadInt32() != WaveInterop.mmioStringToFOURCC("WAVE", 0))
            {
                throw new FormatException("Not a WAVE file - no WAVE header");
            }

            int dataChunkID   = WaveInterop.mmioStringToFOURCC("data", 0);
            int formatChunkId = WaveInterop.mmioStringToFOURCC("fmt ", 0);

            dataChunkLength = 0;

            // sometimes a file has more data than is specified after the RIFF header
            long stopPosition = Math.Min(fileSize + 8, stream.Length);

            // this -8 is so we can be sure that there are at least 8 bytes for a chunk id and length
            while (stream.Position <= stopPosition - 8)
            {
                Int32 chunkIdentifier = br.ReadInt32();
                Int32 chunkLength     = br.ReadInt32();
                if (chunkIdentifier == dataChunkID)
                {
                    dataChunkPosition = stream.Position;
                    dataChunkLength   = chunkLength;
                    stream.Position  += chunkLength;
                }
                else if (chunkIdentifier == formatChunkId)
                {
                    format = WaveFormat.FromFormatChunk(br, chunkLength);
                }
                else
                {
                    // check for invalid chunk length
                    if (chunkLength < 0 || chunkLength > stream.Length - stream.Position)
                    {
                        Debug.Assert(false, String.Format("Invalid chunk length {0}, pos: {1}. length: {2}",
                                                          chunkLength, stream.Position, stream.Length));
                        // an exception will be thrown further down if we haven't got a format and data chunk yet,
                        // otherwise we will tolerate this file despite it having corrupt data at the end
                        break;
                    }
                    if (chunks != null)
                    {
                        chunks.Add(new RiffChunk(chunkIdentifier, chunkLength, stream.Position));
                    }
                    stream.Position += chunkLength;
                }
            }

            if (format == null)
            {
                throw new FormatException("Invalid WAV file - No fmt chunk found");
            }
            if (dataChunkPosition == -1)
            {
                throw new FormatException("Invalid WAV file - No data chunk found");
            }
        }
Esempio n. 32
0
 public WaveWindow(WaveInterop.WaveCallback waveCallback)
 {
     this.waveCallback = waveCallback;
 }
Esempio n. 33
0
 /// <summary>
 /// Place this buffer back to record more audio
 /// </summary>
 // Token: 0x06000BA5 RID: 2981 RVA: 0x00022DDC File Offset: 0x00020FDC
 public void Reuse()
 {
     MmException.Try(WaveInterop.waveInUnprepareHeader(this.waveInHandle, this.header, Marshal.SizeOf(this.header)), "waveUnprepareHeader");
     MmException.Try(WaveInterop.waveInPrepareHeader(this.waveInHandle, this.header, Marshal.SizeOf(this.header)), "waveInPrepareHeader");
     MmException.Try(WaveInterop.waveInAddBuffer(this.waveInHandle, this.header, Marshal.SizeOf(this.header)), "waveInAddBuffer");
 }
Esempio n. 34
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);
             }
         }
     }
 }
        /// <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)
            {
                var hBuffer = (GCHandle)waveHeader.userData;
                var buffer = (WaveInBuffer)hBuffer.Target;

                if (recording)
                {
                    lastReturnedBufferIndex = Array.IndexOf(buffers, buffer);
                    RaiseDataAvailable(buffer);
                    try
                    {
                        buffer.Reuse();
                    }
                    catch (Exception e)
                    {
                        recording = false;
                        RaiseRecordingStopped(e);
                    }
                }

            }
        }
Esempio n. 36
0
 /// <summary>
 /// Stop recording
 /// </summary>
 public void StopRecording()
 {
     recording = false;
     this.callbackEvent.Set(); // signal the thread to exit
     MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop");
 }
Esempio n. 37
0
 private void SetVolume(int stereoVolume)
 {
     MmException.Try(WaveInterop.waveOutSetVolume(hWaveOut, stereoVolume), "waveOutSetVolume");
 }
Esempio n. 38
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;
                // 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. 39
0
 public void StopRecording()
 {
     this.recording = false;
     this.callbackEvent.Set();
     MmException.Try(WaveInterop.waveInStop(this.waveInHandle), "waveInStop");
 }
Esempio n. 40
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)
            {
                // 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
            }
        }