第12章 サウンドその1


カスタムPSG

 サウンドの説明に入ります。しかし!私はサウンド全般についての知識・センスがさっぱりなのです(グラフィックのセンスもありませんが・・・)。 他のサイトをいろいろ調べてみてると、自作の音源ドライバが存在し、多くの人がファミコン音源で作曲をしていることがわかります。サウンドを追求したい人は調べてみてください。 ここでは私が知りたいレベルの話にとどまります。

 ファミコンの音源はPSG(Programmable Sound Generator)を拡張したもので、 矩形波2チャンネル、三角波1チャンネル、ノイズ1チャンネル、デルタ波があります。

 それぞれを有効にするためには、まず最初に$4015のサウンドレジスタにビットフラグを設定します。 ビット0が矩形波チャンネル1、ビット1が矩形波チャンネル2、ビット2が三角波チャンネル、ビット3がノイズとなっています。 このレジスタは読み取りも可能なので、以下のようにOR演算で設定して同時に音を鳴らすと良いでしょう。


	lda $4015		; サウンドレジスタ
	ora #%00000001	; 矩形波チャンネル1を有効にする
	sta $4015

矩形派チャンネル

 矩形波とは、のような形をした波です。まずは矩形波チャンネル1レジスタを見て行きましょう。このレジスタで、 音の減衰を設定します。

	lda #%10111111	; Duty比長さ無効減衰無効減衰率
	sta $4000	; 矩形波チャンネル1制御レジスタ1

 左から順にビット7~0という前提で説明します。ビット7~6はDuty比といって、の高い部分と低い部分の比率です。 2進の10でちょうど半々になります。ビット5は、1ならば鳴り続け、0ならば後で設定した時間($4003で設定する)の間鳴り続けます。 ビット4は1ならば音の減衰が無く、0ならばビット0〜ビット3で指定する0000~1111の数の大きさに比例して減衰します。

 次のレジスタでは、スイープ(音の変化)を設定します。


	lda #%10101011	; スイープ有効変化率方向変化量
	sta $4001	; 矩形波チャンネル1制御レジスタ2

 ビット7を1にするとスイープが有効になります。0だと同じ音程で鳴り続けます。ビット6~4は変化の速さを000~111の数で設定します。 数が大きいほど遅く、小さいほど速くなります。ビット3はスイープの方向で、1ならば尻上がり、0ならば尻下がりな音になります。 ビット2~0は変化する量の大きさです。大きくすると長い音、小さくすると短い音のような感じです。000にすると変化しなくなるので注意。

 次は音の出だしの周波数を設定します。つまり音階です。


	lda #%00000100	; 周波数(下位8ビット)
	sta $4002	; 矩形波チャンネル1周波数レジスタ1
	lda #%11111011	; 再生時間周波数(上位3ビット)
	sta $4003	; 矩形波チャンネル1周波数レジスタ2

 値が小さいほど高音、大きいほど低音になります。ただし、周波数は$4002の下位8ビットと、$4003のビット2~0が上位3ビットで表します。 上の例だと、%01100000100になります。つまり$4002の値だけを変えても音階は微妙に変わるだけで、 $4003の下位3ビットが音階に大きな影響があるということになります。ちなみに$4003のビット7~3は再生時間で、$4000の5ビット目を0にした場合に有効になります。 このように$4015のサウンドレジスタと、矩形波チャンネルの4つのレジスタを設定すれば、矩形波音を鳴らすことができます。

 さらに矩形波チャンネル2が存在し、そのレジスタは$4004~$4007です。機能的にはチャンネル1と全く同じで、対応は以下の通りです。

	$4000→$4004
	$4001→$4005
	$4002→$4006
	$4003→$4007
 以下のようにすれば、チャンネル2を他の音と同時に鳴らすことが出来ます。

	lda $4015	; サウンドレジスタ
	ora #%00000010	; 矩形波チャンネル2を有効にする
	sta $4015

サウンドプログラム

 これをダウンロードして、nesasm giko012.asmしてください。ラベルAKEYSoundとBKEYSoundなどが追加された部分です。Aボタンで上昇音(?)、Bボタンで下降音が鳴ります。 座標によって音が微妙に変わるようになっています。このソースで注意する点は、以下の部分です

setSprite2:
	; 2番目のスプライトの座標更新サブルーチン
	clc		; adcの前にキャリーフラグをクリア
	lda Sprite1_X
	adc #8 		; 8ドット右にずらす
	sta Sprite2_X
	lda Sprite1_Y
	sta Sprite2_Y
	rts
 ファミコンの6502はadcでAレジスタに値を加算するときに、ステータスレジスタの キャリーフラグの1も加算します。ここではその必要が無いので、クリアしています。

 次の章は三角波、ノイズを調べる予定です。


トップページ 前のページ 次のページ
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送