DCSGのノイズについて
DCSGを使い倒すには 何か,超クールなアイコンなんですが...それは置いといて. AY-3-8910と同じだろうと思って,すっかりノーマークだったDCSG.実はかなり違うっぽい. DCSGってのは,TIのPSG音源チップSN76489系の総称...だったと思う.あんまり自信が無い.とりあえず,SegaMasterSystem/メガドラ/GameGear辺りの音源と言っておけば,当たり障りは無いと思う. で,AY-3-8910ってのは,一般的にPSG音源と言われている奴で,PC6001/FM7/MSXとかに乗ってたTI製音源チップ.自分は小学生の頃,FM7のPLAY文/SOUND文でDTMに入った人間なので,非常に馴染み深い.
AY-3-8910とSN76489の違い- ノイズチャンネルの独立
- ノイズ周波数を音階で指定可能(後述)
- PeriodicNoiseという名のパルス波が出せる
- エンベロープ無し
- 音量がノンリニア (訂正AY-3-8910もノンリニア)
で,件のエントリでも取り上げているSN76489のノイズチャンネルだけど,すげー面白い仕様になってる.残念ながら資料が少なく,テストもエミュのみで実機を触った事は無いので,合ってるか判らないけど. まず,DCSGのノイズチャンネルではホワイトノイズの他に"PeriodicNoise"という名前のノイズ. というか資料を読む限りDuty比6.25%(or6.67%)の矩形波を出すことができる.コントロールレジスタの4MSB=0xEの場合,bit2でPeriodic/Whiteを選択して,bit1,0で周波数モードを設定する.また,4MSB=0xFの場合,bit3,2,1,0で音量を設定する. また,ホワイトノイズ用擬似乱数は,各チップで微妙に違うみたいで,MAMEソースによると,
- SN76489は,15bitLFSRで14bitと15bitのXORをフィードバック(多分ファミコンと同じ).
- SN76489A/94/96は,16bitLFSRで14bitと16bitのXORをフィードバック.
- MasterSystemIII/メガドラ/GameGearは,16bitLFSRで13bitと16bitのXORをフィードバック.
この内最初の64Bytesはヘッダなので削除,64Byte目の"4F FF"はGameGear対応の決まり文句なので無視.詳細は省略するけど,このデータは通常よりさらにシンプルで,「レジスタ書き込み命令」"50 dd"と「PALで1フレーム進める命令」"62"しか使ってない.66Byte目から読んで行くと"50 87 50 35 50 AA 50 01 . "なのでこれは,レジスタに87 35 AA 01を次々に書き込んでるって事になる.90Byte目に"62"があるのでこのタイミングでシーケンスが1フレーム進む.以下繰り返し. 後はレジスタ値の意味さえ頭に入っていれば,読み進めることができる.オタクちゃんならこれだけで十分なんだけど,ボクハイッパンジンナノデヨクワカリマセン.ので,もうちょっと読みやすくアセンブラ風に書き直す.以下,エディタの正規表現文字列置換だけで作った即席逆アセンブラで変換したもの.命令は"(t[1-3]|nz)f"で,矩形波1-3ch及びノイズchの周波数設定,"(t[1-3]|nz)a"で各チャンネルの音量設定,"wait"で1フレーム進める.
t1f 0x7 35 t2f 0xA 01 t3f 0xA 06 nzf 0x4 t1a 0x0 t2a 0x9 t3a 0xF nza 0x4 nzf 0x3 wait t1f 0x9 38 t1a 0x7 t2a 0xA nza 0x1 wait t2a 0xB nza 0x2 wait t1f 0xF 3B t2a 0xC nza 0x3 wait t2a 0xD nza 0x4 . t3f 0xA 06 nzf 0x4 t3a 0xF nza 0x4 nzf 0x3 wait nza 0x1 wait nza 0x2 wait nza 0x3 wait nza 0x4 wait nza 0x5 wait nza 0x6 wait t3f 0x5 03 nzf 0x4 nza 0x5 wait .5行目"wait"から16行目"nza 0x6"までを見ると,1フレごとに音量を1下げてる(nza値↑で音量↓)ので,単なる減衰エンベロープだとわかる.ので,減衰エンベロープは省略して,これらは"release 6"とまとめる事にする.これで"release"が登場するまでが1音って事になるのでそこで区切って記述する.ついでに1音内のレジスタ値の意味についてコメントも付けておく.
t3f 0xA 06 // set 3ch freqency (base pitch = 0xA06) nzf 0x4 // . t3a 0xF // set 3ch volume minimum nza 0x4 // set volume 4 nzf 0x3 // set periodic noise andfreq.sync with 3ch (base tone) release 7 t3f 0x5 03 // set 3ch freqency (base pitch = 0x503) nzf 0x4 // set white noise with fixed highest freq. nza 0x5 // set volume 5 wait // wait 20 msec nzf 0x3 // set periodic noise and freq.sync with 3ch (base tone) nza 0x1 // set volume 1 release 6 t3f 0xA 06 // set 3ch freqency (base pitch = 0xA06) nzf 0x4 // set white noise with fixed highest freq. nza 0x4 // set volume 4 wait // wait 20 msec nzf 0x3 // set periodic noise and freq.sync with 3ch (base tone) nza 0x1 // set volume 1 release 6 nzf 0x4 // set white noise with fixed highest freq. nza 0x5 // set volume 5 wait // wait 20 msec nzf 0x3 // set periodic noise and freq.sync with 3ch (base tone) nza 0x1 // set volume 1 release 6 t3f 0x7 07 // set 3ch freqency (base pitch = 0x707) nzf 0x5 // set white noise with fixed middle freq. nza 0x1 // set volume 1 wait // wait 20 msec nzf 0x4 // set white noise with fixed highest freq. release 6 // (This note has no pitch.->Snare note) nzf 0x4 // set white noise with fixed highest freq. nza 0x5 // set volume 5 wait // wait 20 msec nzf 0x3 // set periodic noise and freq.sync with 3ch (base tone) nza 0x1 // set volume 1 release 6 t3f 0xA 06 // set 3ch freqency (base pitch = 0xA06) nzf 0x4 // set white noise with fixed highest freq. nza 0x4 // set volume 4 wait // wait 20 msec nzf 0x3 // set periodic noise and freq.sync with 3ch (base tone) nza 0x1 // set volume 1 release 6 .以上が,ノイズチャンネルと3番チャンネルのシーケンス. 簡単に説明すると,3行目で3chの音量をオフにして,以降3chの周波数(t3f ddd)を使ってperiodic noiseの周波数をコントロールしている(nzf 0x3).また各音の最初20msec(1フレーム)だけホワイトノイズを鳴らす事でアタックを表現している(nzf 0x4).31行目から36行目の音はホワイトノイズのみで3chの周波数を参照していないので,スネア音を表現しているって事になる.
OPMエミュでDCSGのコンセプトを表現するために必要な拡張- PeriodicNoiseの再現
- ノイズチャンネルの周波数指定
- ノンリニアな音量
プログラム技術関連ブログ 最近は Shader Art が好き