i_made_a_subtractive_synthesizer_using_rust.md (7540B)
1 --- 2 title: Rustで減算方式のシンセサイザーを作った 3 tags: 4 - rust 5 - vst 6 - clap 7 - nihplug 8 private: false 9 updated_at: 2026-04-14 00:17 10 id: null 11 organization_url_name: null 12 slide: false 13 --- 14 ## 想定読者 15 16 - Rustacean 17 - CLAPプラグインを書いてみたい人 18 19 ## 成果物 20 https://github.com/minerva-jupiter/mooxide 21 22 ## 使用技術 23 24 - Rust 25 - nih-plug 26 - DAW(REAPER) 27 28 ## 構想 29 30 私は3年前くらいから歌うシンセサイザーを作りたいと思っていました。 31 VOCALOIDは触った程度でしたが、DAWとの結合が甘いのが不満点でした。 32 また、NEUTRINOをメインで使っていましたが、これは完全に別プロセスで、やはりDAWから調声をしたいと思っていました。 33 これらに加えて、人間の声と合成音声の違いについての研究の成果も合わせて、合成音声のVSTiをつくるという構想がありました。 34 それらに向けた習作として、また、自分が使いやすいようなシンセサイザーを作れたら便利だなと思い、開発に踏み切りました。 35 ~~mini moogとか欲しいのだけど、高くて手が出ないからソフトウェアで作っちまえって思いたったのもあります。~~ 36 37 ## nih-plugについて 38 39 [nih-plug](https://github.com/robbert-vdh/nih-plug)はRustでVSTiとCLAPを作成するためのフレームワークです。 40 今回はSteinberg社が規定するVST3 Licenseの関係がめんどくさいと感じた(当社比)ので、CLAPだけに焦点を絞って作りました。 41 42 他の選択肢としてJUCEというフレームワークがあります。 43 これはOSSのC++でアプリやプラグインを作るフレームワークです。 44 また、フレームワークを使わなくてもSteinberg社が出しているVST3 SDKというものを使えばC++でVSTを書くことができます。 45 46 私がそんな中でnih-plugを採用した理由は、ズバリ、Rustで書けるからです。 47 Rustを書いているときにしか得られない栄養があります。(中毒者のセリフ) 48 というかCの扱いが難しすぎてC++に手を出すきになれなかったという方が正しいかもしれないです。 49 50 ## 開発手順概説 51 ### セットアップ 52 53 Rustでプラグインを書く為のnih-plugですが、プロジェクトのセットアップにはpythonを使ったcookiecutterを使用します。 54 まず、pipxが無ければ入れます。 55 ```bash 56 pip install pipx 57 ``` 58 そしてセットアップを実行します。 59 ```bash 60 pipx run cookiecutter gh:robbert-vdh/nih-plug-template 61 ``` 62 ここでプロジェクトの名前などを決めて、気づいたらプロジェクトのフォルダーが完成しています。 63 64 ### CLAPのみに設定 65 66 https://github.com/minerva-jupiter/mooxide/commit/b9406fbce17ead3f25c9e3600eef349993289944 67 具体的な作業はcommitの変更点を参照してください。 68 VST3のバインディングを外して、nih-plugのfeature設定を変更したりしています。 69 70 ### GUIについて 71 72 配布されている殆どのプラグインにはGUIが搭載されています。 73 私はそういうものは基本的に不要だと考えています。 74 曲の中で動的に数値を変えたいとなるとDAW側のエンベロープを用いることになり、結局のところGUIは計算資源の無駄遣いになってしまうんじゃないかなと思ってしまいます。 75 もちろん、エフェクターの配置を自由に変えることができるプラグインなどでGUIが有意義であることは認めます。 76 77 ### オシレーターの実装 78 79 一からすべてを考える必要はありません。 80 nih-plugのリポジトリにシンセサイザーの作例があるので、ありがたく使わせてもらいましょう。 81 https://github.com/robbert-vdh/nih-plug/tree/master/plugins/examples/sine 82 ただ、参考にしたmini moogはオシレーターが3つ付いていたので、その分、detuneやミックスを考慮してコードを書き足していきました。 83 作業としては、structにパラメーターを追記して、それを掛けるなり足すなりするだけなので、コードに高度な変更はしてないです。 84 https://github.com/minerva-jupiter/mooxide/commit/f53c759018bb6a4551fbc61829c9eac3879205c8 85 個人的にはシンセの波の形をプログラムで書くときに、関数として綺麗な形で書く(条件分岐を減らす等)工夫が楽しかったです。 86 87 ### ノイズ生成 88 89 ノイズ生成が一番簡単でした。 90 特にホワイトノイズ。 91 -1~1のランダムな値を返せばそれで終わりですよ。 92 拍子抜け。 93 94 ### ローパスフィルターの実装 95 96 減算方式シンセサイザーの"減算"の部分です。 97 本当は4ラダーフィルターの動きをシミュレートしたかったのですが、あまりうまくいかなかったです。 98 似たようなことをしている先人も見つけることができず、闇に消えました。 99 たどり着いたのは、参考文献の1つ目、セットアップのときに参考にした記事でした。 100 こちらの記事で参考にされている記事で参照されているBiQuadフィルタという非常に簡易的なローパスフィルターの実装をしました。 101 102 ### エンベロープの実装 103 104 フィルターの効き具合や信号強度を、鍵盤が押されてからの時間経過で切り替えるために、エンベロープを実装しました。 105 https://github.com/minerva-jupiter/mooxide/commit/da4a5e14d5894bf3fdfbe7be3657d42cf63c78b9 106 107 ### ビルドとデバック 108 109 作った系の記事ってこれがなくて困るので、私は書きます。 110 ビルドコマンドはReadmeにも書いた通り 111 ``` 112 cargo xtask bundle mooxide --release 113 ``` 114 です。これで`target/release`みたいなフォルダーにCALPプラグインができてます。 115 これをいちいちCLAPの既定の場所に持っていっても良いんですけどめんどくさいので、ReaperのCLAPを探しに行く場所にプロジェクトのリポジトリを追加するという荒業で対応しました。 116 ちなみにReaperだとプラグインのキャッシュを残すのか、一度Reaperを閉じてからもう一度開かないと、うまく変更が適応されない場合がありました。 117 118 あと、最初に書いてあるゲインプログラムは有効な状態で残しといたほうが良いです。 119 もしうまく動かなかったときに、音量が大きすぎるせいor小さすぎるせいという可能性を検証することができるからです。 120 121 ## 最後に 122 123 拙い文章ですが、読んで下さり、ありがとうございます。 124 nih-plugの日本語記事が非常に少数で、楽器を作るとなるとまた非常に少数だったので、記事にしてみました。 125 コーディング難易度も高くなく、成果物がちゃんと音を鳴らす様子を見ると、楽しかったです。 126 みなさんもやってみてください。 127 最後に、構想でも書きましたが、合成音声CLAPの制作をしている途中です。 128 難易度が高いので、一緒にやってくれる人がほしいです。 129 130 ## 参考文献 131 - [Rustで簡単にVST/CLAPプラグインを作る](https://qiita.com/Saisana299/items/003aa9aa3b40db4f6f89)