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.
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|
|$0||00fffaaa||fff = Feedback (FB)
aaa = Algorithm
|$1||0dddmmmm||ddd = Detune (DT)
mmmm = Multiplier (MULT)
|$5||rr0aaaaa||rr = Rate scaling (RS)
aaaaa = Attack rate (AR)
|$9||a00ddddd||a = LFO enabled (AM)
ddddd = (First) decay rate (D1R/DR)
|$D||000ddddd||ddddd = Second decay rate/sustain rate (D2R/SR)||1||70||71||72|
|$11||ssssrrrr||ssss = First decay level/start level (D1L/SL)
rrrr = Release rate (RR)
|$15||0ttttttt||ttttttt = Total level (TL)||1||40||41||42|
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
There are a few exceptions to this rule:
- Michael Jackson's Moonwalker uses a different delta array for voice samples:
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:
|$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
|$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.