我正在开发小型流音频应用程序,audiochat客户端。服务器使用IMA ADPCM音频编解码器,帧速率为8000,帧大小为256字节。
解码后的声音质量很差,编码声音不会被服务器识别为更正的ima adpcm声音。
请帮我在代码中找到问题。
# -*- 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"
答案 0 :(得分:0)
我可以看到一个问题:
elif indexcode>88:
indexcode=88
stepsizecode=stepsizeTable[indexcode]
应该是:
elif indexcode>88:
indexcode=88
stepsizecode=stepsizeTable[indexcode]
这是一个非常显着的差异。
除此之外,我会尝试生成正弦测试音,通过算法运行并检查结果。我还试图排除字节和短路之间转换的任何问题。
此外,文档提供了一些测试向量,您可以使用它们来调试器。