使用DirectSound播放流音頻數(shù)據(jù)_第1頁
使用DirectSound播放流音頻數(shù)據(jù)_第2頁
使用DirectSound播放流音頻數(shù)據(jù)_第3頁
使用DirectSound播放流音頻數(shù)據(jù)_第4頁
使用DirectSound播放流音頻數(shù)據(jù)_第5頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、使用DirectSound播放流音頻數(shù)據(jù)DirectSound 使用第一步,創(chuàng)建一個設(shè)備對象,設(shè)置設(shè)備對象的協(xié)作度。在代碼中可以通過調(diào)用DirectSoundCreate函數(shù)來創(chuàng)建一個支持IDirectSound接口的對象,這個對象通 常代表缺省的播放設(shè)備。當(dāng)然可以枚舉可用的設(shè)備,然后將設(shè)備的GUID傳遞給DirectSoundCreate函數(shù)。如果沒有聲音輸出設(shè)備,這個函數(shù)就返回error,如果聲音輸出設(shè)備正被某個應(yīng)用程序通過waveform 格式的api函數(shù)所控制,該函數(shù)也返回error。下面是創(chuàng)建對象的代碼,極其簡單IDirectSound* m_pDS; / DirectSound c

2、omponentif(FAILED(DirectSoundCreate(NULL, &m_pDS, NULL)MessageBox(NULL, Unable to create DirectSound object, Error, MB_OK);return S_FALSE;注意,Directsound雖然基于COM,但是你并不需要初始化com庫,這些Directsound都幫你做好了。因為Windows是一個多任務(wù)操作環(huán)境,在同一個時刻有可能多個應(yīng)用程序共用同一個設(shè)備,通過協(xié)作 水平,DirectX就可以保證這些應(yīng)用程序在訪問設(shè)備的時候不會沖突,每個Directsound應(yīng)用程序都有一個 協(xié)

3、作度,用來確定來接近設(shè)備的程度,當(dāng)你創(chuàng)建完設(shè)備對象后,一定要調(diào)用IDirectSound:SetCooperativeLevel 來設(shè)置協(xié)作度,否則,你不會聽到聲音的。m_pDS-SetCooperativeLevel(hWnd, DSSCL_PRIORITY);第二步,創(chuàng)建一個輔助Buffer,也叫后備緩沖區(qū)你可以通過IDirectSound:CreateSoundBuffer來創(chuàng)建buffer對象,這個對象主要用來獲取處理數(shù)據(jù),這 種buffer稱作輔助緩沖區(qū),以和主緩沖區(qū)區(qū)別開來,Direcsound通過把幾個后備緩沖區(qū)的聲音混合到主緩 沖區(qū)中,然后輸出到聲音輸出設(shè)備上,達到混音的效果。

4、if(FAILED(pDS-CreateSoundBuffer(&dsbd, &pDSB, NULL)return NULL;第三步,獲取PCM類型的數(shù)據(jù)將WAV文件或者其他資源的數(shù)據(jù)讀取到緩沖區(qū)中。第四步,將數(shù)據(jù)讀取到緩沖區(qū)你可以通過IDirectSoundBuffer:Lock.方法來準(zhǔn)備一個輔助緩沖區(qū)來進行寫操作,通常這個方法返回一 個內(nèi)存地址,見數(shù)據(jù)從你的私人buffer中復(fù)制到這個地址中,然后調(diào)用IDirectSoundBuffer:Unlock.第五步,播放緩沖區(qū)中的數(shù)據(jù)你可以通過IDirectSoundBuffer:Play方法來播放緩沖區(qū)中的音頻數(shù)據(jù),你可以通過 IDirect

5、SoundBuffer:Stop來暫停播放數(shù)據(jù),你可以反復(fù)的停止,播放音頻數(shù)據(jù)。你可以通過 IDirectSoundBuffer:GetVolume 和 IDirectSoundBuffer:SetVolume 函數(shù)來獲取或者設(shè)置正 在播放的音頻的音量的大小。播放流數(shù)據(jù)流緩沖區(qū)用來播放那些比較長的音頻文件,因為數(shù)據(jù)比較長,沒法一次填充到緩沖區(qū)中,一邊播放, 一邊將新的數(shù)據(jù)填充到DirectSound的緩沖區(qū)中??梢酝ㄟ^IDirectSoundBuffer:Play函授來播放緩沖區(qū)中的內(nèi)容,注意在該函數(shù)的參數(shù)中一定要設(shè)置 DSBPLAY_LOOPING 標(biāo)志。通過IDirectSoundBuff

6、er:Stop方法中斷播放,該方法會立即停止緩沖區(qū)播放。將音頻流倒入緩沖區(qū)需要下面三個步驟1、確保你的緩沖區(qū)巳經(jīng)做好接收新數(shù)據(jù)的準(zhǔn)備。2、調(diào)用IDirectSoundBuffer:Lock.函數(shù)鎖住緩沖區(qū)的位置,這個函數(shù)返回一個或者兩個可以寫入數(shù)據(jù) 的地址3、使用標(biāo)準(zhǔn)的copy數(shù)據(jù)的方法將音頻數(shù)據(jù)寫入緩沖區(qū)中4、IDirectSoundBuffer:Unlock.,解鎖這里要講一下DirectSound的通知機制。因為Stream buffer大小只夠容納一部分數(shù)據(jù),因此,在播 放完緩沖區(qū)中的數(shù)據(jù)后,DirectSound就會通知應(yīng)用程序,將新的數(shù)據(jù)填充到DirectSound的緩沖區(qū)中。假如

7、我們設(shè)置DirectSound的buffersize為2000*4,如下圖Notify Point2000400060008000我們可以給DirectSound設(shè)置一個事件,并且設(shè)置buffer通知大小,如下:if(FAILED(m_pDSBuf-QueryInterface(IID_IDirectSoundNotify, (void*)(&m_pDSNotify) return FALSE ;/ create auto notify eventm_hNotifyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );/ Setup the notif

8、ication positionsfor( i = 0; i SetNotificationPositions( NUM_REC_NOTIFICATIONS, m_aPosNotify )return S_FALSE ;當(dāng)DirectSound播放到buffer的2000, 4000, 6000, 8000等位置時,Directsound就會通知應(yīng)用程 序,將m_hNotifyEvent設(shè)置為通知態(tài),應(yīng)用程序就可以通過WaitForMultipleObjects函數(shù)等待DirectSound 的通知,將數(shù)據(jù)填充到DirectSound的輔助緩沖區(qū)。在填充音頻數(shù)據(jù)的時候,開啟一個線程,在Wait

9、ForMultipleObjects等待DirectSound的通知,然后將 音頻數(shù)據(jù)填充到DirectSound的空buffer中。CreateThread(NULL, 0, CDXSoundPlay:notify_stream_thd, (LPVOID)(this), 0, NULL);在notify_stream_thd中填充音頻數(shù)據(jù).while(psmado-m_bPlaying)(/ Wait for a messagedwResult = MsgWaitForMultipleObjects(1, &psmado-m_hNotifyEvent,FALSE, INFINITE, QS_

10、ALLEVENTS);/ Get notificationswitch(dwResult)(case WAIT_OBJECT_0:(psmado-LoadStreamData();break ;default:break ;下面的函數(shù)主要是給空的DirectSound緩沖區(qū)填充音頻數(shù)據(jù)。HRESULT hr;VOID* pvStreamDatal = NULL;DWORD dwStreamLength1 = 0 ;VOID* pvStreamData2 = NULL;DWORD dwStreamLength2 = 0 ;DWORD dwWritePos = 0 ;DWORD dwPlayPos

11、 = 0 ;LONG lLockSize = 0 ;DWORD dwBytesWrittenToBuffer = 0;if( FAILED( hr = m_pDSBuf-GetCurrentPosition( &dwPlayPos, &dwWritePos ) return S_FALSE;lLockSize = dwWritePos - m_dwNextPlayOffset;if( lLockSize Lock( m_dwNextPlayOffset, lLockSize,&pvStreamData1, &dwStreamLength1,&pvStreamData2, &dwStreamLe

12、ngth2, 0L)return FALSE;/ read in the dataif(m_stream_handler)(if (dwStreamLength1 m_stream_handler-GetStock()m_stream_handler-Read(pvStreamData1, m_stream_handler-GetStock();elsem_stream_handler-Read(pvStreamData1, dwStreamLength1) ;/ Move the capture offset alongm_dwNextPlayOffset += dwStreamLengthl;m_dwNextPlayOffset %= m_dwPlayBufSize; / Circular bufferif(pvStreamData2 != NULL)(if(m_stream_handler)(if (dwStreamLength2 m_stream_handler-GetStock()m_stream_handler-Read(pvStreamData2, m_stream_handler-GetStock() ;elsem_stream_handler-Read(pvStreamData2, dwStreamLength2);/ Move the capture offs

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論