初探XAudio2
前言
最近要在遊戲引擎裡播放聲音,本想繼續使用以前的DirectSound來播,但查了一下DirectSound的wiki得知DirectSound已不建議使用,所以打算改成XAudio2來播放聲音,以下是學習心得,在此做個紀錄。內容
在使用XAudio2的開始需要一些範例,但不幸的是Windows10本身沒給範例,所以請到舊的DirectX範例裡下載,裡面有個"XAudio2"的資料夾,範例就在裡面。使用XAudio2時需要"IXAudio2",所有的資源都由這個COM來管理,有點類似OpenGL的context,範例如下
HRESULT hr = CoInitializeEx( nullptr, COINIT_MULTITHREADED ); if (FAILED(hr)) { wprintf(L"Failed to init COM: %#X\n", hr); return 0; } // IXAudio2* pXAudio2 = nullptr; hr = XAudio2Create( &pXAudio2 , 0); if( FAILED( hr ) ) { wprintf( L"Failed to init XAudio2 engine: %#X\n", hr ); CoUninitialize(); return 0; }
在CoInitializeEx()的部分並不是每次要XAudio2Create()之前都要喚起,而是整個程式只要在最開頭喚起一次就好,當然在程式最後也請喚起CoUninitialize()。XAudio2Create()可以依據需要填 入debug的flag,範例裡有示範。
接著來製造"IXAudio2MasteringVoice",這個COM其實我並不是很了解它的作用,但一定要製造,製造的方法很簡單,範例如下
//IXAudio2* pXAudio2; IXAudio2MasteringVoice* pMasteringVoice = nullptr; if( FAILED( pXAudio2->CreateMasteringVoice( &pMasteringVoice ) ) ) { pXAudio2->Release(); CoUninitialize(); return 0; }
接著來製造"IXAudio2SourceVoice",這個就是在播放聲音的COM,依據需要"同時"播放幾個聲音來決定需要的數量,製造前需要決定播放的格式,這個結構是"WAVEFORMATEX",這個結構的資料可以在WAV檔裡的"fmt"的chunk裡找到,可以參考前篇WAV檔案格式學習心得,範例如下
//IXAudio2* pXAudio2; IXAudio2MasteringVoice* pMasteringVoice; WAVEFORMATEX format; //Fill struct data //... IXAudio2SourceVoice* pSourceVoice = nullptr; if( FAILED( pXaudio2->CreateSourceVoice( &pSourceVoice, &format) ) ) { return 0; }
接著將WAV的raw data送到"IXAudio2SourceVoice",範例如下
//IXAudio2* pXAudio2; IXAudio2MasteringVoice* pMasteringVoice; IXAudio2SourceVoice* pSourceVoice; unsigned char* pWAVRawData; size_t wavRawDataSize; XAUDIO2_BUFFER buffer = {0}; buffer.pAudioData = pWAVRawData; buffer.Flags = XAUDIO2_END_OF_STREAM; buffer.AudioBytes = wavRawDataSize; if( FAILED(pSourceVoice->SubmitSourceBuffer( &buffer ) ) ) { pSourceVoice->DestroyVoice(); return 0; }
這裡要注意"IXAudio2SourceVoice"的釋放不是用Release(),而是用DestroyVoice(),接著只要使用Start()
來播放即可,要停止播放使用Stop()。
最後來說說Stream play,請看下圖
Stream play |
參考資料
DirectSound的wiki舊的DirectX範例
沒有留言:
張貼留言