/// <summary> /// Waveout thread procedure /// </summary> private void ThreadProc() { WaveOutBuffer buffer; // create buffers m_wave_out_buffers = new WaveOutBuffer[BufferCount]; for (int i = 0; i < BufferCount; i++) { m_wave_out_buffers[i] = new WaveOutBuffer(this, i); m_wave_out_buffers[i].ClearBuffer(); } // queue buffers for (int i = 0; i < BufferCount; i++) { m_wave_out_buffers[i].Enqueue(); } // thread loop while (m_thread_running) { // wait for wave event m_thread_event.WaitOne(); // find finished buffers and dequeue, fill and enqueue them for (int i = 0; i < BufferCount && m_thread_running; i++) { buffer = m_wave_out_buffers[i]; if (buffer.Free) { buffer.Dequeue(); OnSampleRequest?.Invoke(buffer.Data); buffer.Enqueue(); } } } // stop wave out WaveNative.waveOutReset(m_wave_out_device_handle); // release buffers for (int i = 0; i < BufferCount; i++) { m_wave_out_buffers[i].Dispose(); } // close wave out WaveNative.waveOutClose(m_wave_out_device_handle); m_wave_out_buffers = null; m_wave_out_device_handle = IntPtr.Zero; m_thread = null; m_thread_event.Dispose(); m_thread_event = null; }
/// <summary> /// Static callback function. Called by windows. /// </summary> /// <param name="hdrvr"></param> /// <param name="uMsg"></param> /// <param name="dwUser"></param> /// <param name="wavhdr"></param> /// <param name="dwParam2"></param> internal static void WaveOutProc(IntPtr hdrvr, WaveNative.WaveMessage uMsg, int dwUser, WaveNative.WaveHdr wavhdr, int dwParam2) { try { if (uMsg == WaveNative.WaveMessage.WOM_DONE) { GCHandle hBuffer = (GCHandle)wavhdr.dwUser; WaveOutBuffer buffer = (WaveOutBuffer)hBuffer.Target; buffer.Free = true; buffer.Parent.BufferFinished(buffer); } } catch { } }
/// <summary> /// Buffer finished callback. Called by static callback. /// </summary> /// <param name="in_buffer"></param> private void BufferFinished(WaveOutBuffer in_buffer) { m_thread_event.Set(); }