vst-rsでeguiを使う
この記事はRust Advent Calendar 2022 - Qiitaの14日目の記事です。
はじめに
この記事ではeguiを改造してvst-rsで使っていきます。
他のライブラリでもwinitのバックエンドあるGUIライブラリなら似たようなやり方でvst-rsで使うように改造することはさほど難しくないと思います。

参考
RustでGUI付きのVSTプラグイン作る(Conrod, iced)
vst-rsでGUIを使うための制約
RustでGUI付きのVSTプラグイン作る(Conrod, iced)に書いたようにvst-rsにGUIをつけるには、GUIライブラリが以下を満たしている必要があります
- openメソッドが呼ばれたときに、引数のウインドウハンドルを親にした小ウインドウとして自分のウインドウを作らなくてはいけない。WinAPIでいうと、CreateWindowExWのhWndParentに入れてやる。これを他のプラットフォームでどうやるかわからないのが本記事がWindowsのみである主な理由。
- イベントループはidleメソッドで細切れにやる。つまり、一回走らせるとウインドウを閉じるまで帰ってこないようなGUIライブラリはだめ。
winitバックエンドを持つライブラリであれば1.はwindowsを作るときにwinit::platform::windows::WindowBuilderExtWindows::with_parent_windowを呼ぶだけです(Windowsの場合)。
また、2.はwinitのイベントループをwinit::platform::run_return::EventLoopExtRunReturn::run_returnを使って処理する必要があります。
しかし、eguiを含む大抵のGUIライブラリのバックエンドはwinit::event_loop::EventLoop::runを使ってイベントループを処理しているので(これだと処理が一生帰ってこないのでだめ)、run_returnを使ったイベントループに書き換える必要があります。
eguiの改造
そのままのeframe(eguiのネイティブバクエンド)では上で書いた制約を満たすことができないので改造していきます。
eframeではバックエンドとしてglowとwgpuを選べますが、glowはバージョンが古くパニックが出てしまったので今回はwgpuバックエンドのみ改造します。
コードはこちら https://github.com/hatoo/egui/tree/vst
1. 親ウインドウを指定して子ウインドウにする
これは簡単です。
eguiのバックエンドであるeframeはeframe::NativeOptionsでウインドウの設定を管理しているのでそれに親ウインドウ用の項目を足します。
あとはeframe::NativeOptionsをwinitのビルダーに渡す箇所で親ウインドウのハンドルを設定するだけです。
2. run_returnを使ったイベントループ
run_returnを使ったイベントループをするためにGUIの情報全体をstructでまとめます
ウインドウを閉じる操作は下手なタイミングでやるとクラッシュしてしまうのでクローズ用のフラグを追加しています。
pub struct WgpuIdle {
wgpu_eframe: WgpuWinitApp,
native_options: NativeOptions,
close: bool, // 次のイベントでクローズしてほしい
closed: bool, // 実際にクローズした
}
impl WgpuIdle {
pub fn idle(&mut self) -> bool /* is exited */ {
todo!()
}
pub fn close(&mut self) {
todo!()
}
pub fn size(&self) -> (i32, i32) {
todo!()
}
}
pub fn idle_wgpu(
app_name: &str,
native_options: epi::NativeOptions,
app_creator: epi::AppCreator,
) -> WgpuIdle {
todo!()
}
vst用にrun_returnを使ったイベントループを処理するときは常に*control_flow = ControlFlow::Exit;で大丈夫です。
あとはeguiを含む大抵のいGUIライブラリには、ウインドウを描画する関数、イベントを処理する関数が用意されているのでそれを適当に呼ぶだけです。
詳細はコード参照
利用例
適当なvstプラグインを上記のeguiを使って作ってみました。
コードはこちら https://github.com/hatoo/vst-rs-example-egui

- GUI上の変更がBitWigのGUIに反映されない
- おそらくパラメーターの変更をホストに通知するAPIは存在するが
vst-rsでどうやるかわからない
- おそらくパラメーターの変更をホストに通知するAPIは存在するが
- VstHostではうまく表示されない
などの問題点はありますがだいたい動いてます。

Discussion