SNES Capcom Music Format Spec

Abstruct: this article explains the outline of the structure of SNES Capcom Seq.

カプコンの音楽データ形式について文書形式でまとめておきます。主な調査対象として扱われたのはMega Man Xですが、さらに古いSuper Ghouls 'n Ghostsなども、たいした違いはなさそうです。

Structure / 構造


; song pointer
ff00: dw $b000
; starting point for each track (8ch,7ch,6ch,...)
b000: dw $c000,$c100,$c200,$c300,$c400,$c500,$c600,$c700
; sequence data / 8ch
c000: ; voice cmds to playback...
  • Capcom Seq uses big-endian order / バイトオーダーはビッグエンディアンなので注意
  • The most important channel is 8ch, it should be processed first / 図の通り、最重要チャンネルは8chで、最初に処理されます。

どんな形で演奏データが表現されるのか、アセンブリで擬似的に示してみました。上記の特徴を除けば、ごくありふれた構造かと思います。曲はどこかに一覧で並んでいるような感じですが、新しいものと古いものでは若干違うようにも見えます。音楽と効果音の区別がどの程度あるのかなど、このあたりに関してはよく調べていません。

Voice Bytes / 演奏データ

Mapping
  • ($00) Toggle Triplet
  • ($01) Toggle Portamento
  • ($02) Set Dot(ted Note)
  • ($03) Toggle 2-Octave Up
  • ($04) Set Triplet/Portamento/2-OctUp Directly [xx]
  • ($05) Tempo [xx yy]
  • ($06) Duration Rate [xx]
  • ($07) Volume [xx]
  • ($08) Instrument [xx]
  • ($09) Octave Correction [xx]
  • ($0a) Global Transpose [xx]
  • ($0b) Per-Voice Transpose [xx]
  • ($0c) Tuning [xx]
  • ($0d) Portamento Time [xx]
  • ($0e-11) Loop #1-4 [xx yy zz]
  • ($12-15) Loop Break #1-4 [xx yy zz]
  • ($16) Jump [xx yy]
  • ($17) End of Track
  • ($18) Pan [xx]
  • ($19) Master Volume [xx]
  • ($1a) LFO Parameter [xx yy]
  • ($1b) Echo Param [xx yy]
  • ($1c) Echo On/Off [xx]
  • ($1d) Release Rate [xx]
  • ($1e) (Unknown) [xx]
  • ($1f) (Unknown) [xx]
  • ($20-ff) Note

"($vbyte) Name [arguments] Description..."

($20-ff) Note
  • vbyte itself means the length and key of the note.
    • higher 3-bit is for duration (see the duration table below, also, see $00 and $02 for triplet and dotted note).
    • lower 5-bit is for key, means "rest" when it's 0b00000 (to calc actual key for note, see also $03 and $09).
      • key = lower5bit + ($03_octUpFlag ? 24 : 0) + ($09_octaveCorrection * 12) + $0a_globalTranspose + $0b_voiceTranspose;
  • "dotted note" flag is cleared after it's processed.
  • there's no event just for tie, use portamento vcmd $01 for it.
  • see also $06 for quantize.
1(l64) 2(l32) 3(l16) 4(l8) 5(l4) 6(l2) 7(l1)
normal 3 6 12 24 48 96 192
dotted 0 9 18 36 72 144 0
triplet 2 4 8 10 20 40 80

コマンドバイト自身で音の長さと高さを表します。わかれば綺麗なのですが、知らない人にはちょっと説明のめんどくさいところがあります。ロックマン2の音楽データと似たようなところもあるので、そちらも見るとよいかもしれません。

音の長さは上位3ビットで表します。0b000のときはコマンドなので、音符に用いられるのは1〜7の値です。上の表にあるとおり、7が全音符、6が2分音符……1が64分音符です。音符以前に$02コマンドが出現している場合は、付点つきになります(その音符が処理された時点で付点フラグは解除される)。同様に$00で3連符です(こちらは処理後のフラグ解除なし)。その両方が指定される場合は、付点を優先して処理します(おそらくそんなデータは作るべきでないですが)。スタッカートなどのクオンタイズは$06で指定します。

音の高さは下位5ビットで表します。半音ずつ上がる0〜31の値で、0のときは休符です。これに$03の2オクターブ補正と、$09のオクターブ補正(とトランスポーズ)を加えたものが、実際の音程になります。

なお、タイ専用のコマンドは用意されておらず、$01のポルタメントコマンドを使って表現することになっています。

($00) Toggle Triplet

3連符使用フラグを反転します。Note参照。

($01) Toggle Portamento

ポルタメント使用フラグを反転します。ポルタメントがonのときに発音された音は発音停止処理をおこないません。また、後続の音は再発音を伴わないピッチ変化のみで鳴らされます。同音間で使用することでタイを表現します。

($02) Set Dot(ted Note)

付点フラグをonにします(反転ではない)。Note参照。

($03) Toggle 2-Octave Up

2オクターブ上昇フラグを反転します。Note参照。

($04) Set Triplet/Portamento/2-OctUp Directly [xx]
  • xx
    • |= $08 - 2-octave up (vcmd $03)
    • |= $20 - triplet (vcmd $00)
    • |= $40 - portamento (vcmd $01)

上記のフラグを一度に設定します。それ以外のビットフラグはマスクされるので反映されないはずです。

($05) Tempo [xx yy]
  • bpm = $xxyy * 60000000 / 196608000 ?
    • 196608000 = (timer0) 8ms * 48 * 512 (just a guess)

曲の演奏速度を設定します。値は2バイト値で指定されます。計算式はおおよそ上記のとおりと思われます。

($06) Duration Rate [xx]
  • xx/256 = duration rate

クオンタイズ設定です。少ない値にするほど発音時間が短くなります。

($07) Volume [xx]

チャンネルの音量を設定します。

($08) Instrument [xx]

奏音色を設定します。

($09) Octave Correction [xx]
  • xx should be $00-07

オクターブ補正です。Note参照。値は0〜7の範囲にとどめるべきかと思います。

($0a) Global Transpose [xx]
  • xx = semitones (signed)

全チャンネルの演奏音程をxx上げます(負数も指定可)。

($0b) Per-Voice Transpose [xx]
  • xx = semitones (signed)

単一チャンネルの演奏音程をxx上げます(負数も指定可)。

($0c) Tuning [xx]
  • xx = signed, make the pitch xx/128 semitones? higher.

音程をわずかに変化させます。たぶん128で半音相当です(負数も指定可)。

($0d) Portamento Time [xx]

ポルタメントにかける時間を指定します。単位は明確ではないですが、値が大きいほど音程変化がゆっくりになります。

($0e,$0f,$10,$11) Loop #1-4 [xx yy zz], ($12,$13,$14,$15) Loop Break #1-4 [xx yy zz]
  • xx = count, yyzz = destination address.
  • "Loop" = "jump (loop), for xx times". "Loop Break" = "jump (break), if it's the last time of the loop".
  • Loop #1 and Loop Break #1 share the repeat count. #2, #3, #4 as well.

繰り返しのための命令です。一方は指定回数までジャンプさせるコマンド、一方はループ最終時のみジャンプさせるコマンドです。4種類用意されているのはそれぞれカウンタが独立しているという意味です(チャンネルごと独立ではない)。演奏データを作成しようと思うと一癖ある仕様ですね。

($16) Jump [xx yy]

無条件ジャンプです。主に楽曲のループに用いられます。

($17) End of Track

単一チャンネルの演奏データ終了を意味します。

($18) Pan [xx]
  • xx (signed)

音の左右位置を設定します。負数が左、0が中央、正数が右です。

($19) Master Volume [xx]

楽曲全体の演奏音量を指定します。

($1a) LFO Parameter [xx yy]
  • xx = type, yy = value.
Type Description
$00 Vibrato Depth (pitch modulation)
$01 Tremolo Depth (volume modulation)
$02 LFO Speed
$03 Reset LFO Per Note (non zero = yes, zero = no)

LFOの設定をします。ビブラートやトレモロをかけるのに使います。

$03でのフラグ設定は、たとえばロックマンXのシグマ前の音楽で使われています(遅いトレモロをノート独立でなくかけることで、クレッシェンドとデクレシェンドを繰り返す演奏をおこなう)。

($1b) Echo Param [xx yy]
  • xx = ignored?
  • yy = preset #

主にエコーの設定をします。プリセット番号を指定することで、MVOL、EVOL、ESA、EDL、EFB、FIRが設定されます。とくに指定しない場合、前に演奏されていた曲の状態を引き継ぐように思います。ロックマンXでは本編の音楽にこのコマンドはなく、最初のカプコンのロゴでのみこのコマンドが出現しています。

($1c) Echo On/Off [xx]
  • xx = non zero for echo on, zero for echo off (just works for current channel).

単一チャンネルのエコーの有無を指定します。

($1d) Release Rate [xx]
  • xx = $00-$1f (GAIN exponential decrease parameter)

発音時間終了後の音の減衰率を指定します。値が小さいほど音が持続します。

($1e) (Unknown) [xx]
  • do nothing in Mega Man X, it doesn't in Super Ghouls 'n Ghosts.

ゲームによっては無意味なコマンドですが、ゲームによってはコードがあるようです。ただし、滅多に使われていないように見えます。

($1f) (Unknown) [xx]
  • do nothing in Mega Man X, it doesn't in Super Ghouls 'n Ghosts.

ゲームによっては無意味なコマンドですが、ゲームによってはコードがあるようです。ただし、滅多に使われていないように見えます。