Wwiseサウンドエンジン統合の最初のステップは、ゲーム起動時にサウンドエンジンを構成する各種モジュールを適切に初期化することです。
このサンプルプロジェクトでは、サウンドエンジンの初期化に関する全ての操作を実行するために次の関数が定義されています:
bool InitSoundEngine() { ... Initialization will be done here ... return true; }
これは、メイン関数の開始時に呼び出されます。初期化の必要な各種モジュールを見てみましょう:
Wwiseサウンドエンジンとリンクしているプロジェクトはすべて、いくつかのフックを定義する必要があります。これらは、メモリアクセスメソッドの呼び出しを監視するために使用することができます。
///////////////////////////////////////////////////////////////////////////////// // Custom alloc/free functions. These are declared as "extern" in AkMemoryMgr.h // and MUST be defined by the game developer. ///////////////////////////////////////////////////////////////////////////////// namespace AK { #ifdef WIN32 void * AllocHook( size_t in_size ) { return malloc( in_size ); } void FreeHook( void * in_ptr ) { free( in_ptr ); } // Note: VirtualAllocHook() may be used by I/O pools of the default implementation // of the Stream Manager, to allow "true" unbuffered I/O (using FILE_FLAG_NO_BUFFERING // - refer to the Windows SDK documentation for more details). This is NOT mandatory; // you may implement it with a simple malloc(). void * VirtualAllocHook( void * in_pMemAddress, size_t in_size, DWORD in_dwAllocationType, DWORD in_dwProtect ) { return VirtualAlloc( in_pMemAddress, in_size, in_dwAllocationType, in_dwProtect ); } void VirtualFreeHook( void * in_pMemAddress, size_t in_size, DWORD in_dwFreeType ) { VirtualFree( in_pMemAddress, in_size, in_dwFreeType ); } #endif }
///////////////////////////////////////////////////////////////////////////////// // Custom alloc/free functions. These are declared as "extern" in AkMemoryMgr.h // and MUST be defined by the game developer. ///////////////////////////////////////////////////////////////////////////////// namespace AK { #ifdef AK_APPLE void * AllocHook( size_t in_size ) { return malloc( in_size ); } void FreeHook( void * in_ptr ) { free( in_ptr ); } #endif }
///////////////////////////////////////////////////////////////////////////////// // Custom alloc/free functions. These are declared as "extern" in AkMemoryMgr.h // and MUST be defined by the game developer. ///////////////////////////////////////////////////////////////////////////////// namespace AK { #ifdef AK_APPLE void * AllocHook( size_t in_size ) { return malloc( in_size ); } void FreeHook( void * in_ptr ) { free( in_ptr ); } #endif }
まず始めに初期化しなければならないのは、Memory Manager(メモリマネージャ)です。次のコードにより、20個のメモリプールを持つデフォルトのメモリマネージャが作成されます:
#include <AK/SoundEngine/Common/AkMemoryMgr.h> // Memory Manager #include <AK/SoundEngine/Common/AkModule.h> // Default memory and stream managers (...) bool InitSoundEngine() { // // Create and initialize an instance of the default memory manager. Note // that you can override the default memory manager with your own. Refer // to the SDK documentation for more information. // AkMemSettings memSettings; memSettings.uMaxNumPools = 20; if ( AK::MemoryMgr::Init( &memSettings ) != AK_Success ) { assert( !"Could not create the memory manager." ); return false; } (...) }
|
Note: メモリマネージャはオーバーライドすることができますが、その場合は、上記のコードを必要に応じて適合させる必要があります。詳細は、メモリマネージャのオーバーライド を参照してください。 |
メモリマネージャに関する詳細は、メモリマネージャ を参照してください。
メモリマネージャの初期化が完了したら、今度は Streaming Manager(ストリーミングマネージャ)を初期化します。
次のコードにより、デフォルトのストリーミングマネージャが初期化されます。これにより、インスタンス AK::StreamMgr::IAkFileLocationResolver が要求され、ストリーミングデバイスが作成されます。これが、ストリーミングデバイスのスケジューラタイプ (AK_DEVICE_BLOCKING または AK_DEVICE_DEFERRED_LINED_UP) によって AK::StreamMgr::IAkIOHookBlocking または AK::StreamMgr::IAkIOHookDeferred を要求します。これらのインターフェースは、SDK付属のデフォルトストリームマネージャ実装に固有の全定義を含む AkStreamMgrModule.h で定義されます。
ディスクI/Oに関しては、デフォルトのストリームマネージャ実装を使用し、AkStreamMgrModule.h で定義されているインターフェースを実装するサウンドエンジン統合方法をお勧めします。これらのインターフェースは、低レベルI/Oサブモジュールを構成しています。詳細は、ストリーミング/ストリームマネージャ を参照してください。
この例は、サンプル CAkFilePackageLowLevelIOBlocking をそのまま使用しています。このクラスは、AKStreamMgr::IAkFileLocationResolver と AK::StreamMgr::IAkIOHookBlocking インターフェースの両方を実装し、File Packager(ファイルパッケージャ)ユーティリティで生成されるファイルパッケージをロードすることができます(ファイルパッケージャに関する詳細と、これが低レベルI/Oでどのように動作するかについての解説は、ファイルパッケージ低レベルI/Oの実装 と File Packager ユーティリティ を参照してください)。
低レベルI/Oに関する詳細は、低レベル I/O を参照してください。
#include <AK/SoundEngine/Common/IAkStreamMgr.h> // Streaming Manager #include <AK/Tools/Common/AkPlatformFuncs.h> // Thread defines #include <AkFilePackageLowLevelIOBlocking.h> // Sample low-level I/O implementation (...) // We're using the default Low-Level I/O implementation that's part // of the SDK's sample code, with the file package extension CAkFilePackageLowLevelIOBlocking g_lowLevelIO; (...) bool InitSoundEngine() { (...) // // Create and initialize an instance of the default streaming manager. Note // that you can override the default streaming manager with your own. Refer // to the SDK documentation for more information. // AkStreamMgrSettings stmSettings; AK::StreamMgr::GetDefaultSettings( stmSettings ); // Customize the Stream Manager settings here. if ( !AK::StreamMgr::Create( stmSettings ) ) { assert( !"Could not create the Streaming Manager" ); return false; } // // Create a streaming device with blocking low-level I/O handshaking. // Note that you can override the default low-level I/O module with your own. Refer // to the SDK documentation for more information. // AkDeviceSettings deviceSettings; AK::StreamMgr::GetDefaultDeviceSettings( deviceSettings ); // Customize the streaming device settings here. // CAkFilePackageLowLevelIOBlocking::Init() creates a streaming device // in the Stream Manager, and registers itself as the File Location Resolver. if ( g_lowLevelIO.Init( deviceSettings ) != AK_Success ) { assert( !"Could not create the streaming device and Low-Level I/O system" ); return false; } (...) }
デフォルトストリームマネージャとストリーミングデバイスの初期設定に関する詳細は、Audiokinetic ストリームマネージャ初期化設定 を参照してください。
|
Caution: 初期設定の一部は、 AkThreadProperties のようにプラットフォーム固有のメンバ構造体を使用します。 |
デフォルトの低レベルI/Oの実装、または、完全なストリーミングマネージャをオーバーライドする場合、必要に応じてこのコードを適合させる必要があります。詳細は、ストリーミング/ストリームマネージャ を参照してください。
基本的なモジュールの初期化が終わったので、サウンドエンジンそのものを初期化する準備ができました:
#include <AK/SoundEngine/Common/AkSoundEngine.h> // Sound engine (...) bool InitSoundEngine() { (...) // // Create the Sound Engine // Using default initialization parameters // AkInitSettings initSettings; AkPlatformInitSettings platformInitSettings; AK::SoundEngine::GetDefaultInitSettings( initSettings ); AK::SoundEngine::GetDefaultPlatformInitSettings( platformInitSettings ); if ( AK::SoundEngine::Init( &initSettings, &platformInitSettings ) != AK_Success ) { assert( !"Could not initialize the Sound Engine." ); return false; } (...) }
サウンドエンジン初期化に関する詳細は、サウンドエンジン統合の詳細 を参照してください。
プロジェクトがインタラクティブミュージック(Interactive Music)機能を使用する場合、サウンドエンジンに続いてミュージックエンジンも初期化する必要があります。
#include <AK/MusicEngine/Common/AkMusicEngine.h> // Music Engine (...) bool InitSoundEngine() { (...) // // Initialize the music engine // Using default initialization parameters // AkMusicSettings musicInit; AK::MusicEngine::GetDefaultInitSettings( musicInit ); if ( AK::MusicEngine::Init( &musicInit ) != AK_Success ) { assert( !"Could not initialize the Music Engine." ); return false; } (...) }
Wwiseオーサリングアプリケーションを、ゲームに接続してゲーム内でミキシング、プロファイリングやトラブルシューティングを実行したい場合、次のステップは通信の初期化です。ゲーム内ミキシング、プロファイリングとトラブルシューティングは、サウンドエンジニアにとって、より効率的にゲームオーディオに取り組むための極めて強力な方法なので、通信の初期化を強くお勧めします。
|
Note: 通信を使用するには、CommunicationCentral モジュールとリンクする必要があります。 |
|
Note: 通信は、サウンドエンジンの Debug および Profile コンフィギュレーションでのみご利用可能で、ゲームのリーテルバージョンでは必要とされません。従って、これはサウンドエンジンの Release ビルドには含まれていません。以下のコードは、Release ビルドから通信に固有のコードを除外するために AK_OPTIMIZED シンボルを使用しています。 |
// Include for communication between Wwise and the game -- Not needed in the release version #ifndef AK_OPTIMIZED #include <AK/Comm/AkCommunication.h> #endif // AK_OPTIMIZED (...) bool InitSoundEngine() { (...) #ifndef AK_OPTIMIZED // // Initialize communications (not in release build!) // AkCommSettings commSettings; AK::Comm::GetDefaultInitSettings( commSettings ); if ( AK::Comm::Init( commSettings ) != AK_Success ) { assert( !"Could not initialize communication." ); return false; } #endif // AK_OPTIMIZED (...) }
これで、サウンドエンジンの全モジュール初期化が完了しました。次に、プラグイン(プラグイン統合例 を参照)を登録する必要があります。オーディオを処理するために、ゲームループ内に作成する必要のある呼び出しの詳細については、オーディオ処理実行の反復呼び出し作成 を参照してください。
一部のコンソールの通信ライブラリは、初期化/終了 呼び出しのバランスを適切に保たないため、AKComm::Term の呼び出しにより、コンソール用の基本的な低レベル通信ライブラリを終了させます。これは、ゲームに対するの全てのTCP/IP通信を効果的に閉じます。終了後もゲーム側が通信ライブラリを有効に保つ必要がある場合は、(AkComm:Init と一緒に使用される)AkCommSettingsに、システムライブラリを初期化するかどうかを決めるパラメータがあります。通信ライブラリ自体を初期化する場合、Wwiseサウンドエンジンに使用される以下のコードを確認してください。ゲームは、同様の動作をするはずです。
Windows ソケットの初期化:
WSAData wsaData = { 0 }; ::WSAStartup( MAKEWORD( 2, 2 ), &wsaData )
終了:
::WSACleanup();
AkCommSettings 構造体の AkCommSettings::ports メンバは、Wwiseオーサリングアプリケーションとサウンドエンジン間の通信に使用されるネットワークポートを表します。Wwise 通信が有効にされると、これらの全てのポートがゲーム側で開かれます。
ポート AkCommSettings::Ports::uDiscoveryBroadcast は、動的にすることができません(0に設定することができません)。オーサリングアプリケーションがこのポートを認識し、ネットワーク上でゲームを検出する必要があるからです。更に、ここで指定する値は、オーサリングアプリケーション内 Project Settings(プロジェクト設定)の Network タブで指定した値と同じでなければなりません。
|
Tip: チームがWwiseを使用して複数のゲームに取り組んでいる場合、ゲームごとに異なるディスカバリブロードキャストポートを使用することができます。Wwiseオーサリングアプリケーションの Remote Connections(リモート接続)ウインドウを開いた時に、現在開いている Wwise プロジェクトに対応するゲームのみが表示されます。このポートを変更する場合は、必ずオーサリングアプリケーションの Project Settings およびゲーム内で AK::Comm::Init() に渡す AkCommSettings 構造体の両方において変更を行うようにしてください。 |
構造体の他の2つのポートは、動的(つまり「エフェメラル」)にすることができます。すなわち、固定ポートを使用する代わりに、オペレーティングシステムによって自動的にいずれかのポートが選択されるようにできます。
これらのポートは、デフォルトで動的になっています。他のアプリケーションとの競合の可能性を最小限に抑えるために、動的に保つことをお勧めします。
Wwiseは、正常に動作するために4つの連続チャンネルを必要とし、これらのチャンネルはポート構造で表されている順序どおりに順序付けられる必要があります。Wwiseでは、ベースポートを選択することができます(デフォルトでは8)。
これらが、ゲームの他のコンポーネントに使用されるポートと競合する場合は、AKComm::Init() を呼び出す前に AkCommSettings 構造体で変更してください。
|
Note: マルチプラットフォーム対応のゲームでは、AkCommSettingsPorts::uCommand、AkCommSettingsPorts::uNotification および AkCommSettings::Ports::uControl に対して、プラットフォームごとに異なるポートを使用するのが有効です。 |
|
Tip: 動的/エフェメラルポートの詳細については、次のWebサイト参照してください。 |
Wwise通信に関与するポートがもう1つありますが、このポートはオーサリングアプリケーションのみで開かれるので、AkCommSettingsPorts 構造体の一部ではありません。
このポートは、ネットワーク上で実行されているゲームを検出するために送信される Discovery Broadcast メッセージへの応答を受信するために、オーサリングアプリケーションによって使用されます。このポートは、デフォルトでは動的(0に設定)ですが、オーサリングアプリケーション内のProject Settingsから変更可能です。