我使用VFW和音频捕获回调从Webcam捕获音频数据,同时在同一捕获回调的主体内,使用waveOutWrite将采样数据引导到默认MAPPER。
网络摄像头的信号质量为1通道/8位/11025采样/秒。
默认音频设备支持声音格式,这要归功于
波形打开
具有
格式查询
旗帜
波形写入
是
无错误
,但我能听到的与我的期望相去甚远。房间里很安静,应该听起来像是空虚的白噪音。
请听声音
YouTube rec
它开始时,一包一包大小约为16K,WAVEHDR结构正常。
然后它会逐渐变慢,并以系统未恢复的错误退出。
这和什么相似?
下面是来自VFW的音频dta接收器代码,lpWHdr在视觉上正常,甚至内部标记触发为2=Prepared。。。看起来VFW和WaveAudio是彼此创建的:)
public static void capAudioStreamCallback(UIntPtr hWnd, ref WAVE.WAVEHDR lpWHdr) {
Say(String.Format(DateTime.Now.ToString("mm:ss:fff ") + "Received {0} of audio data", lpWHdr.dwBytesRecorded.ToString()));
Application.DoEvents();
WA.WAVEHDR_FLAGS flag = (WA.WAVEHDR_FLAGS) lpWHdr.dwFlags;
if ((WA.WAVEHDR_FLAGS)lpWHdr.dwFlags != WA.WAVEHDR_FLAGS.WHDR_PREPARED)
CheckWAError("waveOutPrepareHeader", WA.waveOutPrepareHeader(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr)));
CheckWAError("waveOutWrite", WA.waveOutWrite(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr)));
CheckWAError("waveOutUnprepareHeader", WA.waveOutUnprepareHeader(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr)));
return;
}
static void CheckWAError(string Func, WA.MMSYSERR err) {
if (err == WA.MMSYSERR.MMSYSERR_BASE_NOERROR) { Say(Func + " WA Ok"); return; }
IntPtr str = Marshal.AllocHGlobal(200);
string s = "";
WA.waveOutGetErrorText(err, str, 200);
s = Marshal.PtrToStringAnsi(str);
Marshal.FreeHGlobal(str);
Say(Func + " err: " + s);
}
我认为缓冲区没有溢出,因为您可以看到DateTime毫秒戳,它每1400毫秒跳动一次,采样率=11025,缓冲区大小约为16500字节=看起来不错。。
UPD:我刚刚将非托管缓冲区复制到托管缓冲区并查看其值。看起来像锯齿,甚至是过载的鼻窦。
0 4 0 3 0 32 109 213 255 251 255 243 241 97 0 7 0 2 1 0 5 0,然后以相同的数字和相同的周期再次上下移动。
不完全相同(+/-)。
此外,我可以使用内置的Windows录音机录制来自摄像头的信号,我可以看到信号电平在我的声音上下跳动,因此网络摄像头的麦克风也可以。。
我想这可能是VFW输入音频信号馈线的问题。
即使它接受了WAVEFORMATEX并发回了WAVEHDR,它们都是正常的……但缓冲区数据是由其他来源填充的,而不是网络摄像头,尽管VFW表示它必须来自网络摄像头,因为视频是从同一来源捕获的,而且它在工作,我只是添加了一条附加消息:
发送消息(camHwnd,WM_CAP_SET_CALLBACK_WAVESTREAM,0,音频回调);
我非常确定如果我使用waveIn而不是VFW,它会正常工作。。
我稍后再检查。。
但为什么VFW的工作方式与预期不同?