シーケンスデータの構造
スーパードンキーコング2・3 および、Diddy’s Kong Quest, Dixie Kong’s Double Trouble で使用されているRareWare Sound Driver のシーケンスデータの構造について説明します。
APU RAM上の各変数のアドレスについては APU RAMマップ を参照してください。
表記
このマニュアルでは、コマンドの構文を次のように表記します。
0x02, sbyte left, sbyte right
先頭がコマンドのバイト値、続いてパラメータの型と名前をデータ中の順に並べています。型は byte(符号なし8ビット)、sbyte(符号付き8ビット)、ushort(符号なし16ビット、リトルエンディアン)です。ただし、ノートの長さを16ビットで指定する場合のみビッグエンディアンになります。
アドレスはすべてAPU RAM上の絶対アドレスで、シーケンスデータ内のオフセットではありません。
シーケンスデータの配置
シーケンスデータは APU RAM の $1300 から配置されます。
ヘッダ
シーケンスデータの先頭には、曲のヘッダが置かれています。
| オフセット | 型 | 内容 |
|---|---|---|
| +$00 | ushort[8] | 各BGMチャネル(0~7)のシーケンスの開始アドレス |
| +$10 | byte | テンポの初期値 |
| +$11 | byte | SEテンポの初期値 |
| +$12 | ushort[] | 曲のヘッダのアドレスのテーブル(CPUコマンド $83 で、引数を添字として次に再生する曲を選ぶ) |
曲の初期化時には8チャネルすべてが動作を開始します。使用しないチャネルも、コマンド 0x00 だけのシーケンスなど、有効なシーケンスを指している必要があります。
SE
SEは、SE番号 $00~$5F が SEデータ領域($2410)、$60~$7F が追加SEデータ領域($2E94)のテーブルから読み出されます。
| オフセット | 型 | 内容 |
|---|---|---|
| +$00 | byte | テーブルに登録されているSEの数 |
| +$02 | ushort[] | 各SEのシーケンスの開始アドレス(追加SEデータ領域ではSE番号 − $60 を添字とする) |
登録数以上の番号を指定した場合は、SE番号 $00 として扱われます。
SEは、CPUからの指示で指定したBGMチャネル n に対応するSEチャネル n+8 で再生されます。SEのシーケンスはBGMと同じ形式で、同じコマンドを使用できます。
SEの開始時、SEチャネルの音量は左右とも $7F、ADSRは ADSR1 = $8E, ADSR2 = $E0に初期化されます。SEの再生中、BGMチャネル n はシーケンスの処理だけを続け、DSPへの書き込みを行いません。
イベント
シーケンスはイベントの並びです。イベントの1バイト目で種類が決まります。
| 1バイト目 | 種類 |
|---|---|
| 0x00~0x32 | コマンド。パラメータの数はコマンドごとに決まっている |
| 0x80 | 休符 |
| 0x81~0xFF | ノート |
コマンドは処理に時間がかからず、続くイベントが同じティックのうちに読み込まれます。時間が進むのはノートイベントと休符イベントだけです。そのため、ノートや休符を含まない無限ループを作るとドライバが停止します。
0x33~0x7F および未定義のコマンドを実行すると、コマンド処理テーブルの範囲外または不正なアドレスへジャンプし、ドライバが暴走します。
ノートの長さ
ノートイベントと休符イベントの長さはティック単位で指定します。長さの指定方法には次の3つのモードがあり、チャネルごとに切り替えます。
| モード | 長さの指定 | 切り替えコマンド |
|---|---|---|
| 通常 | 各イベントに1バイト | - |
| デフォルト・デュレーション | 各イベントでは指定せず、コマンド 0x06 で設定した長さを使用 | 0x06, 0x07 |
| 16ビット・デュレーション | 各イベントに2バイト(ビッグエンディアン) | 0x2B, 0x2C |
デフォルト・デュレーション・モードと16ビット・デュレーション・モードを同時に有効にした場合は、コマンド 0x06 の引数が2バイトになり、各イベントでは長さを指定しません。
以下は、同じ内容を3つのモードで記述した例です。
// 通常
A5 10 A7 08 A9 08 AA 08 B1 10 00
// デフォルト・デュレーション
A5 10 06 08 A7 A9 AA 07 B1 10 00
// 16ビット・デュレーション
2B A5 00 10 A7 00 08 A9 00 08 AA 00 08 B1 00 10 00
テンポとティック
ドライバはタイマー0の周期で動作します。タイマー0の分周値は 100(80Hz、12.5ms周期)固定です。
タイマー周期ごとにBGMとSEのテンポ加算器にそれぞれのテンポを8ビットで加算し、桁あふれが起きた側のシーケンスを1ティック進めます。
したがって、1秒あたりのティック数は 80 × テンポ ÷ 256 です。たとえば四分音符を16ティックとした場合、テンポ(BPM)は 約 1.17 × テンポ になります。
エフェクトの時間単位
ピッチベンド、ビブラートの時間(ディレイや間隔)は、テンポではなくタイマー周期を単位として数えられます。そのため、テンポを変えてもエフェクトの速さは変わりません。
サブルーチン
コマンド 0x04、0x21 でサブルーチンを呼び出し、コマンド 0x05 で戻ります。コール・スタックはチャネルごとに8段で、深さの確認は行われません。
曲のループには コマンド 0x03 を使用します。
処理の流れ
タイマー周期ごとに、BGMチャネル0~7について次の処理を行います。
- BGMのティックが発生した場合は、残りティック数を1減らし、0になればイベントを読み込む。コマンドは続けて読み込み、ノートイベントか休符イベントで止まる。
- エフェクト(ピッチベンド、ビブラート)を処理する。
- 対応するSEチャネルでSEが再生中であれば、SEのティックについて同じ処理を行う。