VST3プラグインのパラメーターを保存する方法
前回まででいろいろなパラメーターを実装しました。
【参考】
パラメーター実装方法 | パラメーター自体を実装する方法 |
パラメーター実装方法2 | 0.5~30.0の範囲や文字列リスト等のパラメーターを実装する方法。 |
パラメーター実装方法3 | 「フィルタのカットオフ周波数」等の線形でないパラメーターを実装する方法を記載 |
しかし、VSTを終了し再度起動してもパラメーターがデフォルト値に戻ってしまっていたかと思います。
それはVST3ではパラメーター内容を保存する処理を自分で記載しなければならないためです。
今回は作成したパラメーターの値を保存する方法について記載したいと思います。
今回作成するプラグインはVST3プラグインのパラメーター実装方法で作成したプラグインをベースにします。
(コントロールの実装以外に余計なコードが少ないためです。)
- パラメーターは1つ(ボリュームコントロール)
- 入力のボリュームをパラメーターにより調整して出力する
- 入力バス、出力バスは1つで、共にステレオ(2ch)
今回の内容はいままでのパラメーターの実装方法をベースにしています。上記の参考についても必要に応じてご参照ください。
なお、「バス」についての概念はこちらに記載したとおりです。
このVST3プラグインのサンプルソースファイルはこちらからダウンロードできます→vst3dev_20210403
ZIPファイルの中の「vst3dev05_パラメーターを保存する方法」フォルダが今回のサンプルソースファイルになります。
コンパイル・ビルドの方法は簡単にこちらでご説明しております。ご参考までに。→サンプルソースファイルのビルド方法
パラメーターを保存・読込するための関数
パラメーターを保存・読込するためには、音声処理クラスとパラメーター操作クラスで必要な関数をオーバーライドします。
- 音声処理クラス(AudioEffectを継承したクラス)でパラメーターを保存するためのgetState()関数をオーバーライドする
- 音声処理クラス(AudioEffectを継承したクラス)でパラメーターを読み込むためのsetState()関数をオーバーライドする
- パラメーター操作クラス(EditControllerを継承したクラス)でパラメーターを読み込むためのsetComponentState()関数をオーバーライドする
それぞれの関数は下記のように定義しオーバーライドします。
【processor.h】
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
class MyVSTProcessor : public AudioEffect { protected: ParamValue volume; public: // コンストラクタ MyVSTProcessor(); // クラスを初期化する関数(必須) tresult PLUGIN_API initialize(FUnknown* context); // バス構成を設定する関数(ほぼ必須) tresult PLUGIN_API setBusArrangements(SpeakerArrangement* inputs, int32 numIns, SpeakerArrangement* outputs, int32 numOuts); // Processorクラスの状態の読込と保存する関数 tresult PLUGIN_API setState(IBStream* state); tresult PLUGIN_API getState(IBStream* state); // 音声信号を処理する関数(必須) tresult PLUGIN_API process(ProcessData& data); // 自作VST Processorクラスのインスタンスを作成するための関数(必須) static FUnknown* createInstance(void*) { return (IAudioProcessor*)new MyVSTProcessor(); } }; |
【controller.h】
17 18 19 20 21 22 23 24 25 26 27 28 29 |
class MyVSTController : public EditController { public: // クラスを初期化する関数(必須) tresult PLUGIN_API initialize(FUnknown* context); // Processorクラスの保存状態を反映させる関数 tresult PLUGIN_API setComponentState(IBStream* state); // 自作VST Controllerクラスのインスタンスを作成するための関数(必須) static FUnknown* createInstance(void*) { return (IEditController*)new MyVSTController(); } }; |
各メンバー関数の引数などは下記のとおりとなります。
- getState()関数
概要 | 継承元のAudioEffectクラスからオーバーライドしたパラメーターやその他のデータを保存するための関数 DAWの終了時やプリセット保存時に呼び出される |
||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 正常に変換出来た場合はkResultOk、失敗した場合はkResultFalseを返す。 | ||
引数 | 型 | 変数名 | 概要 |
IBStream* | state | VSTデータ入出力ストリームクラスへのポインタ このクラスを利用して、パラメーターやデータを保存する |
- setState()関数
概要 | 継承元のAudioEffectクラスからオーバーライドしたパラメーターやその他のデータを読み込むための関数 DAWの開始時やプリセット読込時に呼び出される |
||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 正常に変換出来た場合はkResultOk、失敗した場合はkResultFalseを返す。 | ||
引数 | 型 | 変数名 | 概要 |
IBStream* | state | VSTデータ入出力ストリームクラスへのポインタ このクラスを利用して、パラメータやデータを読み込む |
- setComponentState()関数
概要 | 継承元のEditControllerクラスからオーバーライドしたパラメーターやその他のデータを読み込むための関数 DAWの開始時やプリセット読込時に呼び出される |
||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 正常に変換出来た場合はkResultOk、失敗した場合はkResultFalseを返す。 | ||
引数 | 型 | 変数名 | 概要 |
IBStream* | state | VSTデータ入出力ストリームクラスへのポインタ このクラスを利用して、パラメーターやデータを読み込む |
パラメーターを保存・読込するための関数の実装
実装はは下記のようにしています。
【processor.cpp】
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
tresult PLUGIN_API MyVSTProcessor::setState(IBStream* state) { // 現在のProcessorクラスの状態を読込 // マルチプラットフォーム対応にする場合はエンディアンに注意 // 保存されているデータを読み込む // 保存されているデータが複数ある場合はstate->readを繰り返す tresult res; res = state->read(&volume, sizeof(ParamValue)); if (res != kResultOk) { // 読込に失敗した場合はkResultFalseを返す。 return kResultFalse; } // 関数の処理に問題がなければkResultOkを返す return kResultOk; } tresult PLUGIN_API MyVSTProcessor::getState(IBStream* state) { // 現在のProcessorクラスの状態を保存 // マルチプラットフォーム対応にする場合はエンディアンに注意 // データを保存する // 保存したいデータが複数ある場合はstate->writeを繰り返す。 state->write(&volume, sizeof(ParamValue)); // 関数の処理に問題がなければkResultOkを返す return kResultOk; } |
【controller.cpp】
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
tresult PLUGIN_API MyVSTController::setComponentState(IBStream* state) { // 現在のProcessorクラスの状態を読込 // マルチプラットフォーム対応にする場合はエンディアンに注意 tresult res; // 保存されているデータを読み込む // 保存されているデータが複数ある場合はstate->readを繰り返す ParamValue volume; res = state->read(&volume, sizeof(ParamValue)); if (res != kResultOk) { // 読込に失敗した場合はkResultFalseを返す。 return kResultFalse; } // 読み込まれたデータをパラメーターに反映する // 反映するデータは0.0~1.0の範囲にしておく volume = plainParamToNormalized(PARAM1_TAG, volume); setParamNormalized(PARAM1_TAG, volume); // 関数の処理に問題がなければkResultOkを返す return kResultOk; } |
getState()関数はホスト(DAWなど)がVSTの状態を保存する際に呼び出されます。
引数であるIBStream* stateを使用して必要なデータを書き込みます。
IBStreamについては後述しますが、難しく考える必要はなくファイル操作と同じ感覚で使用すれば問題ありません。
基本的にはstate->write()を使用します。
setState()関数とsetComponentState()関数はホスト(DAWなど)がVSTの状態を反映させる際に呼び出されます。
引数であるIBStream* stateを使用して必要なデータを読み込みます。
基本的にはstate->read()を使用します。
ちなみにパラメーター操作クラスにもsetState()関数やgetState()ありますがここでは割愛します。
(パラメーター操作クラスだけにしかない何らかのデータを保存する際に使用します。)
IBStreamクラスについて
IBStreamクラスはVSTのデータ入出力ストリームクラスです。
データ入出力ストリームクラスですので、ファイル操作と同じ感覚で使用すれば問題ありません。
IBStreamクラスには下記の4つの関数があります。
- read()関数
概要 | 入出力ストリームからデータを読み込む関数 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 成功すればkResultTrue、失敗すればkResultFalseとなる | ||
引数 | 型 | 変数名 | 概要 |
void* | buffer | 読み込んだデータを保存するためのバッファ | |
int32 | numBytes | 読み込むバイト数。バッファサイズよりも小さくなければならない | |
int32 | numBytesRead | 実際に読み込まれたバイト数。省略可。 省略した場合や0を指定すると無視される |
- write()関数
概要 | 入出力ストリームにデータを書き込む関数 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 成功すればkResultTrue、失敗すればkResultFalseとなる | ||
引数 | 型 | 変数名 | 概要 |
void* | buffer | 書き込むデータの保存されたバッファ | |
int32 | numBytes | 書き込むバイト数。>バッファサイズよりも小さくなければならない | |
int32 | numBytesRead | 実際に書き込まれたバイト数。省略可。 省略した場合や0を指定すると無視される |
- tell()関数
概要 | 入出力ストリーム中のどの位置にあるかを確認する関数 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 成功すればkResultTrue、失敗すればkResultFalseとなる | ||
引数 | 型 | 変数名 | 概要 |
int64* | pos | 現在の位置を格納するためのポインタ |
- seek()関数
概要 | 入出力ストリーム中の位置を設定する関数 | ||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 成功すればkResultTrue、失敗すればkResultFalseとなる | ||
引数 | 型 | 変数名 | 概要 |
int64 | pos | 設定する位置。modeに応じて挙動が変わる modeがkIBSeekSetの場合…入出力ストリームの先頭からのバイト数を設定する modeがkIBSeekCurの場合…現在の位置からのバイト数を設定する modeがkIBSeekEndの場合…入出力ストリームの終わりからのバイト数を設定する |
|
int32 | mode | 位置を設定するためのモード。kIBSeekSet、kIBSeekCur、kIBSeekEndのいづれかを設定する | |
int64 | result | 実際に設定された位置。省略可。 省略した場合や0を指定すると無視される |
パラメーター操作クラスのgetState()関数、setState()関数
今回、記載を省略いたしましたが、パラメーター操作クラスにもgetState()関数、setState()関数があります。
パラメーター操作クラス側のgetState()関数、setState()関数はGUIの状態などを保存する際に使用します。
- getState()関数(パラメーター操作クラス)
概要 | 継承元のEditControllerクラスからオーバーライドしたパラメーターやその他のデータを保存するための関数 DAWの終了時やプリセット保存時に呼び出される |
||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 正常に変換出来た場合はkResultOk、失敗した場合はkResultFalseを返す。 | ||
引数 | 型 | 変数名 | 概要 |
IBStream* | state | VSTデータ入出力ストリームクラスへのポインタ このクラスを利用して、パラメーターやデータを保存する |
- setState()関数(パラメーター操作クラス)
概要 | 継承元のEditControllerクラスからオーバーライドしたパラメーターやその他のデータを読み込むための関数 DAWの開始時やプリセット読込時に呼び出される |
||
---|---|---|---|
戻り値 | 型 | 概要 | |
tresult | 正常に変換出来た場合はkResultOk、失敗した場合はkResultFalseを返す。 | ||
引数 | 型 | 変数名 | 概要 |
IBStream* | state | VSTデータ入出力ストリームクラスへのポインタ このクラスを利用して、パラメーターやデータを読み込む |
パラメーター保存・読込関数の呼び出されるタイミング
パラメーター保存・読込関数の呼び出されるタイミング、順番は下記の通りです。
【ホスト(DAWなど)で上書き保存や名前を付けて保存などを行った場合などに呼び出される関数】
手順 | データ保存先領域 | |
---|---|---|
1 | 音声処理クラスのgetState()関数。 | 音声処理クラス用のデータ領域 |
2 | パラメーター操作クラスのgetState()関数。 | パラメーター操作クラス用のデータ領域 |
【ホスト(DAWなど)の起動時やプロジェクトを読み込んだ場合などに呼び出される関数】
手順 | データ読み込み先領域 | |
---|---|---|
1 | 音声処理クラスのsetState()関数。 | 音声処理クラス用のデータ領域 |
2 | パラメーター操作クラスのsetComponentState()関数。 | 音声処理クラス用のデータ領域 |
2 | パラメーター操作クラスのsetState()関数。 | パラメーター操作クラス用のデータ領域 |
setComponentState()関数は音声処理クラスの情報をパラメーター操作クラスに反映させるためにあります。読み込み先の領域にご注意ください。
最後に
以上でパラメーターを保存する方法することができます。
今回は単純にPalamValue型(double型)のデータを一つだけを保存しましたが、バージョン情報や文字列などを保存することも可能です。
次回はMIDIのノートオン/ノートオフメッセージを受信する方法を記載したいと思います。
このVST3プラグインのサンプルソースファイルはこちらからダウンロードできます → vst3dev_20210403.zip
コンパイル・ビルドの方法は簡単にこちらでご説明しております。ご参考までに。 → サンプルソースファイルのビルド方法
VST3プラグイン作りの情報はこちらにもございます → はじめてのVST3プラグイン作り
ご指摘やご質問などがございましたら、コメント欄か掲示板、Twitterでご連絡いただければと思います。
■掲示板
■Twitterアカウント:@vstcpp URL:https://twitter.com/vstcpp