« wasm と JavaScript の間の文字列(バイト列)の受け渡し | メイン | OpenSL ES と XAudio2 »

2017年02月18日

吉里吉里Z 開発:: XAudio2

    

DirectX のバージョンによって 2.0 ~ 2.7 がある。最新版である 2.7 を対象とすれば問題ないと思われる。
Windows8 は 2.8、Windows10 は 2.9 となっている。
環境にある DLL の xaudio2_7.dll、xaudio2_8.dll、xaudio2_9.dll の内、新しいバージョンの DLL をロードすればよさそうであるが、それだけではうまく動かなさそうである。

ヘッダーファイルを見るとバージョンによって、構造体にメンバが増えていたり、インターフェイスにメソッドが増えていたり、メソッドにパラメータが増えていたりするので、別物として扱う必要がある。
2.8 と 2.9 はヘッダー共通なので、2.7 とそれより後の 2 パターンで使用するメソッドについてラッパーを書けば両バージョンに対応できなくはなさそうである。
dll から XAudio2Create 関数を得て、それ以降で得られるインターフェイスの IXAudio2 などを別物として扱えば、理屈上は両方に対応できるはずである。
もしくは、Windows7 以下を切り捨てるのなら、2.8 と 2.9 のヘッダー(インターフェイス/構造体)でそのまま使える。

Windows7 を切らないという選択を選ぶのであれば、namespace とファイル分離、Factory によって何とかするのが記述量一番少ないと考えられる。
以下のような実装。

namespace xaudio2_7 {
#include "xaudio2_7.h"
#include "xaudio2driver.h"
};
IXAudio2Driver* CreateXAudio2Driver7(HMODULE hDll){...}


namespace xaudio2_9 {
#undef _WIN32_WINNT
#define _WIN32_WINNT _WIN32_WINNT_WIN8
#include "xaudio2_9.h"
#include "xaudio2driver.h"
};
IXAudio2Driver* CreateXAudio2Driver9(HMODULE hDll){...}


extern IXAudio2Driver* CreateXAudio2Driver7(HMODULE);
extern IXAudio2Driver* CreateXAudio2Driver9(HMODULE);

IXAudio2Driver* pDriver = nullptr;
HMODULE hDll = LoadLibrary(L"xaudio2_9.dll");
if( !hDll ) {
  hDll = LoadLibrary(L"xaudio2_8.dll");
}
if( hDll ) {
  pDriver = CreateXAudio2Driver9( hDll );
} else {
  hDll = LoadLibrary(L"xaudio2_7.dll");
  if( hDll ) pDriver = CreateXAudio2Driver7( hDll );
}
return pDriver;

// ここでは放置しているが hDll は使い終わったら FreeLibrary する。
// IXAudio2Driver は自前のインターフェイス

xaudio2_7 と xaudio2_9 でファイルを分離するのは define で定数等定義されているから。
xaudio2driver.h 内に通常の実装を入れて include することで2回書くのを回避する。
xaudio2_7.h は、DirectX SDK のヘッダーをリネームして置いて、xaudio2_9.h は Windows SDK の方のヘッダー。

と書いたものの、ここまでして実装した方がいいかは疑問。
XAudio2 に比べれば複雑になるものの、DirectSound よりは記述量少なそうな WASAPI を選択する方が良さそうに思える。


投稿者 Takenori : 2017年02月18日 04:30




comments powered by Disqus
Total : Today : Yesterday : なかのひと