前にXACT3でWaveを再生する処理を書きましたが、いちいちWaveファイルを固めるのはメンドくさい。
てな訳で、改めてXAudio2でWaveを再生することにしました。まぁサンプルにそのものずばりな物があるので(XAudio2BasicSound)、それを元にゲームで使える様な物に作り替えます。
基本的な処理の流れは、COMを初期化してXAudio2を使えるようにする。マスターボイスを作ってその中にWaveから取り出したソースボイスを入れる。再生。といった感じです。
今回はXAudio2の部分CAudioBaseクラスだけ記述しました。Waveファイルからデータを取り出す処理は次回。
//-------------------------------------------------------------------------------------- // 生成 CAudioBase::CAudioBase() { for (int i=0; i<MAX_SOUND; i++) { pSourceVoice[i]=NULL; pXAudioBuffer[i]=NULL; pbWaveData[i]=NULL; } pXAudio2=NULL; pMasteringVoice=NULL; } //----------------------------------------------------------------------------- // 解放 CAudioBase::~CAudioBase() { Release(); // マスターボイス解放 if (pMasteringVoice!=NULL) { pMasteringVoice->DestroyVoice(); pMasteringVoice=NULL; } // XAudio解放 SAFE_RELEASE(pXAudio2); // COM解放 CoUninitialize(); } //-------------------------------------------------------------------------------------- // 初期化 BOOL CAudioBase::Init() { // COM初期化 CoInitializeEx(NULL, COINIT_MULTITHREADED); // デバッグモードの場合 UINT32 flags=0; #ifdef _DEBUG flags|=XAUDIO2_DEBUG_ENGINE; #endif // XAudio2生成 if (FAILED(XAudio2Create(&pXAudio2, flags))) { CoUninitialize(); return E_FAIL; } // マスターボイス生成 if (FAILED(pXAudio2->CreateMasteringVoice(&pMasteringVoice))) { SAFE_RELEASE(pXAudio2); CoUninitialize(); return E_FAIL; } return S_OK; } //----------------------------------------------------------------------------- // 解放 void CAudioBase::Release() { // ソースボイス解放 for (int i=0; i<MAX_SOUND; i++) { ReleaseSound(i); } } //----------------------------------------------------------------------------- // サウンド解放 void CAudioBase::ReleaseSound(int no) { if (pbWaveData[no]!=NULL) { SAFE_DELETE(pbWaveData[no]); } if (pXAudioBuffer[no]!=NULL) { SAFE_DELETE(pXAudioBuffer[no]); } if (pSourceVoice[no]!=NULL) { pSourceVoice[no]->DestroyVoice(); pSourceVoice[no]=NULL; } } //-------------------------------------------------------------------------------------- // ファイル読み込み int CAudioBase::LoadSound(LPSTR szFilename, int loop_flag) { int i; // 空いているWaveがあるか検索 for (i=0; i<MAX_SOUND; i++) { if (pSourceVoice[i]==NULL) { break; } } if (i>=MAX_SOUND) { return -1; } // Waveファイル読み込み CAudioWave wav; if (FAILED(wav.Open(szFilename, NULL))) { return -1; } // Waveファイルのフォーマット取得 WAVEFORMATEX* pwfx=wav.GetFormat(); // サイズ計算 DWORD cbWaveSize=wav.GetSize(); // メモリにデータを乗せる pbWaveData[i]=new BYTE[cbWaveSize]; if (FAILED(wav.Read(pbWaveData[i], cbWaveSize, &cbWaveSize))) { SAFE_DELETE_ARRAY(pbWaveData[i]); return -1; } // ソースボイス生成 if (FAILED(pXAudio2->CreateSourceVoice(&pSourceVoice[i], pwfx))) { SAFE_DELETE_ARRAY(pbWaveData[i]); return -1; } if (loop_flag!=0) { loop_flag=XAUDIO2_LOOP_INFINITE; } // オーディオバッファ設定 pXAudioBuffer[i]=new XAUDIO2_BUFFER; pXAudioBuffer[i]->Flags=XAUDIO2_END_OF_STREAM; pXAudioBuffer[i]->AudioBytes=cbWaveSize; pXAudioBuffer[i]->pAudioData=pbWaveData[i]; pXAudioBuffer[i]->PlayBegin=0; pXAudioBuffer[i]->PlayLength=0; pXAudioBuffer[i]->LoopBegin=0; pXAudioBuffer[i]->LoopLength=0; pXAudioBuffer[i]->LoopCount=loop_flag; if (FAILED(pSourceVoice[i]->SubmitSourceBuffer(pXAudioBuffer[i]))) { pSourceVoice[i]->DestroyVoice(); SAFE_DELETE_ARRAY(pbWaveData[i]); return -1; } return i; } //-------------------------------------------------------------------------------------- // サウンド再生 void CAudioBase::PlaySound(int no) { if (no==-1 || pSourceVoice[no]==NULL) { return; } StopSound(no); pSourceVoice[no]->FlushSourceBuffers(); pSourceVoice[no]->SubmitSourceBuffer(pXAudioBuffer[no]); HRESULT hr=pSourceVoice[no]->Start(0); } //-------------------------------------------------------------------------------------- // サウンド停止 void CAudioBase::StopSound(int no) { if (no==-1 || pSourceVoice[no]==NULL) { return; } pSourceVoice[no]->Stop(0); }