internal static extern MMResult waveOutWrite(IntPtr hWaveOut, WaveHdr lpWaveOutHdr, int uSize);
internal static extern MMResult waveOutUnprepareHeader(IntPtr hWaveOut, WaveHdr lpWaveOutHdr, int uSize);
/// <summary> /// Initializes the buffer. /// </summary> public void Initialize() { _buffer = new byte[_bufferSize]; var header = new WaveHdr(); _headerHandle = GCHandle.Alloc(header); _userDataHandle = GCHandle.Alloc(this); _bufferHandle = GCHandle.Alloc(_buffer, GCHandleType.Pinned); header.dwUser = (IntPtr) _userDataHandle; header.dwLoops = 1; header.lpData = _bufferHandle.AddrOfPinnedObject(); header.dwBufferLength = _bufferSize; _header = header; lock (_waveOut.LockObj) { WaveOutResult.Try(MMInterops.waveOutPrepareHeader(_waveOut.WaveOutHandle, header, Marshal.SizeOf(header))); } }
/// <summary> /// Callback func. /// </summary> /// <param name="handle">The WaveOutHandle.</param> /// <param name="msg">The WaveMessage.</param> /// <param name="user">The UserData.</param> /// <param name="header">The WaveHdr.</param> /// <param name="reserved">Reserved.</param> private void Callback(IntPtr handle, WaveMessage msg, UIntPtr user, WaveHdr header, UIntPtr reserved) { if (WaveOutHandle != handle) return; if (msg == WaveMessage.WOM_DONE) { var hBuffer = (GCHandle) header.dwUser; var buffer = hBuffer.Target as WaveOutBuffer; Interlocked.Decrement(ref _activeBuffers); if (buffer == null) return; if (_playbackState != PlaybackState.Stopped) { lock (_lockObj) { if (buffer.WriteData()) Interlocked.Increment(ref _activeBuffers); } } if (_activeBuffers == 0) { _playbackState = PlaybackState.Stopped; RaisePlaybackChanged(); } } else if (msg == WaveMessage.WOM_CLOSE) { _playbackState = PlaybackState.Stopped; RaisePlaybackChanged(); } }
/// <summary> /// Disposes the object. /// </summary> /// <param name="disposing">The disposing state.</param> public virtual void Dispose(bool disposing) { lock (_waveOut.LockObj) { if (_header == null || _waveOut.WaveOutHandle == IntPtr.Zero) return; if (_bufferHandle.IsAllocated) _bufferHandle.Free(); if (_headerHandle.IsAllocated) _headerHandle.Free(); if (_userDataHandle.IsAllocated) _userDataHandle.Free(); WaveOutResult.Try(MMInterops.waveOutUnprepareHeader(_waveOut.WaveOutHandle, _header, Marshal.SizeOf(_header))); _header = null; } if (disposing) { } }