Wwise SDK 2023.1.8
|
This topic provides an example of Community plug-in development from start to finish. In this case, we will develop a lowpass filter plug-in.
まず最初に、 wp.py ツールで新しいプラグインプロジェクトを作成します。 Creating Audio Plug-ins に、 new
引数の詳しい内容があります。
WindowsでAuthoringプラットフォームをターゲットとするので、 premake
をコールします:
SoundEngine部分とAuthoring (WwisePlugin) 部分をビルドするためのソリューションが作成されています。
これで、プラグインをビルドしてから、Wwiseでロードされることを確認します。
次に、このプラグインがもう少し役に立つように、処理能力を少し追加します。この式を使って簡単な1次ローパスフィルタを実装します:
y[n] = x[n] + (y[n-1] - x[n]) * coeff
このとき coeff
は0から1の間の浮動小数点とします。
最初に、このフィルタのデータを保持できるように、 SoundEnginePlugin/LowpassFX.h
にいくつかの変数を作成します。
変数値 m_coeff
は浮動小数点としてのフィルタ係数で、全サウンドチャンネルに使います。ベクトル m_previousOutput
が全チャンネルの最後のアウトプット値を保持しますが、これはフィルタの次の値を計算するために必須です。
フィルタエフェクトを適用するには、係数変数を初期化し、チャンネル数に従いベクトルサイズを調整し、各サンプルを前の公式で処理するだけです。
SoundEnginePlugin/LowpassFX.cpp
で:
今は、このフィルタと何のやり取りもできないので、面白みのないフィルタです。それでは、フィルタの周波数にRTPCパラメータをバインドし、リアルタイムでその値を変更できるようにします。プラグインがRTPCパラメータを使えるように、4つの変更を行います。
最初に、その定義を WwisePlugin/Lowpass.xml
に追加します。プラグインテンプレートに、既に"PlaceHolder"という名のパラメータスケルトンがあります。 これを使って"Frequency"パラメータを定義します。 WwisePlugin/Lowpass.xml
で、プレースホルダとしてのプロパティを、以下に置き換えます:
2つ目に、SoundEnginePluginフォルダの中で、 LowpassFXParams.h
と LowpassFXParams.cpp
を更新し、プロパティの変更を反映させます。
LowpassFXParams.h
で、 LowpassRTPCParams
ストラクチャの中のパラメータIDとパラメータ名を更新します。
LowpassFXParams.cpp
も更新します:
3つ目に、 WwisePlugin
フォルダで、バンクに"Frequency"パラメータを書くために Lowpass::GetBankParameters
関数を更新します。
最後に、処理ループでこの公式(formula)を使い、現在の周波数を使ってフィルタ係数を計算します。
coeff = exp(-2 * pi * f / sr)
現在のサンプリングレートを取得する必要があります。
数学記号を含め、
フィルタ係数を計算します:
処理パラメータをバッファサイズ(1つのオーディオバッファチャンネルにおけるサンプル数のことで、一般的に64から2048の間)ごとに一回だけ更新するのでは、不十分であることが多いです。特に、処理周波数やゲインにこのパラメータが影響するのであれば、値をあまりゆっくり更新したのでは、アウトプットサウンドでジッパーノイズやクリックが発生してしまいます。
この問題のシンプルな対策として、バッファ全体に渡り、値を線形補間することができます。今回の周波数パラメータではどのように行うのかを、以下に示します。
オーディオサンプルの新しいフレームを計算する直前、つまり LowpassFX.cpp
の、 Execute
関数の一番上で、周波数パラメータが変化したかどうかをチェックします。 チェックするには、 LowpassFXParams
クラスの AkFXParameterChangeHandler
オブジェクトに聞けばいいのです。周波数に変化があれば、ランプ(ramp)の変数を計算します:
注釈: AkAudioBuffer オブジェクトのメンバ変数 uValidFrames は、バッファに含まれるチャンネルごとの有効サンプル数を表します。 |
このデータがあれば、フレームの各サンプルで、 coeffBegin
を coeffStep
だけ増やせばいいのです。これを、イン・アウトバッファの、各チャンネルに対して行う必要があります。
さて、カットオフ周波数をリアルタイムで制御できる単純なローパスフィルタを実装した、基本的で機能的なプラグインができたところで、デザイン上の懸念点について考えます。
今、全ての信号処理ロジックがプラグインのメインクラスに記述されています。これは悪いデザインパターンで、その理由は以下のように多数あります:
そこで、コードのリファクタリングを行い、フィルタ処理を、自分自身のクラスにカプセル化します。ファイル FirstOrderLowpass.h
を SoundEnginePlugin
フォルダに作成し、このように定義します:
そして、この実装を FirstOrderLowpass.cpp
と呼ばれるファイルに追加します:
これで、メインプラグインクラスでは、 FirstOrderLowpass
オブジェクト(オーディオチャンネル1つに対し、1つ)のベクトルを作成し、その Setup
関数をコールし、それらを使い始めるだけでいいのです。