现在的位置: 首页 > 综合 > 正文

APE文件学习——文件头(1)

2014年09月05日 ⁄ 综合 ⁄ 共 4032字 ⁄ 字号 评论关闭

我没有怎么搜Google关于ape文件格式,一来好像不是很多(或是我没搜到),另一方面是因为下载了Monkey's Audio Codec 的SDK后,里面有定义,所以就自己钻研起来。

原文是酱紫的

APE File Format Overview: (pieces in order -- only valid for the latest version APE files)

    JUNK - any amount of "junk" before the APE_DESCRIPTOR (so people that put ID3v2 tags on the files aren't hosed)

    APE_DESCRIPTOR - defines the sizes (and offsets) of all the pieces, as well as the MD5 checksum

    APE_HEADER - describes all of the necessary information about the APE file

    SEEK TABLE - the table that represents seek offsets [optional]

    HEADER DATA - the pre-audio data from the original file [optional]

    APE FRAMES - the actual compressed audio (broken into frames for seekability)

    TERMINATING DATA - the post-audio data from the original file [optional]

    TAG - describes all the properties of the file [optional]

但是我没有太理解。看下去,(注意,这个头文件定义了 #pragma pach(4),结构体以4字节对齐,这个编译选项是vc的,我用gcc的= =)

/*****************************************************************************************
WAV header structure
*****************************************************************************************/
struct WAVE_HEADER
{
    // RIFF header
    char cRIFFHeader[4];
    unsigned int nRIFFBytes;

    // data type
    char cDataTypeID[4];

    // wave format
    char cFormatHeader[4];
    unsigned int nFormatBytes;

    unsigned short nFormatTag;
    unsigned short nChannels;
    unsigned int nSamplesPerSec;
    unsigned int nAvgBytesPerSec;
    unsigned short nBlockAlign;
    unsigned short nBitsPerSample;
    
    // data chunk header
    char cDataHeader[4];
    unsigned int nDataBytes;
};

这里就很明显了,这个是RIFF的文件格式,是wave文件的头。

我找了一个wav的文件,在linux下用od查看头60个字节(为什么是60?我参考了http://www.cnblogs.com/filamm/archive/2008/08/07/1248821.html 注意后面的评论,我无法决断):

styx@paradiso:~$ od -c cupwav0000.wav -N 60
0000000   R   I   F   F 344 243  \a  \0   W   A   V   E   f   m   t    
0000020 020  \0  \0  \0 001  \0 001  \0   "   V  \0  \0   D 254  \0  \0
0000040 002  \0 020  \0   f   a   c   t 004  \0  \0  \0 332 321 003  \0
0000060   d   a   t   a 264 243  \a  \0   # 322   ( 326
0000074

依照上面链接中的解释,基本上是符合的,后面也有那个fact块和data块。

同样我找了一个ape文件,用od查看头52个字节(因为文件头是4字节对齐,所以数一下就知道了),但是我错了。。。

styx@paradiso:~$ od -c 01\ Never\ Grow\ Old.ape -N 52
0000000   M   A   C     226 017  \0  \0   4  \0  \0  \0 030  \0  \0  \0
0000020   x 001  \0  \0 034 001  \0  \0 270 272 361  \0  \0  \0  \0  \0
0000040  \0  \0  \0  \0 326   m 226 215 347   K 021   : 340 310 220 270
0000060 203   } 240   '
0000064

除了最开头可以看成是MAC的标志,后面的数据跟这个头完全配不上,想起来那个原文的描述,才知道自己不错才怪了= =

然后递增字节个数,差不多到600的时候可以看到了:

(省略前后)

0000660   g 330 354  \0 221 256 356  \0   - 017 360  \0   3 033 361  \0
0000700 210 275 361  \0   R   I   F   F 024 350 244 001   W   A   V   E
0000720   L   I   S   T 346  \0  \0  \0   I   N   F   O   I   A   R   T
0000740 020  \0  \0  \0   T   h   e       C   r   a   n   b   e   r   r
0000760   i   e   s  \0   I   N   A   M 017  \0  \0  \0   N   e   v   e
0001000   r       G   r   o   w       O   l   d  \0  \0   I   P   R   D
0001020   /  \0  \0  \0   W   a   k   e       U   p       a   n   d    
0001040   S   m   e   l   l       t   h   e       C   o   f   f   e   e
0001060       [   B   o   n   u   s       C   D   ]       D   i   s   c
0001100       1  \0  \0   I   G   N   R 004  \0  \0  \0   P   o   p  \0

能从这里看到那个“RIFF”标志,也看到了WAVE,但是依然不符合WAVE文件头。看了源代码才知道:

/*****************************************************************************************
APE_DESCRIPTOR structure (file header that describes lengths, offsets, etc.)
*****************************************************************************************/
struct APE_DESCRIPTOR
{
    char   cID[4];                             // should equal 'MAC '
    uint16 nVersion;                           // version number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes)

    uint32 nDescriptorBytes;                   // the number of descriptor bytes (allows later expansion of this header)
    uint32 nHeaderBytes;                       // the number of header APE_HEADER bytes
    uint32 nSeekTableBytes;                    // the number of bytes of the seek table
    uint32 nHeaderDataBytes;                   // the number of header data bytes (from original file)
    uint32 nAPEFrameDataBytes;                 // the number of bytes of APE frame data
    uint32 nAPEFrameDataBytesHigh;             // the high order number of APE frame data bytes
    uint32 nTerminatingDataBytes;              // the terminating data of the file (not including tag data)

    uint8  cFileMD5[16];                       // the MD5 hash of the file (see notes for usage... it's a littly tricky)
};

/*****************************************************************************************
APE_HEADER structure (describes the format, duration, etc. of the APE file)
*****************************************************************************************/
struct APE_HEADER
{
    uint16 nCompressionLevel;                 // the compression level (see defines I.E. COMPRESSION_LEVEL_FAST)
    uint16 nFormatFlags;                      // any format flags (for future use)

    uint32 nBlocksPerFrame;                   // the number of audio blocks in one frame
    uint32 nFinalFrameBlocks;                 // the number of audio blocks in the final frame
    uint32 nTotalFrames;                      // the total number of frames

    uint16 nBitsPerSample;                    // the bits per sample (typically 16)
    uint16 nChannels;                         // the number of channels (1 or 2)
    uint32 nSampleRate;                       // the sample rate (typically 44100)
};

(代码贴得太长了)

抱歉!评论已关闭.