Wwiseサウンドエンジンでは、イベントとゲームシンクで再生を制御します。これらの要素は、SoundBankに保存した内部サウンド構造を参照しますが、最終的にはルースメディアファイルを参照しますこれらすべては、使用する前にサウンドエンジンにロードする必要があります。
SoundBankは黙示的または明示的のいずれかでロードすることができます。以下に詳細を示す両アプローチとも異なるオプションが用意されていますが、特定のシナリオにおいて評価する必要のある黙示的な利点と不利な点があります。
AK::SoundEngine::LoadBank() のサウンドエンジン API メソッドの1つを使用して、サウンドバンクを明示的にロードすることができます。サウンドバンクがロードされたら、サウンドバンク内にあるすべてのオブジェクトが使用可能になります。
次の例では、BANK_01 サウンドバンクが明示的にロードされます。これは、Wwise_IDs.h ヘッダファイルで定義されているIDによって識別されます。文字列(Unicode または ANSI)または ID を使用したサウンドバンクの識別に関する説明は、 バンクの識別 を参照してください。このバンクには、PLAY_SOUND_01 というイベントと、これに関連するサウンド構造とメディアが含まれています(Wwise でのサウンドバンク生成に関する詳細は、Wwise Help を参照してください)。このバンクがロードされると、イベントがサウンドエンジンにポストされます。
|
Note: サウンドデータは、この目的のために自動作成されるメモリプールに格納されています。メモリ使用に関する詳細は、メモリ使用量 セクションを参照してください。 |
#include "Wwise_IDs.h" // ... AkGameObjectID gameObj = 3; AK::SoundEngine::RegisterGameObj( gameObj ); // Load a bank synchronously, using its ID. AkBankID returnedBankID; AKRESULT eResult = LoadBank( AK::BANKS::BANK_01, // Identifier of the bank to be loaded. AK_DEFAULT_POOL_ID, // Memory pool ID (data is written in the default sound engine memory pool when AK_DEFAULT_POOL_ID is passed). returnedBankID // Returned bank ID. ); if( eResult != AK_Success ) { // Failed loading bank. // Handle error... } // Load succeeded. // Use the bank as required... // For example, if the bank contained the event PLAY_SOUND_01, along with its // associated sound structures and media. AK::SoundEngine::PostEvent( AK::EVENTS::PLAY_SOUND_01, // Unique ID of the event gameObj // Associated game object ID );
バンクは、イベントやゲームシンクを準備することにより、暗黙的にロードすることもできます。このためには、イベントとゲームシンクの定義を含んでいるサウンドバンクを、まず LoadBank() を介して、明示的にロードする必要があります。通常、これらのサウンドバンクはイベントのみを含んでいるので、非常に軽量です。イベントデータのみを含むサウンドバンクを定義する方法に関しては、Wwise Help を参照してください。イベントが参照するサウンド構造と/またはメディアがサウンドバンク内に含まれてない場合、このバンクはこれらを含む1つまたは複数の他のバンクへの参照を持ちます。イベントまたはゲームシンクの定義がロードされると、これらが使用できるように“準備”すればよいだけです( AK::SoundEngine::PrepareEvent() および AK::SoundEngine::PrepareGameSyncs() )。サウンドエンジンは、どのバンクがメモリにロードされるべきかを定義し。これらのバンクに関連するサウンド構造とメディアを取得します。メモリにロードされるのは、サウンドバンクのすべてのメディアではなく、イベントによりアクセスされる可能性があるメディアのみであることに注意してください。これは全て、フードの下で実行されるため、暗黙的なサウンドバンクのロードと称されます。
次の例では、BANK_0 2バンクが明示的にロードされます。このバンクは、PLAY_SOUND_02 イベントの定義を含んでいます。イベントに関連するサウンド構造とメディアは含まないので、イベントが前もって準備されていないと、そのポストが正常に行われません。したがって、バンクが正常にロードされた後、ポストに先立ってイベントが準備されます。イベントの準備が整うと、サウンドエンジンが、イベントの正常なポストに必要なすべてのバンクを自動的にロードします。
#include "Wwise_IDs.h" // ... AkGameObjectID gameObj = 3; AK::SoundEngine::RegisterGameObj( gameObj ); // Load a bank synchronously, using its ID. // This bank may contain only the definition of the events you wish to use. AkBankID returnedBankID; AKRESULT eResult = LoadBank( AK::BANKS::BANK_02, // Identifier of the bank to load. AK_DEFAULT_POOL_ID, // Memory pool ID (data is written in default sound engine memory pool when AK_DEFAULT_POOL_ID is passed). returnedBankID // Returned bank ID. ); if( eResult != AK_Success ) { // Failed loading bank. // Handle error... } // Load succeeded. The definition of the event PLAY_SOUND_02 and its related structures are loaded. // In order to post the event, it needs to be prepared (here, synchronously). AkUniqueID eventToPrepare = AK::EVENTS::PLAY_SOUND_02; eResult = PrepareEvent( Preparation_Load, // Preparation type: load. &eventToPrepare, // Array of event IDs. 1 // Number of event IDs in the array. ); if ( eResult != AK_Success ) { // Failed preparing event. // Handle error... } // Prepare event succeeded: the sound engine has gathered all the media (and sound // structures if necessary) that are required to successfully post the event, by loading all // necessary media under the hood. // Post the event. AK::SoundEngine::PostEvent( AK::EVENTS::PLAY_SOUND_02, // Unique ID of the event gameObj // Associated game object ID );
AK::SoundEngine::PrepareEvent と AK::SoundEngine::PrepareGameSyncs の使用法のより完全な例をご覧になるには、以下のセクションを参照してください:
バンクのロードは、サウンドエンジンの独立したスレッドで実行されます。メイン API の LoadBank()、PrepareEvent() と PrepareGameSyncs() のすべての関数は同期的および非同期的ロードスキームを介して使用できます。
同期的な AK::SoundEngine::LoadBank() 関数は、ブロック関数です。これらの関数は、バンクがロードされた時、または、エラーが発生した時に値を返します。
非同期的な AK::SoundEngine::LoadBank() 関数は即座に値を返し、要求されたアクションが完了した後に、コールバック関数が cookie をパラメータとして呼び出されます。コールが非同期である場合、コールバック関数でエラー処理を実行する必要があります。
cookie のパラメータはオプションであり、必要であれば使用可能です。使用しない場合は、NULL を渡します。サウンドエンジンは、このポインタを使用せず、コールバック関数を使用して値を返します。
LoadBank()、UnloadBank()、 PrepareEvent() と PrepareGameSyncs() の非同期バージョンと使用されるコールバック関数は、このプロトタイプに従う必要があります:
typedef void( *AkBankCallbackFunc )( AkBankID in_bankID, void * in_pInMemoryBankPtr, AKRESULT in_eLoadResult, AkMemPoolId in_memPoolId, void * in_pCookie );
ユーザーは、コールバック関数を実装する責任を持ち、従って、その有効性を保証する必要があります。
PrepareEvent と PrepareGameSync に対するコールバックを受信する時、in_bankID と in_bankID のパラメータは関連性を持たないので、単純に無視してください。
|
Note: メモリプール ID は、AK_DEFAULT_POOL_ID、または、ユーザー作成による任意のプール ID です。バンクメモリアロケーションモデルに関する詳細は、メモリ使用量 を参照してください。 |
コールバック関数に渡されるパラメータの定義に関しては、AkBankCallbackFunc を参照してください。
バンクの識別 ですでに述べたように、ユーザー側でファイルからバンクをロードし、ポインタとサイズで LoadBank() の適切なオーバーロードを提供するか、バンク識別子(ID または文字列、上記の説明を参照)を指定し、ストリームマネージャを介してサウンドエンジンにバンクファイルをロードさせることができます。
メモリからバンクをロードするには、以下の LoadBank() のプロトタイプのいずれかを使用してください:
// Synchronous. AKRESULT LoadBank( void * in_pInMemoryBankPtr, ///< Pointer to the in-memory bank to load AkUInt32 in_uInMemoryBankSize, ///< Size of the in-memory bank to load AkBankID & out_bankID ///< Returned bank ID ); // Asynchronous. AKRESULT LoadBank( void * in_pInMemoryBankPtr, ///< Pointer to the in-memory bank to load AkUInt32 in_uInMemoryBankSize, ///< Size of the in-memory bank to load AkBankCallbackFunc in_pfnBankCallback, ///< Callback function void * in_pCookie, ///< Callback cookie AkBankID & out_bankID ///< Returned bank ID );
メモリはサウンドエンジンの内部にコピーされないので、バンクがアンロードされるまでこれが有効にになっていることを確認する必要があります。バンクのロード先である、提供されたメモリポインタのプラットフォームによっては、アラインメント制限が適用されることがあります。すべてのプラットフォーム上で、メモリを AK_BANK_PLATFORM_DATA_ALIGNMENT バイトにアラインする必要があります。プラットフォームによっては、異なる要件がある場合がありますので、プラットフォーム固有のSDKドキュメンテーションを確認してください。
LoadBank() は、提供されるポインタの最初の数バイトに格納されているバンク ID を解析し、値を返します。バンクを後ほどアンロードするためにこのバンク ID を保持してください。
|
Note: ユーザー側でのファイル I/O 実行を選択し、サウンドエンジンをポインタでフィードする場合、明示的なバンクのロードを使用する必要があります。暗黙的なバンクのロードは、予測できない可能性があります。PrepareXXXX コマンドに従うと、ロードされるバンク数やこれらのバンクのメモリ要件を確認することができません。これは、PrepareEvent と PrepareGameSyncs のメモリ内バージョンが存在しないためです。 |
サウンドエンジンは、ファイルからの読み込みを必要とする場合は常に Stream Manager(ストリームマネージャ)を使用します。バンクの識別と I/Oに 関する説明は、バンクの識別 を参照してください。
AK::SoundEngine::SetBankLoadIOSettings() 関数を使用して、ストリームマネージャに対するサウンドエンジンのバンクローダの動作を微調整することができます。I/O に関する更なる詳細は、 ストリーミング/ストリームマネージャ セクションを参照してください。
サウンドエンジンは、バンクのメタデータを解析し、サウンドエンジンのデフォルトプール内にそのオブジェクトを作成します。
I/O を伴う明示的な LoadBank() 関数では、メディアはディスクから読み込まれ、メモリプール(これらの関数の in_pool ID引数)にコピーされます。AK_DEFAULT_POOL_ID を渡すと、この目的のためにメモリプールが内部的に作成されます。PrepareEvent() と PrepareGameSyncs() を介して暗黙的にロードされたメディアに関しては、サウンドエンジンの初期化設定でカスタムプールを指定することも可能です( AkInitSettings::uPrepareEventMemoryPoolID )。
|
Tip: メモリプール割り当てのプロセスは、ゲームの起動時またはプレイヤーが新たなレベルに入るたびに実行できます。デフォルトのプール割り当てモデルは、バンクサイズが凍結されるまで、開発サイクル初期に使用することができます。このようにして、バンクに割り当てられるメモリを最適に管理することができます。 |
SDKを使用したメモリプールの作成と管理に関する詳細は、プール を参照してください。
バンクを明示的にアンロードするための UnloadBank() のオーバーロードが4つあります:
同様に、Preparation_Unload フラグと共に PrepareEvent() 関数を使用し、これらのイベントに関連付けられた構造とメディアの参照カウントをデクリメントすることができます。暗黙的にロードされたバンク内の全てのオブジェクトの参照カウントが 0 まで低下すると、このバンクは自動的にアンロードされます。
また、Preparation_Unload フラグと共に PrepareGameSyncs() 関数を使用し、指定されたゲームシンクが選択された時にのみ再生する、準備済みイベント用にロードされたメディアをアンロードすることができます。ゲームシンクは参照カウントを持たないので、これを Preparation_Unload フラグで一度呼び出すと、参照されないメディアが即時にアンロードされることに注意してください。
AK::SoundEngine::UnloadBank() 関数は、バンクがロードされたメモリプールの ID を返します。プールがロードバンクで未指定だった場合、または、プールが存在しなかった場合、メモリプール ID は AK_DEFAULT_POOL_ID です。
|
Note: バンクに参照されるサウンドが当該バンクのアンロード時に再生しており、そのサウンド構造がバンクに含まれていると、常にこのサウンドは停止します。当該バンクにはメディアのみが含まれていて、他のロード済みバンクにメディアとサウンド構造が含まれている場合もサウンドが停止する可能性があります。これは、前者または後者のいずれのバンクのデータからメディアが再生されたかによります。バンクコンテンツの重複 を参照してください。 |
|
Note: イベントが当該サウンドのパラメータ変更に使用されている場合(例えば、SetVolume イベントなど)、この情報は削除されます。RTPC、ステートまたはスイッチを使用してパラメータが変更された場合、パラメータはメモリに保持され、サウンドバンクがリロードされると自動的に適用されます。 |
次のコードは、文字列識別子とデフォルトのバンクメモリアロケーションを使用して、バンクを同期的にロードおよびアンロードします。また同様に、PrepareEvent() を介してバンクを暗黙的にロードおよびアンロードします。
AkBankID bankID; AKRESULT eResult = AK::SoundEngine::LoadBank( L"Bank1.bnk", AK_DEFAULT_POOL_ID, bankID ); if( eResult != AK_Success ) { // Failed loading bank. // Handle error... } // Bank load succeeded. // Prepare an event. const char * pszEvent = "Event1"; eResult = PrepareEvent( Preparation_Load, &pszEvent, 1 ); if( eResult != AK_Success ) { // Failed preparing event. // Handle error... } // Use the event and bank data... // Then, unprepare the event. eResult = PrepareEvent( Preparation_Unload, &pszEvent, 1 ); if( eResult != AK_Success ) { // Failed unpreparing event. // Handle error... } // Unload the bank. // Note: The bank is unloaded using the bank ID returned by LoadBank(). The call // AK::SoundEngine::UnloadBank( L"Bank1.bnk" ); // works too: the sound engine internally converts the "Bank1.bnk" string into the bank ID. eResult = AK::SoundEngine::UnloadBank( bankID ); if( eResult != AK_Success ) { // Failed unloading bank. // Handle error... }
LoadBank() および PrepareEvent() 関数に加えて、バンクを準備することも可能です。次のいずれかのメソッドを使用して、バンクの準備をすることができます:
これらのメソッド両方は、実装が少し異なる同じ PrepareBank メカニズムを使用しますが、AkBankContent_All は、最も一般的なシナリオで使用します。
PrepareEvent または PrepareBank を使用する時には、メディアをロードするための有効なメモリプールを提供する必要があることに注意してください。これは、AkInitSettings 構造体の uPrepareEventMemoryPoolID パラメータを SoundEngine に渡すことで実行できます。次のサンプルを参照してください: メソッド4:イベントを準備。
AkBankContent_All
を使用したバンクの準備によって、PrepareEvent() メカニズムの利点を生かしながら、LoadBank() メカニズムの欠点のいくつかを克服することができます。このメソッドを使用する際、バンクにすべてのコンテンツタイプ(イベント、構造体データやメディアファイル)が含まれている可能性がありますが、メディアファイルを完全にロードする代わりに、このメソッドは PrepareEvent メカニズムに類似したメカニズムを使用して、すべてのメディアをメモリにロードします。PrepareBank() でメディアを読み込む場合、Wwise は読み込む前にまずメディアファイルが既にメモリに存在するかを確認します。これにより、メモリ内でのメディアファイルの重複を避けることができ、メモリ使用量が最低限に保たれます。
AkBankContent_All は、PrepareBank() のデフォルトの読み込みメカニズムであり、 バンクにメディアアイテムがあるか確認してから、準備プールに読み込みます。特定のイベントのメディアがバンクに存在しない場合、PrepareEvent()の呼び出しによってルースファイルから後ほど読み込むことができます。
PrepareBank() を AkBankContent_StructureOnly
と共に使う場合、そのイベンドと構造メタデータは、SoundBankから読み込まれますが、バンクに含まれるメディアアイテムは無視されます。PrepareEvent() はディスクからのルースファイルとしてアクセスする必要があり、SoundBank内にあるファイルを読むことができないので、AkBankContent_StructureOnly
は、他の場合には他の読み込みメカニズムを使用し SoundBank にロードするよう計画する場合にのみ有用です。PrepareEvent() で個々にメディアがロードされるという多くのシナリオにおいては、メディアはバンクに含めず、AkBankContent_StructureOnly
フラグが AkBankContent_All
と同じ結果を生成します。
AkBankContent_StructureOnly
フラグが有用である可能性のある一つの例として、複数の読み込み構成を実装することがあげられます。あるゲームは、オンデマンドでスールファイルを読み込むために PrepareEvent() を使用する「ツールモード」、および全体として同じバンクを読み込むためにLoadBank() を使用する「ゲームモード」があるかもしれません。
PrepareBank() は、お好みで APIから同期的または非同期的に呼び出すことができます。しかし、AkBankContent_All
および AkBankContent_StructureOnly
を同じバンクで使用することはお勧めしません。その理由は、 AkBankContent_All
を使って一度メディアを読み込むと、アンロードがイベント、構造、およびメディアをすべてリリースしてしまうからです。
サウンドエンジンの内容をリセットしたい場合、 AK::SoundEngine::ClearBanks()
関数の呼び出しが有用です。SoundEngine::Term()
を呼び出す前に、 ClearBanks()
を呼び出す必要がないことに注意してください。ClearBanks
は内部的に AK::SoundEngine::ClearPreparedEvents
を呼び出します。
この関数が呼び出されると:
AK::SoundEngine::ClearPreparedEvents() 関数を呼び出すと、単一のイベントが準備された回数に関係なく、準備済みの全イベントが準備解除されます。AK::SoundEngine::ClearBanks()
を呼び出すと、AKSoundEngine::ClearPreparedEvents() が内部的に呼び出されます。
各バンクは一度のみロード可能です。同じバンクを明示的に再度ロードしようとすると、バンクロードエラーが発生します。
Wwise サウンドエンジンでは、同一のイベント、サウンド構造、またはメディアを2つ以上のバンクに格納し、これらをすべて同時にロードすることが可能です。
|
Note: AACやOpusの場合はメディアのリロケーションに対応していないので、複数のバンクに共通するサウンドの再生中にそのサウンドを読み出しているサウンドバンクがアンロードされると、このサウンドの再生が停止します。 他のロード済みサウンドバンクのいずれかで、このサウンドのインスタンスへの移行が行われることはありません。 |
PrepareEvent
の使用時に、異なるイベントが同一のメディアコンテンツのロードを要求する場合、ロードされたメディアがメモリ内で重複されることはありません。 複数のイベントによる同じメディアオブジェクトの参照が可能で、このメディアオブジェクトは、これを参照するすべてのイベントが準備解除になった時のみアンロードされます。
LoadBank
使用時にはバンクがエンティティとしてロードされるため、同一のメディアコンテンツをロードするために LoadBank
を PrepareEvent
と共に使用すると、メディアの重複を引き起こす可能性があります。