(1)、本次用到的是IMA ADPCM 44.1Khz 4位单声道。ADPCM格式的wav文件头文件格式有48个文件描述字节,较普通的PCM多出4个字节的文件描述字节分别是
- u16 ByteExtraData; //附加的数据字节、
- 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电子技术开发论坛