バージョン

menu_open
Wwise SDK 2023.1.8
Example: Developing a Lowpass Filter Plug-in

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パラメータをバインドし、リアルタイムでその値を変更できるようにします。プラグインがRTPCパラメータを使えるように、4つの変更を行います。

最初に、その定義を WwisePlugin/Lowpass.xml に追加します。プラグインテンプレートに、既に"PlaceHolder"という名のパラメータスケルトンがあります。 これを使って"Frequency"パラメータを定義します。 WwisePlugin/Lowpass.xml で、プレースホルダとしてのプロパティを、以下に置き換えます:

2つ目に、SoundEnginePluginフォルダの中で、 LowpassFXParams.hLowpassFXParams.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 は、バッファに含まれるチャンネルごとの有効サンプル数を表します。

このデータがあれば、フレームの各サンプルで、 coeffBegincoeffStep だけ増やせばいいのです。これを、イン・アウトバッファの、各チャンネルに対して行う必要があります。

さて、カットオフ周波数をリアルタイムで制御できる単純なローパスフィルタを実装した、基本的で機能的なプラグインができたところで、デザイン上の懸念点について考えます。

処理のカプセル化

今、全ての信号処理ロジックがプラグインのメインクラスに記述されています。これは悪いデザインパターンで、その理由は以下のように多数あります:

  • メインプラグインクラスが膨張していて、今後、複雑なエフェクトをビルドするために新しい処理過程を追加していった場合は、さらにひどくなるはずです。
  • このフィルタをほかのプラグインで使いたくても、再利用しにくいのですが、このような基本的な処理ユニットは、絶対に再利用したくなります!
  • 単一責任の原則(single responsibility principle)に準拠していません。

そこで、コードのリファクタリングを行い、フィルタ処理を、自分自身のクラスにカプセル化します。ファイル FirstOrderLowpass.hSoundEnginePlugin フォルダに作成し、このように定義します:

そして、この実装を FirstOrderLowpass.cpp と呼ばれるファイルに追加します:

これで、メインプラグインクラスでは、 FirstOrderLowpass オブジェクト(オーディオチャンネル1つに対し、1つ)のベクトルを作成し、その Setup 関数をコールし、それらを使い始めるだけでいいのです。

AkSampleType * GetChannel(AkUInt32 in_uIndex)
Definition: AkCommonDefs.h:576
uint16_t AkUInt16
Unsigned 16-bit integer
Audiokinetic namespace
Interface used to write data during sound bank generation.
AkForceInline AkUInt32 NumChannels() const
Get the number of channels.
Definition: AkCommonDefs.h:492
AKRESULT
Standard function call result.
Definition: AkTypes.h:131
AKSOUNDENGINE_API AKRESULT Init(const AkCommSettings &in_settings)
bool WriteReal32(float in_value)
Writes a 32-bit, single-precision floating point value.
float AkReal32
32-bit floating point
AkUInt16 uValidFrames
Number of valid sample frames in the audio buffer
Definition: AkCommonDefs.h:657
#define READBANKDATA(_Type, _Ptr, _Size)
Read and return bank data of a given type, incrementing running pointer and decrementing block size f...
uint32_t AkUInt32
Unsigned 32-bit integer
AkInt16 AkPluginParamID
Source or effect plug-in parameter ID
Definition: AkTypes.h:66
AkForceInline AkUInt32 GetNumChannels() const
Definition: AkCommonDefs.h:75
Defines the parameters of an audio buffer format.
Definition: AkCommonDefs.h:63
AkUInt32 uSampleRate
Number of samples per second
Definition: AkCommonDefs.h:64
#define AK_RESTRICT
Refers to the __restrict compilation flag available on some platforms
Definition: AkTypes.h:45

このページはお役に立ちましたか?

サポートは必要ですか?

ご質問や問題、ご不明点はございますか?お気軽にお問い合わせください。

サポートページをご確認ください

あなたのプロジェクトについて教えてください。ご不明な点はありませんか。

プロジェクトを登録していただくことで、ご利用開始のサポートをいたします。

Wwiseからはじめよう