Actions

SCHG

Difference between revisions of "Music Hacking/DAC Samples, Coordination Flags, Game Specifics, and Real-Time Music Editing"

From Sonic Retro

(Coordination flags)
(corrections to Coordination Flags and Sonic 1 DAC Pointer Table)
Line 38: Line 38:
 
* NOTE: Value is little endian, so swap the bytes to get the real value.
 
* NOTE: Value is little endian, so swap the bytes to get the real value.
 
|-
 
|-
|$05||Byte||Sample rate/pitch. The lower the value, the faster the sample will play.
+
|$04||Byte||Sample rate/pitch. The lower the value, the faster the sample will play.
 
|-
 
|-
|$06-$08||3 Bytes||Unused/redundant.
+
|$05-$07||3 Bytes||Unused/redundant.
 
|}
 
|}
  
Line 141: Line 141:
 
! Flag||Purpose
 
! Flag||Purpose
 
|-
 
|-
|$E0xx||Panning, AMS, FMS
+
|$E0xx||Panning
 
*xx - Value
 
*xx - Value
 
**Bit 7 - Left channel status
 
**Bit 7 - Left channel status
 
**Bit 6 - Right channel Status
 
**Bit 6 - Right channel Status
**Bit 5-3 - AMS
+
**Bit 5-0 - ignored (should be zero)
**Bit 2 - 0
 
**Bit 1-0 - FMS
 
 
|-
 
|-
 
|$E1xx||Set the [[SCHG:Music Hacking/Voice and Note Editing#Notes|channel frequency displacement]] to signed byte xx — that is, this byte is added to the frequency value sent to the sound chip after grabbing that frequency value from the modified note ($E9/$FB)
 
|$E1xx||Set the [[SCHG:Music Hacking/Voice and Note Editing#Notes|channel frequency displacement]] to signed byte xx — that is, this byte is added to the frequency value sent to the sound chip after grabbing that frequency value from the modified note ($E9/$FB)
 
|-
 
|-
|$E2FF||Fade-in to previous song (needed on DAC channel, <span style='color:red;'>Sonic 3 & etc</span>)
+
|$E2FF||Fade-in to previous song (needed on DAC channel, <span style='color:red;'>Sonic 3 & etc</span>)<br>Also implemented in <span style='color:red;'>Sonic 1 & 2</span>, but use unknown.
 
|-
 
|-
 
|$E3||Return (<span style='color:red;'>Sonic 1 & 2</span>)
 
|$E3||Return (<span style='color:red;'>Sonic 1 & 2</span>)
Line 159: Line 157:
 
|$E5xx||Change tempo divider to xx
 
|$E5xx||Change tempo divider to xx
 
|-
 
|-
|$E6xx||Change channel volume by xx; xx is signed
+
|$E6xx||Change FM channel volume by xx; xx is signed
 +
*Using this flag on a PSG channel seems to stop the note on the FM channel with the same number. (e.g. PSG1 stops note on FM1)
 
|-
 
|-
|$E7xx||Prevent next note from attacking
+
|$E7||Prevent next note from attacking
 
|-
 
|-
 
|$E8xx||Set note fill amount to xx
 
|$E8xx||Set note fill amount to xx
Line 167: Line 166:
 
|$E9xx||Add signed xx to the [[SCHG:Music Hacking/Voice and Note Editing#Notes|channel key displacement]]; this value accumulates (that is, if the accumulated value was 4 and xx is 3, the new accumulated value is 7) (<span style='color:red;'>Sonic 1 & 2</span>)
 
|$E9xx||Add signed xx to the [[SCHG:Music Hacking/Voice and Note Editing#Notes|channel key displacement]]; this value accumulates (that is, if the accumulated value was 4 and xx is 3, the new accumulated value is 7) (<span style='color:red;'>Sonic 1 & 2</span>)
 
|-
 
|-
|$EAxx||Set music tempo to xx
+
|$EAxx||Set tempo modifier to xx
 
|-
 
|-
|$EBxx||Change Tempo Modifier to xx for ALL channels
+
|$EBxx||Set tempo divider to xx for ALL channels
 
|-
 
|-
|$ECxx||Change channel volume to xx; xx is signed
+
|$ECxx||Change PSG channel volume by xx; xx is signed
 +
*Also usable on FM channels, but doesn't take effect until the next FM voice change (EF) or volume change (E6).
 
|-
 
|-
 
|$EE||Something with Voice Selection
 
|$EE||Something with Voice Selection
Line 178: Line 178:
 
*00 is the first voice in the bank. So in other words, subtract 01 from the value to get the voice in the bank you want.
 
*00 is the first voice in the bank. So in other words, subtract 01 from the value to get the voice in the bank you want.
 
|-
 
|-
|$F0wwxxyyzz||Modulation
+
|$F0wwxxyyzz||Modulation (also turns modulation on)
 
*ww - Wait for ww period of time before modulation starts
 
*ww - Wait for ww period of time before modulation starts
 
*xx - Modulation Speed
 
*xx - Modulation Speed

Revision as of 05:05, 23 May 2011

Music Hacking: Pointer and Header Format | Voice and Note Editing | DAC Samples, Coordination Flags, Game Specifics, and Real-Time Music Editing | Other Games and Data Locations | Tricks of the Trade



DAC Samples

DAC samples are raw PCM samples, generally used for drums and voices that you hear in game. You can customize these audio samples to your needs. Here is some information to do so below...

DAC Formats

Mega Drive

Typically (though not always), SMPS games do not store their sample data as 8-bit unsigned LPCM (the way the YM2612 takes it), but rather as 4-bit DPCM with a single shared delta array of

db 0, 1, 2, 4, 8, 10h, 20h, 40h
db -80h, -1, -2, -4, -8, -10h, -20h, -40h
This form is almost always incorrectly referred to as "compressed;" jman2050
Sonic Retro
wrote a "compressor/decompressor" to convert samples stored in this format to standard 8-bit LCPM and vice versa
.

There are a few exceptions to this rule:

db 0, 1, 2, 4, 8, 10h, 20h, 40h
db -80h, -1, -3, -4, -8, -10h, -20h, -40h
  • Streets of Rage has the DPCM delta array for each sample as the first 16 bytes of the sample.

32X

SMPS-32X stores PWM samples as 8-bit unsigned LPCM. Note Tempo uses both DPCM samples on the MD side and PWM samples simultaneously; follow the above rules for the DPCM samples.

Sega CD

Each SMPS-PCM bank has a table of samples which are stored as 8-bit sign-magnitude; the same format as the Sega CD's PCM chip demands them. This means that each byte of the sample always consists of a 1-bit sign and 7-bit magnitude. So -1 would be represented as binary 10000001, which is $81. The only exception is $FF, which is used to mark the end of sample data (and time to go back to the loop point), so don't place this in the sample data.

Sonic 1

Samples in Sonic 1 are inside the Z80 portion of the sound driver, located at $72E7C, and compressed in Kosinski format. All following locations are for the decompressed sound driver.

DAC Sample Pointers

  • DAC sample setup index: $D6

Each DAC pointer is listed one after another, and a single entry for one DAC sample is $8 bytes. The format is as follows:

Offset Size Description
$00-$01 Word Location of the DAC sample in decompressed driver.
  • NOTE: Value is little endian, so swap the bytes to get the real value.
$02-$03 Word Size of the compressed DAC sample in decompressed driver.
  • NOTE: Value is little endian, so swap the bytes to get the real value.
$04 Byte Sample rate/pitch. The lower the value, the faster the sample will play.
$05-$07 3 Bytes Unused/redundant.


Sonic 1 has 3 DAC sample slots - one for the kick, one for the snare, and one for the Timpani. The other pitches of Timpani ($88-$8B) are defined by a special table, located at $71CC4, and are fully editable to suit other samples using the Timpani slot ($83).

Sonic 2

DAC Sample Pointers

  • Pointers to DAC Samples in Sonic 2 Beta: $ECDA6


Specifics...

  • $ECDA6 - Sample 81 pointer
  • $ECDA8 - Sample 81 length
  • $ECDAA - Sample 82 pointer
  • $ECDAC - Sample 82 length (skip FF)
  • $ECDAF - Sample 83 pointer
  • $ECDB1 - Sample 83 length
  • $ECDB3 - Sample 84 pointer
  • $ECDB5 - Sample 84 length (skip FF)
  • $ECDB8 - Sample 85 pointer
  • $ECDBA - Sample 85 length
  • $ECDBC - Sample 86 pointer
  • $ECDBE - Sample 86 length -- This one is tricky. You need to skip the second FF, as the first FF is valid.


  • Pointers to DAC Samples in Sonic 2 Final: $ECF7C

Specifics...

  • $ECF7C - Sample 81 pointer
  • $ECF7E - Sample 81 length
  • $ECF81 - Sample 82 pointer
  • $ECF83 - Sample 82 length
  • $ECF85 - Sample 83 pointer
  • $ECF87 - Sample 83 length
  • $ECF8A - Sample 84 pointer
  • $ECF8C - Sample 84 length
  • $ECF8E - Sample 85 pointer
  • $ECF90 - Sample 85 length
  • $ECF93 - Sample 86 pointer
  • $ECF95 - Sample 86 length
  • $ECF97 - Sample 87 pointer
  • $ECF99 - Sample 87 length

These pointers are 4 bytes in size. First two bytes are the pointer to the sample (the pointers add to E0000, little endian, and don't follow the music pointer format. Simple 16-bit absolute), and the other two bytes are the length of the sample (also little endian). If you see an FF, skip it and move on to the next byte.


DAC Master List

  • DAC Master List in Sonic 2 Beta: $ECDC1
  • DAC Master List in Sonic 2 Final: $ECF9C

These work similarly to the master playlist in concept.. The format is two bytes per sample. First byte defines the sample ID, and the second byte defines the rate that the sample is played at. The lower the rate value, the faster the sample is played. This is used to make certain samples (like toms) appear to have different pitches (high tom, low tom, etc). If you see an FF, skip it and move on to the next byte. If you touch the FF, you fuck the entire sound driver. Don't. :P

Sonic 3

Setup Pointers

  • DAC $81-$9A Pointer Index (Adds to $E0000): $E0000
  • DAC $9B-$AA Pointer Index (Adds to $E8000): $E8000
  • DAC $AB-$C0 Pointer Index (Adds to $F0000): $F0000

These pointer indexes work by pointing to the sample setup data for the particular samples. You'll notice there are 3 pointer indexes - this is since not all the samples can fit in a single bank, so they span 3 banks. The pointers are repeated at all 3 indexes, but only the defined samples for the index (listed above) will be in the relevant ROM bank.

DAC Sample Setup Format

The format for a DAC sample entry is pretty simple. Follow along:

Offset Size Function
$00 Byte Sample rate/pitch. The lower the value, the faster the sample will play.
$01-$02 Word Size of the DAC sample, in bytes.
  • NOTE: Value is little endian, so remember to swap the bytes to get the real value.
$03-$04 Word Pointer to the DAC sample, within the current bank.
  • NOTE: Value is little endian, so remember to swap the bytes to get the real value.

32X SMPS - PWM

32X games that use the PWM driver for song samples have a sample table of the form

Offset Size Function
$00 Long The virtual (SH-2 side) address of the sample — take out the first byte for the ROM address.
$04 Long Size of the DAC sample, in bytes.
$08 Long Zero. Purpose unknown.
$0C Long Sample rate/pitch. The lower the value, the slower the playback rate. A sample rate of $00000800 is equal to 11025hz.

Coordination flags

Coordination flags are values in the range of $E0-$FF in notation that perform special functions. The use of coordination flags can range from branching to specific locations in the song to altering volume, voice number, pitch, and other variables in real time.

Three of the coordination flags change between S1/S2 and S3/S&K. The rest are the same throughout.

Flag Purpose
$E0xx Panning
  • xx - Value
    • Bit 7 - Left channel status
    • Bit 6 - Right channel Status
    • Bit 5-0 - ignored (should be zero)
$E1xx Set the channel frequency displacement to signed byte xx — that is, this byte is added to the frequency value sent to the sound chip after grabbing that frequency value from the modified note ($E9/$FB)
$E2FF Fade-in to previous song (needed on DAC channel, Sonic 3 & etc)
Also implemented in Sonic 1 & 2, but use unknown.
$E3 Return (Sonic 1 & 2)
$E4 Fade-in to previous song (needed on DAC channel, Sonic 1 & 2)
$E5xx Change tempo divider to xx
$E6xx Change FM channel volume by xx; xx is signed
  • Using this flag on a PSG channel seems to stop the note on the FM channel with the same number. (e.g. PSG1 stops note on FM1)
$E7 Prevent next note from attacking
$E8xx Set note fill amount to xx
$E9xx Add signed xx to the channel key displacement; this value accumulates (that is, if the accumulated value was 4 and xx is 3, the new accumulated value is 7) (Sonic 1 & 2)
$EAxx Set tempo modifier to xx
$EBxx Set tempo divider to xx for ALL channels
$ECxx Change PSG channel volume by xx; xx is signed
  • Also usable on FM channels, but doesn't take effect until the next FM voice change (EF) or volume change (E6).
$EE Something with Voice Selection
$EFxx Change current voice to xx
  • 00 is the first voice in the bank. So in other words, subtract 01 from the value to get the voice in the bank you want.
$F0wwxxyyzz Modulation (also turns modulation on)
  • ww - Wait for ww period of time before modulation starts
  • xx - Modulation Speed
  • yy - Modulation change per Mod. Step
  • zz - Number of steps in modulation
$F1 Turn on modulation
$F2 Stop the track
$F3xx Change current PSG noise to xx (For noise channel)
  • Applicable values are E0 - E7
  • Anything beyond E7 will wrap back to the E0 waveform
$F4 Turn off modulation
Sonic CD: Same as $F6
$F5xx Change current PSG tone to xx
$F6yyyy Jump to position yyyy
$F7xxyyzzzz Repeat section of music
  • xx - Loop index, for loops within loops without confusing the engine.
    • EXAMPLE: Some notes, then a section that is looped twice, then some more notes, and finally the whole thing is looped three times.
      The "inner" loop (the section that is looped twice) would have an xx of 01, looking something along the lines of F70102zzzz, whereas the "outside" loop (the whole thing loop) would have an xx of 00, looking something like F70003zzzz.
  • yy - Number of times to repeat
    • NOTE: This includes the initial encounter of the F7 flag, not number of times to repeat AFTER hitting the flag.
  • zzzz - Position to loop back to
$F8yyyy Jump to position yyyy (keep previous position in memory for returning)
$F9 Return (Sonic 3 & etc)
$FBxx Add signed value xx to channel key displacement; this value accumulates (that is, if the accumulated value was 4 and xx is 3, the new accumulated value is 7) (Sonic 3 & etc, Sonic CD)
$FCyyyy Loop Sound Effect from position yyyy. (Sonic 3 & etc)

Note on $F3

The $F3 flag determines whether a PSG channel--usually the last one defined in the header--is a tone channel or the noise channel. There is only one noise channel, and 3 tone channels. Also worth noting is that a tone channel can become a noise channel mid-song; however, once it becomes a noise channel, it can not switch back to a tone at any point.

Note on $F8 and $F9/$E3

Flags $F8 and $F9/$E3 work similarly to the opcodes jsr and rts in terms of function. $F8 will branch to a location within the song, saving the previous location to the stack; once the data is parsed, the $F9/$E3 flag will pop the stack to the program counter, continuing on in the song after the initial $F8 branch. This effect is utilized by Puto frequently in the xm4smps program to structure SMPS files similarly internally to XM module files.

Notes on $E0

Only FM and DAC channels can be panned, the PSG channels will ignore this flag. In Sonic 1, if the sixth channel (either FM6 or the DAC) of your Game Over song is panned, the SEGA sound after the reset will be panned as well. In OutRun the DAC channel cannot be panned; each sample has its own panning setting, defined in the DAC table.

Game Specifics

Sonic 2

Master Playlist

Sonic 2 has a special "master playlist" that defines what music ID plays in what slot. It works by taking a base address - generally the start of a music bank - and, for each increment of the value, it reads ahead another word in the current ROM bank. So, say, $00 would be the first word in the bank ($00-$01), $01 would be the next ($02-$03), and so on. The base address for this bank, in both Sonic 2 Beta AND final, is $F0000, and the addressing range spans as far as the value can allow, which is two Z80 ROM banks ($10000 bytes).

However, as a simple guide to understanding how it works (at least, for the casual hacker), all values for the original, untouched music (for the most part, anyway) subtract $1 from the value. So, to change Track 81 to Track 82, change $80 to $81. $80 is $81, $81 is $82, etc. These values go up to slot $9F, or $1F (visually, anyway - the game still uses $80 > values internally) in the final version of the game. The only exception to this is in Sonic 2 Beta, where some songs use the upper $8000 bytes of the bank start address to store music (making the values for calling said music start with $00). The locations for the master playlist are as follows:

  • Master Playlist in Sonic 2 Beta: $ECE9F
  • Master Playlist in Sonic 2 Final: $ECF36

As previously mentioned, track 81 is represented by $80, 82 is reresented by $81, etc. If you see an $FF, skip it and move on to the next byte - these are compression bytes for the driver, and touching them will bork the decompressor in-game, and prevent the sound driver from booting. The "master playlist" is only in Sonic 2 (Beta/Final) as far as I know. If I find it in any other games, I will update this section.

Music Compression

In Sonic 2 Final, there is a compression applied to all music data in the game except for the credits. This format has been dubbed the saxman compression, named after the person who cracked the format. I will not note how to manually decompress this format -- Refer to saxman's hacking guide to do so. The music can be decompressed by using Magus' Sega Data Compressor. Refer to the pointer format to edit the music properly.

Sonic 3

Universal Voice Bank

In Sonic 3, some songs have the value "$D817" as their voice pointer. When a song has this in its voice pointer, that means it's being prepped to use a global set of multiple voices that any song in the game can use. This is generally used to save space for songs that use the same voices. Interestingly enough, though, the Special Stage music has the first 5 voices used in the Universal Voice Bank, and all in the same order, so it's puzzling why they didn't just have the song use the bank (as it's fully capable of doing so).

  • Universal Voice Bank in Sonic 3: $E77D8
Universal Voice Bank definitions

Using the Universal Voice Bank is akin to using voices in a normal song - each voice has a value, defined by coordination flag $EF. Here are some of the voices used in the Universal Voice Bank.

Value Description
$00 Synth Bass 2
$01 Trumpet 1
$02 Slap Bass 2
$03 Synth Bass 1
$04 Bell Synth 1
$05 Bell Synth 2
$06 Synth Brass 1
$07 Synth like Bassoon
$08 Bell Horn type thing
$09 Synth Bass 3
$0A Synth Trumpet
$0B Wood Block
$0C Tubular Bell
$0D Strike Bass
$0E Elec Piano
$0F Bright Piano
$10 Church Bell
$11 Synth Brass 2
$12 Bell Piano
$13 Wet Wood Bass
$14 Silent Bass
$15 Picked Bass
$16 Xylophone
$17 Sine Flute
$18 Pipe Organ
$19 Synth Brass 2
$1A Harpischord
$1B Metallic Bass
$1C Alternate Metallic Bass
$1D Backdropped Metallic Bass
$1E Sine like Bell
$1F Synth like Metallic with Small Bell.
$20 Nice Synth like lead.
$21 Rock Organ
$22 Strike like Slap Bass

Realtime Music Editing

By editing values in savestates, you can edit music, pointers and other various values in realtime. Re-load the savestate to see your changes applied!

Sonic 3/Sonic & Knuckles

Offset Z80 RAM Location Purpose
$001A8C 1618 Music Pointers (Sonic & Knuckles)
$001A8E 161A Music Pointers (Sonic 3)
$001778 1304 Pointer for Music Pointers
$000FD9 0B65 Music Bank IDs (Sonic & Knuckles)
$000FBC 0B48 Music Bank IDs (Sonic 3)
$00177A 1306 Pointer for Sound Effect Pointers
$001AF2 167E Sound Effect Pointers

Sonic 3D

Offset Z80 RAM Location Purpose
$001AD0 165C Music Pointers
$001778 1304 Pointer for Music Pointers
$00177A 1306 Pointer for Sound Effect Pointers
$001AD0 165C Music Pointers
$001B34 16C0 Sound Effect Pointers

Sonic 2 Final

Offset Z80 RAM Location Purpose
$001669 11F5 Master Playlist
$000C16 07A2 Pointer for Master Playlist
$000DF9 0985 Pointer for Sound Effects list
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