リズムボックスを作るに辺り、フォーマットは以下の通りにしました。
・4096Hz
・2data/1byte
・データを 16byte 揃えにする
・16byte目のデータの末尾が $00 なら終了と判定する。
・$00 を終了サインとするので、データとしての $00 を $01 に書き換える
次に再生ルーチンを作ります。
といっても、タイマー割り込みで 1/4096 秒毎に再生処理を呼び出すだけです。
各再生処理は以下の通り、チャンネルによって音の出し方が異なります。
| NR12,NR22,NR42 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| V | V | V | V | E | T | T | T |
bit7-4:初期ボリューム
bit3:エンベロープ 増加/減少
bit2-0:エンベロープステップ時間
|
| FF30-FF3F | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| H | H | H | H | L | L | L | L |
16バイトの上下4bitずつ(計32データ)を波形データとして連続再生する
16バイト1ループの再生時間は音程周波数 NR33,NR34に依存する
|
- 矩形波チャンネル(Ch.A/Ch.B)
[rNR10] スイープはオフにする
[rNR11] 波形デューティ比は 75% に設定
[rNR12] エンベロープの向きフラグを上昇にセットしておく(=データと OR $08 を取る)
[rNR13][rNR14] 音程を最高の $07FF に 設定
[rNR12] 音量レジスタに PCM データを流し込む。1 データ書き込む毎に[rNR14]のイニシャルフラグをセット
- 波形メモリチャンネル(Ch.C)
[rNR30] 波形メモリに書き込む際にはオフ、書き込んだ後にはオンにする
[rNR32] 音量最大
[rNR33][rNR34] $0600 : 1データを 1/4096 秒で再生し 32データを再生し終える周波数 65536/(2048-x)=4096/32 から x=1536 (0x0600)
PCMデータは $FF30-$FF3F に 32/4096 秒間隔で書き込み、[rNR34]のイニシャルフラグをセット
- ノイズチャンネル(Ch.D)
[rNR42] エンベロープの向きフラグを上昇にセットしておく(=データと OR $08 を取る)
[rNR43] ノイズ周波数の最適値はエミュレータや実機の種類(GBC,GBASP等々)によっても違う
[rNR44] PCMデータを書き込む毎にイニシャルフラグをセット
[rNR42] 音量レジスタに PCM データを流し込む
で、出来たのがこれ。
pcm.zip (12.6KB) : GameBoy Rhythm Box
推奨エミュレータは KiGB ということにしておきます。TGB だと酷いことに…。
パッドの上下左右、4ボタンでそれぞれ音が鳴ります。
内訳は以下(書いておかないと判別できないくらい音質悪いので)。
- [Up] Hi-Tom : Ch.B
- [Left] Low-Tom : Ch.B
- [Right] Hand Clap : Ch.C
- [Down] Bass Drum : Ch.D
- [A] Cymbal : Ch.A
- [B] Snare Drum : Ch.C
- [Start] Orchestra Hit : Ch.D
- [Select] Cuica : Ch.C
シンバルのような高周波成分のある音は低サンプリングレートには厳しすぎ。
困ったことに実機でも GBC と GBASP でまともに聴けるチャンネルが違ったりします。
共通して鳴るのは やはり波形メモリ音源くらいでしょうか。
エミュレータも種類によって得手不得手が全然違います。
こんな無茶をする市販ソフトが無いために対応していないだけだとは思いますが。
・追記 2009.12.18
で、サンプリングレートを上げたらどうなるか、やってみたのがこちら。
pcm_16K.zip リズムボックス
上のが 4096Hz なのに対し、こちらは 16384Hz。LSDJ よりもレートが高いです。
ch.Dの出音が相変わらずひどいのはさておき、矩形波チャンネルが意外と頑張っています。シンバルとか合格点。
音の終わりが切れるのは元の WAV ファイルが原因です。
16384 Hz だとファイルサイズが巨大になるのと、速度的に組み込んでの常用は難しそうな気がしますが
なかなか可能性を感じさせる結果に。
ch.C 限定のサンプル再生だと再生レート÷ 32 の割り込みで良いのでかなり楽なんですけどねぇ。