ADPCM解码

       (1)、本次用到的是IMA ADPCM 44.1Khz 4位单声道。ADPCM格式的wav文件头文件格式有48个文件描述字节,较普通的PCM多出4个字节的文件描述字节分别是 

  1. u16 ByteExtraData;   //附加的数据字节、
  2. u16 sampleperblock;      /数据块中的采样数量
typedef struct
{
  uint32_t   uChunkID;       /* 0 */
  uint32_t   uFileSize;      /* 4 */
  uint32_t   uFileFormat;    /* 8 */

  uint32_t   uSubChunk1ID;   /* 12 */
  uint32_t   uSubChunk1Size; /* 16*/
  uint16_t   wAudioFormat;   /* 20 */
  uint16_t   wNbrChannels;   /* 22 */
  uint32_t   uSampleRate;    /* 24 */
  uint32_t   uByteRate;      /* 28 */
  uint16_t   wBlockAlign;    /* 32 */
  uint16_t   wBitPerSample;  /* 34 */

  uint16_t   ByteExtraData;     /* 36 */   //附加的数据字节
  uint16_t   sampleperblock;  /* 38 */     //数据块中的采样数量 

  uint32_t   uSubChunk2ID;   /* 40 */
  uint32_t   uSubChunk2Size; /* 44 */

}WAVE_DESC_T;

       (2)、 APDCM的音频数据与PCM的音频数据有较大区别,ADPCM是压缩的音频数据需要解码,PCM的音频数据是原始数据不需要解码,因此PCM格式的音频数据是以原始的音频流数据顺序存储下去的。ADPCM的音频数据则是以块的形式存取,并且有固定的大小和格式。每一个block包含header和data两部分。

Typedef struct{ 

         short  sample0;    //block中第一个采样值(未压缩) 2个字节

         BYTE  index;     //上一个block最后一个index,第一个block的index=0; 1个字节

         BYTE  reserved;   //尚未使用 1个字节

}MonoBlockHeader  块的头部

        (3)、前2个字节的为未压缩的原始16bit数据,第3个字节为上一个块的index,第4个字节为保留位,ADPCM每个数据块的解压需要前三个字节的数据作为解压函数的dec_state结构体参数输入到解压函数中。解压时输入的是数据块中第四个字节开始,解压出的数据存放在数组的第3位开始前2位已经存放了数据块中的前两个字节的未压缩数据。

struct adpcm_state {
    short	valprev;	/* Previous output value */
    char	index;		/* Index into stepsize table */
};
//解压函数
void adpcm_decoder(char*inbuff, char*outbuff, int len_of_in,struct adpcm_state *state );

 //数据解码
        if(flag)
        {
            dec_state.index =0;  //第一个block的index为 0
            flag=0;
        }
        else
        {
            dec_state.index =EncodeBuf[2];  //其余个block的index为块中的第三个值
        }

        dec_state.valprev =(short)EncodeBuf[0]+((short)(EncodeBuf[1]))*256;   //每一个block里面帧头有一个未压缩的数据 存储时 先低后高
        pCWaveTmp->aBuf[0].aucBuf[0]= EncodeBuf[0];    //存储第一个没有被压缩的数据
        pCWaveTmp->aBuf[0].aucBuf[1]=EncodeBuf[1];     //存储第一个没有被压缩的数据

        pCWaveTmp->wLen = DECODE_SIZE>>1;
        adpcm_decoder(&EncodeBuf[4],&(pCWaveTmp->aBuf[1]),ENCODE_SIZE-4,&dec_state);//解码一个DecodeBuf共4082字节

        (4)、数据0200(小端模式)即02=2表示有附加2个字节的额外数据(我个人的理解),数据F907(小端模式)  即7F9=2041表示 ADPCM每个块有2040采样点数加上1个16bit的原始数据,每4bit表示一个采样点。所以可以求解出ADPCM一个数据块的大小为(2041-1)/2+4=1024即1k,+4是指加上数据块前头部MonoBlockHeader的四个字节数。

        (5)、一个1k数据块解压出的数据量并不是4K而是4082个字节,即2040*2+2=4082,2040个采样点一个采样点可以恢复出2个字节的原始数据,再加上数据块中的原始2字节一共4082个字节。

参考文章:

Microsoft WAVE soundfile format

振南对ADPCM音频编解码原理的通俗阐述 [附振南ADPCM解码源码] - 单片机论坛,单片机技术交流论坛 - 21ic电子技术开发论坛

IMA-ADPCM 文件解析及编解码(参考了正点原子的录音例子) (amobbs.com 阿莫电子论坛 - 东莞阿莫电子网站)

ADPCM 编码 及WAV解析 及实例_wandersky0822的博客-CSDN博客_adpcm编码

振南对WAV音频格式深入剖析(ADPCM编码) 对VS1003录WAV及解码有用 - 单片机论坛,单片机技术交流论坛 - 21ic电子技术开发论坛

音频编码(PCM,ADPCM,WAVE文件) - 静哥哥0224 - 博客园

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值