FM音源プログラム (4) -- EG (4)

lb ドメインでの EG 計算の続きです。
TL は音色パラメータですから、新しいインストゥルメントが選ばれて発音ユニットに新たな音色データがロードされるまでは不変です。
MIDI ノートオン・メッセージの到着で、ピッチ情報とベロシティ情報が決定しますから、この時点で、Rate Key Scale のオフセット量と、ベロシティ・データによるキャリア・オペレータの出力レベル変化量が確定します。
ノートオン処理ルーチンでこれらの量を計算し、変数 tl_lb を設定します。 以後、次のノートオンまで変化しません。
MIDI チャンネル・ボリューム (CC#7) や、エクスプレッション (CC#11) は、ノートオン、ノートオフの状態にかかわらず、任意のタイミングで発生しますから、各処理ルーチンで合計値を変数 vol_lb に設定します。 以後、vol_lb に関係する MIDI イペントが発生すれば更新されます。
LFO は 4 ms のサンプリング周期で更新されます。 その LFO 処理ルーチン内で変数 am_lb を設定します。
EG ルーチンは 1 ms のサンプリング周期で起動されます。
lb ドメインでの EG のエンベロープ値は変数 egacc に保持されています。 egacc の値を更新したあと、tl_lb, vol_lb, am_lb の値と加算し、lb - リニア変換をして 16 ビット・リニア・フォーマットの出力レベル値 ol_lin を求めます。
この出力レベル値は、十数 kHz のサンプリング周波数のオペレータ・ルーチンの中でサイン波 ROM の値と乗算されてウェーブ・データとなります。

EG 計算のステートダイアグラム


アナログシンセの EG 回路では、電圧レベルによる状態遷移は、アタック→ディケイへの遷移だけですが、OPL3 系の EG では、アタック→ディケイ、ディケイ→サステインの遷移でレベルの比較をする必要があります。
アタックは、表現し得る最大の lb 値を egacc の初期値として設定し、順次、値を減らしてゆき、egacc がゼロに達したらディケイに移行します。
ディケイでは、egacc の初期値として 0 から始めて、ディケイ・レートで直線的に値を増やしていき、egacc がサステイン・レベルに達すると、持続音モード (EGT=1) の場合はサステインへ移行して、egacc の値を変化させず、一定のレベルを保持します。
減衰音モード (EGT=0) の場合は、サステインせずにリリースへ移行します。
リリースでは、egacc の値は以前の値を受け継ぎ、リリース・レートで直線的に値を増やしていきます。
エンベロープのレベルが、あらかじめ設定してある最小レベル (-96 dB) より小さくなったら、オペレータを OFF のモードとして出力をミュートして、以後キーオンまで全く状態を変化させません。
現在はダイナミック・ボイス・アサインの機能を組み込んでいませんが、ボイス・アサイナでは、オフになった発音ユニットは、アサインが解除され、自由に使えるユニットとしてプールされることになります。