Actions

SCHG

Difference between revisions of "Sonic Jam/Sounds"

From Sonic Retro

m (SWORLD.SND Map: Typo)
($80 - $8F: Song Flow: Updated information for events $88 - $8F.)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
__NOTOC__
 
__NOTOC__
 
{{SCHG SJ}}
 
{{SCHG SJ}}
==Samples==
+
==PCM Samples==
According to my research so far, most samples are in a signed 8-bit mono format, with a sample rate of 22050Hz. Each byte is a building block (a "sample") of the sample as a whole.
+
According to my research so far, all PCM samples are big-endian, and monaural. Most are in a signed 8-bit format, with a sample rate of 22050Hz. However, some are in a signed 16-bit format, with a sample rate of 11025Hz. These are noted accordingly.
  
There are some exceptions, though.
+
==SWORLD.SND Map==
 +
 
 +
Here's a map of PCM samples that can be found in SWORLD.SND. Start and end addresses are inclusive; they're part of the sample.
 +
 
 +
===Bank 1:===
 +
{|class="mw-collapsible mw-collapsed prettytable" style="width:auto;"
 +
! Start Address || End Address || Description || Notes
 +
|-
 +
| $004A6 || $02D5D || Flute (Low) ||
 +
|-
 +
| $02D5E || $06A7B || Flute (High) ||
 +
|-
 +
| $06A7C || $073B1 || Bass Drum ||
 +
|-
 +
| $073B2 || $08D53 || Snare Drum || 16-bit.
 +
|-
 +
| $08D54 || $0967F || Open Conga Drum || Used for both the Open High Conga and Open Low Conga.
 +
|-
 +
| $09680 || $09CDB || Muted High Conga Drum ||
 +
|-
 +
| $09CDC || $0B189 || Taiko Drum? || Used for MIDI key 87.
 +
|-
 +
| $0B18A || $0C499 || Tambourine ||
 +
|-
 +
| $0C49A || $0CFD1 || Side Stick || Used for both the Side Stick, and MIDI key 86 (Taiko Side Stick?).
 +
|-
 +
| $0CFD2 || $0FF91 || Crash Cymbal || 16-bit.
 +
|-
 +
| $0FF92 || $112B1 || Bass Guitar || 16-bit.
 +
|-
 +
| $112B2 || $120F1 || Trumpet ||
 +
|-
 +
| $120F2 || $14D31 || Brass ||
 +
|-
 +
| $14D32 || $1512F || Sawtooth || 16-bit. Used for the Synth Brass program, one of the leads for the Sonic World BGM.
 +
|-
 +
| $15130 || $1670F || Steel Drum ||
 +
|-
 +
| $16710 || $1CB3B || Tom Drum || 16-bit.
 +
|-
 +
| $1CB3C || $215BB || Piano (Low) ||
 +
|-
 +
| $215BC || $2611D || Piano (High) ||
 +
|-
 +
| $2611E || $2982F || Voice Oohs || Used in two programs, one alone ($0B), and one composited with the Electric Piano sample ($07).
 +
|-
 +
| $29830 || $2AD8F || Electric Piano || Used in two programs, one alone ($0C), and one composited with the Voice Oohs sample ($07).
 +
|-
 +
| $2AD90 || $2EEC7 || Synth Strings ||
 +
|-
 +
| $2EEC8 || $2F287 || Oboe || One of the leads for the Building BGM.
 +
|-
 +
| $2F288 || $2F2AF || Unknown || Inaudible. Key 58 of the drum program; this could be a placeholder for/remnants of a Vibraslap sample.
 +
|}
 +
 
 +
===Bank 2:===
 +
{|class="mw-collapsible mw-collapsed prettytable" style="width:auto;"
 +
! Start Address || End Address || Description || Notes
 +
|-
 +
| $2F94E || $2FEDD || Menu Cancel || Modulated like crazy to make the SFX.
 +
|-
 +
| $2FEDE || $311FD || Menu Confirm || Not full sound, just the sample used to play it.
 +
|-
 +
| $311FE || $3234D || Game Cart Select || For the games collection.
 +
|-
 +
| $3234E || $3294D || S&K Lock On ||
 +
|-
 +
| $3294E || $32BAF || Menu Select/Mission Button ||
 +
|-
 +
| $32BB0 || $358D1 || Warp Noise || The special stage transition sound from the classics. Used for the Big Ring.
 +
|-
 +
| $358D2 || $35B21 || Square Wave || 16-bit. Layered on itself to composite the Skidding SFX.
 +
|-
 +
| $35B22 || $36525 || Landing 1 || Part of the SFX for Sonic landing on the ground. Composited with Landing 2.
 +
|-
 +
| $36526 || $36E67 || Landing 2 || Part of the SFX for Sonic landing on the ground. Composited with Landing 1.
 +
|-
 +
| $36E68 || $37043 || Checkpoint || Low pitched. Double sample rate?
 +
|-
 +
| $37044 || $37A0F || Spring || High pitched. Half sample rate?
 +
|-
 +
| $37A10 || $381FB || Sine Wave || 16-bit. Used for the Secret Point trumpets, an FM instrument.
 +
|-
 +
| $381FC || $399F9 || Code Monitor Interact ||
 +
|-
 +
| $399FA || $39B03 || Door Open || High pitched. Half sample rate?
 +
|-
 +
| $39B04 || $3BE83 || Wind || Unused.
 +
|-
 +
| $3BE84 || $3DCF3 || Honk/Door Creak || Unused.
 +
|-
 +
| $3DCF4 || $3FBDF || Leaf Rustling ||
 +
|-
 +
| $3FBE0 || $40021 || Tails Flight ||
 +
|-
 +
| $40022 || $423D1 || Rock Organ || 16-bit.
 +
|-
 +
| $423D2 || $44DD1 || Splash ||
 +
|-
 +
| $44DD2 || $46E63 || Waterfall ||
 +
|-
 +
| $46E64 || $4A863 || Ring Pick-up ||
 +
|-
 +
| $4A864 || $4C6F7 || Balloon Pop ||
 +
|-
 +
| $4C6F8 || $4C71F || Unknown || Inaudible. Looks to be used by programs that are silent. Placeholder?
 +
|-
 +
| $4C720 || $4ED8D || Jump ||
 +
|}
  
Some samples are "stereo", in that the sample is in the left ear, while there's data/code in the right ear. The stereo format has every other sample starting with the first be in the left ear, and every other sample starting with the second be in the right ear. Due to every other sample being used, these have a halved sample rate; 11025Hz instead of 22050Hz.
+
==Music and SFX==
  
In addition, some simply have different sample rates despite being mono.
+
The music in Sonic World (and interestingly, the SFX in both Sonic World and the Genesis ports) is performed in real-time via a variation of the MIDI standard (as opposed to just playing back a prerecorded audio file).
  
==SWORLD.SND Map==
+
A Saturn MIDI file (at least as Sonic Jam handles them) consists of a Header, and a series of Tracks, which consist of a Tempo Track, and Play Data.
  
Here's a map of samples that can be found in SWORLD.SND. Start and end addresses are inclusive; they're part of the sample.
+
===MIDI Header===
  
NOTE: Sample start and end times are currently estimates based on looking at the waveform and patterns in the hex. Finding the exact start and end of each sample will likely require digging into the code.
+
A MIDI Header is very simple, consisting of only two components:
 
{|class="prettytable" style="width:auto;"
 
{|class="prettytable" style="width:auto;"
! Start Address || End Address || Description || Notes
+
! Function || Size || Notes
 
|-
 
|-
| $004A2 || $02D59 || Flute (Low) ||
+
| Number of Tracks || word ||
 
|-
 
|-
| $02D5A || $06A79 || Flute (High) ||
+
| Offset of Track 1 || long || From the top of the header.
 
|-
 
|-
| $06A79 || $073B1 || Snare Drum ||
+
| Offset of Track 2 || long || From the top of the header.
 
|-
 
|-
| $08D54 || $09677 || Bongo (Low) ||
+
| etc. || ||
 +
|}
 +
 
 +
===Tempo Track===
 +
 
 +
A Tempo Track defines the Resolution of a track, the Tempo, any Tempo Changes that occur, and when they happen.
 +
{|class="prettytable" style="width:auto;"
 +
! Function || Size || Notes
 
|-
 
|-
| $09678 || $09CDB || Bongo (High)? ||
+
| Resolution || word || Number of MIDI ticks per quarter-note (typically $01E0). Holding all else equal, lowering the value will slow the apparent tempo. Must be between $0018 and $03C0, inclusive, otherwise the song won't play.
 
|-
 
|-
| $09CDC || $0B189 || Tom-Tom (Low)? ||
+
| Number of Tempos || word || The number of Tempo Duration and Tempo pairs defined below. Must have at least 1 pair.
 
|-
 
|-
| $0B18A || $0C4A2 || Maracas? ||
+
| Length of Tempo Track || word || In bytes. Counting starts at MSB of Resolution.
 
|-
 
|-
| $0C4A3 || $0CFD1 || Tom-Tom (High)? ||
+
| Length of Tempo List || word || In bytes. Counting starts at MSB of first Tempo Duration. Must be a multiple of 8 (4 bytes for each Tempo Duration, 4 bytes for each Tempo).
 
|-
 
|-
| $0FF92 || $112B1 || Bass Guitar || Stereo. Sample's in left ear.
+
| Tempo 1 Duration || long || The amount of time (in MIDI ticks) to play the song at the following tempo for, before changing to the next tempo (when applicable; otherwise this is ignored).
 
|-
 
|-
| $112B2 || $120F0 || Trumpet ||
+
| Tempo 1 || long || Tempo to play the song at, in microseconds per quarter-note.
 
|-
 
|-
| $120F1 || $14D31 || Brass ||
+
| Tempo 2 Duration || long ||  
 
|-
 
|-
| $14D32 || $1512F || Sawtooth? || Unsure if sample(s). Stereo, sawtooth in left ear, but right ear's a pair of sawtooth samples that seem to be stereo too.
+
| Tempo 2 || long ||  
 
|-
 
|-
| $15130 || $16719 || Steel Drum ||
+
| etc. || ||  
 +
|}
 +
 
 +
Any tempo changes done within a loop won't work as intended on subsequent loops. The progression of tempos only goes forward, won't jump backwards when a loop is triggered, and the last tempo will play forever rather than wrapping back to the start of the list. This looks to be intentional, reading the Saturn docs.
 +
 
 +
===Play Data===
 +
 
 +
The Play Data of a track consists of a continuous series of MIDI events. Each MIDI event consists of a Status byte, and a variable number of parameter bytes, ranging from 0 to 4. All possible MIDI events are defined below.
 +
 
 +
====$00 - $7F: Note On====
 +
 
 +
For Note On events, the upper nybble of Status is bit flags.
 +
{|class="prettytable" style="width:auto;"
 +
! Bit Mask || Function
 
|-
 
|-
| $1671A || $1CB3B || Bass Drum(?) || Stereo. Sample's in left ear.
+
| $10 || Mutes the note when set, essentially changing this event to a rest.
 
|-
 
|-
| $1CB3C || $215D2 || Piano (Low) ||
+
| $20 || Extension bit for Delta Time parameter.
 
|-
 
|-
| $215D3 || $2611D || Piano (High) ||
+
| $40 || Extension bit for Length parameter.
 +
|}
 +
 
 +
The lower nybble of Status is the channel to play the note on.
 +
 
 +
Note On events have 4 parameters.
 +
{|class="prettytable" style="width:auto;"
 +
! Parameter || Function || Notes
 
|-
 
|-
| $2611E || $2982E || Synth(?) "Doo" ||
+
| $01 || Pitch || Middle C is $3C.
 
|-
 
|-
| $2982F || $2AD8F || Electric Piano || Has an almost bell sound to it.
+
| $02 || Volume || Clamped from $00 to $7F.
 
|-
 
|-
| $2AD90 || $2EEC7 || Synth Pad ||
+
| $03 || Length || How long the note plays, in MIDI ticks.
 
|-
 
|-
| $2EEC8 || $2F287 || Saxophone? || Sample's too short to easily tell.
+
| $04 || Delta Time || How long to wait before triggering this event, in MIDI ticks.
 +
|}
 +
 
 +
====$80 - $8F: Song Flow====
 +
 
 +
These events are for manipulating the song's flow.
 +
{|class="prettytable" style="width:auto;"
 +
! Status || Event || Parameters || Notes
 
|-
 
|-
| $2F948 || $2FEDD || Museum Select ||
+
| $80 || Invalid || N/A || Abruptly terminates the song, cutting off any active notes.
 
|-
 
|-
| $2FEDE || $311FD || Museum Confirm || Not full sound, just the sample used to play it.
+
| $81 || Reference? || 3: Offset (High), Offset (Low), Count || Copies [Count] events, starting with the one at [Offset] from the start of the track. Needs confirmation.
 
|-
 
|-
| $311FE || $3234D || Unknown ||
+
| $82 || Loop Start/End || 1: Delta Time || First call is where loop starts, second call is where the loop ends. Delta Time is in MIDI ticks.
 
|-
 
|-
| $3234E || $3294F || Unknown ||
+
| $83 || End Song || 0 || Immediately ends the song, letting any active notes play out.
 
|-
 
|-
| $32950 || $32BAF || Mission Button || Played on press and release.
+
| $84 - $87 || Invalid || N/A || Has the same behavior as event $80.
 
|-
 
|-
| $32BB0 || $358D1 || Big Ring Warp ||
+
| $88 || Quarter Note Extend || 0 || Adds the length of a quarter note to the next Note On (can stack).
 
|-
 
|-
| $35B22 || $36548 || Landing || Played when Sonic lands on the ground.
+
| $89 || Whole Note Extend || 0 || Like $88, but the length of a whole note.
 
|-
 
|-
| $36549 || $36E68 || Unknown ||
+
| $8A || 2x Whole Note Extend || 0 || Like $88, but the length of two whole notes.
 
|-
 
|-
| $36E69 || $37A11 || Spring || Mono, sample rate 11025Hz.
+
| $8B || 4x (and a Quarter) Note Extend || 0 || Like $88, but the length of four whole notes, plus a quarter. Could probably do with a double-check, that length seems strange.
 
|-
 
|-
| $37A12 || $381FD || Unknown || Unsure if sample. Stereo, left ear is sine wave, right ear seems like noise.
+
| $8C || One-eighth rest || 0 || Adds the delta time of an eighth rest to the next Note On (can stack).
 
|-
 
|-
| $381FE || $399F9 || Code Monitor || Played on interaction.
+
| $8D || Quarter rest || 0 || Ditto, for a quarter note.
 
|-
 
|-
| $399FA || $3BE83 || Wind || Unused.
+
| $8E || Whole rest || 0 || Ditto, for a whole note.
 
|-
 
|-
| $3BE84 || $3DCF3 || Honk || Unused.
+
| $8F || 2x Whole rest || 0 || Ditto, for two whole notes.
 +
|}
 +
 
 +
====$90 - $9F: Invalid====
 +
 
 +
On testing, these all seem to behave the same as event $80.
 +
 
 +
====$A0 - $AF: Unused====
 +
 
 +
The MIDI Standard and the Saturn’s docs seem to imply these are supposed to be Polyphonic Key Pressure events; however, the Saturn docs state (inconsistently) that this is unimplemented. Maybe this is just a ghost of that? I certainly don’t notice any difference when I fiddle around with it.
 +
 
 +
For any who wish to play around with them, they have 3 parameters, the last of which is Delta Time.
 +
 
 +
====$B0 - $BF: Control Change====
 +
 
 +
For Control Change events, the lower nybble of Status is the channel to change the control for.
 +
 
 +
Control Change events have 3 parameters.
 +
{|class="prettytable" style="width:auto;"
 +
! Parameter || Function || Notes
 
|-
 
|-
| $3DCF4 || $3FBDE || Unknown || Sounds like rustling, but sounds different from the in-game trees/bushes.
+
| $01 || Control ID || The control to change. Could use some investigation and documenting.
 
|-
 
|-
| $3FBDF || $40020 || Unknown ||
+
| $02 || Value || The value to set the control to.
 
|-
 
|-
| $40021 || $423D1 || Electric Organ || Stereo, sample's in left, right is data/code.
+
| $03 || Delta Time || How long to wait before triggering this event, in MIDI ticks.
 +
|}
 +
 
 +
====$C0 - $CF: Program Change====
 +
 
 +
For Program Change events, the lower nybble of Status is the channel to change the program for.
 +
 
 +
Program Change events have 2 parameters.
 +
{|class="prettytable" style="width:auto;"
 +
! Parameter || Function || Notes
 
|-
 
|-
| $423D2 || $44DD1 || Splash ||
+
| $01 || Program || The program to change the channel to. Could use some investigation and documenting.
 
|-
 
|-
| $44DD2 || $46E65 || Waterfall ||
+
| $02 || Delta Time || How long to wait before triggering this event, in MIDI ticks.
|-
+
|}
| $46E66 || $4A863 || Ring Pick-up ||
+
 
 +
====$D0 - $DF: Unused====
 +
 
 +
Similar to the $A_ events. Docs imply they are an unimplemented ghost of Channel Pressure. I can’t notice any changes when I fiddle with it.
 +
 
 +
2 parameters, the last is Delta Time.
 +
 
 +
====$E0 - $EF: Pitch Wheel====
 +
 
 +
For Pitch Wheel events, the lower nybble of Status is the channel to apply the pitch wheel to.
 +
 
 +
Pitch Wheel events have 2 parameters.
 +
{|class="prettytable" style="width:auto;"
 +
! Parameter || Function || Notes
 
|-
 
|-
| $4A864 || $4C720 || Balloon Pop ||
+
| $01 || Pitch || The pitch to set the wheel to. Could use some investigation and documenting.
 
|-
 
|-
| $4C721 || $4ED8D || Jump ||
+
| $02 || Delta Time || How long to wait before triggering this event, in MIDI ticks.
 
|}
 
|}
 +
 +
====$F0 - $FF: System Events====
 +
 +
I've yet to see any of these in use, and none of them seem particularly useful for ROM hacking purposes (assuming the docs are accurate).
 +
 +
If someone wants to document them, feel free.
  
 
{{SCHGuides}}
 
{{SCHGuides}}
 
[[Category:SCHG: Sonic Jam]]
 
[[Category:SCHG: Sonic Jam]]

Latest revision as of 09:09, 30 April 2024

SCHG: Sonic Jam
Main Article
Sonic World

Models
Animations
Textures
Sounds
RAM Editing

PCM Samples

According to my research so far, all PCM samples are big-endian, and monaural. Most are in a signed 8-bit format, with a sample rate of 22050Hz. However, some are in a signed 16-bit format, with a sample rate of 11025Hz. These are noted accordingly.

SWORLD.SND Map

Here's a map of PCM samples that can be found in SWORLD.SND. Start and end addresses are inclusive; they're part of the sample.

Bank 1:

Start Address End Address Description Notes
$004A6 $02D5D Flute (Low)
$02D5E $06A7B Flute (High)
$06A7C $073B1 Bass Drum
$073B2 $08D53 Snare Drum 16-bit.
$08D54 $0967F Open Conga Drum Used for both the Open High Conga and Open Low Conga.
$09680 $09CDB Muted High Conga Drum
$09CDC $0B189 Taiko Drum? Used for MIDI key 87.
$0B18A $0C499 Tambourine
$0C49A $0CFD1 Side Stick Used for both the Side Stick, and MIDI key 86 (Taiko Side Stick?).
$0CFD2 $0FF91 Crash Cymbal 16-bit.
$0FF92 $112B1 Bass Guitar 16-bit.
$112B2 $120F1 Trumpet
$120F2 $14D31 Brass
$14D32 $1512F Sawtooth 16-bit. Used for the Synth Brass program, one of the leads for the Sonic World BGM.
$15130 $1670F Steel Drum
$16710 $1CB3B Tom Drum 16-bit.
$1CB3C $215BB Piano (Low)
$215BC $2611D Piano (High)
$2611E $2982F Voice Oohs Used in two programs, one alone ($0B), and one composited with the Electric Piano sample ($07).
$29830 $2AD8F Electric Piano Used in two programs, one alone ($0C), and one composited with the Voice Oohs sample ($07).
$2AD90 $2EEC7 Synth Strings
$2EEC8 $2F287 Oboe One of the leads for the Building BGM.
$2F288 $2F2AF Unknown Inaudible. Key 58 of the drum program; this could be a placeholder for/remnants of a Vibraslap sample.

Bank 2:

Start Address End Address Description Notes
$2F94E $2FEDD Menu Cancel Modulated like crazy to make the SFX.
$2FEDE $311FD Menu Confirm Not full sound, just the sample used to play it.
$311FE $3234D Game Cart Select For the games collection.
$3234E $3294D S&K Lock On
$3294E $32BAF Menu Select/Mission Button
$32BB0 $358D1 Warp Noise The special stage transition sound from the classics. Used for the Big Ring.
$358D2 $35B21 Square Wave 16-bit. Layered on itself to composite the Skidding SFX.
$35B22 $36525 Landing 1 Part of the SFX for Sonic landing on the ground. Composited with Landing 2.
$36526 $36E67 Landing 2 Part of the SFX for Sonic landing on the ground. Composited with Landing 1.
$36E68 $37043 Checkpoint Low pitched. Double sample rate?
$37044 $37A0F Spring High pitched. Half sample rate?
$37A10 $381FB Sine Wave 16-bit. Used for the Secret Point trumpets, an FM instrument.
$381FC $399F9 Code Monitor Interact
$399FA $39B03 Door Open High pitched. Half sample rate?
$39B04 $3BE83 Wind Unused.
$3BE84 $3DCF3 Honk/Door Creak Unused.
$3DCF4 $3FBDF Leaf Rustling
$3FBE0 $40021 Tails Flight
$40022 $423D1 Rock Organ 16-bit.
$423D2 $44DD1 Splash
$44DD2 $46E63 Waterfall
$46E64 $4A863 Ring Pick-up
$4A864 $4C6F7 Balloon Pop
$4C6F8 $4C71F Unknown Inaudible. Looks to be used by programs that are silent. Placeholder?
$4C720 $4ED8D Jump

Music and SFX

The music in Sonic World (and interestingly, the SFX in both Sonic World and the Genesis ports) is performed in real-time via a variation of the MIDI standard (as opposed to just playing back a prerecorded audio file).

A Saturn MIDI file (at least as Sonic Jam handles them) consists of a Header, and a series of Tracks, which consist of a Tempo Track, and Play Data.

MIDI Header

A MIDI Header is very simple, consisting of only two components:

Function Size Notes
Number of Tracks word
Offset of Track 1 long From the top of the header.
Offset of Track 2 long From the top of the header.
etc.

Tempo Track

A Tempo Track defines the Resolution of a track, the Tempo, any Tempo Changes that occur, and when they happen.

Function Size Notes
Resolution word Number of MIDI ticks per quarter-note (typically $01E0). Holding all else equal, lowering the value will slow the apparent tempo. Must be between $0018 and $03C0, inclusive, otherwise the song won't play.
Number of Tempos word The number of Tempo Duration and Tempo pairs defined below. Must have at least 1 pair.
Length of Tempo Track word In bytes. Counting starts at MSB of Resolution.
Length of Tempo List word In bytes. Counting starts at MSB of first Tempo Duration. Must be a multiple of 8 (4 bytes for each Tempo Duration, 4 bytes for each Tempo).
Tempo 1 Duration long The amount of time (in MIDI ticks) to play the song at the following tempo for, before changing to the next tempo (when applicable; otherwise this is ignored).
Tempo 1 long Tempo to play the song at, in microseconds per quarter-note.
Tempo 2 Duration long
Tempo 2 long
etc.

Any tempo changes done within a loop won't work as intended on subsequent loops. The progression of tempos only goes forward, won't jump backwards when a loop is triggered, and the last tempo will play forever rather than wrapping back to the start of the list. This looks to be intentional, reading the Saturn docs.

Play Data

The Play Data of a track consists of a continuous series of MIDI events. Each MIDI event consists of a Status byte, and a variable number of parameter bytes, ranging from 0 to 4. All possible MIDI events are defined below.

$00 - $7F: Note On

For Note On events, the upper nybble of Status is bit flags.

Bit Mask Function
$10 Mutes the note when set, essentially changing this event to a rest.
$20 Extension bit for Delta Time parameter.
$40 Extension bit for Length parameter.

The lower nybble of Status is the channel to play the note on.

Note On events have 4 parameters.

Parameter Function Notes
$01 Pitch Middle C is $3C.
$02 Volume Clamped from $00 to $7F.
$03 Length How long the note plays, in MIDI ticks.
$04 Delta Time How long to wait before triggering this event, in MIDI ticks.

$80 - $8F: Song Flow

These events are for manipulating the song's flow.

Status Event Parameters Notes
$80 Invalid N/A Abruptly terminates the song, cutting off any active notes.
$81 Reference? 3: Offset (High), Offset (Low), Count Copies [Count] events, starting with the one at [Offset] from the start of the track. Needs confirmation.
$82 Loop Start/End 1: Delta Time First call is where loop starts, second call is where the loop ends. Delta Time is in MIDI ticks.
$83 End Song 0 Immediately ends the song, letting any active notes play out.
$84 - $87 Invalid N/A Has the same behavior as event $80.
$88 Quarter Note Extend 0 Adds the length of a quarter note to the next Note On (can stack).
$89 Whole Note Extend 0 Like $88, but the length of a whole note.
$8A 2x Whole Note Extend 0 Like $88, but the length of two whole notes.
$8B 4x (and a Quarter) Note Extend 0 Like $88, but the length of four whole notes, plus a quarter. Could probably do with a double-check, that length seems strange.
$8C One-eighth rest 0 Adds the delta time of an eighth rest to the next Note On (can stack).
$8D Quarter rest 0 Ditto, for a quarter note.
$8E Whole rest 0 Ditto, for a whole note.
$8F 2x Whole rest 0 Ditto, for two whole notes.

$90 - $9F: Invalid

On testing, these all seem to behave the same as event $80.

$A0 - $AF: Unused

The MIDI Standard and the Saturn’s docs seem to imply these are supposed to be Polyphonic Key Pressure events; however, the Saturn docs state (inconsistently) that this is unimplemented. Maybe this is just a ghost of that? I certainly don’t notice any difference when I fiddle around with it.

For any who wish to play around with them, they have 3 parameters, the last of which is Delta Time.

$B0 - $BF: Control Change

For Control Change events, the lower nybble of Status is the channel to change the control for.

Control Change events have 3 parameters.

Parameter Function Notes
$01 Control ID The control to change. Could use some investigation and documenting.
$02 Value The value to set the control to.
$03 Delta Time How long to wait before triggering this event, in MIDI ticks.

$C0 - $CF: Program Change

For Program Change events, the lower nybble of Status is the channel to change the program for.

Program Change events have 2 parameters.

Parameter Function Notes
$01 Program The program to change the channel to. Could use some investigation and documenting.
$02 Delta Time How long to wait before triggering this event, in MIDI ticks.

$D0 - $DF: Unused

Similar to the $A_ events. Docs imply they are an unimplemented ghost of Channel Pressure. I can’t notice any changes when I fiddle with it.

2 parameters, the last is Delta Time.

$E0 - $EF: Pitch Wheel

For Pitch Wheel events, the lower nybble of Status is the channel to apply the pitch wheel to.

Pitch Wheel events have 2 parameters.

Parameter Function Notes
$01 Pitch The pitch to set the wheel to. Could use some investigation and documenting.
$02 Delta Time How long to wait before triggering this event, in MIDI ticks.

$F0 - $FF: System Events

I've yet to see any of these in use, and none of them seem particularly useful for ROM hacking purposes (assuming the docs are accurate).

If someone wants to document them, feel free.

Sonic Community Hacking Guide
General
SonED2 Manual | Subroutine Equivalency List
Game-Specific
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (Master System) | Sonic 3 | Sonic 3 & Knuckles | Chaotix | Sonic Jam | Sonic Jam 6 | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Forces
Technical information
Sonic Eraser | Sonic 2 (Nick Arcade prototype) | Sonic CD (prototype; 1992-12-04) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic & Knuckles Collection | Sonic R | Sonic Shuffle | Sonic Advance | Sonic Advance 3 | Sonic Battle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Free Riders | Sonic Lost World
Legacy Guides
The Nemesis Hacking Guides The Esrael Hacking Guides
ROM: Sonic 1 | Sonic 2 | Sonic 2 Beta | Sonic 3

Savestate: Sonic 1 | Sonic 2 Beta/Final | Sonic 3

Sonic 1 (English / Portuguese) | Sonic 2 Beta (English / Portuguese) | Sonic 2 and Knuckles (English / Portuguese)
Move to Sega Retro
Number Systems (or scrap) | Assembly Hacking Guide | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | SMPS Music Hacking Guide | Mega Drive technical information