#define _CRT_SECURE_NO_DEPRECATE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#include "resource.h"
#include "audioeffectx.h"
#include "vstcontrols.h"
// ============================================================================================
// 設計情報の記入
// ============================================================================================
#define MY_VST_VENDOR "test vendor" //作者(ベンダー)名
#define MY_VST_VERSION 1 //このVSTバージョン
#define MY_VST_PRODUCT_NAME "Sample VST GUI" //このVSTの製品名
#define MY_VST_NAME "GUI" //このVSTの名前
#define MY_VST_INPUT_NUM 2 //入力数。モノラル入力=1、ステレオ入力=2
#define MY_VST_OUTPUT_NUM 2 //出力数。モノラル出力=1、ステレオ出力=2
#define MY_VST_UNIQUE_ID 'SMPL' //ユニークID
//公開する場合は以下URLで発行されたユニークIDを入力する。
//http://ygrabit.steinberg.de/~ygrabit/public_html/index.html
#define MY_VST_PRESET_NUM 1 //プリセットプログラムの数
#define MY_VST_PARAMETER_NUM 2 //パラメータの数
#define MYVST_VOLUME_L 0
#define MYVST_VOLUME_R 1
// ============================================================================================
// VST GUIクラス
// ============================================================================================
class VstGui2 : public AEffGUIEditor, CControlListener
{
public:
VstGui2 (void* effect);
virtual ~VstGui2 ();
// GUIのWindowを開いたときと閉じたときに処理を行う関数
virtual bool open (void *ptr);
virtual void close ();
// ボタンやつまみ等が動かされたときに処理を行う関数
virtual void valueChanged (CDrawContext *pContext, CControl *pControl);
virtual void setParameter (VstInt32 index, float value);
protected:
// ボリュームを操作するつまみ
CKnob* knobVolumeL;
CKnob* knobVolumeR;
};
VstGui2::VstGui2 (void* effect)
: AEffGUIEditor ((AudioEffect*)effect)
{
// 継承元のにあるrect変数を初期化。
// このrect変数にGUIのWindowsサイズを設定する。
// (設定を行わないとWindowが開けない)
rect.left = 0;
rect.top = 0;
rect.right = 512;
rect.bottom = 256;
// VstGui2クラス固有の初期化を行う
knobVolumeL = 0;
knobVolumeR = 0;
}
VstGui2::~VstGui2 ()
{
}
void VstGui2::valueChanged (CDrawContext *pContext, CControl *pControl)
{
// どのパラメーターが操作されたかを取得する。
VstInt32 index = pControl->getTag();
// パラメーターの値を取得する。
float value = pControl->getValue ();
// 取得した値をパラメーターに反映させる
this->setParameter(index, value);
}
void VstGui2::setParameter (VstInt32 index, float value)
{
switch (index)
{
case MYVST_VOLUME_L:
// つまみに値を設定し、画面を更新する(描画させる。)
knobVolumeL->setValue (value);
// MyVstGui2(AudioEffectXを継承して作ったクラス)に
// 操作されたパラメーターを通知して更新させる
// (setParameterAutomatedは内部でsetParameterを呼び出す)
effect->setParameterAutomated(index, value);
break;
case MYVST_VOLUME_R:
// MYVST_VOLUME_Lの処理とほぼ同様
knobVolumeR->setValue (value);
effect->setParameterAutomated(index, value);
break;
default:
break;
}
}
bool VstGui2::open (void *ptr)
{
// まずは継承元の関数を呼び出す(必須)
AEffGUIEditor::open (ptr);
// 次にフレーム(CFrame)を作成する。
// ボタンやつまみ等はこのフレームの上に配置する形になる
// ここではWindowと同じサイズのフレームを作成している
CRect size (rect.left, rect.top, rect.right, rect.bottom);
CFrame* cframe = new CFrame (size, ptr, this);
// 作成したフレームは継承元にあるframe変数に値を保存する必要がある。
this->frame = cframe;
// -----------------------------------------------------------------
// つまみを作成する。
// つまみ用の画像をリソースから読み込み
CBitmap *KnobBack = new CBitmap (BITMAP_KNOB_BACK);
CBitmap *KnobHandle = new CBitmap (BITMAP_KNOB_HANDLE);
// つまみの大きさを設定
CRect knobsize (0, 0, KnobBack->getWidth (), KnobBack->getHeight ());
// つまみの位置を設定
knobsize.offset (16, 16);
// つまみ画像をどこから表示するかの設定。基本的に0, 0でよいはず。
CPoint point (0, 0);
knobVolumeL = new CKnob (knobsize, this, MYVST_VOLUME_L, KnobBack, KnobHandle, point);
// つまみの中心とハンドルまでの長さ
knobVolumeL->setInsetValue (7);
// 現在のボリュームをMyVstGui2(AudioEffectXを継承して作ったクラス)から取得する
knobVolumeL->setValue(effect->getParameter(MYVST_VOLUME_L));
// つまみをframeに追加する
frame->addView (knobVolumeL);
// knobVolumeLとほぼ同様
knobsize (0, 0, KnobBack->getWidth (), KnobBack->getHeight ());
knobsize.offset (64, 16);
knobVolumeR = new CKnob (knobsize, this, MYVST_VOLUME_R, KnobBack, KnobHandle, point);
knobVolumeR->setInsetValue (7);
knobVolumeR->setValue(effect->getParameter(MYVST_VOLUME_R));
frame->addView (knobVolumeR);
// つまみ用の画像を解放する
KnobBack->forget();
KnobHandle->forget();
// 処理に問題がなければtrueを返す
return true;
}
void VstGui2::close ()
{
// frameをdeleteすることを忘れないようにする
if (frame)
{
delete frame;
}
frame = 0;
}
// ============================================================================================
// VSTの基本となるクラス
// ============================================================================================
class MyVstGui2 : public AudioEffectX
{
public:
MyVstGui2 (audioMasterCallback audioMaster);
~MyVstGui2 ();
// エフェクターのパラメータに関するメンバー関数
virtual void setParameter (VstInt32 index, float value);
// 音声信号を処理するメンバー関数
virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
protected:
float volumeL;
float volumeR;
};
// ============================================================================================
// このVSTのを生成するための関数
// ============================================================================================
AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
{
//newでこのVSTを生成したポインタを返す
return new MyVstGui2 (audioMaster);
}
// ============================================================================================
// コンストラクタ、デストラクタ(VSTの初期化、終了処理を記述)
// ============================================================================================
MyVstGui2::MyVstGui2 (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の設定
isSynth (false); //このVSTがSynthかどうかのフラグを設定。
//Synthの場合…true、Effectorの場合…false
canProcessReplacing (); //このVSTが音声処理可能かどうかのフラグを設定。
//音声処理を行わないVSTはないので必ずこの関数を呼び出す。
// GUIを設定する
editor = new VstGui2(this);
//このVSTのパラメータを初期化する。
volumeL = 0.0f;
volumeR = 0.0f;
}
MyVstGui2::~MyVstGui2 ()
{
//VSTの終了処理をする。
//このVSTでは特に実行する処理はなし。
// GUIはdeleteしなくていいっぽい
}
void MyVstGui2::setParameter (VstInt32 index, float value)
{
switch (index)
{
case MYVST_VOLUME_L:
volumeL = value;
break;
case MYVST_VOLUME_R:
volumeR = value;
break;
default:
break;
}
}
// ============================================================================================
// 音声信号を処理するメンバー関数
// ============================================================================================
void MyVstGui2::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
{
float *inL = inputs[0]; //入力 左用
float *inR = inputs[1]; //入力 右用
float *outL = outputs[0]; //出力 左用
float *outR = outputs[1]; //出力 右用
for (int i = 0; i <sampleFrames ; i++)
{
// 入力をそのまま出力へ
outL[i] = volumeL * inL[i];
outR[i] = volumeR * inR[i];
}
}