APE文件格式解析

来源:互联网 发布:大数据对城市规划意义 编辑:程序博客网 时间:2024/05/06 14:50

一、APE简单介绍

APE是Monkey’s Audio提供的一种无损压缩音频格式。与mp3、ogg有损压缩方式不同,庞大的WAV音频文件通过Monkey’Audio软件进行“瘦身”压缩, 压缩比大约为2 ∶ 1(为源文件的60%左右)。由于采用特殊算法,保证音质不受损失,通过解压缩可以得到与源文件一致的品质,即通过Monkey’还原成WAV,还可把APE音频格式刻录成CD保存。而还原后的音乐文件与压缩前一模一样,没有任何音质损失,因此可以用他来保存、复制CD。因为被压缩后的APE 文件容量要比WAV源文件小一半多,如用于网络音频文件传输,可以节约传输所用的时间且能保持音质。其特点如下所示:

(1)Monkey‘s Audio是高优化和高效率的;

(2)无损压缩,没有质量损失;

(3)可以被大多数的流行players和rippers支持,如Media Center、Foobar、WMP、Winamp等;

(4)完全免费和开源。

二、APE文件结构

1、Header句法结构

Header的内容包括:文件的属性、sound的参数(如声道数、采样率等)、内部结构(如帧数、Seek Table,甚至可能包括WAV的header)。Header的句法结构如下图所示:


2、Header句法元素含义

(1)tag:此元素的值为四个字符“MAC ”,是APE文件的标志。可以通过该标志来判断一个媒体文件是否为APE文件。

(2)compression_level:压缩等级,对应的等级如下所示:


(3)format_flags:APE文件标记,标记了APE文件以及APE编码格式的一些属性,如sample的位数、是否含有CRC校验、是否含有WAVE Header等等。ffmpeg对format_flags值的定义如下所示,这也是在句法结构图中的那些数字的含义。

#define MAC_FORMAT_FLAG_8_BIT                 1 // is 8-bit [OBSOLETE]#define MAC_FORMAT_FLAG_CRC                   2 // uses the new CRC32 error detection [OBSOLETE]#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL        4 // uint32 nPeakLevel after the header [OBSOLETE]#define MAC_FORMAT_FLAG_24_BIT                8 // is 24-bit [OBSOLETE]#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS    16 // has the number of seek elements after the peak level#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER    32 // create the wave header on decompression (not stored)

(4)seek_table_length:标识了seek_table的长度。在file_version大于等于3980的版本中,seek_table_length是seek_table所占用的字节数;而在file_version小于3980的版本中,seek_table_length是seek_table包含的数组元素个数,与seek_table包含字节数为四倍的关系。

(5)seek_table:seek_table中存放的是每个frame在APE文件中的position。但是,在真正去读取frame的时候,需要考虑四字节对齐的问题。

(6)tatal_frames:包含frame的个数。

(7)blocks_per_frame:标识每个frame包含的block的个数,这只对前total _frames - 1的frame有效。对于最后一个frame,它所包含的block的个数由句法元素final_frame_blocks的值来指定。

(8)final_frame_blocks:最后一个frame包含的block的个数。

3、APE Tag结构

APE tag用来存放metadata数据,比如歌名、演唱者、专辑名等等,这些信息就称为tag(标签)信息。APE tag有两个版本,即APEV1与APEV2。APEV1一般放在文件的末尾,而APEV2具有与ID3v2一样的灵活性和可括展性,字段名可自定义,字段长度可扩展,同时格式定义又不像ID3v2那么繁琐。APEV2的格式很简单,实现起来也很方便,tag存放位置是可选的,既可以在文件头也可以在文件尾。APEV1与APEV2的区别主要有两个方面:

(a)APEV1使用的是ACSII编码,二APEV2使用的是UTF-8编码,使得可以实现unicode支持。

(b)APEV2标准里增加了一个APE Tags Header,APEV1里面没有。

APEV1与APEV2的结构分别如下图所示:

(1)APE Tags Header

APE Tags Header只在APEV2中才有,其内容包括整个tag的长度、item的个数等。最开始是固定的8个字符“APETAGEX”,用来标识tag header的开始。APE Tags Header与APE Tags Footer的结构相似,唯一的不同就是Tags Flag中的一个bit,这也是用于区分APE Tags Header与APE Tags Footer的一个标记。APE Tags Header的结构如下所示:

(2)APE Tag Item

APE Tag Item存在于APEV1和APEV2中,其结构如下所示:

(3)APE Tags Footer

APE Tags Footer与APE Tags Header的结构相似,但它可以存在于APEV1和APEV2中。唯一的不同就是Tags Flag中的一个bit位,这也是用于区分APE Tags Header与APE Tags Footer的一个标记。最开始是固定的8个字符“APETAGEX”,用来标识tag footer的开始。APE Tags Footer的结构如下所示:

(4)一个简单的示例

上面的几个图来自wiki,可能有点抽象。我们以一个简单的示例来说明一下,这样比较直观。如下图所示,图为在Linux平台用ghex打开的一个APE文件。

从图中可以看出,该tag为APEV2 tag。

a、APE Tags Header

首先是APE Tags Header,从图中可以很容易的找到,以“APTTAGEX”开始,然后是4个字节的version,0x00 00 07 D0,即version为2000。

然后是四个字节的tag size,为0x00 00 00 72,即整个APE tag包括114个字节,其中不包括APE Tags Header的长度。可以从图中数一下,确实是114个字节。

在然后的四个字节是item的个数,0x00 00 00 03,即包括三个item。

紧接着是4个字节的flags,为0xA0 00 00 00。

最后是reserved的8个字节,全部为0。

b、APE Tag Item

由对APE Tags Header的分析可以知道,该tag中包括了三个item,从图中也可以看的出来,分别为Title、Artist和Album。我们可以以Title这个item为例进行分析。APE Tags Header为固定的32个字节,因此,跳过32个字节之后便是Title这个item的内容。

首先是四个字节的length,0x00 00 00 0C,即为12个字节。这个12表示该item的value占12个字节。

然后是四个字节的flags,这里为0x00 00 00 00。

接着是item的key,这里为Title,是ASCII编码。item的key后面是一个字节的标志位,为0x00,用于标识item的key结束。

最后是item的value,由上面的分析可以知道为12个字节。

c、APE Tags Footer

APE Tags Footer的结构和APE Tags Header的结构是一样的,而且内容几乎一样,唯一的区别就在于flag。APE Tags Header的flag为0xA0 00 00 00,而APE Tags Footer的flag为0x80 00 00 00。查看了几个APE文件,APE Tags Header的flag都为0xA0 00 00 00,而APE Tags Footer的flag都为0x80 00 00 00,这两个flag的值可能是固定的值(个人猜测),以此来区分APE Tags Footer与APE Tags Header。