APE结构组成
APE_DESCRIPTOR | 描述信息 |
APE_HEADER | 头 |
Table | 表 |
(Wav头) | 标识头 |
Frame* | 帧 |
1,APE_DESCRIPTOR:
APE结构的描述数据块。它描述了APE的长度,偏移量等信息内容
<4*1> | cID[4] | 必须为:‘MAC ‘ |
版本号<4> | nVersion | 大于3980为现有的新版本,其他的为老式的压缩编解码 |
描述块<4> | nDescriptorBytes | 为以后的头扩展用 |
表<4> | nHeaderBytes | 表(Table)块的大小 |
头数据块<4> | nSeekTableBytes | 源文件中获得 |
帧数据<4> | nHeaderDataBytes | 帧数据所占的总字节数 |
高次序的帧数据<4> | nHeaderDataBytesHigh |
|
终止符<4> | nTerminatingDataBytes | APE文件的终止符 |
MD5<16*1> | CFileMD5[16] |
|
注:<n> n为字节数
2,APE_HEADER
压缩比<2> | nCompressionLevel | Fast=1000;normal=2000;high=3000;extrahigh=4000;insane=5000 |
格式标识<2> | nFormatFlags | 用来判定有没有wave数据块 |
每一帧的大小<4> | nBlocksPerFrame | 为每一帧采样数的大小 |
最后一帧的大小<4> | nFinalFrameBlocks |
|
总帧数<4> | nTotalFrames |
|
量化位数<2> | nBitsPerSample |
|
声道<2> | nChannels |
|
采样率<4> | nSampleRate |
|
注:<n> n为字节数
3,Table< APE_DESCRIPTOR 中nSeekTableBytes大小 / 4>
4,Wav头格式(可选)<44>:
用APE_HEADER nFormatFlags判断
5,frame
① Frame-header <4> | ② (etc) <4> | ③ <1> | ④ Buffer <1> | ⑤ Data <n> | ①Frame-header |
注:<m> m代表字节数。此结构为ape帧的结构。第一帧的并不是音频数据,可能只是为了便于压缩而用。()代表可选,根据实际情况而定。
①
该数据块为帧头,所占的字节数,根据当前帧所处的位置而确定该帧所取的4个字节
根据m_nBits和m_nRefillBitThreshold的值确定:
m_nBits为开辟的缓存区所占的位数,m_nRefillBitThreshold=m_nbits-512。从第一帧开始计数为m_nCurrentBitIndex=0,然后依次读取并改变m_nCurrentBitIndex的值,并且进行下列判断:
if(m_nCurrentBitIndex> m_nRefillBitThreshold)
m_nCurrentBitIndex= m_nCurrentBitIndex&31
②
该数据块根据Frame-header值判断是否存在。
If(帧头的数据值与0x80000000的与运算值)
存在,获取该值,该值的获取与①相同
Else
不存在
③
此字节可以忽略,但是文件指针的值必须移动,该值的获取与①相同
④
此字节为解码中缓存的大小,用于后期解码音频数据之用,该值的获取与①相同
⑤
音频数据块,即样本值。该音频的样本数大小根据APE_HEADER的nBlocksPerFrame的值确定,当样本数=nBlocksPerFrame时,代表该帧结束。最后一帧的样本数= nFinalFrameBlocks时结束。
整个解码过程中用m_nCRC = 0xFFFFFFFF 进行CRC循环校验。
官网:http://www.monkeysaudio.com/