VST 2.4サポート終了について
ここではVST 2.4の開発について記載させていただいておりますが、公式サポートが終了しており内容を更新しておりません。
これから開発を始める方は、新しいVSTバージョンで開発することをお勧めさせていただきます。
新しいVSTバージョンの開発情報はこちら → はじめてのVSTプラグインの作り
簡単なエフェクターを作成してみる
前項では、VSTプラグインとして最低限動作するものを作成しました。
せっかくなので入力信号を加工する簡単なエフェクターを作成してみます。
作成するエフェクターはトレモロにします。
理由は、比較的簡単に実装でき、エフェクター効果がわかりやすいためです。
作成するVSTプラグインの概要は下記のとおりです。
- ホストアプリケーション上でエフェクターとして動作する
- 入力、出力共にステレオ(2チャンネル)
- 入力された音声にトレモロをかけて出力する
- サンプリング周波数は44,100Hzのみ対応
なお、前回作成したVSTプラグインはここを参照してください。 → VSTプラグインを作成してみる
また、プロジェクトの作成方法についてはここを参照してください。 → Visual Studioのプロジェクト作成する
トレモロとは
トレモロとは入力音声の音量(振幅)を一定周期で増減させるエフェクターです。
入力信号に0Hz~30Hz程度の正弦波や三角波を掛け合わせることで実装することができます。
実装イメージ(入力信号と正弦波の掛け合わせ)
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 |
void tremolo() { // input[]、output[]はそれぞれ入力信号と出力信号のバッファ、 // wavelenghtはバッファのサイズ、サンプリング周波数は44100Hzとする // トレモロのパラメーター float theta; // sin関数の角度 θ。初期値は0 float tremolospeed; // トレモロのスピード。角速度ωと同じ。 float tremolodepth; // トレモロの効き具合。0~1の間。 // パラメータの初期化 (値はサンプルです。) float Hz = 4.0f// トレモロの周期 theta = 0; tremolospeed = ( 2.0f * 3.14159265f * Hz ) / 44100.0f; tremolodepth = 0.3; // 入力信号と正弦波を掛け合わせる for(int i = 0; i < wavelength; i++) { // 角度θに角速度を加える theta += tremolospeed; // sin関数の結果を0~1の間にする float a = ( sin(theta) * 0.5f ) + 0.5f; // tremolodepthと先ほどの結果から掛け合わせる値を計算する float b = ( 1.0f - tremolodepth ) + ( a * tremolodepth ); // 入力信号と掛け合わせる output[i] = b * input[i]; } } |
ソースコードの説明
ここで作成するVSTプラグインの全ソースコードは下記のリンク先に記載しています。
ここでは下記のソースコードをもとに説明いたします。
ソースファイル | 概要 |
---|---|
MyMiniTremoloVST.cpp | VSTプラグインのメインとなるソースファイル。 |
ソースコード全体はここに記載しています。 → ソースコード全体
ヘッダーファイルのインクルード
まず、VSTプラグインを作るために必要なヘッダーファイルのインクルードと定数の定義を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// ============================================================================================ // インクルードファイル // ============================================================================================ #include "audioeffectx.h" #include <math.h> // ============================================================================================ // 設計情報の記入 // ============================================================================================ #define MY_VST_PRESET_NUM 1 //プリセットプログラムの数 #define MY_VST_PARAMETER_NUM 0 //パラメータの数 #define MY_VST_INPUT_NUM 2 //入力数。モノラル入力=1、ステレオ入力=2 #define MY_VST_OUTPUT_NUM 2 //出力数。モノラル出力=1、ステレオ出力=2 |
前項で説明したヘッダファイル(audioeffectx.h)以外に、Sin関数等の算術関数を使うため5行目でmath.hをインクルードしております。
そのほかは変わっておりません。
VSTプラグインクラスの定義
次にVSTプラグインクラスの定義を行います。今回は前項のメンバー関数に加えてトレモロのパラメーターを定義しています。(赤色部分)
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// ============================================================================================ // VSTの基本となるクラス // ============================================================================================ class MyMiniTremoloVST : public AudioEffectX { private: float theta; // sin関数の角度 θ。初期値は0 float tremolospeed; // トレモロのスピード。角速度ωと同じ。 float tremolodepth; // トレモロの効き具合。0~1の間。 public: MyMiniTremoloVST(audioMasterCallback audioMaster); // 音声信号を処理するメンバー関数 virtual void processReplacing(float** inputs, float** outputs, VstInt32 sampleFrames); }; |
各メンバー変数はクラス外部から参照される必要はありませんので、privateで定義しております。それぞれのメンバー変数の内容は下記のとおりです。
型 | 変数名 | 内容 |
---|---|---|
float | theta | sin関数の角度 θ。初期値は必ず0にする。 |
float | tremolospeed | トレモロのスピード。角速度ωと同じ。 サンプリング周期ごとにthetaに足し合わせる。 トレモロスピードは2×π×トレモロの周波数÷サンプリング周波数で求める |
float | tremolodepth | トレモロの効き具合。 0~1の間で、0がトレモロはまったく効かない状態で1がもっともトレモロの効く状態 |
VSTプラグインの初期化
VSTプラグインの初期化を行います。前項のコンストラクタで説明したVSTプラグインの基本設定(55~65行目)に加え、トレモロのパラメータを初期化しています。(赤色部分)
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
// ============================================================================================ // コンストラクタ(VSTの初期化) // ============================================================================================ MyMiniTremoloVST::MyMiniTremoloVST(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, MY_VST_PRESET_NUM, MY_VST_PARAMETER_NUM) { //VSTの初期化を行う。 //以下の関数を呼び出して入力数、出力数等の情報を設定する。 //必ず呼び出さなければならない。 setNumInputs(MY_VST_INPUT_NUM); //入力数の設定 setNumOutputs(MY_VST_OUTPUT_NUM); //出力数の設定 setUniqueID(MY_VST_UNIQUE_ID); //ユニークIDの設定 //このVSTがSynthかどうかのフラグを設定。Synthの場合…true、Effectorの場合…false isSynth(false); //このVSTが音声処理可能かどうかのフラグを設定。音声処理を行わないVSTはないので必ずこの関数を呼び出す。 canProcessReplacing(); //上記の関数を呼び出した後に初期化を行う theta = 0.0f; float Hz = 4.0f; // トレモロの周期 tremolospeed = (2.0f * 3.14159265f * Hz) / 44100.0f ; //トレモロの周期を角速度に変換 tremolodepth = 0.5f; //トレモロの振幅 0.5 } |
tremolospeedとtremolodepthは今回は適当な値を設定しています。
入力信号への正弦波の掛け合わせ
最後にprosessReplacing関数で入力信号(第1引数 inputs)と正弦波を掛け合わせます。掛け合わせた結果は前項のとおり、第2引数のoutputsに代入します。
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
// ============================================================================================ // 音声信号を処理するメンバー関数 // ============================================================================================ void MyMiniTremoloVST::processReplacing(float** inputs, float** outputs, VstInt32 sampleFrames) { int L = 0; int R = 1; for (int i = 0; i < sampleFrames; i++) { //ここで音声処理を行う。 // theta(θ)にtremolospeed(=角速度)を加え、更新する // 2π(360°)を超えた場合は、2π分戻す。 theta += tremolospeed; if (theta > 2 * 3.14159265f) { theta -= 2 * 3.14159265f; } // sin関数の結果を0~1の間にする float a = (sin(theta) * 0.5f) + 0.5f; // tremolodepthと先ほどの結果から掛け合わせる値を計算する float b = (1.0f - tremolodepth) + (a * tremolodepth); //入力信号と掛け合わせ、出力バッファへ書き込む。 outputs[L][i] = b * inputs[L][i]; outputs[R][i] = b * inputs[R][i]; } } |
まず、89行目でSin関数の角度thetaにtremolospeed(=角速度)を加えて角度thetaを更新します。
次に96行目でSin関数の振幅を取得し、0~1の範囲にします。
99行目で入力信号と掛け合わせる値をtremolodepthとSin関数の振幅(0~1の範囲にしたもの)から計算します。
そして最後に102~103行目で入力信号と掛け合わせ、出力バッファ(outputs[])に代入します。
コンパイルとビルド
以上の内容でコンパイルとビルドを行えば、トレモロエフェクターとして動作するVSTプラグイン完成するはずです。
前項で説明したとおり、いくつかのwarningとエラーが発生しますが、プロジェクトのReleaseフォルダ配下に「~~.dll」が
作成されていれば特に問題はありません。
最後に
いかがでしたでしょうか?
今回は簡単でわかりやすいという理由からトレモロを実装しました。簡単なコードですがそこそこきれいにトレモロがかかるかと思います。
しかし、パラメーターがハードコーディングされているためホストアプリケーション上で調整がまったくできません。
次項はここで作成したエフェクターのパラメーターをホストアプリケーション上からコントロールするための機能を追加いたします。