サウンド
目次
アーキテクチャ
概要
ファミコンのサウンドはAPU(Audio Processing Unit)により統括されていて、ファミコンの場合はAPUはCPU(6502)にワンチップ化されています。
FM音源4チャンネルとPCM音源1チャンネルの計5チャンネルから成り立っています。また、それぞれのチャンネルには完全な役割分担がなされており、矩形波が2チャンネル、三角波1チャンネル、ノイズ1チャンネル、DPCM1チャンネルとなっています。
再生方法
- I/O【$4015】で設定するチャンネルの再生をオフにする
- チャンネルのレジスタに情報を設定
- I/O【$4015】で設定したチャンネルの再生をオンにする
矩形波
概要
矩形波を出力するチャンネルで、主に音楽のメロディ部分や効果音に使われます。矩形波は2チャンネル用意されていて、チャンネル1はI/O【$4000-$4003】を、チャンネル2はI/O【$4004-$4007】で設定を行います。チャンネル2に関しては、チャンネル1と同じレジスタ構成になっているのでこれからの記述は全てチャンネル1を想定します。
再生周波数
矩形波はI/O【$4002-$4003】に再生したい音の周波数を11bit値で設定することで、任意の高さの音を再生することが出来ます。
例えば、「ラ」の音を出したい場合は440Hzの音を再生することになるのですが、周波数レジスタにそのまま440と入力するわけではありません。ここに設定する値は「システムクロック周波数(1.79MHz)からの分周値」となっているのです。
と言うことは「1790000 / x = 440」と言うことで「x = 4068.18...」としたいところですが、実際に設定される分周値は、周波数設定レジスタに指定した値を内部的に5bit左シフトをした値となっています。それらを総合すると、周波数レジスタに設定する値と実際に再生される音の間には次の式が成り立ちます。
- レジスタに設定する値 = CPUのクロック周波数 / (再生したい周波数 * 32) - 1
ここで最後の「-1」に関しては、あくまで予想ですが多分内部的に0除算が起きるのを防止しているものと思われます。
また、実際に上の式に当てはめて音階を作ってみると高音になればなるほど設定する値が小さくなって行きます。さらに小数部は四捨五入するので高音になればなるほど周波数に誤差が生まれていくことになります。つまりファミコンのゲームの高音がちょっと音痴に聞こえるのはこのためです。
三角波
概要
主に音楽のベース部分に使われるチャンネルです。I/O【$4008-$400B】で制御し、次のような特徴があります。
と言うことで非常に設定項目が少いので、矩形波よりも簡単に制御出来ると思います。
再生周波数
基本的には矩形波と同じように、I/O【$400A-$400B】に再生周波数を設定するのですが、注意しなくてはならないのは周波数レジスタから生成される分周値が矩形波と異なり6bitシフトした値となりますので、矩形波と同じ周波数を設定すると1オクターブ低い音が出力されることになります。
ノイズ
概要
主に効果音や音楽のリズムに使われるチャンネルです。I/O【$400C-$400F】で制御します。
私自身適当にしか使ってないので細かい部分は分かりません。よって細かい説明は省略…。
DPCM
概要
ファミコン唯一のPCM音源のチャンネルで、任意の波形を出力する事が出来ます。その気になればボイスデータ等の複雑な波形も再生する事ができますが、基本的にメモリ空間の少ないファミコンで音声データはあまりにもサイズが大きく、実際には音楽のドラム音ぐらいにしか使われていない事が多いです。
ちなみに、このチャンネルはI/O【$4010-$4013】を使って制御しますが、細かい設定方法はI/Oポートを参照してください。
IOポート
$4000 (矩形波CH1制御レジスタ1)
矩形波CH1の設定を行います。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7-6 |
Duty Cycle |
0=87.5% , 1=75.0% , 2=50.0% , 3=25.0% |
5 |
再生時間カウンタ有効 |
オフ |
オン |
4 |
音響選択 |
音響可変 |
音響固定 |
3-0 |
ボリューム値 |
データ値 |
$4001 (矩形波CH1制御レジスタ2)
矩形波CH1の設定を行います。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7 |
周波数変化 |
固定 |
可変 |
6-4 |
周波数変化速度 |
データ値 |
3 |
周波数の変化方法 |
増加 |
減少 |
2-0 |
周波数範囲値 |
データ値 |
$4002 (矩形波CH1周波数値レジスタ1)
矩形波CH1の再生周波数の設定を行います。
書き込み
位置 |
内容 |
値 |
7-0 |
再生周波数下位8bit |
データ値 |
$4003 (矩形波CH1周波数値レジスタ2)
矩形波CH1の再生周波数と再生時間の設定を行います。
書き込み
位置 |
内容 |
値 |
7-3 |
再生時間 |
データ値 |
2-0 |
再生周波数上位3bit |
データ値 |
$4004 (矩形波CH2制御レジスタ1)
矩形波CH2の設定を行います。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7-6 |
Duty Cycle |
0=87.5% , 1=75.0% , 2=50.0% , 3=25.0% |
5 |
再生時間カウンタ有効 |
オフ |
オン |
4 |
音響選択 |
音響可変 |
音響固定 |
3-0 |
ボリューム値 |
データ値 |
$4005 (矩形波CH2制御レジスタ2)
矩形波CH2の設定を行います。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7 |
周波数変化 |
固定 |
可変 |
6-4 |
周波数変化速度 |
データ値 |
3 |
周波数の変化方法 |
増加 |
減少 |
2-0 |
周波数範囲値 |
データ値 |
$4006 (矩形波CH2周波数値レジスタ1)
矩形波CH2の再生周波数の設定を行います。
書き込み
位置 |
内容 |
値 |
7-0 |
再生周波数下位8bit |
データ値 |
$4007 (矩形波CH2周波数値レジスタ2)
矩形波CH2の再生周波数と再生時間の設定を行います。
書き込み
位置 |
内容 |
値 |
7-3 |
再生時間 |
データ値 |
2-0 |
再生周波数上位3bit |
データ値 |
$4008 (三角波制御レジスタ)
三角波の設定を行います。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7 |
再生時間カウンタ有効 |
オフ |
オン |
6-0 |
再生時間 |
データ値 |
$400A (三角波周波数値レジスタ1)
三角波の再生周波数の設定を行います。
書き込み
$400B (三角波周波数値レジスタ2)
三角波の再生周波数と再生時間の設定を行います。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7-3 |
再生時間 |
オフ |
オン |
2-0 |
周波数上位3bit |
データ値 |
$400C (ノイズ制御レジスタ)
ノイズの設定を行います。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7-6 |
未使用 |
|
|
5 |
再生カウンタ有効 |
オフ |
オン |
4 |
音響選択 |
音響可変 |
音響固定 |
3-0 |
ボリューム値 |
データ値 |
$400E (ノイズ乱数レジスタ)
ノイズの乱数の設定を行います。
書き込み
位置 |
内容 |
値 |
7 |
乱数のタイプ |
|
6-4 |
未使用 |
|
3-0 |
サンプルレート |
データ値 |
$400F (ノイズ時間レジスタ)
ノイズの再生時間の設定を行います。
書き込み
位置 |
内容 |
値 |
7-3 |
再生時間 |
データ値 |
2-0 |
未使用 |
|
$4010 (DPCM制御レジスタ1)
DPCMのサンプルレートの設定を行います。
書き込み
位置 |
内容 |
値 |
7-4 |
未使用 |
|
3-0 |
サンプルレートビット数 |
データ値 |
$4011 (DPCM制御レジスタ2)
DPCMのボリュームを設定を行います。
書き込み
$4012 (DPCM制御レジスタ3)
DPCMの音声テーブルのアドレス設定を行います。
書き込み
位置 |
内容 |
値 |
7-0 |
テーブルアドレス |
N x $40 + $C000 |
$4013 (DPCM制御レジスタ4)
DPCMの音声テーブルのサイズ設定を行います。
書き込み
位置 |
内容 |
値 |
7-0 |
テーブルバイトサイズ |
N x 16 + 1 |
$4015 (音声チャンネル制御レジスタ)
再生する音声チャンネルを設定します。
書き込み
位置 |
内容 |
クリア時 |
セット時 |
7-5 |
予約 |
|
|
4 |
DPCMチャンネル再生 |
オフ |
オン |
3 |
ノイズチャンネル再生 |
オフ |
オン |
2 |
三角波チャンネル再生 |
オフ |
オン |
1 |
矩形波2チャンネル再生 |
オフ |
オン |
0 |
矩形波1チャンネル再生 |
オフ |
オン |