User Tools

Site Tools

“Don't learn from these docs! Bug people on IRC instead.”

return_of_samus:technical_information:music_format

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

return_of_samus:technical_information:music_format [2020/03/18 23:55] (current)
kkzero created
Line 1: Line 1:
 +====== Music Format ======
 +This page aims to explain how Metroid II's music works on the inside. ​
 +
 +Bank 4 is dedicated to all the music and sound data and code. The game almost always leaves this bank in the swappable bank area of the system'​s memory map in order to focus on interpreting the music data.
 +
 +===== Game Boy Audio Specs =====
 +Just for quick reference, the Game Boy utilizes a stereo PSG composed of four monophonic channels. Their details are listed below.
 +^ # ^ Details ​                                                                                                      ^
 +| 1 | Pulse-wave - Can generate pulse waves at duty cycles of 12.5%, 25%, 50%, or 75%. Also has a frequency sweep. ​ |
 +| 2 | Pulse-wave - Same as above, except lacking the sweep. ​                                                        |
 +| 3 | 4-bit Wavetable - Can generate customizable waveforms from a table of 32.                                     |
 +| 4 | White Noise - Can generate only white noise. Used as percussion in music. ​                                    |
 +
 +===== Song List =====
 +At 0x11F30 in the ROM starts the list where the game finds the next music track to play. There are 32 2-byte pointers to each of them.
 +Right after this list ends is another list, this time 32 1-byte flags determining how each song in the last list utilizes the stereo panning.
 +<​code>​
 +STEREO FLAGS
 +DB - Pulse channel 2 is panned to the right.
 +DE - Pulse channel 1 is panned to the left, and pulse channel 2 is panned to the right.
 +FF - Song is totally center-panned.
 +</​code>​
 +^ Song                         ^ Flag ^
 +| 01 - Baby Metroid ​           | FF   |
 +| 02 - VS. Queen Metroid ​      | FF   |
 +| 03 - Chozo Ruins             | FF   |
 +| 04 - Main Caves              | FF   |
 +| 05 - Sub Caves 1             | FF   |
 +| 06 - Sub Caves 2             | FF   |
 +| 07 - Sub Caves 3             | FF   |
 +| 08 - Final Caves             | FF   |
 +| 09 - Metroid Hive (no intro) | FF   |
 +| 0A - Item Acquired ​          | DB   |
 +| 0B - Queen Metroid Hallway ​  | FF   |
 +| 0C - VS. Metroid ​            | FF   |
 +| 0D - Sub Caves 4             | FF   |
 +| 0E - Earthquake ​             | DE   |
 +| 0F - Metroid Defeated ​       | DE   |
 +| 10 - Nothing ​                | FF   |
 +| 11 - Title                   | FF   |
 +| 12 - Samus Appearance ​       | DE   |
 +| 13 - Ending ​                 | FF   |
 +| 14 - Chozo Ruins (dupe of 03)| FF   |
 +| 15 - Main Caves (not intro) ​ | FF   |
 +| 16 - Sub Caves 1 (no intro) ​ | FF   |
 +| 17 - Sub Caves 2 (no intro) ​ | FF   |
 +| 18 - Sub Caves 3 (no intro) ​ | FF   |
 +| 19 - Final Caves (dupe of 08)| FF   |
 +| 1A - Metroid Hive (dupe of 09)| FF  |
 +| 1B - Item Acquired (dupe of 0A)| DB  |
 +| 1C - Queen Metroid Hallway (dupe of 0B)| FF   |
 +| 1D - VS. Metroid (dupe of 0B)| FF   |
 +| 1E - Sub Caves 4 (no intro)| FF   |
 +| 1F - Metroid Hive|FF ​  |
 +| 20 - Missile Expansion| DE   |
 +
 +===== Song Header =====
 +Each song is defined by a header of 0x0B bytes.
 +<​code>​
 +SONG HEADER
 +Note Offset - 1 byte - A signed value determining how much to add to or subtract from the song's pitch.
 +Tempo Offset - 2 bytes - Points to the tempo array to be used in the song.
 +Channel Instruction Pointers - 8 bytes (2 for each channel) - Points to the instruction list for each sound channel to play. Can be set to 0000 to completely ignore the channel, and can even point to the same list, as some songs set both pulse channels to the same pointer.
 +</​code>​
 +===== Instruction Lists =====
 +These contains all the pointers to each instruction pattern.
 +<​code>​
 +INSTRUCTION LIST COMMANDS
 +0000 - Stops playing sound through the channel for the rest of the song's playing.
 +00F0 - Loops the channel starting from the specified offset following the command.
 +</​code>​
 +
 +===== Instructions =====
 +Each offset pointed to by the instruction lists is just a sequence of bytes the game interprets. What they do is detailed below.
 +
 +==== 00 ====
 +Ends the instruction pattern, passing it on to the next pointer in the instruction list.
 +
 +==== 01 ====
 +A rest note.
 +
 +==== 03 ====
 +Echoes the preceding note at a volume of 0x46.
 +
 +==== 05 ====
 +Echoes the preceding note at a volume of 0x66.
 +
 +==== Ax ====
 +Changes the note length, x being the requested index in the currently-loaded tempo array.
 +
 +==== F1 ====
 +Initializes the instrument in the pulse and wave channels.
 +Pulse - Envelope, sweep, and duty cycle are represented by 3 bytes in that order.
 +Wave - First 2 bytes point to the waveform to be loaded, last one defines volume.
 +
 +==== F2 ====
 +Loads the tempo array from the specified 2-byte pointer.
 +
 +==== F3 ====
 +Transposes the song.
 +
 +==== F4 ====
 +Repeats a section of instructions the number of times specified by the byte right after.
 +
 +==== F5 ====
 +Encloses the section mentioned above.
 +
 +===== Note Values =====
 +Just about every other byte is a note value. They range from 0x02 to 0x9E, and should all be even values. They are listed below.
 +
 +^ Note ^ 0   ^ 1   ^ 2   ^ 3   ^ 4   ^ 5   ^ 6   ^
 +| C    | 0x02| 0x1A| 0x32| 0x4A| 0x62| 0x7A| 0x92|
 +| C#   | 0x04| 0x1C| 0x34| 0x4C| 0x64| 0x7C| 0x94|
 +| D    | 0x06| 0x1E| 0x36| 0x4E| 0x66| 0x7E| 0x96|
 +| D#   | 0x08| 0x20| 0x38| 0x50| 0x68| 0x80| 0x98|
 +| E    | 0x0A| 0x22| 0x3A| 0x52| 0x6A| 0x82| 0x9A|
 +| F    | 0x0C| 0x24| 0x3C| 0x54| 0x6C| 0x84| 0x9C|
 +| F#   | 0x0E| 0x26| 0x3E| 0x56| 0x6E| 0x86| 0x9E|
 +| G    | 0x10| 0x28| 0x40| 0x58| 0x70| 0x88| |
 +| G#   | 0x12| 0x2A| 0x42| 0x5A| 0x72| 0x8A| |
 +| A    | 0x14| 0x2C| 0x44| 0x5C| 0x74| 0x8C| |
 +| A#   | 0x16| 0x2E| 0x46| 0x5E| 0x76| 0x8E| |
 +| B    | 0x18| 0x30| 0x48| 0x60| 0x78| 0x90| |
 +
 +In determining what pitch the values play at in the song, the following formula is used.
 +<​code>​
 +base note value + (0x18 * note level) + noteoffset - if noteoffset is an odd number
 +(In the case of a negative noteoffset like 0xFE, replace noteoffset with (256 - noteoffset))
 +</​code>​
 +
 +===== Tempo =====
 +From 0x1009E-0x10106 are nine arrays of 0xD bytes. They are loaded as the song tempo in the header or by instruction F2, and each individual byte is loaded by an Ax instruction.
 +
 +^ Offset ^ Values seemingly geared to 4/8/16-beat ^ Values seemingly geared to 3/6/12-beat ^ Unknown beat ^
 +| 0x1009E | 01, 01, 02, 04, 08, 10 [448BPM] | 03, 06, 0C | 01, 03, 01, 20 |
 +| 0x100AB | 01, 02, 04, 08, 10, 20 [224BPM] | 06, 0C, 18 | 02, 05, 01, 40 |
 +| 0x100B8 | 02, 03, 06, 0C, 18, 30 [150BPM] | 09, 12, 24 | 04, 08, 01, 60 |
 +| 0x100C5 | 02, 04, 08, 10, 20, 40 [112BPM] | 0C, 18, 30 | 05, 0A, 01, 80 |
 +| 0x100D2 | 03, 05, 0A, 14, 28, 50 [90BPM] | 0F, 1E, 3C | 07, 0E, 01, A0 |
 +| 0x100DF | 03, 06, 0C, 18, 30, 60 [75BPM] | 12, 24, 48 | 08, 10, 02, C0 |
 +| 0x100EC | 03, 07, 0E, 1C, 38, 70 [64BPM] | 15, 2A, 54 | 09, 12, 02, E0 |
 +| 0x100F9 | 04, 08, 10, 20, 40, 80 [56BPM] | 18, 30, 60 | 0A, 14, 02, FF |
 +| 0x10106 | 04, 09, 12, 24, 48, 90 [50BPM] | 1B, 36, 6C | 0C, 1A, 02, FF |
  
return_of_samus/technical_information/music_format.txt ยท Last modified: 2020/03/18 23:55 by kkzero