From CloudModding OoT Wiki

Audioseq contains data for playing the game's sequenced music. The sequenced music in the Zelda 64 games follows a MIDI type format which is a slightly updated version of that used in earlier games like Super Mario 64.

Moving Audioseq

To move the Audioseq file to another location in ROM, you will need to correct its entry in the file table, update the assembly code used to load sequences from the file, and update the CRC. This can be found at 0xB5A4AC (Debug ROM) and looks like:

3C05 xxxx 24A5 yyyy

In MIPS assembly:

LUI       $A1,xxxx
ADDIU     $A1,$A1,yyyy
  • x = upper half of address
  • y = lower half of address

Sequence Pointer Table

code (File)
Sequence Table List
VersionOffsetVRomVRam
Debug1386A000BCC6A000BCCD908015550080155BF0
NTSC 1.0102AD000B89AD000B8A1C080113B7080114260
NTSC 1.1102C9000B89C9000B8A38080113D3080114420
NTSC 1.2102B4000B89B4000B8A2308011422080114910
PAL 1.010029000B8929000B899808011197080112060
PAL 1.11002D000B892D000B899C0801119B0801120A0
JP GC1021F000B881F000B888E0801130D0801137C0
JP MQ1021D000B881D000B888C0801130B0801137A0
USA GC1021D000B881D000B888C0801130B0801137A0
USA MQ1021B000B881B000B888A08011309080113780
PAL GC0FF9C000B879C000B880B0801108C080110FB0
PAL MQ0FF9A000B879A000B88090801108A080110F90
JP Collection1021D000B881D000B888C0801130B0801137A0

The sequence pointer table begins with an 0x10 byte header:

/* 0x00 */ short NumberOfSequences = 0x6E;
/* 0x04 */ int AudioSeq_StartAddress; //ram only
/* 0x08-0x0F is padded to 0 */

Following that is a record for each sequence in the table:

xxxxxxxx yyyyyyyy uuaa 0000 00000000

  • x = Pointer to the start of the sequence in the sequenced music file. In rom, this value is an offset relative to the start of the file, while in ram, this value will be converted into the VRom address that the sequence is located at
  • y = Length of the sequence, in bytes.
  • u = Unknown. Value set to 0x02
  • a = Sequence Type, affects memory allocation. 0x00 is Hyrule Field, 0x01 is fanfares, 0x02 is BGM

Format

There are generally three different parts to the sequences:

Sequence Header
This is the part of the sequence that controls things such as master volume, tempo and loop settings.

Channel Header
Controls volume, pan, etc. and points to music data to be played back on each channel.

Music Data
Contains the data for which notes should be played, their velocity, length, etc.

From here, all numbers will be given in hexadecimal unless stated otherwise.

Sequence Header Commands

Command Description
D3 xx Seems to be something to do with the sequence type or format; for Super Mario 64, xx is usually 80, for Zelda 64, xx is usually 20.
D5 xx Unknown. xx usually takes the value of 32. For sequences that don't play any music xx is 46.
D7 xxxx Enables channels given by xxxx (boolean, each channel is one bit).
9x yyyy Points to a channel header offset. x is the channel number (0 - F) and yyyy is the offset of that channel's header relative to the start of the sequence file.
DB xx Master volume control, xx is the volume.
DD xx Tempo control, xx is the tempo value in beats per minute.
CC yyxx Unknown. yy starts at zero and increases each time the command appears, xx is (always?) 73.
FD xx / FD yyyy Timestamp (number of 'ticks' to wait before the next command is read, relative to tempo), variable length. If xx goes above 7F, add 8000 to it to get yyyy.
FB xxxx Offset to loop from, xxxx is the offset relative to the start of the sequence file.
D6 xxxx Disables channels given by xxxx.
FF Marks the end of the sequence header.

Some sequences have the following data after the first four bytes of their sequence header. Its purpose is currently unknown but it may be to do with continuing playback mid-sequence after returning to the area from a house/shop:
D7FFFF 8776CCFF7786F3 vv F2 ww C801F3 xx [C801FA yyyy] FB zzzz

v, w and x are unknowns, y and z seem to be pointers to 9x commands for different parts of the sequence within the sequence header. The part in square brackets is repeated in some sequences.

Channel Header Commands

Command Purpose Variables
C4 Initialises the channel for music playback
8x yyyy Points to music data to be played on the current channel x is 'note layer' to be used (8 - B). A maximum of four note layers can be loaded per channel.
y is the offset of the music data to be played, relative to the start of the sequence file.
DF xx (yy) Channel volume x is the volume value
y is a timestamp used between control changes (when the volume is changing constantly)
DD xx Channel pan x is the pan amount, 00 = hard left, 3F = centre, 7F = hard right
E9 xx Priority. Unknown how it is used x = ?
D4 xx Effects level (echo) x is the effect amount
D8 xx (yy) Vibrato x Vibrato amount. Higher values can produce odd sounds.
y is a timestamp used between control changes
D3 xx (yy) Pitch bend x Pitch bend amount, signed.
y is a timestamp used between control changes
C2 xx Transposition x is the number of semitones to transpose by. Signed value
C1 xx Sets the instrument number x instrument number to be used for the current channel
FD xx / FD yyyy Timestamp (see sequence header commands).
FF Marks the end of the channel header.

Music Data

Things get a little more complicated here.

Command Format Description Values Notes
nn
(0x00 to 0x3F)
tt(tt)vvgg Play note n = Note value
t = Variable length timestamp
v = Note velocity
g = Gate time
nn
(0x40 to 0x7F)
tt(tt) vv n = Note value + 40
t = Variable length timestamp
v = Note velocity
Gate time is the same as was used for the previous play note command.
nn
(0x80 to 0xBF)
vv gg n = Note value + 80
v = Note velocity
g = Gate time
Timestamp is the same as was used for the previous play note command.
C0 xx, or
yyyy
Timestamp / rest x or y is the variable length timestamp value Used when no music needs to be played for a set amount of time
FC xxxx Jump to offset x is offset relative to the start of the sequence file to jump to Plays the data from there until it reaches the next FF command
FF Terminator Marks the end of the current music data.

Note: It seems that some of the channel header commands are valid for use in the music data but the only one that's really useful is the C2 command (transposition).

Differences with the Super Mario 64 format

In Super Mario 64, the 8x yyyy command appears as:

9x yyyy

Where x is the 'note layer' to use (0 - 3) and yyyy is the offset to load music data from relative to the start of the sequence file.
Super Mario 64 does not use the E9 (priority) command and does not seem to be compatible with the way Zelda 64 does control changes. There may be other differences but this has not been looked into fully as of yet.

Tips for converting from MIDI

Zelda note value = MIDI note value - 0x15
Zelda timestamp = (MIDI timestamp/0x80)*0x18

Instrument Sets

There is no master instrument index in Zelda 64 as there is for MIDI sequences, instead there are different instrument sets that contain the instruments needed to play each sequence. The instrument set a sequence uses is not defined in the sequence itself but is defined externally. The lookup table for this data is retrieved in a rather unusual way:

In the Debug Rom for example, address BCC4E0 acts as the start address to the table. In order to reach the instrument set record, the game reads the halfword at BCC4E0 + (SequenceId * 2), then adds that to BCC4E0 to reach the appropriate record. Fortunately, this calculation can be simplified as being Table Start (BCC4E0 for debug) + DD + (SequenceId * 2) for all but sequence 0, where you'll have to subtract the result by 1.

nnii*

  • n is number of Instrument Sets within the record
  • i is the Instrument Set number for the Sequence
code (File)
Instrument Sets
VersionOffsetVRomVRam
Debug1384E000BCC4E0?80155340?
NTSC 1.010291000B89910?801139B0?

Here's a list of which sequences use which instrument sets:

OoT instrument sets list

Instrument
Set Number
Purpose Dependent
Sequences
0x00 Ocarina songs

0x44
0x45
0x46
0x47
0x48
0x49

0x01 Actor Sounds none
0x02 Nature Sounds 0x01
0x03 Hyrule Field

0x02
0x03
0x04
0x05
0x06
0x07
0x08
0x09
0x0A
0x0B
0x0C
0x0D
0x0E
0x0F
0x10
0x11
0x12
0x13
0x14
0x15
0x16
0x17
0x19
0x1A
0x1B
0x1F
0x21
0x23
0x2B
0x2D
0x31
0x32
0x38
0x3B
0x43
0x4A
0x51
0x52
0x53
0x54
0x62
0x6C

0x04 Deku Tree 0x1C
0x05 Market

0x1D
0x3E

0x06 Title Screen 0x1E
0x07 Jabu Jabu's Belly 0x26
0x08 Kakariko Village (guitar)

0x27
0x4C

0x09 Fairy Fountain

0x28
0x29
0x3A
0x3D
0x4B
0x4F
0x57
0x66
0x6A

0x0A Fire Temple 0x2A
0x0B Dodongo's Cavern 0x18
0x0C Forest Temple 0x2C
0x0D Lon Lon Ranch 0x2F
0x0E Goron City 0x30
0x0F Kokiri Forest 0x3C
0x10 Spirit Temple 0x3F
0x11 Horse Race

0x40
0x41
0x42

0x12 Warp songs (ocarina songs 2)

0x25
0x33
0x34
0x35
0x36
0x37
0x59

0x13 Goddess Cutscene

0x4D
0x56
0x5D

0x14 Shooting Gallery 0x4E
0x15 Zora's Domain 0x50
0x16 Shop 0x55
0x17 Ice Cavern 0x58
0x18 Shadow Temple 0x5B
0x19 Water Temple 0x5C
0x1A Blank? none
0x1B Gerudo Valley 0x5F
0x1C Lakeside Laboratory 0x60
0x1D Kotake and Koume's Theme 0x61
0x1E Ganon's Castle (organ) 0x2E
0x1F Inside Ganon's Castle 0x63
0x20 Ganondorf Battle/Boss Battle 2

0x5E
0x64
0x65
0x6B

0x21 Ending sequence 1

0x67
0x69

0x22 Ending sequence 2 0x68
0x23 Game Over/Fanfares

0x20
0x22
0x24
0x39

0x24 Owl 0x5A

Legacy Credits

messiaen, DeathBasket - Sequence format
messiaen - pointer table format
DeathBasket - Instrument set lists for OoT and MM
DeathBasket - Writing this