11 March 2016 - Forum Rules

Main Menu

Keep the Balance (GBC) music research

Started by DevEd, February 24, 2017, 11:32:00 AM

Previous topic - Next topic


So lately I've been researching the music format in Keep the Balance. Here's what I have so far:

Sound bank locations:
$28000 (Title screen)
$2C000 (Credits theme)
$44000 (In-game 1)
$48000 (In-game 2)
$4C000 (In-game 3)
$50000 (In-game 4)
$54000 (In-game 5)

NOTE: All addresses listed are relative to start of sound bank.

$0000: Length of pattern table
$0001-$0002: ??? ($0001 doesn't seem to affect anything, $0002 causes the song to glitch up if set to anything other than $07)
$0003: Timer divider (usually set to $05)
$0004: Song speed
$0005-[value of $0000]: Pattern table
[end of pattern table]-[end of pattern table + $11]: Unknown (Pointer table of some sort? Values seem to be the same across all sound banks)
[end of unknown area]-[end of unknown area + $10]: CH3 waveform (same for all songs but can be modified)
[end of waveform]-[variable]: Song data (see below for format)
[end of song data]-[variable]: SFX data (TODO: Document this!)

Song data consists of many rows. Each row consists of $16 bytes, layed out in a tracker-style format. This is further divided into columns, which defines the note to play for each channel in order for that particular row.
Example row (taken from title screen music):
1A 80 04 00 | 24 50 03 00 | 18 00 07 00 | 3D 50 05 00

For CH1 and CH2:
Byte 1 = Note (see note table below)
Byte 2 = Volume (first nybble)*, Delay (second nybble)
Byte 3 = Command (first nybble) / Pulse width (second nybble)**
Byte 4 = Command parameters

For CH3:
Byte 1 = Note
Byte 2 = Volume (first nybble), Delay (second nybble)
Byte 3 = Command (first nybble) / Unknown (second nybble, must be 7 or no sound will play!)
Byte 4 = Command parameters

For CH4:
Byte 1 = Noise type
Byte 2 = Volume (first nybble), Delay (second nybble)
Byte 3 = Command (first nybble) / Unknown (second nybble) (must be 05 if no other command is used otherwise no sound will play!)
Byte 4 = Command parameters

* If volume is 0 and delay is zero, engine assumes max volume. If volume is zero and delay is some other value, engine assumes delayed note cut (?)
** 1 = 12.5%, 2 = 25%, 3 = 50% (square), 4 = 75% (sounds like 25%)

Command list seems to be mostly the same as the .XM format, with a few exceptions.
TODO: Finish figuring out which XM commands work and which don't.
0 = Arpeggio
1 = Note slide up
2 = Note slide down
3 = ???
4 = ??? (Vibrato?)
A = Volume slide
D = Pattern break

01=C-2 02=C#2 03=D-2 04=D#2 05=E-2 06=F-2 07=F#2 08=G-2 09=G#2 0A=A-2 0B=A#2 0C=B-2
0D=C-3 0E=C#3 0F=D-3 10=D#3 11=E-3 12=F-3 13=F#3 14=G-3 15=G#3 16=A-3 17=A#3 18=B-3
19=C-4 1A=C#4 1B=D-4 1C=D#4 1D=E-4 1E=F-4 1F=F#4 20=G-4 21=G#4 22=A-4 23=A#4 24=B-4
25=C-5 26=C#5 27=D-5 28=D#5 29=E-5 2A=F-5 2B=F#5 2C=G-5 2D=G#5 2E=A-5 2F=A#5 30=B-5
31=C-6 32=C#6 33=D-6 34=D#6 35=E-6 36=F-6 37=F#6 38=G-6 39=G#6 3A=A-6 3B=A#6 3C=B-6
3D=C-7 3E=C#7 3F=D-7 40=D#7 41=E-7 42=F-7 43=F#7 44=G-7 45=G#7 46=A-7 47=A#7 48=B-7

Note that my research is not complete yet, but it should be possible to create custom music using what I've been able to research so far. Given the tracker-style format, it would be more efficient to create a simple .XM converter rather than manually hex edit the music in by hand. Although manually hex editing the music in is certainly an option...

Also, here is a video I made featuring a simple edit of the title screen music.

EDIT: Custom music insertion is definitely possible, proof: