[英]Python IMA ADPCM codec
I am developing small streaming audio app, audiochat client. 我正在开发小型流音频应用程序,audiochat客户端。 Server uses IMA ADPCM audio codec, framerate 8000, 256 bytes frame size. 服务器使用IMA ADPCM音频编解码器,帧速率为8000,帧大小为256字节。
I'm using algoritm described here 我使用algoritm描述这里
Refernce compressed sound available here 参考压缩声音在这里可用
The quality of decoded sound is poor, and coded sound don't recognising by server as corrected ima adpcm sound. 解码声音的质量很差,并且服务器无法将编码声音识别为已校正的ima adpcm声音。
Please help me to find problem in my code. 请帮助我在代码中查找问题。
# -*- coding: Utf-8 -*-t
import wave, struct
indexTable=[
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
]
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
]
def pcm2adpcm(frame): #frame - 1024 Bytes uncompressed
indexcode = 0
stepsizecode = 7
global indexTable
global stepsizeTable
predictedSample = 0
lstres=list()
for i in range(0,len(frame)): # Taking bytes
if (i+1)%2==0:
binsample=frame[i-1:i+1:]
originalsample=struct.unpack('h',binsample)[0] # To signed int
difference = originalsample-predictedSample
if difference>=0:
newSampleCode=0
else:
newSampleCode=8
difference=-difference
mask=4
tempStepsize=stepsizecode
for i in range(0,3):
if difference>=tempStepsize:
newSampleCode|=mask
difference-=tempStepsize
tempStepsize>>=1
mask>>=1
lstres.append(newSampleCode)
difference=0
if newSampleCode&4:
difference+=stepsizecode
if newSampleCode&2:
difference+=stepsizecode>>1
if newSampleCode&1:
difference+=stepsizecode>>2
difference+=stepsizecode>>3
if newSampleCode&8:
difference=-difference
predictedSample+=difference
if predictedSample>32767:
predictedSample=32767
if predictedSample<-32767:
predictedSample=-32767
indexcode+=indexTable[newSampleCode]
if indexcode<0:
indexcode=0
elif indexcode>88:
indexcode=88
stepsizecode=stepsizeTable[indexcode]
resultBinary=''
for i in range(0,len(lstres)):
if (i+1)%2==0:
#print lstres[i], lstres[i-1], (lstres[i]<<4)|lstres[i-1]
resultBinary+=chr((lstres[i]<<4)|lstres[i-1])
return resultBinary
def adpcm2pcm(frame): #frame - 256 Bytes compressed
index = 0
stepsize = 7
global indexTable
global stepsizeTable
newSample = 0
resultBinary=''
for i in range(0,len(frame)): # Taking bytes
binsample=frame[i]
originalsample=ord(frame[i]) #
secoundsample=originalsample>>4 # Secound 4 bit sample
firstsample=(secoundsample<<4)^originalsample # first 4 bit sample
lst=[firstsample,secoundsample] # To list
for originalsample in lst:
difference=0
if originalsample & 4:
difference+=stepsize
if originalsample & 2:
difference+=stepsize >> 1
if originalsample & 1:
difference+=stepsize >> 2
difference+=stepsize >> 3
if originalsample & 8:
difference=-difference
newSample+=difference
if newSample>32767:
newSample=32767
elif newSample<-32767:
newSample=-32767
resultBinary+=struct.pack('h',newSample)
index+=indexTable[originalsample]
if index<0:
index = 0
elif index>88:
index = 88
stepsize=stepsizeTable[index]
return resultBinary
if __name__ == '__main__':
#===========================================================================
# fout=wave.open('res.wav', 'wb')
# fout.setnchannels(1)
# fout.setsampwidth(2)
# fout.setframerate(8000)
# f=open('1.wav','rb')
# f.seek(60)
# for i in range (0,153):
# out=adpcm2pcm(f.read(256))
# fout.writeframesraw(out)
# fout.close()
#===========================================================================
f=open('1.wav','rb')
header=f.read(60)
foutcompr=open('resCompr.wav','wb')
foutcompr.write(header)
fout=wave.open('res.wav', 'rb')
n=0
while n<fout.getnframes():
foutcompr.write(pcm2adpcm(fout.readframes(512)))
n+=512
foutcompr.close()
print "finish"
I can see one problem: 我可以看到一个问题:
elif indexcode>88:
indexcode=88
stepsizecode=stepsizeTable[indexcode]
should be: 应该:
elif indexcode>88:
indexcode=88
stepsizecode=stepsizeTable[indexcode]
That's a pretty significant difference. 那是一个相当大的差异。
Aside from that I would try generating a sine test tone, running that through the algorithm and examining the result. 除此之外,我将尝试生成正弦测试音,通过算法运行并检查结果。 I'd also try to rule out any issues with the conversion between bytes and shorts. 我还将尝试排除字节和短裤之间转换的任何问题。
Also, the documentation gives some test vectors that you could use to step through with a debugger. 此外,文档还提供了一些测试向量,您可以使用它们逐步调试程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.