iPlug2でVSTプラグインを作るメモ

 インストール

https://github.com/iPlug2/iPlug2 

CodeからDownload Zipでソースコードをダウンロード

https://www.steinberg.net/developers/ 

VST 3 Audio Plug-Ins SDK をダウンロード

VST3を作成して配布するにはスタインバーグとの契約が必要なようです。

 

iPlug2を解凍して「Dependencies\IPlug\VST3_SDK」フォルダーにVST SDKの

「base」「pluginterfaces」「public.sdk」をコピーする


GUIのバックエンドをSkiaに変更する

https://github.com/iPlug2/iPlug2/blob/master/Dependencies/README.md

Readmeのリンクからビルド済みのlibファイルをダウンロードする

解凍して「iPlug2/Dependencies/Build/」に配置する。

 

プロジェクトの設定を変更する。

https://github.com/iPlug2/iPlug2/wiki/03_Switching_graphics

Windowsの場合Configフォルダーの .propsファイルのEXTRA_ALL_DEFS を変更する

-    <EXTRA_ALL_DEFS>IGRAPHICS_NANOVG;IGRAPHICS_GL2</EXTRA_ALL_DEFS>
+    <EXTRA_ALL_DEFS>IGRAPHICS_SKIA;IGRAPHICS_CPU</EXTRA_ALL_DEFS>
 
Visual Studioのバージョンがlibファイルと合わないと、ビルドした時リンクエラーになる様です。
 
skiaのGL2にすると終了した時、IGraphicsSkia.cppの
void IGraphicsSkia::OnViewDestroyed()
{
RemoveAllControls();

#if defined IGRAPHICS_GL
mSurface = nullptr;
mScreenSurface = nullptr;
mGrContext = nullptr; //<-ここで止まる。
 
CPUだと閉じたとき、メモリーリークが出てるような。
メモリーは開放されているように感じるから気にしない事にした。
 
IntelGPUの環境だと、NanoVGを使うとウインドウサイズを変更した時、
メモリーが1Gぐらいまで増えて、少しずつ減っていく。IntelGPUの仕様らしい。 
 

ウインドウサイズを変更できるようにする。

Config.hに追加
#define PLUG_HOST_RESIZE 1
#define PLUG_MIN_WIDTH 256
#define PLUG_MIN_HEIGHT 256
#define PLUG_MAX_WIDTH 8192
#define PLUG_MAX_HEIGHT 8192

メインの.hに追加
#if IPLUG_EDITOR
void OnParentWindowResize(int width, int height) override;
bool OnHostRequestingSupportedViewConfiguration(int width, int height) override { return true; }
#endif

メインの .cppのについか
mLayoutFunc = [&](IGraphics* pGraphics) {
//追加
if (pGraphics->NControls()) {
//サイズ変更の処理
return;
}
 pGraphics->SetLayoutOnResize(true); //OnParentWindowResizeが呼ばれる
 //ここまで
 ....
}

これも追加
#if IPLUG_EDITOR
void IPlugSideChain::OnParentWindowResize(int width, int height)
{
if (GetUI())
GetUI()->Resize(width, height, 1.f, false);//mLayoutFuncが呼ばれる}
#endif

main.rcのスタイルを変更する。

IDD_DIALOG_MAIN DIALOG 0, 0, 300, 300
//STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "IPlugResponsiveUI"

WindowsのAbleton Liveだとウインドウサイズがうまく反映しないので、
「IGrafics.cpp」の「 void IGraphics::Resize 」に+の部分を追加したら治りました。

  PlatformResize(GetDelegate()->EditorResizeFromUI(windowWidth, windowHeight, needsPlatformResize));

+#if VST3_API
+  if(!needsPlatformResize)
+    GetDelegate()->SetEditorSize(mWidth, mHeight);

+#endif
  ForAllControls(&IControl::OnResize);
  SetAllControlsDirty();
  DrawResize();

 

タイマーで画面を更新

コントローラのどこかに追加 
    mTimer = std::unique_ptr<Timer>(Timer::Create([&](Timer& t) {
//更新処理

SetDirty(false);
}, 20));
追加
 private:
 std::unique_ptr<Timer> mTimer;
止めるとき
mTimer->Stop();

プロジェクトをコピーする

Examplesフォルダーにスクリプトがあるので下のコマンドを実行します。
python ./duplicate.py IPlugEffect MyNewPlugin MyManufacturerName

UnicodeDecodeError: 'cp932' codec can't decode
cp932エラーが発生したら下のコードを上の方に張り付ける。 
# Windows 環境向けのハック
# 参考: https://stackoverflow.com/questions/31469707/changing-the-locale-preferred-encoding-in-python-3-in-windows
#https://blog.tsukumijima.net/article/python3-windows-unicodedecodeerror-hack/ 
import os
if os.name == 'nt':
import _locale
_locale._getdefaultlocale_backup = _locale._getdefaultlocale
_locale._getdefaultlocale = (lambda *args: (_locale._getdefaultlocale_backup()[0], 'UTF-8')) 
 
Windowsの場合はGUI版があります。便利だけど日本語が文字化けします。 
https://github.com/flutomax/IPlugDublicater

新しいプロジェクトを開いたらconfig.hを編集します。
PLUG_MFR_UIDとPLUG_UNIQUE_IDは、必ず変更してください。

日本語を入力するとコンパイルできない。

プロジェクトのプロパティを開いて「構成プロパティ」->「C/C++」->「コマンドライン」
の追加のオプションに↓を入力する
/source-charset:utf-8 /execution-charset:utf-8 

リサイズのメッセージ順番

APPの場合 
IPlugAPP_dialog.cppのMainDlgProcからOnParentWindowResizeを呼ぶと
IGraphics::Resize
OnParentWindowResize
の順番で呼び出される 
 
チャンクについて
何もしなければ自動で SerializeParams と UnserializeParamsが
呼ばれて自動でパラメーターをプロジェクトに保存してくれる。
単純に順番で保存されているのでバージョンアップした時、
並び順を変えたり、パラメーターを削除すると正常にパラメーターが読めなくなるので、
バージョン番号を付けて管理する。 
 
自分で保存の処理をするには、SerializeState と UnserializeState をオーバーライドする。
バージョン番号を追加するには、
bool MimiCopyAnalyze::SerializeState(IByteChunk& chunk) const
{
//バージョン番号とウインドウサイズを保存する。
double version = 1;
chunk.Put(&version);
chunk.Put(&mWidth);
chunk.Put(&mHeight);
  return SerializeParams(chunk); 
}
int MimiCopyAnalyze::UnserializeState(const IByteChunk& chunk, int startPos)
{
int pos = startPos;

double ver = 0.0;

//バージョン番号とウインドウサイズを取得
  startPos = chunk.Get(&ver, startPos);
startPos = chunk.Get(&mWidth, startPos);
startPos = chunk.Get(&mHeight, startPos);
  return UnserializeParams(chunk, startPos);
}

スクリーンスケール

スケーリングするとスタンドアローン版でCPU負荷がたかくなるので、調べた。
IPlugAPP_dialog.cppの
#ifdef OS_WIN 
//scale = GetScaleForHWND(hwndDlg);
#endif 
と、IGraphics.cppの
void IGraphics::SetScreenScale(float scale)
{
//todo mScreenScale = scale;
int windowWidth = WindowWidth() * GetPlatformWindowScale();
int windowHeight = WindowHeight() * GetPlatformWindowScale();
と、IGraphicsWin.cppの
 /*if (!GetCapture()) // workaround Windows issues with window sizing during mouse move
{
float scale = GetScaleForHWND(mPlugWnd);
if (scale != GetScreenScale())
SetScreenScale(scale);
}*/
をコメントアウト
プロジェクトのプロパティを開いて、
マニフェストツール->すべてのオプション->DPI認識を「なし」以外を選択する。

やってみたけど画面が小さいままだった。

VST3は、スケール1で処理してるけど、スケーリングされるのはなんでだろう?

 

ホストからのバイパスが検出できない

試してみたけどメッセージが来てなかった。

IPlugProcessor.hに追加

virtual void OnBypass(bool bypassd) { TRACE }


 IPlugVST3_ProcessorBase.cppに追加

            case kBypassParam:
            {
              const bool bypassed = (value > 0.5);

              if (bypassed != GetBypassed())
+             {
                SetBypassed(bypassed);
+               OnBypass(bypassed);
+             }
              break;
 

 

プロジェクトのプロパティ

プリプロセッサ

コマ落ちしを無視する

IGRAPHICS_DISABLE_VSYNC

同時に起動する
APP_ALLOW_MULTIPLE_INSTANCES

 

コード生成

ランタイムライブラリをマルチスレッドDLL(/MDd)にする。


 

使った感想

規模が小さめなので改造しやすい。便利な機能が少ない。
リストボックスがない。コンボボックスはある。 
OpenGLが使える。OpenGLは環境によって動作が変わるのでデバックしにくい。
GUIにSkiaが使える。すべての機能を使うには改造が必要。

ライセンスの制限が少ないので使いやすい。

コードが短めに作れるかも

GUI関係の不具合が多いかな。


yuki

初めての作業で調べた事、困った時の解決方法を記録するブログ。 主なテーマは、パソコン、プログラミング、カメラ、DTM、スピリチュアル、化学物質過敏症

コメントを投稿

Please Select Embedded Mode To Show The Comment System.*