protected override void WndProc(ref Message m) { switch (m.Msg) { case (int)WaveMsg.WOM_DONE: case (int)WaveMsg.WIM_DATA: { WaveHeader header = new WaveHeader(); IntPtr waveOutHandle = m.WParam; System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, header); //header von wparam _waveCallback(waveOutHandle, (WaveMsg)m.Msg, UIntPtr.Zero, header, UIntPtr.Zero); break; } case (int)WaveMsg.WOM_OPEN: case (int)WaveMsg.WOM_CLOSE: case (int)WaveMsg.WIM_CLOSE: case (int)WaveMsg.WIM_OPEN: { _waveCallback(m.WParam, (WaveMsg)m.Msg, UIntPtr.Zero, null, UIntPtr.Zero); break; } default: base.WndProc(ref m); break; } }
protected virtual void Dispose(bool disposing) { lock (_waveOut.LockObj) { if (_header == null || _waveOut.WaveOutHandle == IntPtr.Zero) { return; } try { MmException.Try(MMInterops.waveOutUnprepareHeader(_waveOut.WaveOutHandle, _header, Marshal.SizeOf(_header)), "waveOutUnprepareHeader"); //don't throw? } catch (MmException ex) { if (ex.Result != MmResult.WAVERR_STILLPLAYING) { throw; //can't fix bug } } if (_bufferHandle.IsAllocated) { _bufferHandle.Free(); } if (_headerHandle.IsAllocated) { _headerHandle.Free(); } if (_userDataHandle.IsAllocated) { _userDataHandle.Free(); } _header = null; } }
public void Initialize() { _buffer = new byte[_bufferSize]; _header = new WaveHeader(); _headerHandle = GCHandle.Alloc(_header, GCHandleType.Pinned); _bufferHandle = GCHandle.Alloc(_buffer, GCHandleType.Pinned); _userDataHandle = GCHandle.Alloc(this); _header.bufferLength = _bufferSize; _header.dataBuffer = _bufferHandle.AddrOfPinnedObject(); _header.loops = 1; _header.userData = (IntPtr)_userDataHandle; Prepare(); AddBuffer(); }
public void Initialize() { _buffer = new byte[_bufferSize]; WaveHeader header = new WaveHeader(); _headerHandle = GCHandle.Alloc(header); _userDataHandle = GCHandle.Alloc(this); _bufferHandle = GCHandle.Alloc(_buffer, GCHandleType.Pinned); header.userData = (IntPtr)_userDataHandle; header.loops = 1; header.dataBuffer = _bufferHandle.AddrOfPinnedObject(); header.bufferLength = _bufferSize; _header = header; lock (_waveOut.LockObj) { MmException.Try(MMInterops.waveOutPrepareHeader(_waveOut.WaveOutHandle, header, Marshal.SizeOf(header)), "waveOutPrepareHeader"); } }
protected override void WndProc(ref Message m) { switch (m.Msg) { case (int)WaveMsg.WOM_DONE: case (int)WaveMsg.WIM_DATA: WaveHeader header = new WaveHeader(); IntPtr hWaveOut = m.WParam; System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, header); //header von wparam _waveCallback(hWaveOut, (WaveMsg)m.Msg, UIntPtr.Zero, header, UIntPtr.Zero); break; case (int)WaveMsg.WOM_OPEN: case (int)WaveMsg.WOM_CLOSE: case (int)WaveMsg.WIM_CLOSE: //WaveIn Messages für spätere WaveIn implementierung case (int)WaveMsg.WIM_OPEN: _waveCallback(m.WParam, (WaveMsg)m.Msg, UIntPtr.Zero, null, UIntPtr.Zero); break; default: base.WndProc(ref m); break; } }
public static extern MmResult waveInUnprepareHeader(IntPtr hWaveIn, WaveHeader waveHdr, int headerSize);
protected virtual void Callback(IntPtr handle, WaveMsg msg, UIntPtr user, WaveHeader header, UIntPtr reserved) { if (_hWaveOut != handle) return; //message does not belong to this waveout instance if (msg == WaveMsg.WOM_DONE) { GCHandle hBuffer = (GCHandle)header.userData; WaveOutBuffer buffer = hBuffer.Target as WaveOutBuffer; System.Threading.Interlocked.Decrement(ref _activeBuffers); if (buffer == null) return; if (_playbackState != SoundOut.PlaybackState.Stopped) { lock (_lockObj) { if (buffer.WriteData()) System.Threading.Interlocked.Increment(ref _activeBuffers); } } if (_activeBuffers == 0) { _playbackState = SoundOut.PlaybackState.Stopped; RaiseStopped(); } } else if (msg == WaveMsg.WOM_CLOSE) { var state = _playbackState; _playbackState = SoundOut.PlaybackState.Stopped; if (state != SoundOut.PlaybackState.Stopped) RaiseStopped(); Debug.WriteLine("WaveOut::Callback: Closing WaveOut."); } }
public static extern MmResult waveOutUnprepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);
public static extern MmResult waveOutWrite(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);
private void Callback(IntPtr handle, WaveMsg msg, IntPtr user, WaveHeader header, IntPtr reserved) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId + "|" + msg); if (_waveOutHandle != handle) return; if (msg == WaveMsg.WOM_DONE) { if (_callbackThread == null) { _callbackThread = Thread.CurrentThread; Debug.WriteLine("CallbackThread: " + Thread.CurrentThread.ManagedThreadId); } Debug.Assert(_callbackThread == Thread.CurrentThread, "Strange thread?"); var index = (int) header.userData; WaveOutBuffer buffer = _buffers[index]; Interlocked.Decrement(ref _activeBuffers); /* * The Play method starts all buffers. * In order to do that, it calls the waveOutWrite function. * If there is a delay between buffer0 and buffer1 * and buffer0 gets fired through this callback, the * waveOutWrite method for buffer1 can't be called * -> deadlock since the callback method waits until the * Play method releases the lock. * In order to avoid that, we are using a timeout of 10ms. * If the timeout exceeds, the index of the buffer gets * saved and fired within the next callback. * */ if (Monitor.TryEnter(_lockObject, 10)) { try { callback0: if (buffer != null && PlaybackState != PlaybackState.Stopped) { try { FireUpBuffer(buffer); } catch (Exception exception) { StopFromCallback(exception); } } if (_failedBuffers.Count > 0) { //continue until we find a buffer that failed and is not in queue. while (_failedBuffers.Count > 0 && (buffer = _buffers[(index = _failedBuffers.Dequeue())]).IsQueued == false) { Debug.WriteLine("Already queued:" + index); } if (buffer != null && !buffer.IsQueued) { Debug.WriteLine("Failed buffer: " + index); goto callback0; } } } finally { Monitor.Exit(_lockObject); } } else { _failedBuffers.Enqueue(index); } if (_activeBuffers <= 0) StopFromCallback(null); } else if (msg == WaveMsg.WOM_CLOSE) { if (PlaybackState != PlaybackState.Stopped) StopFromCallback(null); } else if (msg == WaveMsg.WOM_OPEN) Debug.WriteLine("open"); }
protected virtual void Callback(IntPtr handle, WaveMsg msg, UIntPtr user, WaveHeader header, UIntPtr reserved) { if (msg == WaveMsg.WIM_DATA) { if (!stopped) { var buffer = ((GCHandle)header.userData).Target as WaveInBuffer; RaiseDataAvailable(buffer); try { buffer.Reset(); } catch (MmException) { stopped = true; RaiseStopped(); } } } else if (msg == WaveMsg.WIM_CLOSE) { RaiseStopped(); } }
public static extern MmResult waveInAddBuffer(IntPtr hWaveIn, WaveHeader waveHdr, int headerSize);
public static extern MmResult waveInPrepareHeader(IntPtr hWaveIn, WaveHeader waveHdr, int headerSize);
protected virtual void Dispose(bool disposing) { if (disposing) { //dispose managed } if (_header != null) { try { Unprepare(); } catch (Exception) { } finally { _header = null; } } if (_bufferHandle.IsAllocated) _bufferHandle.Free(); if (_headerHandle.IsAllocated) _headerHandle.Free(); if (_userDataHandle.IsAllocated) _userDataHandle.Free(); }
private void Callback(IntPtr handle, WaveMsg msg, IntPtr user, WaveHeader header, IntPtr reserved) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId + "|" + msg); if (_waveInHandle != handle) return; if (msg == WaveMsg.WIM_DATA) { if (_callbackThread == null) _callbackThread = Thread.CurrentThread; //Debug.Assert(_callbackThread == Thread.CurrentThread, "Strange thread?"); if(_callbackThread != Thread.CurrentThread) Debugger.Break(); var index = (int) header.userData; WaveInBuffer buffer = _buffers[index]; Interlocked.Decrement(ref _activeBuffers); if (Monitor.TryEnter(_lockObj, 10)) { try { callback0: //only add buffer to queue again, if we are still recording if (buffer != null && RecordingState != RecordingState.Stopped) { try { //todo: should we care about recordingstate when firing dataavailable? RaiseDataAvailable(buffer); FireUpBuffer(buffer); } catch (Exception exception) { StopFromCallback(exception); } } if (_failedBuffers.Count > 0) { while (_failedBuffers.Count > 0 && (buffer = _buffers[(index = _failedBuffers.Dequeue())]).IsInQueue == false) { Debug.WriteLine("Already queued."); } if (buffer != null && !buffer.IsInQueue) { Debug.WriteLine("Failed buffer: " + index); goto callback0; } } } finally { Monitor.Exit(_lockObj); } } else { _failedBuffers.Enqueue(index); } if (_activeBuffers <= 0) StopFromCallback(null); _callbackThread = null; } else if (msg == WaveMsg.WIM_CLOSE) { if (RecordingState != RecordingState.Stopped) StopFromCallback(null); } }
protected virtual void Dispose(bool disposing) { lock (_waveOut.LockObj) { if (_header == null || _waveOut.WaveOutHandle == IntPtr.Zero) return; try { MmException.Try(MMInterops.waveOutUnprepareHeader(_waveOut.WaveOutHandle, _header, Marshal.SizeOf(_header)), "waveOutUnprepareHeader"); //don't throw? } catch (MmException ex) { if (ex.Result != MmResult.WAVERR_STILLPLAYING) throw; //can't fix bug } if (_bufferHandle.IsAllocated) _bufferHandle.Free(); if (_headerHandle.IsAllocated) _headerHandle.Free(); if (_userDataHandle.IsAllocated) _userDataHandle.Free(); _header = null; } }