FM音源プログラム (19) -- オペレータ (12)

Wave Select

本来、FM音源の出力はサイン波が基本で、6 オペレータ、32 アルゴリズムを誇る DX7 の音源でもサイン波出力だけです。
オペレータ数の少ないローエンドのFM音源では、複雑な変調はできないことを補う意味もあって、OPL 系で言えば OPL II (YM3812) の世代から、出力波形は 4 種類に増えました。
さらに、OPL3 (YMF262) の世代からは出力波形は 8 種類になっています。
携帯電話用音源チップのシリーズで言えば、MA-2 (YMU759) は OPL3 と同様の出力波形 8 種類で、MA-3 (YMU762) では、サイン波のほかに三角波や、のこぎり波、矩形波を含む 32 種類で、その内 3 種類は SRAM 上の任意波形を使用できるようになっています。
OPL3/MA-2 の音色パラメータでは、3 ビットの WS (Wave Select) で 8 種類の波形を選択します。
それらは、サイン波を半波整流や全波整流したような波形になっています。 基本的にはサイン波テーブルを利用して加工したものになっており、追加の波形データが必要ないものに限られています。

WS = 0


WS=0 は、普通のサイン波です。
この波形が基本だけあって、使用頻度が高いので、プログラムの実行時間がなるべく短くなるように配慮する必要があります。

WS = 1


WS=1 は、サイン波を半波整流したような波形で、\pi 以上の部分がゼロになっています。
式で表すと、
y = \left { \begin{array}{ll} \sin(x) \qquad & (0 \le x \lt \pi) \\ 0 & (\pi \le x \lt 2\pi)\end{array}

WS = 2


WS=2 は、サイン波を全波整流したような波形です。
プログラムとしては、「S」ビットを見て符号反転する手間がいらず、テーブルから読み出した正の値をそのまま使えば良いので、WS=0 より処理は簡単になります。
式で表すと、
y = \left { \begin{array}{ll} \sin(x) \qquad\qquad & (0 \le x \lt \pi) \\ -\sin(x) & (\pi \le x \lt 2\pi)\end{array}

WS = 3


WS=3 は WS=2 の波形を 1/4 周期ずつ2箇所をゼロに落とした波形です。
式で表すと、
y = \left { \begin{array}{ll} \sin(x) \qquad\qquad & (0 \le x \lt \pi/2) \\ 0 & (\pi/2 \le x \lt \pi) \\ -\sin(x) & (\pi \le x \lt 3\pi/2) \\ 0 & (3\pi/2 \le x \lt 2\pi)\end{array}

WS = 4


WS=4 は 2 倍の周波数のサイン波1周期分と、もとの周波数での半周期分のゼロの組み合わせです。
サイン波部分を 2 倍の周波数にするには、フェーズアキュムレータから抽出するビット位置を下に 1 ビット分ずらしてテーブルインデクスを切り出します。
式で表すと、
y = \left { \begin{array}{ll} \sin(2x) \qquad & (0 \le x \lt \pi) \\ 0 & (\pi \le x \lt 2\pi)\end{array}

WS = 5


WS=5 は WS=4 の波形を全波整流したような波形で、プログラムとしては WS=4 より簡単になります。
式で表すと、
y = \left { \begin{array}{ll} \sin(2x) \qquad & (0 \le x \lt \pi/2) \\ -\sin(2x) \qquad & (\pi/2 \le x \lt \pi) \\ 0 & (\pi \le x \lt 2\pi)\end{array}

WS = 6


WS=6 は方形波です。
「S」ビットを見て出力の符号を決めます。
式で表すと、
y = \left { \begin{array}{ll} +1 \qquad & (0 \le x \lt \pi) \\ -1 & (\pi \le x \lt 2\pi)\end{array}

WS = 7

(2011/01/08 追記: YMF262 の出力を測定した結果、WS = 7 は実際には「エクスポネンシャル」な波形であることが分かりました。 詳しくは→こちらこちら。)

WS=7 は、「rege」*1 Page 11 の図では、何が何だか良く分かりませんが、MA-2 オーサリングツールのFM音色エディタで WS=7 を選んで発音した波形を観察して、この図のような波形であろうと推測しました。
位相 0 〜 \pi/23\pi/22\pi に 1/4 周期サイン波形がオフセットを付けて配置されています。
式で表すと、
y = \left { \begin{array}{ll} 1-\sin(x) \qquad\qquad & (0 \le x \lt \pi/2) \\ 0 & (\pi/2 \le x \lt 3\pi/2) \\ -1-\sin(x) & (3\pi/2 \le x \lt 2\pi)\end{array}

関数へのポインタの使用

WS は音色パラメータですから、いったんロードされると、次の音色データで置き換わるまで、同じ値が持続します。
ひとつのオペレータ関数の中で、サンプリング周期ごとに毎回 WS の値を調べて処理を選択するのは、時間の無駄と言えます。
そこで、WS の値それぞれに対応する専用のオペレータ関数を作成しておき、オペレータ関数の呼び出しは直接ではなく、関数へのポインタを利用して間接的に行うことにします。
音色データのロード時に WS の値を見て、どの専用関数を使うかを決定し、関数ポインタにそのアドレスを代入しておきます。

*1:「YMF715x (OPL3-SA3) -Register Description Document-」