最近写个录音相关的程序,参考了网上的源码,自己改了改测试的时候有个问题没有搞懂。代码是通过C#封装后的Wave系列API来实现。播放和录音是单独的线程。问题:即使我没有将播放的缓存中放入数据,录音线程仍然抓到了我生成的信号?没可能啊
下面是代码片段:
//Main
bool isTesting = falseprivate void Start()
{
Stop(); try
{
_waveFormat = new WaveFormat(_audioFrameSize, _audioBitsPerSample, _audioChannels);
if (!isTesting)
_Player = new WaveOutPlayer(-1, _waveFormat, _audioFrameSize*2, 3, new BufferFillEventHandler(Filler));
_Recorder = new WaveInRecorder(-1, _waveFormat, _audioFrameSize*2, 3, new BufferDoneEventHandler(DataArrived));
}
catch (System.Exception ex)
{
//
}
}private void Filler(IntPtr data, int size)
{
if (isTesting == false)
{
// …… for (int i = 0; i < _playerBuffer.Length; i++)//生成信号sin波,_playerBuffer是全局数组
{
_playerBuffer[i] = (byte)(128 * Math.Sin(2*Math.PI*i/512));// (byte)i;
}
//!!!!!!!!注意这里,我没有COPY到播放设备的缓存上啊!!我Mark掉了录音时还抓到了sin波
//System.Runtime.InteropServices.Marshal.Copy(_playerBuffer, 0, data, size);
}
}private void DataArrived(IntPtr data, int size)
{
if (_recorderBuffer == null || _recorderBuffer.Length < size)
_recorderBuffer = new byte[size];
if (_recorderBuffer != null)
{
System.Runtime.InteropServices.Marshal.Copy(data, _recorderBuffer, 0, size);
//if (isTesting == false)
// _stream.Write(_recorderBuffer, 0, _recorderBuffer.Length);
//_audioFrame.Process(ref _recorderBuffer);
//_audioFrame.RenderTimeDomain(ref pictureBox1);
//_audioFrame.RenderFrequencyDomain(ref pictureBox2);
}
}//Waveout Class
public class WaveOutPlayer : IDisposable
{
private IntPtr m_WaveOut;
private WaveOutBuffer m_Buffers; // linked list
private WaveOutBuffer m_CurrentBuffer;
private Thread m_Thread;
private BufferFillEventHandler m_FillProc;
private bool m_Finished;
private byte m_zero; private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveOutBuffer.WaveOutProc); public WaveOutPlayer(int device, WaveFormat format, int bufferSize, int bufferCount, BufferFillEventHandler fillProc)
{
m_zero = format.wBitsPerSample == 8 ? (byte)128 : (byte)0;
m_FillProc = fillProc;//Filler
WaveOutHelper.Try(WaveNative.waveOutOpen(out m_WaveOut, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
//分配缓存……
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
} internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WOM_DONE)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveOutBuffer buf = (WaveOutBuffer)h.Target;
buf.OnCompleted();
}
catch
{}
}
}
//……}
//WaveIn Class
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 WaveInRecorder(int device, WaveFormat format, int bufferSize, int bufferCount, BufferDoneEventHandler doneProc)
{
m_DoneProc = doneProc;//DataArrived
WaveInHelper.Try(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));//打开录音设备
//分配缓存 ……
WaveInHelper.Try(WaveNative.waveInStart(m_WaveIn));//开始录音
m_Thread = new Thread(new ThreadStart(ThreadProc));//启动线程
m_Thread.Start();
} internal static void WaveInProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WIM_DATA)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveInBuffer buf = (WaveInBuffer)h.Target;
buf.OnCompleted();
}
catch
{}
}
} // ……
}
下面是代码片段:
//Main
bool isTesting = falseprivate void Start()
{
Stop(); try
{
_waveFormat = new WaveFormat(_audioFrameSize, _audioBitsPerSample, _audioChannels);
if (!isTesting)
_Player = new WaveOutPlayer(-1, _waveFormat, _audioFrameSize*2, 3, new BufferFillEventHandler(Filler));
_Recorder = new WaveInRecorder(-1, _waveFormat, _audioFrameSize*2, 3, new BufferDoneEventHandler(DataArrived));
}
catch (System.Exception ex)
{
//
}
}private void Filler(IntPtr data, int size)
{
if (isTesting == false)
{
// …… for (int i = 0; i < _playerBuffer.Length; i++)//生成信号sin波,_playerBuffer是全局数组
{
_playerBuffer[i] = (byte)(128 * Math.Sin(2*Math.PI*i/512));// (byte)i;
}
//!!!!!!!!注意这里,我没有COPY到播放设备的缓存上啊!!我Mark掉了录音时还抓到了sin波
//System.Runtime.InteropServices.Marshal.Copy(_playerBuffer, 0, data, size);
}
}private void DataArrived(IntPtr data, int size)
{
if (_recorderBuffer == null || _recorderBuffer.Length < size)
_recorderBuffer = new byte[size];
if (_recorderBuffer != null)
{
System.Runtime.InteropServices.Marshal.Copy(data, _recorderBuffer, 0, size);
//if (isTesting == false)
// _stream.Write(_recorderBuffer, 0, _recorderBuffer.Length);
//_audioFrame.Process(ref _recorderBuffer);
//_audioFrame.RenderTimeDomain(ref pictureBox1);
//_audioFrame.RenderFrequencyDomain(ref pictureBox2);
}
}//Waveout Class
public class WaveOutPlayer : IDisposable
{
private IntPtr m_WaveOut;
private WaveOutBuffer m_Buffers; // linked list
private WaveOutBuffer m_CurrentBuffer;
private Thread m_Thread;
private BufferFillEventHandler m_FillProc;
private bool m_Finished;
private byte m_zero; private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveOutBuffer.WaveOutProc); public WaveOutPlayer(int device, WaveFormat format, int bufferSize, int bufferCount, BufferFillEventHandler fillProc)
{
m_zero = format.wBitsPerSample == 8 ? (byte)128 : (byte)0;
m_FillProc = fillProc;//Filler
WaveOutHelper.Try(WaveNative.waveOutOpen(out m_WaveOut, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
//分配缓存……
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
} internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WOM_DONE)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveOutBuffer buf = (WaveOutBuffer)h.Target;
buf.OnCompleted();
}
catch
{}
}
}
//……}
//WaveIn Class
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 WaveInRecorder(int device, WaveFormat format, int bufferSize, int bufferCount, BufferDoneEventHandler doneProc)
{
m_DoneProc = doneProc;//DataArrived
WaveInHelper.Try(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));//打开录音设备
//分配缓存 ……
WaveInHelper.Try(WaveNative.waveInStart(m_WaveIn));//开始录音
m_Thread = new Thread(new ThreadStart(ThreadProc));//启动线程
m_Thread.Start();
} internal static void WaveInProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WIM_DATA)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveInBuffer buf = (WaveInBuffer)h.Target;
buf.OnCompleted();
}
catch
{}
}
} // ……
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货