初探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範例

沒有留言:
張貼留言