FM音源のフィードバックを考える

WSGとかPSG系の音を作っていて、「いい感じにできた!」と思ったら音程変えるとノイジーというか「何か違う感じ」になってしまうことがあって。レトロな音源特有のノイズだったらアリなんですけど、それとも違う。

多めにフィードバックかけた音にありがちな気がしたので、じゃあどこまでならOKかというのを考えてみた。

OPN(とかOPMとかその他)のフィードバックは、オペレータのうち1番だけが使えて、こんな記号で表されている。

たぶん中身はこんな感じ。

\(\)OPの出力(★)を \(f(\omega t)\) とすると、それにTLで決まる値 \(a_\mathrm{TL}\) が掛けられて出力されるんだけれど、そこへ更にFBで決まる値 \(a_\mathrm{FB}\) が掛けられて、PG(フェーズジェネレータ)の出力した値に足されてOPに入力される。OPは単なる \(\sin\) 関数。

(実際のチップの中は、掛け算なんかしてなくて対数の加算でやってるらしい。)

これをまとめると、こんな式が成り立つような出力になっているはず。\(a\)は\(a_\mathrm{TL} \times a_\mathrm{FB}\)。

\[f(\omega t)=\sin(\omega t+a f(\omega t))\]

(実際には、この式が成り立っているわけではなく、フィードバックされるのは過去のサンプル、それも1つ前のサンプルだと猛烈に発振したりするので過去2サンプルの平均が使われているらしいけれど、とりあえずそこは考えない。)

この式を図にするとこんな感じ。

式が成り立つのは、傾き \(\frac{1}{a}\) の直線(赤)と \(\sin\) の交点になるわけだけれど、直線の傾きが浅い(\(a\) が大きい)と図の下のみたいに複数の点で交差するので、どの値になるか決まらない。これが、不安定というかノイズになるんじゃないかなという予想。

交点が複数にならない条件は \(\frac{1}{a}\) が1以上、つまり \(a \leq 1\) 。

\(a\) はどう決まるかというと、OPNのパラメータのTLが0でFBが7のときが最大で \(4\pi\)。TLは8増える毎に半分。FBは1減る毎に半分。FBが0のときは1のときの半分ではなくオフ \((a=0)\) だけど、フィードバックがないなら今回の話は関係ないので置いておく。

\[a=4\pi \times 2^{-\frac{\mathrm{TL}}{8}-(7-\mathrm{FB})}\]

この式をこねくり回すと、これが \(a \leq 1\) になるのは、

\[\mathrm{TL} \geq 8\times\mathrm{FB}-26.788\cdots\]

TLもFBも整数なので、結局こんな感じ。

FBTL(最低値)
730
622
514
46
0~30

上記の値を守っていればフィードバックが安定するので、これが原因のノイズはなくなるはず。まあ、いろいろ無視したので実際は違うかもしれませんが。

(普通はこのノイズも含めてアタックとかに使っているわけですが、今回は冒頭で書いたようにPSG系の持続音なので。)