MP3文件结构概述

Layer-3音频文件。MPEG(MovingPicture 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。

MP3文件大体分为三部分:TAG_V2(ID3V2),音频数据。TAG_V1(ID3V1),当中ID3V2是ID3V1的补充,并非全部的MP3都有ID3V2补充。即是不是全部的MP3文件都有ID3V2。

ID3V2

假设MP3文件存在ID3V2。则一定在文件的头部,ID3V2结构分为头部(header)和若干标签帧。当中头部长度为10字节。10个字节的结构如表1:

0

1

2

3

4

5

6

7

8

9

内容为”ID3”

版本

副版本

存放标志的字节

ID3V2总大小(帧头和之后的若干标签帧总和)

表1

由于3、4、5字节所代表的意义并非MP3解码的重点,故此仅仅讲解前三字节和后四字节:

  1. 从表1可看出推断MP3文件是否存在ID3V2。仅仅须要推断文件前三个字节是否是”ID3”。

  2. ID3V2数据大小计算公司:

total_size = (Size[0]&0x7F)*0x200000+ (Size[1]&0x7F)*0x400 + (Size[2]&0x7F)*0x80 +(Size[3]&0x7F)

当中。size[0~3]。各自是表1中的6~9字节。

须要注意的是。这个公司计算的长度并不包含ID3V2的10个字节的头部。

ID3V2头部之后的若干标签帧每一帧结构分为标签ID(4字节)、帧内容大小(4字节。不包含标签帧帧头)、存放标志位(2字节)、内容。

当中标签ID的含义例如以下:

TEXT: 歌词作者    TENC:
编码        WXXX: URL链接(URL)        TCOP:
版权(Copyright)   TOPE: 原艺术家

TCOM: 作曲家      TDAT:
日期        TPE3: 指挥者              TPE2:
乐队               TPE1: 艺术家相当于ID3v1的Artist

TPE4: 翻译(记录员、改动员)          TYER:
即ID3v1的Year      USLT:
歌词               TSIZ: 大小

TALB: 专辑相当于ID3v1的Album         TIT1:
内容组描写叙述

TIT2: 标题相当于ID3v1的Title       TIT3:
副标题

TCON: 流派(风格)相当于ID3v1的Genre AENC:
音频加密技术

TBPM: 每分钟节拍数COMM:
凝视相当于ID3v1的Comment

TDLY: 播放列表返录                 
TRCK: 音轨(曲号)相当于ID3v1的Track

TFLT: 文件类型             
        TIME: 时间 

TKEY: 最初keyword                   
TLAN: 语言

TLEN: 长度             
           TMED: 媒体类型

TOAL: 原唱片集             
        TOFN: 原文件名称

TOLY: 原歌词作者                   
TORY: 最初发行年份

TOWM: 文件全部者(许可证者)          TPOS:
作品集部分

TPUB: 发行人                       
TRDA: 录制日期

TRSN: Intenet电台名称                 TRSO:
Intenet电台全部者   UFID: 唯一的文件标识符  

TSRC: ISRC(国际的标准记录代码)     TSSE:
编码使用的软件(硬件设置)

读取MP3文件ID3V2信息的函数可例如以下:

//定义头部和标签帧

typedefstruct ID3v2Header{

char Identify[3];         // ID3v2固定标志:ID3

。字义为abc00000

char Size[4];             //
标签大小,一共四个字节,但每一个字节仅仅使用7位,最高位不使用恒为0,所以格式:
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx

}ID3v2Header;

typedef个字节

{

char FrameID[4];          //
标志对比符。如TEXT,TOPE,TDAT....

char Size[4];             //
帧体的大小。依照正常的8位存储的,FSize
= Size[0]*0x100000000 + Size[1]*0x10000 + Size[2]*0x100 + Size[3];

char Flag[2];             //
存放标志

}ID3v2Frame;

//输出信息并返回ID3V2大小

int ReadID3v2(FILE *pf)

{

ID3v2Headermp3header;

ID3v2Frame mp3Frame;

int FSize      = 0;

char str[4096] = {0};

char str2[5]   = {0};

int ID3size;

inthead_size = 0;

inti;

if(!pf)

return -1;

fseek(pf,0,SEEK_SET);

fread(&mp3header,sizeof(mp3header),1,pf);

if (mp3header.Identify[0]!='I' || mp3header.Identify[1]!='D'
|| mp3header.Identify[2]!='3' ){

printf("此歌曲不支持ID3v2标准!\n");

//文件复位

rewind(pf);

return -2;

}

printf("ID3v2标志:%.3s\n",mp3header.Identify);

printf("ID3v2版本号:%d\n",  mp3header.Ver);

ID3size= (mp3header.Size[0]& 0x7F)<< 21|(mp3header.Size[1]& 0x7F)<< 14|(mp3header.Size[2] & 0x7F) << 7|(mp3header.Size[3] & 0x7F);

printf("标签大小:%d\n***********\n",ID3size);

for (i=0;i<ID3size;i=i+11+FSize){

memset(&mp3Frame,0,sizeof(mp3Frame));

memset(&str,0,sizeof(str));

fseek(pf,10+i,SEEK_SET);               //移动到标签帧头

fread(&mp3Frame,sizeof(mp3Frame),1,pf);

//原则上是不用-1的,可是实际发现,总有一个字节的差距,为了计算方便-1。所以出现-1时标明此区块无内容

FSize  = (int)(mp3Frame.Size[0]*0x100000000 + mp3Frame.Size[1]*0x10000+ mp3Frame.Size[2]*0x100 + mp3Frame.Size[3]-1);

if (FSize>0)   {

fseek(pf,10+11+i,SEEK_SET);//移动到内容区

fread(str,FSize,1,pf);

GetStr(mp3Frame.FrameID,str2);

printf("%s-%s:\t%s\n",str2,mp3Frame.FrameID,str);

head_size+=11;

}else{

return ID3size+10;

}

}

return ID3size+10;

}

//通过FrameID获取相应的中文名

void GetStr(char* oldstr,char*
str)

{

if (0==memcmp((LPCTSTR)"TIT2",oldstr,4))

{

memcpy(str,"标题",4);

}elseif(0==memcmp((LPCTSTR)"TPE1",oldstr,4)){

memcpy(str,"作者",4);

}elseif(0==memcmp((LPCTSTR)"TALB",oldstr,4)){

memcpy(str,"专辑",4);

}elseif(0==memcmp((LPCTSTR)"TRCK",oldstr,4)){

memcpy(str,"音轨",4);

}elseif(0==memcmp((LPCTSTR)"TYER",oldstr,4)){

memcpy(str,"年代",4);

}elseif(0==memcmp((LPCTSTR)"COMM",oldstr,4)){

memcpy(str,"备注",4);

}elseif(0==memcmp((LPCTSTR)"TCON",oldstr,4)){

memcpy(str,"类型",4);

}else{

memcpy(str,"未知",4);  //其它的不是非常重要,所以省略了

}

}

MP3文件数据结构及处理流程

MP3数据解码流程借用图1描写叙述。

图1

MP3文件的音频数据部分。是分为非常多数据帧存放。每一帧数据播放的时间长度计算公式:

每帧持续时间(毫秒)
=每帧採样数 /採样频率 * 1000

如果每帧採样数为1152,採样频率为44.1K,则每帧数据播放的时间约为26ms。

没帧数据的结构包含帧头(header)、帧边信息(side)、主数据(main
data)。

帧头(header)

数据帧帧头长度为4字节,结构如图2所看到的。

图2

由图可知。同步信息(synchronizationword)11位皆为1,其它位信息如表

版本号(ID)

2bit

00-MPEG 2.5  01-没有定义    10-MPEG
2    11-MPEG 1

层(layer)

2bit

00-没有定义     01-Layer
3    10-Layer 2     11-Layer 1

CRC校验

1bit

0-校验       1-不校验

位率索引

4bit

bits

V1,L1

V1,L2

V1,L3

V2,L1

V2,L2

V2,L3

0000

free

free

free

free

free

free

0001

32

32

32

32(32)

32(8)

8 (8)

0010

64

48

40

64(48)

48(16)

16 (16)

0011

96

56

48

96(56)

56(24)

24 (24)

0100

128

64

56

128(64)

64(32)

32 (32)

0101

160

80

64

160(80)

80(40)

64 (40)

0110

192

96

80

192(96)

96(48)

80 (48)

0111

224

112

96

224(112)

112(56)

56 (56)

1000

256

128

112

256(128)

128(64)

64 (64)

1001

288

160

128

288(144)

160(80)

128 (80)

1010

320

192

160

320(160)

192(96)

160 (96)

1011

352

224

192

352(176)

224(112)

112 (112)

1100

384

256

224

384(192)

256(128)

128 (128)

1101

416

320

256

416(224)

320(144)

256 (144)

1110

448

384

320

448(256)

384(160)

320 (160)

1111

bad

bad

bad

bad

bad

bad

V1 - MPEG 1    V2 - MPEG 2 and MPEG 2.5

L1 - Layer 1   L2 - Layer 2

L3 - Layer 3

"free"表示位率可变

"bad" 表示不同意值

採样频率

2bit

MPEG-1: 00-44.1kHz   01-48kHz   10-32kHz     11-没有定义

MPEG-2: 00-22.05kHz  01-24kHz   10-16kHz     11-没有定义

MPEG-2.5: 00-11.025kHz 01-12kHz   10-8kHz      11-没有定义

是否填充

1bit

0-无需调整,1-调整

保留(reserved)

1bit

声道模式

2bit

00-立体声Stereo   01-Joint
Stereo   10-双声道       11-单声道

保留(reserved)

2bit

版权标志

1bit

0-不合法  1-合法

原版标志

1bit

0-非原版  1-原版

强调方式

2bit

00-没有定义    01-50/15ms    10-保留      11-CCITT
J.17

表2

数据帧大小计算公式:

Size=((採样个数 *
(1 / 採样率))*帧的比特率)/8 +帧的填充大小

对于Mp3格式:

Size=((1152 * (1 /採样率))*帧的比特率)/8 +帧的填充大小=
144*帧的比特率/採样率+帧的填充大小

当中:帧的填充大小便是23bit,不是0则为1。

帧边信息(side)

帧边信息解码的主要目的在于找出解这帧的各个參数。包含主数据開始位置,尺度因子长度等。

帧边信息如图3所看到的。

图3

当中,main_data_begin(主数据開始)是一个偏移值。指出主数据是在同步字之前多少个字节開始。

须要注意的是。1.帧头不一定是一帧的開始,帧头CRC校验字和帧边信息在帧数据中是滑动的。

2.这个数值忽略帧头和帧边信息的存在,假设main_data_begin
= 0, 则主数据从帧边信息的下一个字节開始,示意图如图4.

图4

块类型(block_type)分为三种类型:

block_type = 0长块

block_type = 1開始块

block_type = 3结束块

block_type = 2短块

在编码过程中进行IMDCT变换时。针对不同信号为同一时候得到较好的时域和频域分辨率定义了两种不同的块长:长块的块长为18个样本,短块的块长为6个样本。这使得长块对于平稳的声音信号能够得到更高的频率分辨率,而短块对跳变信号能够得到更高的时域分辨率。由于在短块模式下。3个短块取代1个长块,而短块的大小恰好是一个长块的1/3。所以IMDCT的样本数不受块长的影响。

对于给定的一帧声音信号,IMDCT能够所有使用长块或所有使用短块,也能够长短块混合使用。

由于低频区的频域分辨率对音质有重大影响,所以在混合块模式下,IMDCT对最低频的2个子带使用长块,而对其余的30个子带使用短块。

这样,既能保证低频区的频域分辨率。又不会牺牲高频区的时域分辨率。

长块和短块之间的切换有一个过程。一般用一个带特殊长转短(即,起始块block_type
= 1)或短转长(即终止块,block_type = 3)数据窗体的长块来完毕这个长短块之间的切换。

因此长块也就是包括正常窗,起始块和终止块数据窗体的数据块;短块也包括18个数据,可是是由6个数据独立加窗后在经过连接计算得到的。

主数据(main_data)

main_data中有两粒度组。没个粒度组分为两个声道,取数据存储结构如图5。

图5

当中,每一个通道(chN_data)的结构图6.

图6



MP3文件结构及解码概述的更多相关文章

  1. 多媒体文件格式分析 MP3文件结构及编解码流程

    多媒体文件格式分析 http://blog.csdn.net/taniya001/article/details/7962864 多媒体文件格式分析 MP3文件结构及编解码流程 http://www. ...

  2. MP3文件结构解析(超详细)

    转自:http://blog.csdn.net/u010650845/article/details/53520426 MP3文件结构解析(超详细) 1. MP3文件结构解析 1.1. 概述 1.1. ...

  3. 转载:AAC编解码概述

    转自:http://www.cnblogs.com/gaozehua/archive/2012/05/03/2479960.html 编码概述 其整体AAC 编解码系统,如图所示,其编码流程概述如下: ...

  4. jpeg编解码概述

    本博文为概览性介绍.后面有空了再分几篇博文分别介绍所用到的技术细节. 1.编解码目标 编码和解码是个逆过程.jpeg编码的目的在于图形去冗余,进行数据压缩,解码的目的在于还原图像,使能够进行预览. 2 ...

  5. 一、MP3文件概述

    一.概述 MP3 文件是由帧(frame)构成的,帧是 MP3 文件最小的组成单位.MP3 的全称应为 MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts G ...

  6. MP3格式音频文件结构解析

    MP3的全称是MPEG Audio Layer3,它是一种高效的计算机音频编码方案,它以较大的压缩比将音频文件转换成较小的扩展名为.MP3的文件,基本保持原文件的音质.MP3是ISO/MPEG标准的一 ...

  7. android MediaCodec 音频编解码的实现——转码

    原文地址:http://blog.csdn.net/tinsanmr/article/details/51049179 从今天开始 每周不定期更新博客,把这一周在工作与学习中遇到的问题做个总结.俗话说 ...

  8. MP3 信息读取

    MP3 信息读取 运行环境:Window7 64bit,.NetFramework4.61,C# 7.0: 编者:乌龙哈里 2017-03-13 参考: MP3-wikipedia ID3v1 MPE ...

  9. MP3文件头格式

    MP3文件结构及编解码流程 http://blog.sina.com.cn/s/blog_67b7cb7b01018i2l.html http://blog.csdn.net/liuyan4794/a ...

随机推荐

  1. 标准I/O介绍

    标准I/O库 1. 标准I/O介绍 不仅是在UNIX系统中,很多操作系统上都实现了标准I/O库. 标准I/O库由ANSI C 标准说明 标准 I/O 库处理很多细节,例如带有缓冲分配.以优化长度执行的 ...

  2. zookeeper应用——集中配置管理系统的实现

    http://blog.csdn.net/huangfengxiao/article/details/8844239

  3. ListVeiw新增记录及 滚动条移动到指定位置

    C# 自带的ListView控件的滚动条移动到指定位置. lvwList为ListView控件 lvwList.EnsureVisible(lvwList.Items.Count - 1); 新增记录 ...

  4. Android与JS混编(js调用java)

    项目中需要使用android与js的混编来开发app. 下面就介绍一下吧. 有时候我们需要用js调用native控件,要想实现这个功能,我们需要做的就只有三步: 1.允许webview执行js脚本 2 ...

  5. 网站飘窗js代码

    <SCRIPT> var imagepath="/${res}/images/geren.jpg" ; var imagewidth=178 ;//这两行写图片的大小 ...

  6. 华为oj - 统计大写字母个数

    练手而已. 给初学者参考 #include <stdio.h> #include <string.h> int main(void) { char string[200]={' ...

  7. Kendo Web UI Grid数据绑定,删除,编辑,并把默认英文改成中文

    Kendo Web UI 是个不错的Jquery框.可惜老外写的,很多都是默认的英文,当然我们也可以设置成中文,接下来,我们就看看Grid是如何实现的数据绑定(Kendo Grid数据绑定实现有很多方 ...

  8. php每秒输出一次

    首先说到php.ini中的两个配置 output_buffering配置•Off: 表示关闭PHP输出缓存•On: 打开无限大的输出缓存•4096: 打开大小为4096Byte的输出缓存(默认) im ...

  9. ACM训练计划step 2 [非原创]

    (Step2-500题)POJ训练计划+SGU 经过Step1-500题训练,接下来可以开始Step2-500题,包括POJ训练计划的298题和SGU前两章200题.需要1-1年半时间继续提高解决问题 ...

  10. cf C. Quiz

    http://codeforces.com/contest/337/problem/C 得到的分数为:(2^1+2^2+...+2^X)*k + m-X*k = (2^(X+1)-2)*k + m-X ...