I'm working on a project that requires ADPCM compression of 8-bit samples to 2-bit. The ADPCM implementation I used is based off the IMA ADPCM algorithm, except adapted to 8-bit samples and 2 bit compression. I already have an encoder and decoder set up, but I've encountered a lot of noise in the conversion.
The project I'm working on is for the Sega Genesis, an old video game system; I want to stream PCM files as level music for a game. However, the Genesis only has 4MB of ROM space, so the audio files need to be compressed by at least a 4:1 ratio. Some of the decompression on the Genesis side is done using a lookup table; calculations in this part can be as complex as necessary, since it'll all be precalculated. The part that is calculated with a table is highlighted red in the decoder source; no complex floating point operations or filters can be done outside of that part in the decoder. (Anything can be changed in the encoder, since the Genesis doesn't handle the encoding.)
Here's the source for both the encoder and decoder (for the computer, not the Genesis). It's in BASIC, so hopefully it'll be pretty easy to understand despite my lack of commenting.
Function encodeSample(sample#)
Local code#
Local diff#
Local step_#
Local diffQ#
step_ = stepTable(index)
diff = sample - predSample
If diff >= 0 Then
code = 0
Else
code = 2
diff = -diff
EndIf
diffQ = step_
If diff >= step_ Then
code = code Or 1
diffQ = diffQ + step_
EndIf
If (code And 2) Then
predSample = predSample - diffQ
Else
predSample = predSample + diffQ
EndIf
If predSample > 127 Then predSample = 127
If predSample < -127 Then predSample = -127
index = index + indexTable(code)
If index < 0 Then index = 0
If index > 31 Then index = 31
Return (code And $03)
End Function
Function decodeSample(code)[color=#FF0000]
Local step_%
Local diffQ#
step_ = stepTable(index)
diffQ = step_
If (code And 1) Then
diffQ = diffQ + step_
EndIf[/color]
If (code And 2) Then diffQ = -diffQ
predSample = predSample + diffQ
If predSample > 127 Then predSample = 127
If predSample < -127 Then predSample = -127
[color=#FF0000]
index = index + indexTable(code)
If index < 0 Then index = 0
If index > 31 Then index = 31
[/color]
Return predSample
End Function
Also, here's the step table and index table that I'm using:
6,7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45
50,55,60,66,73,80,88,97,107,118,127
-1,1,-1,1
Finally, here's a sample of what the compression sounds like (it's pretty crappy).
Original File
Compressed File
For comparison, here's a sample of what 8:4 compression sounds like. I'd like to get somewhat near this quality, if possible.
8:4 Compressed File
Any help on this would be greatly appreciated. Note that I'm a newbie to this stuff, so any complex math will probably go right over my head. =P