Sonic Jam/Sounds
From Sonic Retro
SCHG: Sonic Jam |
---|
Main Article |
Sonic World |
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.