VOGONS


First post, by bananaboy

User metadata
Rank Newbie
Rank
Newbie

I recently got interested in how the ADPCM worked on the Soundblaster, specifically the 4-bit version. I looked at the dosbox ADPCM code but it turns out that came from reverse engineering Blaster Master (old MS-DOS sound software) under the assumption that it used the Creative SDK and so the algorithm was correct and accurate. But the Creative SDK doesn't have any libs to decompress ADPCM so Gary Maddox author of Blaster Master must have figured it out himself.

But a few years ago TubeTime dumped an SB 2.02 DSP so we have the source of truth! Apologies if there has been previous discussion on this but I couldn't find anything.

It turns out the decoder looks something like this:

uint8_t DecodeADPCM4(uint8_t data, uint8_t& sample, uint8_t& accum)
{
assert(data < 0x10);

uint8_t halfAccum = accum >> 1;
uint8_t value = data & 7;
uint8_t delta = (value * accum) + halfAccum;
if (data & 8)
{
// data is negative
sample = (uint8_t)std::max((int16_t)sample - delta, 0);
}
else
{
// data is positive
sample = (uint8_t)std::min((int16_t)sample + delta, 0xff);
}

if (value == 0)
{
accum = halfAccum;
if (accum == 0)
accum = 1;
}
else if (value >= 5)
{
accum <<= 1;
if (accum == 0x10)
accum = 8;
}

return sample;
}

So it doesn't use tables, unlike dosbox. However, I compared this to dosbox and it seems to be binary identical! So great job Gary Maddox!

I found what looks like a bug in the decoding though (so a bug in the original SB - not the only one as TubeTime points out in the comments). Line 1692 loads register r3 with 4. That line is setting the number of samples to process when running the "no reference byte" DMA command. I'm fairly sure this should be 2 here though because in 4-bit each byte has two samples. In fact when the handler requests another data byte it does correctly set r3 to 2 (line 487). So it seems to me that when "no reference byte" mode is used, the first two samples will play twice.

There is also a little bug in the dosbox emulation - dosbox doesn't seem to send the first reference byte to the DAC whereas the SoundBlaster does.

Anyway I thought that was all pretty interesting.

Cheers,
Sam