Sequence data structure
Explains the structure of the sequence data of the RareWare Sound Driver used in Super Donkey Kong and Donkey Kong Country.
For the addresses of each variable in APU RAM, see the APU RAM map.
Notation
In this manual, command syntax is written as follows.
0x02, sbyte left, sbyte right
The command’s byte value comes first, followed by the type and name of each parameter in the order they appear in the data. The types are byte (unsigned 8-bit), sbyte (signed 8-bit) and ushort (unsigned 16-bit, little-endian). The only exception is when note lengths are specified in 16 bits, which are big-endian.
All addresses are absolute addresses in APU RAM, not offsets within the sequence data.
Sequence data placement
Sequence data is placed starting at $12A0 in APU RAM. A sequence file stored in ROM is transferred to APU RAM according to its 4-byte header. The first 2 bytes are the destination (entry point), always $12A0, and the last 2 bytes are the data size.
Header
The song header is placed at the start of the sequence data.
| Offset | Type | Contents |
|---|---|---|
| +$00 | ushort[8] | Sequence start address of each BGM channel (0-7) |
| +$10 | byte | Initial tempo |
| +$11 | byte | Initial SE tempo |
When a song is initialized, all 8 channels start running. Unused channels must also point to a valid sequence, such as one consisting only of command 0x00.
Sound effects
At the start of the SE data area ($2380), the sequence start addresses (ushort) of each sound effect are listed in sound effect number order. The number of entries is not stored in the table.
The table is looked up using the low 8 bits of the sound effect number times two, so valid sound effect numbers are $00-$7F.
A sound effect is played on SE channel n+8, which corresponds to the BGM channel n specified by the CPU. Sound effect sequences have the same format as BGM and can use the same commands.
When a sound effect starts, the SE channel’s volume is initialized to $7F for both left and right, and its ADSR to ADSR1 = ADSR2 = 0. While the sound effect plays, BGM channel n continues only sequence processing and does not write to the DSP.
Events
A sequence is a series of events. The first byte of an event determines its type.
| First byte | Type |
|---|---|
| 0x00-0x30 | Command. The number of parameters is fixed for each command |
| 0x80 | Rest |
| 0x81-0xFF | Note |
Commands take no time to process, and the following event is read within the same tick. Time advances only with note events and rest events. Therefore, creating an infinite loop that contains no notes or rests will hang the driver.
Executing 0x31-0x7F jumps outside the command handler table or to an invalid address, and the driver crashes.
Note length
The length of note events and rest events is specified in ticks. There are three modes for specifying length, switched per channel.
| Mode | Length specification | Switching command |
|---|---|---|
| Normal | 1 byte per event | - |
| Default duration | Not specified per event; uses the length set with command 0x06 | 0x06, 0x07 |
| 16-bit duration | 2 bytes per event (big-endian) | 0x2B, 0x2C |
If default duration mode and 16-bit duration mode are enabled at the same time, the argument of command 0x06 becomes 2 bytes and no length is specified in each event.
Below is an example of the same content written in the three modes.
// Normal
A5 10 A7 08 A9 08 AA 08 B1 10 00
// Default duration
A5 10 06 08 A7 A9 AA 07 B1 10 00
// 16-bit duration
2B A5 00 10 A7 00 08 A9 00 08 AA 00 08 B1 00 10 00
Tempo and ticks
The driver runs at the timer 0 period. The timer 0 divider has an initial value of 60 (about 133.3Hz, a period of about 7.5ms) and can be changed with command 0x2A.
Every timer period, each tempo is added to its BGM or SE tempo accumulator as an 8-bit addition, and the side whose accumulator overflowed advances its sequence by one tick.
Therefore, the number of ticks per second is (8000 ÷ timer 0 divider) × tempo ÷ 256. For example, if a quarter note is 16 ticks, the tempo in BPM is about 1.95 × tempo.
Time unit of effects
The times (delays and intervals) of pitch bend, vibrato and tremolo are counted in timer periods, not in tempo. Therefore, changing the tempo does not change the speed of effects (changing the timer period with command 0x2A does).
Subroutines
A subroutine is called with command 0x04 and returned from with command 0x05. Each channel’s call stack has 8 levels, and the depth is not checked.
Use command 0x03 to loop a song. Use command 0x2D to branch depending on the game situation.
Processing flow
Every timer period, the following is done for BGM channels 0-7.
- If a BGM tick occurred, decrement the remaining tick count by 1, and read events when it reaches 0. Commands are read in succession, stopping at a note event or rest event.
- Process effects (pitch bend, vibrato, tremolo).
- If a sound effect is playing on the corresponding SE channel, do the same processing for the SE tick.
If a BGM tick occurred, fade-out processing (command 0x29) is also done before the channel processing.