SMPS/Voices and samples

From Sega Retro

Back to: SMPS.

SMPS is in command of two synthesizers (YM2612 and SN76489) and three samplers (the YM2612's DAC channel, RF5C164, and the Sega 32X PCM chip). We refer to the instrument format of the synthesizers as voices and the instrument format of the samplers samples.

YM2612 Voices

Mega Drive SMPS allows songwriters to program their own YM2612 FM voices: each song carries an array of YM2612 voices; the first field in the SMPS header points to the voice array.

YM2612 voices are arrays of $19 bytes that get mapped to one of the YM2612's various operators:

Offset Byte Layout (Binary) Description Operator Register
Ch.1/3 Ch.2/4 Ch.3/6
$0 00fffaaa fff = Feedback (FB)
aaa = Algorithm
-- B0 B1 B2
$1 0dddmmmm ddd = Detune (DT)
mmmm = Multiplier (MULT)
1 30 31 32
$2 3 38 39 3A
$3 2 34 35 36
$4 4 3C 3D 3E
$5 rr0aaaaa rr = Rate scaling (RS)
aaaaa = Attack rate (AR)
1 50 51 52
$6 3 58 59 5A
$7 2 54 55 56
$8 4 5C 5D 5E
$9 a00ddddd a = LFO enabled (AM)
ddddd = (First) decay rate (D1R/DR)
1 60 61 62
$A 3 68 69 6A
$B 2 64 65 66
$C 4 6C 6D 6E
$D 000ddddd ddddd = Second decay rate/sustain rate (D2R/SR) 1 70 71 72
$E 3 78 79 7A
$F 2 74 75 76
$10 4 7C 7D 7E
$11 ssssrrrr ssss = First decay level/start level (D1L/SL)
rrrr = Release rate (RR)
1 80 81 82
$12 3 88 89 8A
$13 2 84 85 86
$14 4 8C 8D 8E
$15 0ttttttt ttttttt = Total level (TL) 1 40 41 42
$16 3 48 49 4A
$17 2 44 45 46
$18 4 4C 4D 4E

It should be noted that some games, such as Sonic the Hedgehog 2, store operator bytes in the order 1-2-3-4 instead of 1-3-2-4; use the following image to see how to adjust the proper bytes:

SN76489 (PSG) Voices

For Mega Drive SMPS, the driver itself maintains the array of PSG voices. For Master System and Game Gear SMPS, it is believed that the songs carry their own, like with Mega Drive SMPS and YM2612 voices.

A PSG voice is merely a list of PSG volumes. PSG volumes range from $00 (loudest) to $0F (silent). Timing for when a new volume is chosen is not known (though it is believed to be every vertical interrupt). The list ends with the final volume's highest bit set; if the resultant byte is $80, the previous byte value is treated as the last.

Mega Drive PCM Samples

Every Mega Drive SMPS game formats the DAC array differently.

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 PWM Samples

The slave SH-2 references the PWM table which is stored in a different place in each ROM. The table is just an array of entries of the following format:

Offset Size Function
$00 Long The SH-2 side address of the sample — take out the first byte (bitwise AND $00FFFFFF) for the ROM address.
$04 Long Size of the 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.

SMPS-32X stores PWM samples as 8-bit unsigned LPCM. Note Tempo uses both YM2612 DAC samples and PWM samples simultaneously; follow the Mega Drive SMPS rules for the DPCM samples.

Sega CD PCM Samples

Each SMPS-PCM bank has a table of samples of the form

dc.l number of samples
dc.l pointer to sample structure for sample 1
dc.l pointer to sample structure for sample 2
; ...

Each pointer points to a sample structure of the form

Offset Size Function
$00 Long Sub 68000 side address of sample; bitwise AND $3FFFF to get the address within the bank file.
$04 Long Length of sample.
$08 Long Loop point. Whether or not a value of 0 means no loop is unknown.
$0C Word Purpose unknown; it is used by some sort of preloading routine.
$0E Word 0. Possibly unused.

Samples are stored as 8-bit sign-magnitude; the same format as the RF5C164 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.