public WaveOutBuffer(int size) { _hdr = new Native.WAVEHDR(); _gchThis = GCHandle.Alloc(this); _gchHdr = GCHandle.Alloc(_hdr, GCHandleType.Pinned); _hdr.dwUser = (IntPtr)_gchThis; _data = new byte[size]; _gchData = GCHandle.Alloc(_data, GCHandleType.Pinned); _hdr.lpData = _gchData.AddrOfPinnedObject(); _hdr.dwBufferLength = size; }
internal static void WaveOutProc(IntPtr hdrvr, int uMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2) { if (uMsg == Native.MM_WOM_DONE) { try { System.Diagnostics.Debug.Assert(dwInstance != IntPtr.Zero); WinMMAudioRender instance = (WinMMAudioRender)((GCHandle)dwInstance).Target; System.Diagnostics.Debug.Assert(dwParam1 != IntPtr.Zero); Native.WAVEHDR hdr = (Native.WAVEHDR)Marshal.PtrToStructure(dwParam1, typeof(Native.WAVEHDR)); System.Diagnostics.Debug.Assert(hdr.dwUser != IntPtr.Zero); WaveOutBuffer waveOutBuffer = (WaveOutBuffer)((GCHandle)hdr.dwUser).Target; if (hdr.dwBufferLength > 0) { instance._totalDuration += hdr.dwBufferLength; instance._callback.PlaybackProgress(instance._totalDuration, hdr.dwBufferLength, instance._fmt.nAvgBytesPerSec); } // if we are still playing get a new audio buffer if (instance._started) { int length = 0; if (instance._callback.NextAudioBuffer(waveOutBuffer._data, ref length)) { System.Diagnostics.Debug.Assert(length <= waveOutBuffer._data.Length); waveOutBuffer._hdr.dwBufferLength = length; int result = Native.waveOutWrite(instance._hWaveout, waveOutBuffer._gchHdr.AddrOfPinnedObject(), Marshal.SizeOf(waveOutBuffer._hdr)); System.Diagnostics.Debug.Assert(result == Native.MMSYSERR_NOERROR); } else { // end of stream read instance._started = false; } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); } } }