ファミコンで鳴らせる波形として三角波があるが、実際には純粋な三角波ではなくて16段階の階段状になっている (Nesdev wiki)。 その場合に純粋な三角波とどういう違いになるのか聞き比べてみた。
WebAudioで階段状の三角波を鳴らすには、周期的な波なのでフーリエ級数展開して得た係数を createPeriodicWave()で波形を生成し、 オシレータのsetPeriodicWaveで指定すればよい (フーリエ展開すると段差で大きく振動するので、その影響は別途検証する必要があるかも…)。
周期を1、階段の段数を \(d\) とするとフーリエ級数展開の係数は、
$$ \begin{align*} a_n &= 2 \sum_{j=0}^{2 d} k_j \frac{1}{2 n \pi} \left\lbrace \sin \left\lparen 2 n \pi \frac{j+1}{2d} \right\rparen - \sin \left\lparen 2 n \pi \frac{j}{2d} \right\rparen \right\rbrace, \\ k_j &= \left\lbrace \begin{array}{ll} j < d \cdots 1 - \frac{2j}{d-1} \\ j \ge d \cdots -1 + \frac{2(j-d)}{d-1} \end{array} \right. \end{align*} $$
となる (直流成分\(a_0=0\)、\(b_n\)はsinを-cosにしたもの…と思ったが結局すべて0だった)。
聞き比べてみると階段状のほうが倍音が強くて尖った音に聞こえ、特に音が低いときに顕著 (ドラクエ3の名前入力時など無音なはずのところでノイズ音が聞こえるのはこれが原因)。
階段の段数を減らして2段にすると矩形波に、フーリエ級数の足し合わせる項の数を数を減らすとサイン波になるということで、聞こえ方もそれらの中間という感じになっている。
ファミコンエミュレータで三角波チャンネルを再現する際には、違いは微妙だしフーリエ展開面倒だしノイジーな階段状より純粋な三角波のほうがいいんじゃないと思うんだけど、 悪用というか効果として活用してしまう猛者もいるらしい…恐るべし。
追記
- ファミコン疑似三角波のフーリエ級数展開 - hsjoihs’s diary デシベル表示の図があってわかりやすい