Wwise SDK 2024.1.0
|
エフェクトプラグインは、入力オーディオデータとして供給された既存サウンドにDSPアルゴリズムを適用します。エフェクトプラグインの記述は、AK::IAkInPlaceEffectPlugin または AK::IAkOutOfPlaceEffectPlugin インターフェースのいずれかを実装することより構成されています。ここでは、これらのインターフェースに固有の関数のみがカバーされています。他のプラグインタイプと共有されるインターフェースコンポーネント(AK::IAkPlugin インターフェース)に関する情報については、 Sound Engineプラグインの作成 を参照してください。詳細は、提供のAkDelay プラグインを参照してください( サンプル )。
このメソッドは、データ処理のためにエフェクトプラグインを準備し、メモリを割り当て、初期条件を設定します。
The plug-in is passed in a pointer to a memory allocator interface (AK::IAkPluginMemAlloc
). We recommend that you allocate all dynamic memory through this interface using the provided memory allocation macros (refer to Allocating/De-allocating オーディオプラグインにおけるメモリ) so that Wwise can track the memory, and so that any underlying memory hooks in the game engine can use it. For the most common memory allocation needs, specifically allocation at initialization and release at termination, the plug-in does not need to retain a pointer to the allocator. It is also provided to the plug-in on termination.
The AK::IAkEffectPluginContext
interface can access the global context through AK::IAkPluginContextBase::GlobalContext()
.
The plug-in also receives a pointer to its associated parameter node interface (AK::IAkPluginParam
). Most plug-ins keep a reference to the associated parameter node to be able to retrieve parameters at runtime. 詳細は、 Communication Between Parameter Nodes and Plug-ins. を参照してください。
All of these interfaces remain valid throughout the plug-in's lifespan so it is safe to keep an internal reference to them when necessary.
Effect plug-ins also receive the input/output audio format (which stays the same during the lifespan of the plug-in) to be able to allocate memory and set up processing for a given channel configuration.
注釈: AK::IAkEffectPlugin::Init() is called every time the effect is instantiated, which happens when a voice starts playing or a mixing bus is instantiated. Because other sounds are typically playing already, this must occur within a reasonable amount of time. If you need to initialize large common/global data structures, do so when registering the plug-in library. 詳細は、 プラグインからグローバル サウンド エンジン コールバックを使用する を参照してください。 |
エフェクトプラグインは、次の2つのインターフェースのいずれかを実装することもできます:AK::IAkInPlaceEffectPlugin または AK::IAkOutOfPlaceEffectPlugin 。一般的には、(入力および出力データの両方に対して同じオーディオバッファを使用する)インプレース効果を、ほとんどのエフェクトに対して使用する必要があります。ただし、データフローの変化(たとえば、タイムストレッチ効果など)がある場合には、アウトオブプレースインターフェースを代わりに実装する必要があります。
注意: 異なる入力/出力チャンネル構成のアウトオブプレース効果を、マスターミキサー階層に挿入することができます。しかし、ミキシングバスにレートが変化するエフェクトをかけることはできません。異なる入力/出力バッファ長のエフェクトは、アクターミキサー階層にのみ挿入することができます (ソースエフェクトとして)。 |
このメソッドは、プラグインの信号処理アルゴリズムを指定されたオーディオバッファに対してインプレースで実行します(詳細は、AkAudioBuffer構造体を使用するデータにアクセスする を参照してください)。この構造体は、入力サンプルがいくつ有効かに関する情報(AkAudioBuffer::uValidFrames)およびバッファが収容可能な最大オーディオサンプルフレーム数に関する情報(AkAudioBuffer::MaxFrames() メソッド)をプラグインに提供します。AkAudioBuffer::eState 構造体メンバは、最後の実行であるか(AK_NoMoreData)否か(AK_DataReady)をプラグインに通知します。
AK::IAkInPlaceEffectPlugin::TimeSkip() は、バーチャルボイスが経過時間から再生された時にプラグインが必要に応じてその内部状態を更新し続けることができるように、Execute() に置換されます。
このメソッドは、アウトオブプレース アルゴリズム用のプラグインの信号処理を実行します。AkAudioBuffer 構造体は、入力バッファ用に1つ、出力バッファ用に1つ、全部で2つ使用されます。パイプラインは、現在のエフェクトの状態を判断するために出力オーディオバッファで eState を使用します。エフェクトは、入力バッファを全て消費した場合(そして後により多くのデータで実行を続けて行くために AK_DataNeeded を返す場合)、または全出力バッファが充填された時に AK_DataReady を出力した場合にのみに返されます。エフェクトが内部状態のフラッシュを完了するまで(AK_NoMoreData が返される必要のある時点まで)、AK_DataReady により受信される AK_NoMoreData を変更することにより、エフェクトテールをアウトオブプレースエフェクトに実装することも可能です。
入力バッファは、完全に消費されるまでパイプラインにより解放されることはありません。従って、最後の Execute() コールが中断されたところでデータの読み取りを開始するために in_uInOffset オフセットパラメータを使用することが重要です。以下のサンプルはこれを実現する方法を示しています。
AK::IAkOutOfPlaceEffectPlugin::TimeSkip() は、バーチャルボイスが経過時間から再生された時にプラグインが必要に応じてその内部状態を更新し続けることができるように、Execute() に置換されます。従って、この関数は、指定数の出力フレームを生成するのに通常どのぐらいの入力サンプルが消費されるかをパイプラインに知らせる役割を担います。
エフェクトの一部(特にディレイラインを持つエフェクト)は、入力が正常に減衰の再生を終了した後に出力される必要のある内部状態を持っています。エフェクトAPI は、有効な入力データがなくても実行を継続することを可能にします。AkAudioBuffer 構造体の eState フラグが AK_NoMoreData になると、パイプラインは、現在の実行後に有効な入力サンプルフレームをプラグインに供給しなくなります。その後、プラグインは、入力信号が終了した後にディレイラインを空にできるよう、新しい(後続の)フレームをバッファ内に(MaxFrames() が返す値まで)自由に書き込むことができるようになります。オーディオパイプラインには、適切に uValidFrames フィールドを更新することによって出力されたフレーム数を常に知らせる必要があります。エフェクトテールのフラッシュを完了するためにプラグイン Execute() 関数が再び呼び出される必要がある場合には、eState メンバが AK_DataReady に設定されなければなりません。エフェクトが、eState フィールドに AK_NoMoreData を設定した場合には、パイプラインはプラグイン Execute() の呼び出しのみを停止します。
テールを処理する最も簡単な方法は、SDK で提供の AkFXTailHandler サービスクラスを使用することです。プラグイン用のクラスメンバとして保持されている AkFXTailHandler のインスタンスで、インプレースエフェクト内でする必要のあることは、AkFXTailHandler::HandleTail() を呼び出して、これに AkAudioBuffer といったん出力が終了した時に出力するオーディオサンプル総数(パラメータに基づいて実行ごとに変更される場合あり)を渡すことのみです。詳細は、AkDelay プラグインソースコードを参照してください( サンプル )。
注釈: Effectプラグインの実行に関する重要な注意事項
|
プラグインは、UI、イベント、RTPC など様々なメカニズムを通じて Wwise やゲーム内でバイパスすることができます。このような場合、プラグイン Execute() ルーチンは呼び出されません。プラグインが unbypass 上で再開し実行関数が再び呼び出されると、プラグインはその処理を再始動します。エフェクトが最終的にバイパスされない場合、新たなスタートのためにディレイラインや他の状態情報をクリアすることができるように、プラグインの Reset() 関数がバイパス上に呼び出されます。詳細は、AK::IAkPlugin::Reset() を参照してください。
注意: 実行時のバイパスやバイパス解除は、プラグインや処理されているサウンドマテリアルによっては、信号の不連続を引き起こす場合があります。 |
詳細については、以下のセクションを参照してください:
モニタリングとは、オーディオプラグインの状態を再生中に観察するプロセスのことです。
Authoringアプリケーションをコミュニケーションモジュール経由で接続すると、Sound Engineプラグインインスタンスが、自分のステートを任意のデータバッファとして提供し、プラグインのAuthoring側に渡すことができます。 このデータは、例えば実行プロセスから計算したパフォーマンス測定であったり、様々な処理ステージにおけるメータリング用の信号レベルであったりします。
このセクションは、Sound Engine側のモニタリングに関するものです。 受信側やデシリアライズ処理の詳細は Authoringにおけるモニタリング を参照してください。
モニタリングデータの送信
送信を行うのは、プラグインのSound Engine部分です。その流れの各段階を、以下に示します:
long
というサイズは、 64-bitプラットフォームの一部では4バイト(LLP64)を採用し、ほかでは8バイト(LP64)を採用するので、注意してください。また、アライメント要件の異なるプラットフォームでは、パッケージングストラテジによって struct
レイアウトが異なることがあるので、注意してください。カスタムのパッキングアライメントを指定するには、 pack
pragmaを使います。AK::IAkPluginContextBase::PostMonitorData()
を使い、プロファイラのコミュニケーションチャンネルでデータを送信します。この関数は、 Execute
関数内でコールしてください。注釈: モニタリングデータは非同期で送信するので、 AK::IAkPluginContextBase::PostMonitorData() が、Sound Engineプラグインの提供するバッファをコピーします。つまり、バッファを安心してスタックにアロケーションできるほか、 PostMonitorData がコールされたあとは解放できます。 |
モニタリングデータを常に送信できるわけではなく、モニタリングデータを使えるのは、Wwise Authoringアプリケーションがプロファイリング中のときだけです。Authoringがプロファイリング中でないときや、単純にゲームをプロファイリングすることが不可能なときなどに、データの準備や送信を行うのは無駄です。このような不要なコストを避けるには、2つの方法があります:
AK::IAkPluginContextBase::CanPostMonitorData()
は、プロファイリングがアクティブでないときや、モニタリングデータをポストすることに対応していない場合に、falseを返します。この関数を使い、モニタリングに対応するかどうかを、 AK::IAkPluginContextBase::PostMonitorData()
をコールする前に必ずチェックしてください。AK_OPTIMIZED
に対してプリプロセッサチェックを行います。AK_OPTIMIZED
は、Wwise Plug-in開発ツールの wp.py
を使うと、デフォルトでリリースビルドに定義されます。モニタリングデータのシリアライズと送信の方法が、以下のコード例から分かります:
オブジェクトプロセッサは、各オブジェクトがそれぞれ所有する個々のオーディオ信号のアレイを、 Execute
関数内で意図的に扱うオーディオプラグインから派生しています。 Execute
は、 AkAudioBuffer
インスタンスを1つずつ受け取らずに、 1つのオブジェクトに対して1つの AkAudioBuffer
インスタンスがある一覧表を、 Ak3DAudioObjects
wrapperオブジェクトとして受信します。
1つのオブジェクトプロセッサプラグインが、複数のオーディオバッファのアレイを処理するので、このプラグインが送信するモニタリングデータには、処理される全てのオブジェクトに関連するモニタリングデータの、アグリゲーションを入れる必要があります。一番簡単なのは、オブジェクトの数を送信し、各シグナルに関係するモニタリングデータを、アレイとしてシリアライズする方法です。
オブジェクトプロセッサの詳細は、 Sound Engine Object Processorプラグインの作成 を参照してください。