MP3编码分析

目录

一、MP3文件格式解析....2

1、MP3文件及MPEG概述...2

二、MP3编码原理....4

1、MP3编码流程...4

2、子带滤波器排——编码流程图中编号为1......5

3、改良后的DCT(MDCT)——编码流程图中编号为2......7

4、声音心理学模型——编码流程图中编号为3......8

5、位元分配、量化和Huffman编码——4......12

三、SHINE程序分析....13

1、文件数据结构...13

2、编码前化工作...14

3、MP3编码...14

4、后处理...17

注:下面的资料参考网上论文整理而来

一、MP3文件格式解析

1、MP3文件及MPEG概述

MP3文件是由帧(frame)构成的,帧是MP3 文件最小的组成单位。MP3 的全称应为MPEG1 Layer-3 音频文件。

MPEG(MovingPicture Experts Group),MPGE音频层指MPGE文件中的声音部分,根据编码质量和复杂程度分为3层,即Layer-1、Layer2、Layer3,对应MP1、MP2、MP3三种格式文件。

2、MP3文件结构

MP3文件分为TAG_V2(ID3V2),Frame, TAG_V1(ID3V1)共3部分。

(1)Frame格式

帧头为4个字节,其结构如下

typedef FrameHeader{

unsigned intsync:11;           //同步信息

unsigned intversion:2;          //版本

unsigned intlayer:2;            //层

unsigned intprotection:1;        // CRC校验

unsigned intbitrate:4;           //位率

unsigned intfrequency:2;        //采样频率

unsigned intpadding:1;          //帧长调节

unsigned intprivate:1;           //保留字

unsigned intmode:2;            //声道模式
unsigned int mode extension:2;    //扩充模式

unsigned intcopyright:1;          // 版权

unsigned intoriginal:1;            //原版标志

unsigned intemphasis:2;          //强调模式

}HEADER, *LPHEADER;

无论帧多长,每帧播放时间为26ms。MAIN_DATA长度为

Length(MAIN_DATA)=((version==MPEG1)?144:72)* bitrate / frequency + padding;

(2)ID3V1格式

ID3V1存放在MP3文件结尾,共128Bytes,各项信息都顺序存放,不足部分使用’\0’补足,可使用UltraEdit打开查看。

typedef struct tagID3V1
{

char Header[3]; /*标签头必须是"TAG"否则认为没有标签*/
char Title[30]; /*标题*/
char Artist[30]; /*作者*/
char Album[30]; /*专集*/
char Year[4]; /*出品年代*/
char Comment[28]; /*备注*/
char reserve; /*保留*/
char track;; /*音轨*/
char Genre; /*类型*/

}ID3V1,*pID3V1;

(3)ID3V2格式

ID3V2存放在MP3文件的首部,由1个标签头和若干标签帧组成。

标签头为10个字节,

char Header[3];          /*必须为"ID3"否则认为标签不存在*/
char Ver;                /*版本号ID3V2.3 就记录3*/
char Revision;            /*副版本号此版本记录为0*/
char Flag;               /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4];             /*标签大小,包括标签头的10 个字节和所有的标签帧的大小*/

每个标签帧都有一个10个字节的帧头和至少一个字节的不固定长度的内容组成为,帧头的定义如下:

char FrameID[4];    /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表*/
char Size[4];         /*帧内容的大小,不包括帧头,不得小于1*/
char Flags[2];        /*存放标志,只定义了6 位,稍后详细解说*/

 

二、MP3编码原理

1、MP3编码流程

MP3编码流程图

信号描述

(1)MP3编码输入信号:PCM(Pulse Code modulation)声音信号,有些.wav格式的音频文件为PCM信号。

(2)MP3编码输出信号:MP3格式码流

wav文件头格式

wav数据块

WAV格式文件所占容量= (取样频率X 量化位数X 声道)X 时间/ 8 (字节= 8bit)。

14H~15H的2个字节值为1时表示数据位PCM编码格式,可以作为MP3编码器的输入。

 

2、子带滤波器排——编码流程图中编号为1

子带滤波器及MDCT处理

子带滤波过程

为多重相位相位滤波器,将PCM信号输入后,滤波器系统看做线性系统,则有

           

再将用32点进行下采样,得子带滤波器输出结果为

  

ISO-M标准给出了如下图所示的实现方法,我们的程序将按照该实现方法编写。

ISO-M给出的滤波器组的实现

将上图整个流程综合用表达式表示为

其中

为分析矩阵的系数。是窗函数的系数,共512个点,其值在ISO11172-3标准的 ANNEX_C.DOC文档中给出了,为子带序列号,范围为0~31,为第i个子带的样点,且t是取样间隔的整数倍。

3、改良后的DCT(MDCT)——编码流程图中编号为2

DCT变换的目的:进一步提高频谱解析度,将每一个子频带细分为18个次频带。

在正式DCT运算前,需要对子带信号进行加窗处理,有如下4中窗框,长窗框(Normal Window)、长短窗框(Start Window)、短窗框(Short Window)与短长窗框(Stop Window)。

长窗框具有高的频谱解析度,短窗框的时间解析度比较高。

然后进行DCT变换,变换表达式 如下,

 

为DCT变换前加窗处理后的结果,如果加短窗框,则DCT运算中的,若加长框,则DCT运算中的。

在提高频域解析度的同时,加长框后会有假象(混叠现象)产生,因为不同子带之间存在混叠的信号,加长框会对混叠的信号当做该子带内正常信号处理,一种避免的办法是减弱混叠信号的强度。

噢,现在我们是知道了,所谓改良的DCT只不过是,(1)DCT变换前加窗处理(2)DCT变换(3)长框假象的处理 这3个过程。

到这里,还有一个问题,那就是窗框的选择问题,该如何选择窗框?窄的窗框具有好的时间分辨率,宽的窗框具有好的频率分辨率。我们回到编码流程图,

请注意图中的标号3,3表示声音心理学模型,窗框的宽窄选择与声音心里学模型相关,下面来分析该模型。

4、声音心理学模型——编码流程图中编号为3

研究声音心理学模型用途有:

1)研究模型的PE值决定做MDCT变换时使用长窗框还是短窗框

(2)研究模型的SMR值决定量化编码时的比特数分配

现在不明白以上2条用途没关系,我们先来分析几个重要的概念

(1)SPL(Sound Pressure Level),表示声音强度的名词,SPL是评价听觉刺激强度的标准,也就是说,我们对外界声音的感觉强度完全由它决定,其单位为dB。

(2)静音门槛曲线

横轴为f(HZ),纵轴为SPL(dB),若声音强度(SPL)低于该曲线的值表示人听不到声音,如下图所示。从图中可以得出几条结论:

第一,人的听觉频率范围大约在10Hz~20KHz之间

第二,大约在3KHz到4KHz时SPL有最小值,也就是所人在该频率范围内的听觉最敏锐

(3)临界频带(Critical Bands)

因为人耳对不同频率的敏感程度不同,MPEG1/Audio将22KHz范围内可感知的频率范围划分为23~26个临界频带,如下图。

从表中能得出几条结论:

第一,当当中心频率值在500Hz以内时,不同临界频带的带宽()几乎相同,约100Hz

当中心频率值大于500Hz后,随着f值得上升,临界频带的带宽剧增

第二,从表中也可以看出,人耳对低频的解析度要比高频更好

(4)频域上的遮蔽效应

SPL较大的信号容易掩盖频率相近的SPL较小的信号,叫声音的遮蔽效应。就比如在机场很难听到打电话的声音。

如上图所示,Masking Threshold将大约在0.7kHz,1.6kHz和2.3kHz的信号遮蔽了,当然0.7kHz信号的SPL在静音门槛曲线之下,不被遮蔽也是听不到的。

在这里,涉及3个重要的量——SMR、SNR和MNR。

SMR(signal-to-maskratio):指在一个临界频带内,从masker到遮噪门槛值的距离。

SNR(signal-to-noiseratio):指信号经过m位元量化后的信噪比,等于量化前信号方差和量化噪声的方差之比,。

MNR(mask-to-noise):用来测量人耳可以感知的失真参数,

如下图所示,展示了3者之间的关系,其中的灰色区域Critial Band指临界频带,Masking Threshold就是遮噪门槛曲线,图中的SMR指在临界频带内最大的SMR值。

遮噪门槛曲线和SMR、SNR、NMR

值得注意的是,(1)我们上面讨论的SMR、SNR和NMR三者都是基于临界频带的,但遮蔽效应不仅对临界频带有影响,对临近的临界频带也有影响,称为遮噪延展性(2)上图所显示的是一个临界频带内的一条遮噪曲线,实际情况存在多条遮噪曲线,结果是这些曲线的叠加。

(5)时域上的遮噪曲线

从上图可以看出,在一段很短的时间内(200ms左右),若出现了两个声音,不管出现的先后顺序,SPL大的声音(masker)会遮蔽SPL小的声音(maskee)。

若maskee出现在前,则遮噪曲线如上图的Pre-Masking;若maskee出现在后,则遮噪曲线如上图中的Post-Masking。由图中很容易看出,Post-Masking要比Pre-Masking在时间轴上要长很多。Pre-Masking能遮蔽前回音,这是选择MDCT窗口的一个依据。

(6)感知熵Perceptual Entropy(PE)

最重要的一点,PE能显示特定信号在理论上的压缩极限。PE的单位是bits/sample,代表每个取样在维持CD音质的情况下,能够压缩到的最低位元数。

 

重新回到本小节一开始就提到的声音心里学模型的用途,重新列一下:

(1)研究模型的PE值决定做MDCT变换时使用长窗框还是短窗框

(2)研究模型的SMR值决定量化编码时的比特数分配

对于第一条,MP3中定义,当PE>1800时,使用短窗框的MDCT来处理该grannul(MP3每个数据帧包含2grannul,每个grannul包含18*32subband采样)的子频带信号。因为当PE>1800表示这段音讯变化比较大,可能产生回音,不适合使用长框。

对于第二条,下面的位元分配将给出解释。

5、位元分配、量化和Huffman编码——4

(1)位元分配

位元分配目的是使每个频带的MNR达到最大,使音质最佳。过程为:寻找最小的MNR频带,分配位元给该频带以提高MNR,接着重新计算各频带的MNR。重复上述过程,直到位元分配结束。

[a]可编码位元数计算方法,1152指每个编码框的取样个数,

比如,以单声道为例,比特率为128kbps,采样频率为44.1kHz,则每个编码框可编码的位元数为3344。但考虑到挡头的32位,附属资料的136位和可选择的16位CRC,所以最终可用的位元数为3344-32-136-16=3160,实际编码最小单位为grannul,所以每个grannul可用位元数为3160/2=1580。

[b]MNR计算方法,在前面心理学模型中已经提到,

其中SMR由声音心理学模型提供,SNR信噪比则是由量化确定的。

(2)非均匀量化

上式为MP3量化的公式,其中为MDCT输出并调整后的值,为量化后的整数值,0.75是为了使量化器提供一致的SNR值,表示四舍五入。

下图为量化器的输入输出曲线,量化器的输入为浮点值频率,输出为整形值的频率。

由图知,量化器将输入的浮点值量化后变为整型值,且量化过程为非线性非均匀的。

频谱量化器的输入输出

三、SHINE程序分析

SHINE是一个C语言编写的MP编码程序,总共由11个源文件构成。将源文件添加到VC新建的控制台应用程序中即可运行,但运行时得使用命令行方式。

1、文件数据结构

在types.h中定义了一个config_t的结构体类型,并用它初始化了一个全局变量config,该变量作用相当于面向对象语言中的“对象”,用于在整个编码流程中对编码数据和参数进行保存和管理。

定义了一个用于存储PCM脉冲格式文件信息的结构体类型wave_t,并且用wave_t在config_t中定义了wave变量,该变量保存了MP3编码的源的信息,作为MP3编码器的输入。

定义了一个用于存储MP3编码后信息的结构体类型mpeg_t,同样用mpeg_t在config_t中定义了mpeg变量,该变量存储的信息作为编码后的MP3参数信息输出。

typedefstruct {

    time_t start_time;     /*记录编码起始时间*/

    char* infile;          /*编码输入文件*/

    wave_t wave;         /*PCM文件头信息*/

    char* outfile;         /*编码输出码流文件*/

    mpeg_t mpeg;        /*MP3文件头信息*/

} config_t;

以上的结构体主要用于保存“头”信息,编码输出后的字节流实体信息保存在bs结构体(bitstream.h文件中定义)中,bs结构体定义为

staticstruct

{

  FILE *f;           /* bitstream output file handle */

  unsigned int i;      /*file buffer index */

  unsigned char *b;   /* buffer pointer */

} bs;

结构体中的文件指针与指向同一个输出文件,b指向编码后的码流,编码结束后写入文件中。

2、编码前化工作

包括初始化config.mpeg结构体变量的默认值,打开wave类型文件(SHINE程序中此时只读取了文件头信息,没读取实体信息),根据读取的信息对mpeg输出信息进行配置。

3、MP3编码

MP3编码主要由3步组成,分析子频带滤波器组,MDCT变换到频域,位元分配与量化。每次的操作对象为输入PCM的一帧。

                              MP3编码核心调用

 /* polyphase filtering */

   for(gr=0; gr<config.mpeg.granules; gr++)

     for(ch=0; ch<config.mpeg.channels; ch++)

       for(i=0;i<18;i++)

         L3_window_filter_subband(&buffer[ch],&l3_sb_sample[ch][gr+1][i][0] ,ch);

 

    /* applymdct to the polyphase output */

    L3_mdct_sub(l3_sb_sample, mdct_freq);

 

    /* bit andnoise allocation */

    L3_iteration_loop(mdct_freq, &side_info, l3_enc,mean_bits);

 

    /* writethe frame to the bitstream */

    L3_format_bitstream(l3_enc, &side_info);

(1)子频带滤波器

下图是ISO11172-3标准给出的Analysis subband filter flow chart。其步骤为

【a】输入32个音频samples

【b】建立一个数组x[n], for n=0~511用于保存输入的采样值。将x[n]看做一个最多能容纳512个元素的队列,x[511]为队首,x[0]为队尾, 每次接收新的samples前将队首32个元素移出,将samples放入队尾。

【c】加窗滤波器处理,窗函数系数为C[i],i=0~512,通过实现窗函数滤波器

【d】计算64个Yi值,表达式如流程图中所示

【e】计算32个子带滤波器采样值Si,这里使用到矩阵M[i][k],

M[i][k] = cos [(2i + 1)(k - 16)p/64] ,     

for  i = 0 to 31, and   k = 0 to 63.

实际计算时可以将非线性的运算用查Table的方法以减小运算的复杂度。

 

当然,在SHINE程序中,作者对M[i][k]×Y[k]的运算做了简化,主要从两方面:

第一,cos函数在k=16和k=48处的对称性;第二,从各滤波器的相关性考虑,即cos(2i+1)的对称性考虑。

(2)MDCT实现

DCT(离散余弦变换)的原始表达式为

DCT可以通过蝶形运算提高运算效率,具体内容可参考数字信号处理教材的内容。

DCT运算的蝶形图

MDCT的表达式为

MDCT快速算法蝶形图

计算一样可以通过蝶形图运算来提高效率,蝶形运算中最重要的是系数值,使用短窗框的MDCT运算点数为12,长窗框则为36

ISO 11172-3ANNEX_AB.DOC文档中Table 3-B.9给出了蝶形运算的系数如下

Table 3-B.9  Layer III coefficients for aliasingreduction:

 

              (i)           ci

       ------------------------------------

              0            -0.6

              1            -0.535

              2            -0.33

              3            -0.185

              4            -0.095

              5            -0.041

              6            -0.0142

              7            -0.0037

 

 

蝶形系数csi和cai通过下面2个式子计算

                       

 

带假象处理的MDCT/IMDCT编解码图

32个频带每个频带的蝶形运算都需要8次,SHINE中蝶形运算的程序如下

     for(band=31; band--; )

       for(k=8;k--; )

       {

          /* must left justifyresult of multiplication here because the centre

           * two values in eachblock are not touched.

           */

         bu = muls(mdct_enc[band][17-k],cs[k])+ muls(mdct_enc[band+1][k],ca[k]);

         bd =muls(mdct_enc[band+1][k],cs[k]) - muls(mdct_enc[band][17-k],ca[k]);

         mdct_enc[band][17-k] = bu;

         mdct_enc[band+1][k]  = bd;

       }

(3)Huffman编码与位元分配

在经过声音心理模型和分析滤波器排之后提供信息之后,就可以对Audio进行位元分配和量化编码了。SHINE程序在该部分做了很多工作,位元分配和量化编码通过3个回圈实现:[a]Iteration Loop [b]Outer Loop [c]Inner Loop。且[a]包含[b],[b]包含[c]。

[c]主要完成量化工作,[b]计算量化后失真大小以决定是否需要重新量化,[a]计算剩余位元数并放在储存处。

位元分配与量化是整个编码过程中计算量最大的部分,是整个编码过程的核心。

1】外部回圈分析

根据下面的公式计算失真度大小

对于量化误差大于人耳所能能最大可容忍失真的情况,则需将最大的可容忍失真度放大并且将每个未量化前的频带xr[i]放大。

2】内部回圈分析

首先,根据下面公式进行量化

若出现溢位或者位元数不够分配的情况,则按+1逐渐增大stepsize,直到前述情况不存在。

接着,计算编码所需位元数,通过位元数选择Huffman码表。

4、后处理

将结果写入比特流中,关闭PCM文件和码流存储文件。计算整个编码过程算法运行时间end_time -=config.start_time。


转自:http://blog.csdn.net/xiahouzuoxin/article/details/7849249#comments

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解析MP3音频格式 一、概述 MP3 文件是由帧(frame)构成的,帧是MP3 文件最小的组成单位。MP3 的全称应为MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts Group)在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG 音频文件是MPEG1 标准中的声音部分,也叫MPEG 音频层,它根据压缩质量和编码复杂程度划分为三层,即 Layer-1、Layer2、Layer3,且分别对应MP1、MP2、MP3 这三种声音文件,并根据不同的用途,使用不同层 次的编码。MPEG音频编码的层次越高,编码器越复杂,压缩率也越高,MP1 和MP2 的压缩率分别为4:1 和 6:1-8:1,而MP3 的压缩率则高达10:1-12:1,也就是说,一分钟CD 音质的音乐,未经压缩需要10MB的存储空间,而经过MP3 压缩编码后只有1MB 左右。不过MP3 对音频信号采用的是有损压缩方式,为了降低声音失真度,MP3 采取了“感官编码技术”,即编码时先对音频文件进行频谱分析,然后用过滤器滤掉噪音电平,接着通过量化的方式将剩下的每一位打散排列,最后形成具有较高压缩比的MP3 文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。 名词解释: 比特率是指每秒传送的比特(bit)数。单位为 bps(Bit Per Second),比特率越高,传送的数据越大。 比特率比特率表示经过编码(压缩)后的音、视频数据每秒钟需要用多少个比特来表示,而比特就是二进制里面最小的单位,要么是0,要么是1。比特率与音、视频压缩的关系,简单的说就是比特率越高,音、视频的质量就越好,但编码后的文件就越大;如果比特率越少则情况刚好相反。 采样率(也称为采样速度或者采样频率)定义了每秒从连续信号中提取并组成离散信号的采样个数,单位用赫兹(Hz)来表示。采样频率的倒数是采样周期(也称为采样时间),它表示采样之间的时间间隔。这里要注意不要将采样率与位速相混淆。 二、MP3文件整体结构 MP3文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1) ID3V2标签帧 ID3v2在文件头,以字符串“ID3”为标志,包含了演唱者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。 音频数据帧 一系列的帧,个数由文件大小和帧长决定,每个FRAME的长度可能不固定,也可能固定,由位率bitrate决定,每个FRAME又分为帧头和数据实体两部分,帧头记录了mp3的位率,采样率,版本等信息,每个帧之间相互独立 ID3V1标签帧 ID3v1在文件结尾,以字符串“TAG”为标记,其长度是固定的128个字节,包含了演唱者、歌名、专辑、年份等信息。 三、MP3结构具体分析 1.ID3V2标签 每个ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3 文件的首部。 标签头 在文件的首部顺序记录10 个字节的ID3V2.3 的头部。数据结构如下: char Header[3]; /*必须为"ID3"否则认为标签不存在*/ char Ver; /*版本号ID3V2.3 就记录3*/ char Revision; /*副版本号此版本记录为0*/ char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/ char Size[4]; /*标签大小,包括标签头的10 个字节和所有的标签帧的大小*/ 注:最后4个字节表示ID3V2标签的大小,在实际寻找首帧的过程中,我发现大部分的mp3文件的标签大小是包含标签头的,但有的又是不包含的,可能是某些mp3编码器写标签的BUG,所以为了兼容只好认为其是包含的,如果按大小找不到,再向后搜索,直到找到首帧为止。 计算ID3V2标签帧的大小: 最后四个字节表示,但每个字节只用7 位,最高位不使用恒为0。所以格式如下: 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 计算大小时要将0 去掉,得到一个28 位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如 下: int ID3V2_Size; ID3V2_Size = (Size[0]&0x7F;)*0x200000 +(Size[1]&0x7F;)*0x4000 +(Size[2]&0x7F;)*0x80 +(Size[3]&0x7F;) (2) 标签帧 每个标签帧都有一个10 个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。 一般我们从标签头中获取信息计算出整个ID3V2标签的大小即可,对于ID3V2的标签帧就不再仔细分析。 2.音频数据 数据帧往往有多个,至于有多少,由文件大小和帧大小来决定。每个帧都有一个四字节长的帧头,接下来可能有两个字节的CRC校验,其存在由帧头中的具体信息决定。接着就是帧的实体数据,也就是MAIN_DATA了。 (1)音频数据帧的帧头 格式如下: AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM 符号 长度(bit) 位置(bit) 描述 A 11 (31~21) 帧同步(所有位置1) B 2 (20~19) MPEG 音频版本ID 00 – MPEG 2.5 01 – 保留 10 – MPEG 2 (ISO/IEC 13818-3) 11 – MPEG 1 (ISO/IEC 11172-3) C 2 (18~17) Layer描述 00 - 保留 01 - Layer III 10 - Layer II 11 - Layer I D 1 (16) 校验位(0 - 紧跟帧头后有16位即2个字节用作CRC校验1 - 没有校验) E 4 (15~12) 比特率(位率)(见比特率索引表) F 2 (11~10) 采样率(见采样率索引表) G 1 (9) 填充位(填充用来达到正确的比特率。) 0 – 没有填充 1 – 填充了一个额外的空位 H 1 (8) 私有bit,可以用来做特殊应用。例如可以用来触发应用程序的特殊事件。 I 2 (7~6) 声道 00 立体声 01 联合立体声(立体声) 10 双声道(立体声) 11 单声道(单声) J 2 (5~4) 扩展模式(仅在联合立体声时有效) 扩展模式用来连接对立体声效果无用的信息,来减少所需的资源。这两个位在联合立体声模式下有编码器动态指定。 K 1 (3) 版权 0无版权 1有版权 L 1 (2) 原创 0 原创拷贝 1 原创 M 2 (1) 强调 00 - 无 01 - 50/15 ms 10 - 保留 11 - CCIT J.17 【帧头信息表】 索引值 MPEG1 MPEG2&MPEG2;.5 Layer1 Layer2 Layer3 Layer1 Layer2&3 0000 Free 0001 32 32 32 32 8 0010 64 48 40 48 16 0011 96 56 48 56 24 0100 128 64 56 64 32 0101 160 80 64 80 40 0110 192 96 80 96 48 0111 224 112 96 112 56 1000 256 128 112 128 64 1001 288 160 128 144 80 1010 320 192 160 160 96 1011 352 224 192 176 112 1100 384 256 224 192 128 1101 416 320 256 224 144 1110 448 384 320 256 160 1111 Bad 【比特率索引表】 Bits MPEG1 MPEG2 MPEG3 00 44100 22050 11025 01 48000 24000 12000 10 32000 16000 8000 11 保留 【采样率索引表】 (2)如何计算音频数据帧长度 我们首先区分两个术语:帧大小和帧长度。帧大小即每帧采样数表示一帧中采样的个数,这是恒定值。其值入下表所示 MPEG1 MPEG2 MPEG2.5 Layer1 384 384 384 Layer2 1152 1152 1152 Layer3 1152 576 576 【每帧采【每帧采样数表】 帧长度是压缩时每一帧的长度,包括帧头。它将填充的空位也计算在内。LayerI的一个空位长4字节,LayerII和LayerIII的空位是1字节。当读取MPEG文件时必须计算该值以便找到相邻的帧。 注意:因为有填充和比特率变换,帧长度可能变化。 从头中读取比特率,采样频率和填充, LyaerI使用公式: 帧长度(字节) = 每帧采样数 / 采样频率(HZ) * 比特率(bps)/ 8 +填充 * 4 LyerII和LyaerIII使用公式: 帧长度(字节)= 每帧采样数 / 采样频率(HZ) * 比特率(bps)/ 8 + 填充 例: LayerIII 比特率 128000,采样频率 44100,填充0 =〉帧大小 417字节 (3)计算每帧的持续时间 之前看了一些文章都说mp3的一帧的持续时间是26ms,结果在实际程序的编写中发现无法正确按时间定位到帧,然后又查了一些文章才知道,所谓26ms一帧只是针对MPEG1 Layer III而且采样率为44.1KHz来说是对的,但mp3文件并不都是如此,其实这个时间也是可以通过计算来获得,下面给出计算公式 每帧持续时间(秒) = 每帧采样数 / 采样频率(HZ) 可以这么理解:每帧采用数就是要采取的总数,采样率就是采取的速度,相除 就得到时间。 这样通过计算可知 MPEG1 Layer III 采样率为44.1KHz的一帧持续时间为26.12...不是整数,不过我们权且认为它就是26毫秒吧。 如果是MPEG2 Layer III 采样率为16KHz的话那一帧要持续36毫秒,这个相差还是蛮大的,所以还是应该通过计算来获的,当然可以按MPEG版本,层数和采样率来建一个表,这样直接查表就可以知道时间了。 3.ID3V1标签 ID3v1标签用来描述MPEG音频文件。包含艺术家,标题,唱片集,发布年代和流派。另外还有额外的注释空间。位于音频文件的最后固定为128字节。可以读取该文件的最后这128字节获得标签。以最后128个字节的头三个字节为“TAG”作为有ID3V1的判断依据。 结构如下: AAABBBBB BBBBBBBB BBBBBBBB BBBBBBBB BCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDEEE EFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFG 符号 长度(byte) 位置 描述 A 3 (0~2) 标签标志。如果存在标签并且正确的话,必须包含'TAG'。 B 30 (3~32) 标题 C 30 (33~62) 艺术家 D 30 (63~92) 唱片集 E 4 (93~96) 年代 F 30 (97~126) 注释 G 1 (127) 流派 有了上述的这些信息,我们就可以自己写代码,从MP3文件中抓取信息以及修改文件名了。但是,如果真的想写一个播放软件,还是需要读它的数据帧,并进行解码。 四、解析方法 当你想读取MPEG文件的信息时,解析前三个字节,判断是否有ID3V2标签,有则根据上面的方法算出ID3V2标签的总大小,这样就找到了音频数据帧的第一帧,读取它的头信息,获取比特率、采样率、MPEG版本号、Layer描述号等信息,根据上面提供的方法算出每帧的长度和每帧持续时间,对于定比特率的其它帧是相同的,也就是说解析第一帧就达到了目的。但这也不是所有情况。变比特率的MPEG文件使用使用所谓比特变换,也就是说每一帧的比特率依照具体内容变化。这时就需要你每一帧都解析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值