/// <summary> /// Writes the audio data. /// </summary> /// <param name="deviceHandle">The device handle.</param> /// <param name="header">The header.</param> /// <exception cref="TimeoutException">Occurs when the interop lock cannot be acquired.</exception> /// <exception cref="MmException">Occurs when the MME interop call fails</exception> public static void WriteAudioData(IntPtr deviceHandle, WaveHeader header) { if (deviceHandle == IntPtr.Zero) { return; } if (header == null) { return; } var acquired = false; Monitor.TryEnter(SyncLock, LockTimeout, ref acquired); if (acquired == false) { throw new TimeoutException(TimeoutErrorMessage); } try { MmException.Try( NativeMethods.waveOutWrite(deviceHandle, header, Marshal.SizeOf(header)), nameof(NativeMethods.waveOutWrite)); } catch { throw; } finally { Monitor.Exit(SyncLock); } }
/// <summary> /// Writes the audio data. /// </summary> /// <param name="deviceHandle">The device handle.</param> /// <param name="header">The header.</param> /// <exception cref="TimeoutException">Occurs when the interop lock cannot be acquired.</exception> /// <exception cref="LegacyAudioException">Occurs when the MME interop call fails</exception> public static void WriteAudioData(IntPtr deviceHandle, WaveHeader header) { if (header == null || !TryEnterWaveOperation(deviceHandle)) { return; } try { LegacyAudioException.Try( NativeMethods.WriteWaveAudioData(deviceHandle, header, Marshal.SizeOf(header)), nameof(NativeMethods.WriteWaveAudioData)); } finally { Monitor.Exit(SyncLock); } }
/// <summary> /// Initializes a new instance of the <see cref="WaveOutBuffer"/> class. /// </summary> /// <param name="deviceHandle">WaveOut device to write to</param> /// <param name="bufferSize">Buffer size in bytes</param> /// <param name="waveStream">Stream to provide more data</param> public WaveOutBuffer(IntPtr deviceHandle, int bufferSize, IWaveProvider waveStream) { BufferSize = bufferSize; Buffer = new byte[BufferSize]; DeviceHandle = deviceHandle; WaveStream = waveStream; BufferHandle = GCHandle.Alloc(Buffer, GCHandleType.Pinned); header = new WaveHeader(); HeaderHandle = GCHandle.Alloc(header, GCHandleType.Pinned); header.DataBuffer = BufferHandle.AddrOfPinnedObject(); header.BufferLength = bufferSize; header.Loops = 1; header.UserData = IntPtr.Zero; WaveInterop.AllocateHeader(DeviceHandle, header); }
private GCHandle callbackHandle; // for the user callback /// <summary> /// Initializes a new instance of the <see cref="WaveOutBuffer"/> class. /// </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; buffer = new byte[bufferSize]; bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); this.waveOutPtr = hWaveOut; waveStream = bufferFillStream; this.waveOutLock = waveOutLock; header = new WaveHeader(); headerHandle = GCHandle.Alloc(header, GCHandleType.Pinned); header.DataBuffer = bufferHandle.AddrOfPinnedObject(); header.BufferLength = bufferSize; header.Loops = 1; callbackHandle = GCHandle.Alloc(this); header.UserData = (IntPtr)callbackHandle; lock (waveOutLock) { MmException.Try(WaveInterop.NativeMethods.waveOutPrepareHeader(hWaveOut, header, Marshal.SizeOf(header)), "waveOutPrepareHeader"); } }
public static extern MmResult waveOutWrite(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);
public static extern MmResult waveOutUnprepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);