VST3プラグインのパラメーター実装方法2
前回はパラメーターを実装しましたが、0.0~1.0の範囲の値しか表示できませんでした。
実際にVSTプラグインを作成する際には、0~1の間だけでなくいろいろな値を表示する場合があると思います。
今回は任意の範囲を表示するパラメーターと文字列リストを表示するパラメーターを実装したいと思います。
今回作成するプラグインは下記のとおりです。
- ボリュームコントロール、トレモロ、パンニングの機能を持つエフェクター
- パラメーターは3つ
- ボリュームコントロール(0.0~1.0の範囲のパラメーター)
- トレモロスピード(0.5~30.0Hzの範囲のパラメーター)
- トレモロタイプ(ボリュームコントロール・トレモロ・パンニングの文字列リストパラメーター)
- 入力バス、出力バスは1つで、共にステレオ(2ch)
今回の内容は前回の説明をもとにしていますので、パラメーターの追加方法等については、前回の説明をご参照ください。
「バス」についての概念はこちらに記載したとおりです。
このVST3プラグインのサンプルソースファイルはこちらからダウンロードできます→vst3dev_20210403
ZIPファイルの中の「vst3dev03_パラメーター実装方法2」フォルダが今回のサンプルソースファイルになります。
コンパイル・ビルドの方法は簡単にこちらでご説明しております。ご参考までに。→サンプルソースファイルのビルド方法
任意の範囲を表示するパラメーター
任意の範囲(例えば0.5Hz~30Hz 等)を表示するためには、RangeParameterクラスを使用します。
RangeParameterクラスはParameterクラスから継承されたクラスです。
RangeParameterクラスのパラメーターを使用するには、下記手順を行います。
- newでRangeParameterクラスのインスタンスを生成
- パラメーター操作クラスにparameters.addParameter()関数で追加
今回のRangeParameterクラスパラメーターは下記のようにして追加しています。
【controller.cpp】
1 2 3 4 5 |
// 範囲パラメーターを作成 RangeParameter* param1 = new RangeParameter(STR16("Speed"), PARAM_SPEED_TAG, STR16("Hz"), 0.5f, 30.0f, 5.0f); param1->setPrecision(2); // 小数第何位まで表示するか // 範囲パラメーターをコントローラーに追加 parameters.addParameter(param1); |
RangeParameterを作成するときのコンストラクタの引数については下記のとおりとなります。
- RangeParameterコンストラクタ
概要 | RangeParameterのコンストラクタ。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
戻り値はありません(コンストラクタのため) | |||
引数 | 型 | 変数名 | 概要 |
TChar* | title | パラメーターの名前。 (TCharはwchar_tの再定義。文字コードはUTF-16で設定する) |
|
int32 | tag | パラメーターのタグ。重要。他のパラメーターのタグと重複しないほうがよい。 | |
TChar* | units | パラメーターの単位(dB、sec 等)。省略可。省略した場合 NULL になる。(単位が表示されない) (TCharはwchar_tの再定義。文字コードはUTF-16で設定する) |
|
ParamValue | minPlain | 表示値の最小値。省略可。省略した場合 0.0 になる。(ParamValueはdoubleの再定義) | |
ParamValue | maxPlain | 表示値の最大値。省略可。省略した場合 1.0 になる。 | |
ParamValue | defaultValuePlain | 表示値の初期値。省略可。省略した場合 0.0 になる。 | |
int32 | stepCount | 何段階のパラメーターか? 例: 3を指定した場合…minPlain、(minPlain+maxPlain)/2、maxPlainの3段階 0を指定すると0.0~1.0を滑らかに動く。 省略した場合 0 になる。 |
|
int32 | flags | パラメーターのフラグ。省略可。 省略した場合 ParameterInfo::kCanAutomateになる。基本的に省略でいいはず。 |
|
UnitID | unitID | 詳細不明。省略可。省略した場合 kRootUnitId になる。基本的に省略でいいはず。 |
RangeParameterクラスのsetPrecision()関数は小数第何位まで表示するかを指定しています。関数呼び出し自体を省略しても問題ありません。
省略時は小数第4位まで表示されます。
前回はaddParameter()関数にパラメーターに関する引数を直接指定していましたが、今回は事前に作成したパラメータークラスのポインタをaddParameter()関数に渡すことでパラメーターを追加しています。
addParameter()関数は他にも引数にParameterInfoを渡すことでパラメーターを作成するものもありますが、詳細については割愛いたします。
その他、STR16マクロ等については前回をご参照ください。
文字列リストを表示するパラメーター
文字列リスト(例えば「Volume、Tremolo、Panning」 等)を表示するためには、StringListParameterクラスを使用します。
StringListParameterクラスはParameterクラスから継承されたクラスです。
StringListParameterクラスのパラメーターを使用するには、下記手順を行います。
- newでStringListParameterクラスのインスタンスを生成
- StringListParameterクラスのappendString()関数でリスト項目を追加
- パラメーター操作クラスにparameters.addParameter()関数で追加
今回のStringListParameterクラスパラメーターは下記のようにして追加します。
【controller.cpp】
1 2 3 4 5 6 7 |
// 文字列リストパラメーターを作成、追加 StringListParameter* param2 = new StringListParameter(STR16("Type"), PARAM_TYPE_TAG); param2->appendString(STR16("Volume")); // リスト項目を追加 param2->appendString(STR16("Tremolo")); param2->appendString(STR16("Panning")); // 文字列リストパラメーターをコントローラーに追加 parameters.addParameter(param2); |
StringListParameterを作成するときのコンストラクタの引数については下記のとおりとなります。
- StringListParameterコンストラクタ
概要 | StringListParameterのコンストラクタ。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
戻り値はありません(コンストラクタのため) | |||
引数 | 型 | 変数名 | 概要 |
TChar* | title | パラメーターの名前。 (TCharはwchar_tの再定義。文字コードはUTF-16で設定する) |
|
int32 | tag | パラメーターのタグ。重要。他のパラメーターのタグと重複しないほうがよい。 | |
TChar* | units | パラメーターの単位(dB、sec 等)。省略可。省略した場合 NULL になる。(単位が表示されない) (TCharはwchar_tの再定義。文字コードはUTF-16で設定する) |
|
int32 | flags | パラメーターのフラグ。省略可。 省略した場合 ParameterInfo::kCanAutomate | ParameterInfo::kIsList になる。基本的に省略でいいはず。 |
|
UnitID | unitID | 詳細不明。省略可。省略した場合 kRootUnitId になる。基本的にでいいはず。 |
StringListParameterクラスのappendString()関数はリスト項目を追加する関数です。下記のとおりとなります。
- appendString()関数
概要 | StringListParameterクラスのリスト項目を追加する関数。 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
戻り値はありません | |||
引数 | 型 | 変数名 | 概要 |
String128 | string | 追加するリスト項目の文字列 (String128は長さ128の2Byte文字配列。__wchar_t[128]と同じ。文字コードはUTF-16で設定する) |
音声処理クラスでのパラメーター値の受け取り
次は追加したパラメーターの値を音声処理クラスのprocess関数内で受け取る部分です。
実は今回追加したどのパラメーターも必ず0.0~1.0の範囲で渡されます。
ですので、自作するVSTで使用しやすい値に再度変換する必要があります。
今回は下記のように処理しています。
赤く強調された部分が追加したパラメーター使用しやすい値に再変換している部分になります。
【processor.cpp】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// パラメーター変更の処理 // 与えられたパラメーターがあるとき、dataのinputParameterChangesに // IParameterChangesクラスへのポインタのアドレスが入る if (data.inputParameterChanges != NULL) { // 与えられたパラメーターの数を取得 int32 paramChangeCount = data.inputParameterChanges->getParameterCount(); // 与えられたパラメーター分、処理を繰り返す。 for (int32 i = 0; i < paramChangeCount; i++) { // パラメーター変更のキューを取得 // (処理するサンプル内に複数のパラメーター変更情報がある可能性があるため、 // キューという形になっている。) IParamValueQueue* queue = data.inputParameterChanges->getParameterData(i); if (queue != NULL) { // どのパラメーターが変更されたか知るため、パラメーターtagを取得 int32 tag = queue->getParameterId(); // 変更された回数を取得 int32 valueChangeCount = queue->getPointCount(); ParamValue value; int32 sampleOffset; // 最後に変更された値を取得 if (queue->getPoint(valueChangeCount - 1, sampleOffset, value) == kResultTrue) { // tagに応じた処理を実施 switch (tag) { case PARAM_DEPTH_TAG: // depthを変更する。 depth = value; break; case PARAM_SPEED_TAG: // depthを変更する。 // RangeParameterで作成されたパラメーターも、プロセッサクラスに渡されるときは // 0.0~1.0となってしまう。 // 自分で各RangeParameterに応じた範囲を設定する必要がある。 freq = (29.5f * value) + 0.5f; // 0.5~30.0の間に変更 break; case PARAM_TYPE_TAG: // typeを変更する。 // StringListParameterで作成されたパラメーターも、プロセッサクラスに // 渡されるときは0.0~1.0となってしまう。 // 今回はリスト数は3つなので、Volume…0.0f、Tremolo…0.5f、Panning…1.0fとなる。 // リストの数が4つの場合、0.0f、0.333…、0.666…、1.0fとなる。 // 「1.0f / (リストの数 - 1)」で求められる。 type = (int32)(value * 2.0f); break; } } } } } |
音声処理クラスでの音声信号の処理
パラメーター値を受け取り、再変換した後は音声信号を処理します。
今回は単純にtypeに合わせ出力する音声信号の計算方法を振り分けているだけです。
赤く強調された部分が今回変更した部分になります。
【processor.cpp】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// 入力・出力バッファのポインタをわかりやすい変数に格納 // inputs[]、outputs[]はAudioBusの数だけある(addAudioInput()、addAudioOutput()で追加した分だけ) // 今回はAudioBusは1つだけなので 0 のみとなる // channelBuffers32は32bit浮動小数点型のバッファで音声信号のチャンネル数分ある // モノラル(kMono)なら 0 のみで、ステレオ(kStereo)なら 0(Left) と 1(Right) となる Sample32* inL = data.inputs[0].channelBuffers32[0]; Sample32* inR = data.inputs[0].channelBuffers32[1]; Sample32* outL = data.outputs[0].channelBuffers32[0]; Sample32* outR = data.outputs[0].channelBuffers32[1]; // numSamplesで示されるサンプル分、音声を処理する for (int32 i = 0; i < data.numSamples; i++) { // sin関数の結果を0~1の間にする(トレモロ、パン用) Sample32 a = (sin(theta) * 0.5f) + 0.5f; // depthとaから入力信号に掛け合わせる値を計算する Sample32 b = (1.0f - depth) + (a * depth); Sample32 c = (1.0f - depth) + ((1.0f - a) * depth); switch (type) { case 0: // ボリュームの場合 // 入力信号とdepthを掛け合わせる(先ほどのaとbは無視) outL[i] = depth * inL[i]; outR[i] = depth * inR[i]; break; case 1: // トレモロの場合 // 入力信号とbを掛け合わせる(左右同じ音量にするのでbのみ使用) outL[i] = b * inL[i]; outR[i] = b * inR[i]; break; case 2: // パンの場合 // 入力信号とb、cを掛け合わせる(左右で異なる音量にする) outL[i] = b * inL[i]; outR[i] = c * inR[i]; break; } // 角度θに角速度を加える theta += (2.0f * 3.14159265f * freq) / 44100.0f; } |
表示値と正規化値
VST3ではパラメーター操作クラスが表示に使う値と実際に音声処理クラスに渡される値が異なります。
パラメーター操作クラスが表示に使う値(上記のトレモロのスピード…0.5~30.0やタイプ…Volume/Tremolo/Panningなど)は表示値と呼び、0.0~1.0の範囲になった値を正規化値と呼びます。
次回のように特殊なパラメータークラスを自作する場合や、VSTのGUIなどを作成する場合は、この表示値と正規化値を明確に区別しながら作成する必要があります。
最後に
以上で0.0~1.0以外の表示を行うパラメーターをVST3プラグインに追加することができます。
次回は「デジタルフィルタのカットオフ周波数」のような指数的に値が増加するパラメーターを追加する方法について記載したいと思います。
次回→パラメーター実装方法3
このVST3プラグインのサンプルソースファイルはこちらからダウンロードできます → vst3dev_20210403.zip
コンパイル・ビルドの方法は簡単にこちらでご説明しております。ご参考までに。→サンプルソースファイルのビルド方法
VST3プラグイン作りの情報はこちらにもございます → はじめてのVST3プラグイン作り
ご指摘やご質問などがございましたら、コメント欄か掲示板、Twitterでご連絡いただければと思います。
■掲示板
■Twitterアカウント:@vstcpp URL:https://twitter.com/vstcpp