使用DirectShow寫一個(gè)音頻捕捉例子
DirectShow對(duì)硬件的支持是通過特定的包裝Filter來實(shí)現(xiàn)的。
聲卡使用的是Audio Capture Filter,F(xiàn)ilter內(nèi)部使用以waveIn開頭
的一套API實(shí)現(xiàn)(如waveInOpen等)。
運(yùn)行GraphEdit,插入Filter時(shí),在“Audio Capture Sources”目錄下,
就能看到所有代表本地機(jī)器上的聲卡的各個(gè)Filter(裝了幾張聲卡,就會(huì)有幾個(gè)Filter)
DirectShow加入一個(gè)硬件Filter,是靠“枚舉”;聲卡Filter也不例外。
代表聲卡的Filter都注冊(cè)在CLSID_AudioInputDeviceCategory目錄下,
使用系統(tǒng)設(shè)備枚舉器枚舉這個(gè)目錄,就能發(fā)現(xiàn)要?jiǎng)?chuàng)建的聲卡對(duì)象。
(如何枚舉這里就不再贅述了。)
當(dāng)成功加入聲卡Filter后,接下去的問題就是要將這個(gè)Filter與其他Filter相連。
想捕捉生成一個(gè)Wave文件,采用過濾器的勾連如下
聲卡filter--->Wave Dest Filter ---->File Writer Filter
Wave Dest Filter是微軟DirectX SDK自帶的過濾器
其功能是,當(dāng)結(jié)束捕捉時(shí),往Wave文件中寫入一個(gè)文件頭信息。
Filte Write Filter 是微軟系統(tǒng)過濾器。
用graphedit可以勾連后測試下。
//采用程序來連接過濾器的大致方法:
//沒有處理錯(cuò)誤
void BuildAudioCaptureGraph(void)
{
IBaseFilter *pSrc = NULL, //捕捉音頻設(shè)備
*pWaveDest = NULL, //處理音頻過濾器
*pWriter = NULL; //產(chǎn)生文件過濾器
IFileSinkFilter *pSink= NULL;
IGraphBuilder *pGraph;
// Create the Filter Graph Manager.
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);
// Add the audio capture filter.
//這里省略了枚舉設(shè)備處理
FindAudioCapture(&pSrc);
// audio capture devices and picks one.
pGraph->AddFilter(pSrc, L"Capture");
// Add the WavDest and the File Writer.
AddFilterByClsid(pGraph, L"WavDest", CLSID_WavDest, &pWavDest);
AddFilterByClsid(pGraph, L"File Writer", CLSID_FileWriter, &pWriter);
//是writer接口中屬性
pWriter->QueryInterface(IID_IFileSinkFilter, (void**)&pSink);
pSink->SetFileName(L"C:\test.wav", NULL);
//連接filter
ConnectTwoFilters(pGraph, pSrc, pWavDest);
ConnectTwoFilters(pGraph, pWavDest, pWriter);
}