public void Dispose()
{
if (m_Header.lpData != IntPtr.Zero)
WaveNative.waveInUnprepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header));
m_HeaderHandle.Free();
m_Header.lpData = IntPtr.Zero;
}
m_RecordEvent.Close();
if (m_HeaderDataHandle.IsAllocated)
m_HeaderDataHandle.Free();
GC.SuppressFinalize(this);
public int Size
get { return m_Header.dwBufferLength; }
public IntPtr Data
get { return m_Header.lpData; }
public bool Record()
lock(this)
m_RecordEvent.Reset();
m_Recording = WaveNative.waveInAddBuffer(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)) == WaveNative.MMSYSERR_NOERROR;
return m_Recording;
public void WaitFor()
if (m_Recording)
m_Recording = m_RecordEvent.WaitOne();
else
Thread.Sleep(0);
private void OnCompleted()
m_RecordEvent.Set();
m_Recording = false;
public class WaveInRecorder : IDisposable
private IntPtr m_WaveIn;
private WaveInBuffer m_Buffers; // linked list
private WaveInBuffer m_CurrentBuffer;
private Thread m_Thread;
private BufferDoneEventHandler m_DoneProc;
private bool m_Finished;
private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveInProc);
public static int DeviceCount
get { return WaveNative.waveInGetNumDevs(); }
public WaveInRecorder(int device, WaveFormat format, int bufferSize, int bufferCount, BufferDoneEventHandler doneProc)
m_DoneProc = doneProc;
WaveInHelper.Try(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
AllocateBuffers(bufferSize, bufferCount);
for (int i = 0; i < bufferCount; i++)
SelectNextBuffer();
m_CurrentBuffer.Record();
WaveInHelper.Try(WaveNative.waveInStart(m_WaveIn));
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
~WaveInRecorder()
Dispose();
if (m_Thread != null)
try
m_Finished = true;
if (m_WaveIn != IntPtr.Zero)
WaveNative.waveInReset(m_WaveIn);
WaitForAllBuffers();
m_Thread.Join();
m_DoneProc = null;
FreeBuffers();
WaveNative.waveInClose(m_WaveIn);
finally
m_Thread = null;
m_WaveIn = IntPtr.Zero;
private void ThreadProc()
while (!m_Finished)
Advance();
if (m_DoneProc != null && !m_Finished)
m_DoneProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size);
private void AllocateBuffers(int bufferSize, int bufferCount)
if (bufferCount > 0)
m_Buffers = new WaveInBuffer(m_WaveIn, bufferSize);
WaveInBuffer Prev = m_Buffers;
for (int i = 1; i < bufferCount; i++)
WaveInBuffer Buf = new WaveInBuffer(m_WaveIn, bufferSize);
Prev.NextBuffer = Buf;
Prev = Buf;
Prev.NextBuffer = m_Buffers;
private void FreeBuffers()
m_CurrentBuffer = null;
if (m_Buffers != null)
WaveInBuffer First = m_Buffers;
m_Buffers = null;
WaveInBuffer Current = First;
do
WaveInBuffer Next = Current.NextBuffer;
Current.Dispose();
Current = Next;
} while(Current != First);
private void Advance()
m_CurrentBuffer.WaitFor();
private void SelectNextBuffer()
m_CurrentBuffer = m_CurrentBuffer == null ? m_Buffers : m_CurrentBuffer.NextBuffer;
private void WaitForAllBuffers()
WaveInBuffer Buf = m_Buffers;
while (Buf.NextBuffer != m_Buffers)
Buf.WaitFor();
Buf = Buf.NextBuffer;
1.2) WaveOut.cs
// Speech recognition
// waveout => show graph on screen
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace SoundViewer
internal class WaveOutHelper
public static void Try(int err)
if (err != WaveNative.MMSYSERR_NOERROR)
throw new Exception(err.ToString());
public delegate void BufferFillEventHandler(IntPtr data, int size);
internal class WaveOutBuffer : IDisposable
public WaveOutBuffer NextBuffer;
private AutoResetEvent m_PlayEvent = new AutoResetEvent(false);
private IntPtr m_WaveOut;
private WaveNative.WaveHdr m_Header;
private byte[] m_HeaderData;
private GCHandle m_HeaderHandle;
private GCHandle m_HeaderDataHandle;
private bool m_Playing;
internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
if (uMsg == WaveNative.MM_WOM_DONE)
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveOutBuffer buf = (WaveOutBuffer)h.Target;
buf.OnCompleted();
catch
public WaveOutBuffer(IntPtr waveOutHandle, int size)
m_WaveOut = waveOutHandle;
m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned);
Ñòðàíèöû: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12