Python IMA ADPCM编解码器

Python IMA ADPCM编解码器,python,audio,Python,Audio,我正在开发小型流媒体音频应用程序,audiochat客户端。服务器使用IMA ADPCM音频编解码器,帧速率8000,帧大小256字节 我正在使用描述的算法 参考压缩声音 解码声音的质量较差,服务器无法将编码声音识别为正确的ima adpcm声音 请帮我找出代码中的问题 # -*- coding: Utf-8 -*-t import wave, struct indexTable=[ -1, -1, -1, -1, 2, 4, 6, 8, -

我正在开发小型流媒体音频应用程序,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"
#-*-编码:Utf-8-*-t
导入波,结构
不可名状=[
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
] 
阶梯形=[
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(帧):#帧-1024字节未压缩
indexcode=0
stepsizecode=7
全局可索引
全局可分级
predictedSample=0
lstres=list()
对于范围(0,len(frame))中的i:#取字节
如果(i+1)%2==0:
binsample=帧[i-1:i+1:]
originalsample=struct.unpack('h',binsample)[0]#到带符号整数
差异=原始样本预测样本
如果差值>=0:
newSampleCode=0
其他:
newSampleCode=8
差异=-差异
掩码=4
tempStepsize=stepsizecode
对于范围(0,3)内的i:
如果差异>=tempStepsize:
newSampleCode |=掩码
差异-=步长
tempStepsize>>=1
掩码>>=1
lstres.append(newSampleCode)
差=0
如果newSampleCode&4:
差值+=步长码
如果newSampleCode&2:
差异+=步长码>>1
如果newSampleCode&1:
差异+=步长码>>2
差异+=步长码>>3
如果新闻示例代码为&8:
差异=-差异
预测样本+=差异
如果predictedSample>32767:
predictedSample=32767
如果predictedSample>3
如果原始样本&8:
差异=-差异
newSample+=差异
如果newSample>32767:
newSample=32767
elif newSample我可以看到一个问题:

elif indexcode>88:
    indexcode=88
stepsizecode=stepsizeTable[indexcode]
应该是:

elif indexcode>88:
    indexcode=88
    stepsizecode=stepsizeTable[indexcode]
这是一个非常显著的区别

除此之外,我会尝试生成一个正弦测试音调,通过算法运行它并检查结果。我还试图排除字节和短字符之间转换的任何问题


此外,文档中还提供了一些测试向量,您可以使用这些向量逐步完成调试器。

您可以发布您遇到的错误吗?杰夫,谢谢您的回复。我没有任何错误。脚本运行得很好,但音质很差。你有过这样的工作吗?需要同样的东西。是的,我需要。资料来源如下: