Last Update 08/02/08

音楽・効果音関係(間違ってたらゴメンナサイ)


サウンドバンク(NESヘッダ$10バイトを含む)
ロックマン3 : BANK16,17,18($2C010〜$3100F, BANK18は前半部分のみ)
ロックマン4 : BANK1E,1F,1D($3C010〜$4000F, $3A010〜$3C00F, 順序に注意)
ロックマン5 : BANK18,19,1A($30010〜$3600F)
ロックマン6 : BANK34,35,36($68010〜$6E00F)

以下,サウンドバンクの先頭からのオフセット
$A40 トラック数
$A41〜A42 モジュレーション定義の先頭アドレス(ビッグエンディアン)
$A43〜 各トラックの開始アドレス、1トラックあたり2バイト(ビッグエンディアン)

ROM内でのアドレス = サウンドバンク先頭アドレス + (トラックの開始アドレス - $8000)(ロックマン4を除く)




音楽トラック
00で始まり、SQ1,SQ2,TRI,NOIの先頭アドレス(それぞれ2バイト,ビッグエンディアン)が続く。


◆音符データ
ほぼロックマン2と同じ(Y0に20が追加されている)
Y0(20,40,60,80,A0,C0,E0) + XX(00〜1F)
Yで音符の長さ(20 -> 40 -> 60 -> … の順に2倍ずつ長くなる)
XXで音の高さ。
XX=00で休符。
0A,0B命令で変更しなければXX = 01がド, 02がド#, 03がレ,…(でいいと思う)
(ノイズはXX=01〜10でノイズの種類(00で休符), 値によって出る音がロックマン2とは逆?)

・音長カウンタ(次の音符までの時間)に入る値

音符の長さ  20 40 60 80 A0 C0 E0
---------------------------------
00命令時    02 04 08 10 20 40 80 (テーブル)
通常時      03 06 0C 18 30 60 C0 (テーブル)
02命令時    04 09 12 24 48 90 20 (通常時 + (通常時 >> 1) の値が入る。1byteで管理しているため長さE0を1.5倍すると20になってしまう)


・音長カウンタ(音を鳴らす時間)に入る値

音長カウンタ(次の音符までの時間)の値 * 歯切れの良さ(06命令で指定)の値 / 256
ただし、結果が0になった場合は01が入る。


・1フレーム毎の音長カウンタの減少値

(テンポの値 + 前フレームまで加算してきたテンポの合計(下位8bit)) / 256

例えば、テンポの値(05命令で指定)が$0140ならば、
$0140 + $00 = $0140 -> 下位8bit=$40, 音長カウンタから引く値=1 
$0140 + $40 = $0180 ->          $80,                        1
$0140 + $80 = $01C0 ->          $C0,                        1
$0140 + $C0 = $0200 ->          $00,                        2
$0140 + $00 = $0140 ->          $40,                        1 
 ・
 ・
 ・
のようになる。
音長カウンタ(音を鳴らす時間)が0以下になると、音のフェードアウトが始まる。
音長カウンタ(次の音符までの時間)が0以下になると、次の音符の処理を行う。


◆命令表
00 … 00〜00の範囲の音の長さを少し短くする(2/3) (トグル)(*)
01 … 01〜01の範囲(とその次の音)をタイでつなぐ?(例えば、01 A1 01 A1なら2個のA1がつながれる) (トグル)(*)
02 … 次の音の長さを1.5倍にする
03 … 03〜03の範囲を2オクターブ上げる (トグル)(*)

04 XX ジャンプ命令の飛び先にやたらに置かれている(トグル命令をまたいでジャンプしなければ置かなくても実害無し?)
   +08 -> 03命令を開始・継続する効果(加算しなければ03命令を終了)
   +20 -> 00命令を開始・継続する効果(加算しなければ00命令を終了)
   +40 -> 01命令を開始・継続する効果(加算しなければ01命令を終了)
   XX = 00で全トグル命令終了

(*)トグル命令00,01,03は、実行の度に効果のON・OFFが切り替わる。
   04命令は各トグル命令のON・OFFを強制的に設定できる。

05 XX YY … 全体のテンポの設定(ビッグエンディアン, 大きい程速い。SQ1に置く)
06 XX … 歯切れのよさ(クオンタイズ?)
07 XX … チャンネルの最大音量(TRIは設定不可)
08 XX … モジュレーション定義読み込み(読み込まないと音が出ないので全チャンネル必須)
09 XX … オクターブ指定(00〜07)
0A XX … トラックの基本となるキーの高さ(符号付き1バイト整数, SQ1に置く)
0B XX … そのチャンネルの基本となるキーの高さ(符号付き1バイト整数)
0C XX … ピッチの調節(符号付き1バイト整数, 負数だと高くなり、正数だと低くなる)
0D XX … 直前の音の高さから今鳴らすべき音の高さの方向にピッチが変わっていく?(ピッチベンド?00で無効)

0E ZZ XX YY … アドレスXXYYへジャンプ(ZZ回ループ、0だとループしない)(*)
0F ZZ XX YY … 〃
10 ZZ XX YY … 〃
11 ZZ XX YY … 〃

(*)参照するループカウンタが各チャンネル・命令毎に異なるので、多重ループを実現できる。

12 ZZ XX YY … 命令0Eのループカウンタが1になっていればアドレスXXYYへジャンプ(ジャンプの際に命令"04 ZZ"を実行し、トグル命令のON・OFFを設定する)(*)
13 ZZ XX YY … 〃  0F
14 ZZ XX YY … 〃  10
15 ZZ XX YY … 〃  11
16 XX YY … アドレスXXYYへジャンプ(主に曲の無限ループに使われている)  
17 … 終了命令(チャンネル毎に置き忘れないように)
18 XX … 音色指定(00,40,80,C0) (ロックマン2と違いこの命令でノイズの指定はできない?ノイズの音色はモジュレーション定義で指定)

(*)命令0E〜11のジャンプ条件が満たされない場合にジャンプする。
  例えば、

L1:
 ・
 ・
 ・
0E 03 L1

  の場合、命令0Eでのジャンプは3回となり、ラベルL1〜命令0E間は計4回繰り返されることになる。
  ここで、命令12を途中に挟むと、

L1:
 ・
 ・
12 00 L2
 ・
 ・
0E 03 L1
L2:

  4回目の繰り返しの途中で命令12を通った時に、ラベルL2にジャンプすることになる。



◆モジュレーション定義(なんかモジュレーション以外もいろいろ定義してる気がしますが)
8バイトで1個のデータ

byte0 … 音のフェードインの速さ(1Fで最初から最大)(00〜1F)
byte1 … 最大音量になった後、最小音量に向かう速さ(ただし、00を指定すると即座に最小音量になる)(00〜1F)
byte2 … 最小音量(X0の形)(0〜F)
byte3 … 音のフェードアウトの速さ(音長カウンタ(音を鳴らす時間)が0以下になった時がフェードアウト開始。1Fで即座に音量0まで下がる)(00〜1F)


byte4 … ピッチ・音量の変化の速さ(大きい程単位時間当たりの変位回数が増える)
         bit7   -> 1音毎に変化周期カウンタをリセットするか
         bit6-0 -> 変化周期カウンタに加算する値

byte5 … ピッチの最大変位(00〜7F)
byte6 … 音量の最大変位(00〜7F)

byte7 … ノイズの音色指定(00 or 80)


効果音
先頭バイトは効果音上書き優先順位。
それ以降は、
[制御命令] [使用するチャンネル分だけ出力命令] [制御命令] … と続く。


◆制御命令

00 XX YY … XX -> 次の音までの時間
            YY -> 使用チャンネル(+01 -> 矩形波1 +02 -> 矩形波2 +04 -> 三角波 +08 -> ノイズ)

01 ZZ XX YY WW VV … $XXYYにジャンプ(ZZ回繰り返し,ZZ=$00なら無限回。その後,制御命令"00 WW VV"を実行)

02 XX YY ZZ … XX -> 歯切れの良さ(クオンタイズ?)
               YY -> 次の音までの時間
               ZZ -> 使用チャンネル(+01 -> 矩形波1 +02 -> 矩形波2 +04 -> 三角波 +08 -> ノイズ)

03 ZZ XX YY WW VV UU … $XXYYにジャンプ(ZZ回繰り返し,ZZ=$00なら無限回。その後,制御命令"02 WW VV UU"を実行)

06 XX YY ZZ WW … XX -> 歯切れの良さ
                  YY -> 全トラックの基本となるキーの高さ
                  ZZ -> 次の音までの時間
                  WW -> 使用チャンネル(+01 -> 矩形波1 +02 -> 矩形波2 +04 -> 三角波 +08 -> ノイズ)

FF … 終了


◆出力命令
[オペランドの指定(1バイト)] [オペランド(可変長)] [音の高さ(1バイト)]の構成。

オペランドの指定
000X XXXX
   | ||||
   | |||+--- モジュレーション定義呼び出し(音楽トラックと同じ)
   | ||+---- 音色指定(00,40,80,C0)
   | |+----- 音量(00〜0F)
   | +------ ピッチエンベロープ(最上位bitが符号で下位7bitは絶対値?負数だと高くなり、正数だと低くなる)
   +-------- ピッチ調節

オペランドの並び順は下位bitのものから。設定し直す必要のない項目は省略可能。
音の高さは80〜FFを指定することで新しく値を設定し直さない(前の音の終わりの状態を引き継ぐ)。

------------------------------------------------------
過去の痕跡

00 XX … XX -> 音の高さ

01 XX YY … XX -> モジュレーション定義呼び出し
            YY -> 音の高さ

02 XX YY

03 ????? (未使用)

04 XX YY … XX -> 音量
            YY -> 音の高さ

05 XX YY ZZ … XX -> モジュレーション定義呼び出し
               YY -> 音量
               ZZ -> 音の高さ

06 XX YY ZZ
07 XX YY ZZ WW

08 XX YY … XX -> ピッチエンベロープ
            YY -> 音の高さ

09 XX YY ZZ

0A ????? (未使用)

0B XX YY ZZ WW

0C XX YY ZZ

0D XX YY ZZ WW … XX -> モジュレーション定義呼び出し
                  YY -> 音量
                  ZZ -> ピッチエンベロープ?
                  WW -> 音の高さ

0E ????? (未使用)
0F XX YY ZZ WW VV … XX -> モジュレーション定義呼び出し
                     YY -> 音色指定($00,$40,$80,$C0)
                     ZZ -> 音量($00〜$0F?)
                     WW -> ピッチエンベロープ?正の値なら音が低くなり負の値なら高くなる(00で変化なし)
                     VV -> 音の高さ

10 XX YY
11 ?????? (未使用)
12 ?????? (未使用)
13 ?????? (未使用)
14 XX YY ZZ
15 XX YY ZZ WW
16 ?????? (未使用)
17 XX YY ZZ WW VV
18 XX YY ZZ
19 XX YY ZZ WW
1A ?????? (未使用)
1B ?????? (未使用)
1C ?????? (未使用)
1D XX YY ZZ WW VV
1E ??????
1F XX YY ZZ WW VV UU … XX -> モジュレーション定義呼び出し
                        YY -> 音色指定
                        ZZ -> 音量
                        WW -> ピッチエンベロープ
                        VV -> ピッチ
                        UU -> 音の高さ

------------------------------------------------------



資料作成にあたって、ゲイムのお部屋さまの音楽関係資料が大変参考になりました。
貴重な資料の公開に感謝します。