利用DirectSound實(shí)現聲卡錄音
摘要:本文詳細講述了如何利用DirectSound對經(jīng)過(guò)聲卡和麥克風(fēng)的數據進(jìn)行捕獲,進(jìn)行錄音,并保存為wave格式的文件。
曾經(jīng)學(xué)習過(guò)Directshow的開(kāi)發(fā),對于Dsound一直沒(méi)有仔細的學(xué)習,以前只是知道Dsound是做音頻開(kāi)發(fā)的,我一直以為它和Dshow的結構體系差不多,經(jīng)過(guò)仔細學(xué)習后,發(fā)現,其實(shí)他們完全兩碼事。DirectSound雖然也基于COM,但不象Dshow那樣多個(gè)的filter組成鏈表。
閑話(huà)少說(shuō),下面我們看看DirectSound到底能幫我們做些什么。
1、播放WAVE格式的音頻文件或者資源。
2、可以同時(shí)播放多個(gè)音頻。
3、Assign high-priority sounds to hardware-controlled buffers
4、播放3D立體聲音
5、在聲音中添加特技效果,比如回聲,動(dòng)態(tài)的改變特技的參數等
6、將麥克風(fēng)或者其他音頻輸入設備的聲音錄制成wave格式的文件
DirectSound就能做這么多事情,到這里,我都有點(diǎn)懷疑DirectSound是不是就是封裝了mmio系列和wav系列的函數。因為這些底層的API也能夠完成這些事情。這里我們主要討論一下,如果使用Directsound進(jìn)行錄音,并保存成wave格式的文件。
在開(kāi)始工作之前,要先介紹DirectSound錄音用到的三個(gè)非常重要的對象:
·IDirectSoundCapture8 ,設備對象,根據你錄音的設備創(chuàng )建的設備對象,利用該對象可以獲取設備的屬性。
·IDirectSoundCaptureBuffer8,緩沖區對象,該對象由設備對象創(chuàng )建,主要用來(lái)操作音頻數據
·IDirectSoundNotify8 ,事件通知對象,該對象用來(lái)通知應用程序從緩沖區中將數據取走,寫(xiě)入文件保存起來(lái)。
利用DirectSound錄音的主要思路,就是先根據選擇的錄音設備創(chuàng )建設備對象,然后通過(guò)設備對象創(chuàng )建輔助緩沖區對象,開(kāi)始錄音的時(shí)候,設備將數據寫(xiě)入緩沖區,應用程序主動(dòng)的從緩沖區將數據讀出來(lái)寫(xiě)文件即可,就實(shí)現了錄音功能。這里簡(jiǎn)單介紹一下dsound的通知功能,應用程序會(huì )創(chuàng )建一個(gè)通知對象,然后將通知對象邦定,然后設定通知位置(position),什么是通知位置呢,比如緩沖區的大小為4000字節,如果你想當數據達到緩沖區一半的時(shí)候能得到通知開(kāi)始copy數據,那么此時(shí)你就可以將通知位置設定為2000,通知位置可以任意的設定,當緩沖區的數據達到你設定的位置時(shí),就會(huì )通知應用程序將緩沖區的數據copy到文件中,緩沖區是循環(huán)利用的,當緩沖區填充滿(mǎn)了以后,就會(huì )從頭開(kāi)始充填數據,所以,緩沖區就是一邊讀,一邊寫(xiě)的過(guò)程。
下面我講一下錄音的主要步驟,可以使大家的思路更清晰一些
1、枚舉錄音的設備
2、根據選擇的設備創(chuàng )建設備對象
3、利用設備對象創(chuàng )建緩沖區對象
4、設置通知機制
5、創(chuàng )建工作線(xiàn)程,用來(lái)將緩沖區的數據寫(xiě)入文件。
先來(lái)定義一下用到的數據
LPDIRECTSOUNDCAPTURE8 g_pDSCapture = NULL;//設備對象指針
LPDIRECTSOUNDCAPTUREBUFFER g_pDSBCapture = NULL;//緩沖區對象指針
LPDIRECTSOUNDNOTIFY8 g_pDSNotify = NULL;//用來(lái)設置通知的對象接口
GUID g_guidCaptureDevice = GUID_NULL; //設備id
BOOL g_bRecording = FALSE; //是否正在錄音
WAVEFORMATEX g_wfxInput; //輸入的音頻格式
DSBPOSITIONNOTIFY g_aPosNotify[ NUM_REC_NOTIFICATIONS + 1 ]; //設置通知標志的數組
HANDLE g_hNotificationEvent; //通知事件
BOOL g_abInputFormatSupported[20];
DWORD g_dwCaptureBufferSize; //錄音用緩沖區的大小
DWORD g_dwNextCaptureOffset;//偏移位置
DWORD g_dwNotifySize;// 通知位置
CWaveFile* g_pWaveFile;//
枚舉錄音的設備
如果你的程序只是想從用戶(hù)缺省的設備上進(jìn)行聲音的錄制,那么就沒(méi)有必要來(lái)枚舉出系統中的所有錄音的設備,當你調用DirectSoundCaptureCreate8 或者另外一個(gè)函數DirectSoundFullDuplexCreate8的時(shí)候,其實(shí)就默認指定了一個(gè)缺省的錄音設備。
當然,在下面的情況下,你就必須要枚舉系統中所有的設備,例如,你的應用程序并不支持所有的輸出設備,或者你的應用程需要兩個(gè)或者多個(gè)設備,或者你希望用戶(hù)自己來(lái)選擇輸出設備。
枚舉設備,你首先要定義一個(gè)回調函數,這個(gè)回調函數可以被系統中的每個(gè)設備來(lái)調用,你可以在各函數做任何事情,這個(gè)函數的命名也沒(méi)有任何的限制,但是函數應該以DSEnumCallback為原型,如果枚舉沒(méi)有結束,這個(gè)回調函數就返回TRUE,如果枚舉結束,例如你找到合適的設備,這個(gè)函數就要返回FALSE。
下面是回調函數的一個(gè)例子,這個(gè)函數將枚舉的每一個(gè)設備都添加到一個(gè)combox中,將設備的GUID保存到一個(gè)item 中,這個(gè)函數的前三個(gè)參數由設備的驅動(dòng)程序提供,第四個(gè)參數有DirectSoundCaptureEnumerate函數提供,這個(gè)參數可以是任意的32位值,這個(gè)例子里是combox的句柄,
BOOL CALLBACK DSEnumProc(LPGUID lpGUID,
LPCTSTR lpszDesc,
LPCTSTR lpszDrvName,
LPVOID lpContext )
{
HWND hCombo = (HWND)lpContext;
LPGUID lpTemp = NULL;
if (lpGUID != NULL) // NULL only for "Primary Sound Driver".
{
if ((lpTemp = (LPGUID)malloc(sizeof(GUID))) == NULL)
{
return(TRUE);
}
memcpy(lpTemp, lpGUID, sizeof(GUID));
}
//下面的代碼主要主要是將設備添加到CComboBox,其實(shí)你完全直接將CComboBox指針傳遞過(guò)來(lái),直接的添加,這里采用的是給combox窗口發(fā)送消息的方法,
ComboBox_AddString(hCombo, lpszDesc);
ComboBox_SetItemData(hCombo,
ComboBox_FindString(hCombo, 0, lpszDesc),
lpTemp );
free(lpTemp);
return(TRUE);
}
枚舉設備通常都是在對話(huà)框初始化的時(shí)候才進(jìn)行的,我們假設hCombo就是combox句柄,hDlg就對話(huà)框的句柄,看看我們怎么來(lái)枚舉設備的吧。
if (FAILED(DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK)DSEnumProc,
(VOID*)&hCombo)))
{
EndDialog(hDlg, TRUE);
return(TRUE);
}
在這個(gè)例子中,combox的句柄作為參數傳遞到DirectSoundEnumerate函數中,然后又被傳遞到回調函數中,這個(gè)參數你可以是你想傳遞的任意的32位值。
注:第一個(gè)被枚舉的設備通常稱(chēng)為Primary sound driver,并且回調函數的lpGUID為NULL,這個(gè)設備就是用戶(hù)通過(guò)控制面板設置的缺省的錄音聲音設備,
廣告
2007-5-31 16:01:31
本主題貼數3,分頁(yè): [1]
管理選項:
修改tag |
鎖定 |
解鎖 |
提升 |
刪除 |
移動(dòng) |
固頂 |
總固頂 |
獎勵 |
懲罰 |
發(fā)布公告 W 3 C h i n a ( 2 0 0 3 - 2 0 0 7 ) 旗 下 站 點(diǎn)
蘇ICP備05006046號《全國人大常委會(huì )關(guān)于維護互聯(lián)網(wǎng)安全的決定》《計算機信息網(wǎng)絡(luò )國際聯(lián)網(wǎng)安全保護管理辦法》本站域名、主機由萬(wàn)維中華(www.wwwchina.cn)免費提供, FTP由www.eawan.com免費提供!
234.375ms