情弱

情弱のVST作製メモ

JUCEでソフトシンセをつくる 2 ~ AM・FMオシレータ

前回は

MIDI入力を通して任意音階のSine波が鳴らせるようになりました。 

今回は

先のSineOsillatorから、AM・FM Oscillatorを作ります。

AM・FM波の演算式は、それぞれ以下のものとして実装してみます。

 \displaystyle y_{AM}(t) = (1+p_{ma} \sin{2 \pi f_m t}) \sin{2 \pi f_c t}

 \displaystyle y_{FM}(t) = \sin{(2 \pi f_c t + p_{ma} \sin{2 \pi f_m t})}

ここで、 f_c , f_mは、それぞれ、キャリアSineOscの周波数、モジュレータSineOscの周波数になります。また、 p_{ma} (0 \leq p_{ma} \leq 1)は、ユーザー側がホストDAWGUIを通じて設定できるパラメータになります。

 f_cは、MIDI入力によって決まるので、 f_mは、 p_{mr} (\geq1)というパラメータを定義して、以下のようにします。

 \displaystyle f_m = p_{mr} \times f_c

以上より、今回の目的は、

"2種類のパラメータを用意し、それをキャリア・モジュレータSine波に適用させ、AM・FM波を合成する機能を実装する"ということになります。

 プロジェクトの設定

下の画像のように設定します。

f:id:aogiri_m2d:20170610235701j:plain

前回のプロジェクトに、"OscParameters"、"ModOscillator"というソースファイルを新たに追加しています。それぞれに、パラメータとAM・FMオシレータの実装を記述していきます。

また、前回の"SineOscillator"も合わせて、オシレータ関係のソースファイルをまとめておきます。

パラメータの実装

以下のように実装します。

パラメータの実装については、以前に少し書いてたので参考にしてください。

Sine波オシレータの修正

前回実装したSineOscillatorを少し改修します。

主な変更点としては、

  • MIDI-ON以外のタイミングでも周波数を変更できるよう、changeFrequency関数を追加
  • メンバ変数をprotectedに変更し、各種関数の内部に空の仮想関数を追加(NVIによって挙動を拡張できるようにする)

これらは、このSineOscillator Classを派生させAM・FMオシレータを実装するための下準備になります。AM・FMもオシレータであるため、結局は、SineOscillatorと同じようなインターフェイス構成を持ちます。従って、今回は継承を使って実装することにしました。 

AM・FMオシレータの実装

SineOscillator Classの派生クラスとして実装します。派生クラスにprotected継承されたメンバ変数を、キャリアオシレータのパラメータとして扱っています。

ProcessBlockでOscを走らせる

後は、前回同様にsynthソースファイルにMIDI入力の処理を書いて、ProcessBlockでModOscillatorを走らせるだけです。これについては、前回とほぼ同じ実装なので詳細は割愛します。下記に今回のAM・FMオシレータシンセの全ソースコードを置いておくので参照してください。

動作確認

ModTypeで、AM・FMモードが切り替えられます。

FMはまだしも、AMはSin波同士だと思ったよりしょっぱいですね。

f:id:aogiri_m2d:20170611005346j:plain

次回の予定

たぶん、アンプエンベロープかポリフォニックの実装をします。