前回のディレイに続いて、logue SDK 2.0を使ったシンセサイザのユーザユニットも作成してみます。
シンセサイザはlogue SDK 2.0で大きく変わったところです。というのは、シンセサイザの構成というのはざっくり下図のようになっているのですが
loge SDK 1系で作ることができるのは、この中のオシレータの部分でした。
ですので与えられたピッチに応じた信号をただ作っていれば良かったのです。
ですがlogue SDK 2.0では、シンセサイザユニットとして、下の図の枠で囲った部分を全部開発するようになりました。
オシレータだけ作るのではなく、単体でシンセサイザとして完結したものを作ることができます。MIDI入力やシーケンサからの信号をどう扱うかも含めてすべて実装できますので、自由度は上がりましたが、考慮することも増えました。
今回は、とにかくシンプルに
・モノシンセ
・オシレータは矩形波
・フィルタは無し
・エンベロープは無し、ベロシティには対応
・パラメータは無し
というものを作ってみます。要するにキーを押したらプーと音が出るだけのシンセです。
このシンセはパラメータとしてノート番号を提供していないので、drumlogueのシーケンサからは音高を設定することができません。音高を変えて鳴らすにはMIDI入力デバイスを接続する必要があります。
ソースコードはSDK付属のdummy-synthユニットをコピーして、synth.hだけ修正します。
以下が修正したsynth.hです。
ちょっと長いですが、半分以上はもともと含まれていたコードです。
修正前のsynth.hとの差分を中心に、以下解説しておきます。
12行目:powf()を使うためにmath.hをインクルードしています。powf()はMIDIノート番号を周波数に変換するために使います。
16行目:127の逆数を定数で定義しています。ベロシティの値(0~127)を0~1.0に変換するために使います。
30行目:Initの中でResetを呼んで、メンバ変数を初期化します。
38~39行目:メンバ変数を初期化します。pitch_はオシレータの周波数、gate_は音量(0.0~1.0)です。
54~56行目:オシレータ波形の生成です。w0は1サンプルあたり、波形の位相がどれだけ進むかを表します。オシレータの作り方については以前の記事を見てください。
57行目:音量を掛け算します。
58行目:生成した信号をバッファに出力します。
59~60行目:波形の位相を1サンプル分進めます。phi_は1.0を超えたら0に戻ります。
89~91行目:ノートONイベントが来たら、ノート番号に対応する周波数をpitch_に格納し、ゲートをONします。
94~110行目:ノートOFF、ゲートON/OFF、AllNoteOffの処理です。
134行目:サンプリングレートの逆数を定数にしています。ピッチからw0を計算するのに使います。サンプリングレートはInit時にdescパラメータから取得できるのですが、今回は48KHzに決め打ちにしています。
というわけで、とりあえずシンセユニットを作成することができました。
w0を計算するところなど、logue SDK 1系ではライブラリが提供されていたのですが、今回は何も無いので自分で作る必要があります。ただ、CPUがパワフルなので、マイコン向けで行うような最適化は、当面は考えずにコードを書いて大丈夫そうです。
コメント