Skip to content

Instantly share code, notes, and snippets.

@Staars
Created January 4, 2024 13:14
Show Gist options
  • Save Staars/86d24b93c28cd664663c33fd9b363275 to your computer and use it in GitHub Desktop.
Save Staars/86d24b93c28cd664663c33fd9b363275 to your computer and use it in GitHub Desktop.
Berry ADPCM decoder
# Berry class to decode ADPCM sample
# ADPCM decoder implementation based on https://github.com/jwzhangjie/Adpcm_Pcm/blob/master/adpcm.c
class ADPCM
static indexTable = [
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
]
static stepSizeTable = [
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,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
]
var statePrevSample, statePrevIndex
def init()
self.statePrevSample = 0
self.statePrevIndex = 0
end
# util to clamp a number within a given range
def clamp(num, min, max)
return num <= min ? min : num >= max ? max : num
end
def decodeAdpcm(inputBuffer)
print(inputBuffer)
var outputBuffer = bytes(-(size(inputBuffer) * 4))
var outputBufferOffset = 0
for inputBufferOffset:range(0,size(inputBuffer) - 1)
var b = inputBuffer[inputBufferOffset]
outputBuffer.seti(outputBufferOffset,self.decodeSample((b >> 4) & 0xF),2)
outputBuffer.seti(outputBufferOffset+2,self.decodeSample(b & 0xF),2)
outputBufferOffset += 4
end
return outputBuffer;
end
def decodeSample(sample)
var predSample = self.statePrevSample
var index = self.statePrevIndex
var step = self.stepSizeTable[index]
var difference = step >> 3
# compute difference and new predicted value
if (sample & 0x4) difference += step end
if (sample & 0x2) difference += (step >> 1) end
if (sample & 0x1) difference += (step >> 2) end
# handle sign bit
predSample += (sample & 0x8) ? -difference : difference
# find new index value
index += self.indexTable[sample]
index = self.clamp(index, 0, 88)
# clamp output value
predSample = self.clamp(predSample, -32767, 32767)
self.statePrevSample = predSample
self.statePrevIndex = index
predSample <<= 2 # amplify
return predSample
end
end
#-
var f = open("/test.adcpm","r")
var ib = f.readbytes()
f.close()
a = ADPCM()
var raw = a.decodeAdpcm(ib)
a = nil
var f = open("/test.raw","w")
f.write(raw)
f.close()
-#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment