mp3的设计与应用.docx
《mp3的设计与应用.docx》由会员分享,可在线阅读,更多相关《mp3的设计与应用.docx(43页珍藏版)》请在冰豆网上搜索。
mp3的设计与应用
本科毕业设计(论文)
题目mp3的设计与应用
部系地方生部
专业电子信息工程
学员王傈
指导教员张力
中国人民解放军海军航空工程学院
2010年7月
前言
MP3的全称应为MPEG1Layer-3音频文件,MPEG(MovingPictureExpertsGroup)在汉语中译为活动图像专家组,特指活动影音压缩标准,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文件,并使压缩后的文件在回放时能够达到比较接近原音源的声音效果。
MP3播放机要分几个部分:
中央处理器、解码器、存储设备、主机通讯端口、音频DAC和功放、显示界面和控制键。
其中中央处理器和解码器是整个系统的核心。
这里的中央处理器我们通常称为MCU(单片微处理器),简称单片机。
它运行MP3的整个控制程序,也称为fireware(或者固件程序)。
控制MP3的各个部件的工作:
从存储设备读取数据送到解码器解码;与主机连接时完成与主机的数据交换;接收控制按键的操作,显示系统运行状态等任务。
解码器是芯片中的一个硬件模块,或者说是硬件解码(有的MP3播放机是软件解码,由高速中央处理器完成)。
它可以直接完成各种格式MP3数据流的解码操作,并输出PCM或I2S格式的数字音频信号。
存储设备是MP3播放机的重要部分,通常的MP3随身听都是采用半导体存储器(FLASHMEMORY)或者硬盘(HDD)作为储存设备的。
它通过接受储存主机通讯端口传来的数据(通常以文件形式),回放的时候MCU读取存储器中的数据并送到解码器。
数据的存储是要有一定格式的,众所周知,PC管理磁盘数据是以文件形式,MP3也不例外,最常用的办法就是直接利用PC的文件系统来管理存储器,微软操作系统采用的是FAT文件系统,这也是最广泛使用的一帧2シ呕?
渲幸桓鋈挝窬褪且?
迪諪AT文件系统,即可以从FAT文件系统的磁盘中按文件名访问并读出其中的数据。
主机通讯端口是MP3播放机与PC机交换数据的途径,PC通过该端口操作MP3播放机存储设备中的数据,拷贝、删除、复制文件等操作。
目前最广泛使用的是USB总线,并且遵循微软定义的大容量移动存储协议规范,将MP3播放机作为主机的一个移动存储设备。
这里需要遵循几个规范:
USB通信协议、大容量移动存储器规范和SCSI协议。
音频DAC是将数字音频信号转换成模拟音频信号,以推动耳机、功放等模拟音响设备。
这里要介绍一下数字音频信号。
数字音频信号是相对模拟音频信号来说的。
我们知道声音的本质是波,人说能听到的声音的频率在20Hz到20kHz之间,称为声波。
模拟信号对波的表示是连续的函数特性,基本的原理是不同频率和振幅的波叠加在一起。
数字音频信号是对模拟信号的一种量化,典型方法是对时间坐标按相等的时间间隔做采样,对振幅做量化。
单位时间内的采样次数称为采样频
率。
这样一段声波就可以被数字化后变成一串数值,每个数值对应相应抽样点的振幅值,按顺序将这些数字排列起来就是数字音频信号了。
这是ADC(模拟-数字转换)过程,DAC(数字-模拟转换)过程相反,将连续的数字按采样时候的频率顺序转换成对应的电压。
MP3解码器解码后的信息属于数字音频信号(数字音频信号有不同的格式,最常用的是PCM和I2S两种),需要通过DAC转换器变成模拟信号才能推动功放,被人耳所识别。
MP3播放机的显示设备通常采用LCD或者OLED等来显示系统的工作状态。
控制键盘通常是按钮开关。
键盘和显示设备合起来构成了MP3播放机的人机交互界面。
MP3播放机的软件结构跟硬件是相对应的,即每一个硬件部分都有相应的软件代码,这是因为大多数的硬件部分都是数字可编程控制的。
看了上面的介绍是不是已经被单片机原理,编程,信号与系统,电子线路以及诸多协议标准的单词轰炸得晕头转向了。
其实这只不过是让大家了解,MP3虽然简单但也很复杂。
总结起来工作流程为读取贮体上的信号-→到解码芯片对信号进行解码(或解压缩)-→通过数模转换器将解出来的数字信号转换成模拟信号-→再把转换后的模拟音频放大-→低通滤波后到耳机输出口。
第一章编码与解码
本文先介绍符合ISO/IEC11172-3(MPEG1AudiocodecLayerI,LayerIIandLayerIIIaudiospecifications)或ISO/IEC13818-3(BCAudioCodec)的音频编码原理。
通过madlib解码库进行实现。
1.1程序系统结构
mp3解码流程图
其中同步及差错检查包括了头解码模块
在主控模块开始运行后,主控模块将比特流的数据缓冲区交给同步及差错检查模块,此模块包含两个功能,即头信息解码及帧边信息解码,根据它们的信息进行尺度因子解码及哈夫曼解码,得出的结果经过逆量化,立体声解码,混淆缩减,IMDCT,频率反转,合成多相滤波这几个模块之后,得出左右声道的PCM码流,再由主控模块将其放入输出缓冲区输出到声音播放设备。
1.2主控模块
主控模块的主要任务是操作输入输出缓冲区,调用其它各模块协同工作。
其中,输入输出缓冲区均由DSP控制模块提供接口。
输入缓冲区中放的数据为原始mp3压缩数据流,DSP控制模块每次给出大于最大可能帧长度的一块缓冲区,这块缓冲区与上次解帧完后的数据(必然小于一帧)连接在一起,构成新的缓冲区。
输出缓冲区中将存放的数据为解码出来的PCM数据,代表了声音的振幅。
它由一块固定长度的缓冲区构成,通过调用DSP控制模块的接口函数,得到头指针,在完成输出缓冲区的填充后,调用中断处理输出至I2S接口所连接的音频ADC芯片(立体声音频DAC和DirectDrive耳机放大器)输出模拟声音。
1.3同步及差错检测
同步及差错检测模块主要用于找出数据帧在比特流中的位置,并对以此位置开始的帧头、CRC校验码及帧边信息进行解码,这些解码的结果用于后继的尺度因子解码模块和哈夫曼解码模块。
Mpeg1layer3的流的主数据格式见下图:
主数据的组织结构图
其中granule0和granule1表示在一帧里面的粒度组1和粒度组2,channel0和channel1表示在一个粒度组里面的两个通道,scalefactor为尺度因子quantizedvalue为量化后的哈夫曼编码值,它分为bigvalues大值区和count11值区
CRC校验:
表达式为X16+X15+X2+1
1.3.1 帧同步
帧同步目的在于找出帧头在比特流中的位置,ISO1172-3规定,MPEG1的帧头为12比特的“111111111111”,且相邻的两个帧头隔有等间距的字节数,这个字节数可由下式算出:
N=144*比特率/采样率
如果这个式子的结果不是整数,那么就需要用到一个叫填充位的参数,表示间距为N+1。
1.3.2 头信息解码
头信息解码目的是找出这一帧的特征信息,如采样率,是否受保护,是否有填充位等。
头信息见下图:
帧头信息结构图
其长度为4字节,数据结构如下:
typedefstructtagHeader{
unsignedintsync:
11;//同步信息
unsignedintversion:
2;//版本
unsignedintlayer:
2;//层
unsignedinterror2protection:
1;//CRC校正
unsignedintbit2rate2index:
4;//位率索引
unsignedintsample2rate2index:
2;//采样率索引
unsignedintpadding:
1;//空白字
unsignedintextension:
1;//私有标志
unsignedintchannel2mode:
2;//立体声模式
unsignedintmodeextension:
2;//保留
unsignedintcopyright:
1;//版权标志
unsignedintoriginal:
1;//原始媒体
unsignedintemphasis:
2;//强调方式
}HEADER
1.3.3 帧边信息解码
帧边信息解码的主要目的在于找出解这帧的各个参数,包括主数据开始位置,尺度因子长等。
帧边信息如下图所示:
帧边信息(side_infomation)表
1.3.4 main_data_begin
main_data_begin(主数据开始)是一个偏移值,指出主数据是在同步字之前多少个字节开始。
需要注意的是,1.帧头不一定是一帧的开始,帧头CRC校验字和帧边信息在帧数据中是滑动的。
2.这个数值忽略帧头和帧边信息的存在,如果main_data_begin=0,则主数据从帧边信息的下一个字节开始。
参见下图:
同步示意图
1.3.5 block_type
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个数据独立加窗后在经过连接计算得到的。
1.3.6big_values,count1
每一个粒度组的频谱都是用不同的哈夫曼表来进行编码的。
编码时,把整个从0到奈奎斯特频率的频率范围(共576个频率线)分成几个区域,然后再用不同的表编码。
划分过程是根据最大的量化值来完成的,它假设较高频率的值有较低的幅度或者根本不需要编码。
从高频开始,一对一对的计算量化值等于“0”的数目,此数目记为“rzero”。
然后4个一组地计算绝对值不超过“1”的量化值(也就是说,其中只可能有-1,0和+1共3个可能的量化级别)的数目,记为“count1”,在此区域只应用了4个哈夫曼编码表。
最后,剩下的偶数个值的对数记为“bigvalues”,在此区域只应用了32个哈夫曼编码表。
在此范围里的最大绝对值限制为8191。
此后,为增强哈夫曼编码性能,进一步划分了频谱。
也就是说,对bigvalues的区域(姑且称为大值区)再细化,目的是为了得到更好的错误顽健性和更好的编码效率。
在不同的区域内应用了不同的哈夫曼编码表。
具体使用哪一个表由table_select给出。
从帧边信息表中可以看到:
当window_switch_flag==0时,只将大值区在细分为2个区,此时region1_count无意义,此时的region0_count的值是标准默认的;但当window_switch_flag==1时再将大值区细分为3个区。
但是由于region0_count和region1_count是根据从576个频率线划分的,因此有可能超出了big_values*2的范围,此时以big_values*2为准.region0_count和region1_count表示的只是一个索引值,具体频带要根据标准中的缩放因子频带表来查得.
参见下图:
缩放因子、大值区、1值区和零值区分布图
1.3.7处理流程
1.4缩放因子(scalefactor)解码
缩放因子用于对哈夫曼解码数据进行逆量化的样点重构。
根据帧边信息中的scalefactor_compress和标准中的对应表格来确定的slen1和slen2对缩放因子进行解码,即直接从主数据块中读取缩放因子信息并存入表scalefac_l[gr][ch][sfb]和scalefac_s[gr][ch][sfb]中。
对第2粒度组解码时,若为长块,则必须考虑尺度因子选择信息。
1.4.1尺度因子带(scalefactor-band)
在mpeglayer3中576条频率线根据人耳的听觉特性被分成多个组,每个组对应若干个尺度因子,这些组就叫做尺度因子带,每个长窗有21个尺度因子带而每个短窗有12个尺度因子带。
1.4.2scfsi
scfsi(尺度因子选择信息)用于指出是否将粒度组1的尺度因子用于粒度组2。
如果为0表示不用,则在比特流中需读取粒度组2的尺度因子。
1.4.3处理流程
缩放因子解码流程图
1.5哈夫曼解码
哈夫曼编码是一种变长编码,在mp3哈夫曼编码中,高频的一串零值不编码,不超过1的下一个区域使用四维哈夫曼编码,其余的大值区域采用二维哈夫曼编码,而且可选择地分为三个亚区,每个有独立选择的哈夫曼码表。
通过每个亚区单独的自适应码表,增强编码效率,而且同时降低了对传输误码的敏感度。
在程序实现上,哈夫曼表逻辑存储采用了广义表结构,物理存储上使用数组结构。
查表时,先读入4bit数据,以这4bit数据作为索引,其指向的元素有两种类型,一种是值结构,另一种是链表指针式结构,在链表指针式结构中给出了还需要读取的bit数,及一个偏移值。
如果索引指向的是一个值结构,则这个值结构就包含了要查找的数据。
如果索引指向的是一个链表指针式结构,则还需再读取其中指定的比特数,再把读取出的比特数同偏移值相加,递归的找下去,直到找到值结构为止。
1.5.1处理流程
1.6逆量化
1.6.1逆量化公式
逆量化由下面公式算出:
短窗模式:
长窗模式:
其中:
is[i]:
由huffman编码构造的频率线
sbg:
subblock_gain
scalefac_multiplier:
=(scalefac_scale+1)/2
其它值均可在帧边信息中找到。
1.7联合立体声转换
1.7.1强度立体声转换
在强度立体声模式中,左声道传的是幅值,右声道的scalefactor传的是立体声的位置is_pos。
需要转换的频率线有一个低边界,这个低边界是由右声道的zero_part决定的,并且使用右声道的尺度因子来作为is_pos。
强度立体声比
左声道:
右声道:
1.7.2M_S立体声转换
在M_S立体声模式中,传送的是规格化的中间/旁边声道的信息
左声道
右声道
其中Mi是channel[0]的值,Si是channel[1]的值
1.7.3处理流程
强度立体声模式:
MS_STEREO因公式单一,较易理解,故流程图略去。
1.7.4数据帧
PCM信号进行MP3压缩时,以1152个PCM采样值为单位,封装成具有固定长度的MP3数据帧,帧是MP3文件的最小组成单位。
在解码时,利用数据帧里的信息就可以恢复出1152个PCM采样值。
这1152个采样值被分为2个粒度组,每个粒度组包含576个采样值。
一个MP3数据帧分为5个部分:
帧头、CRC校验值、边信息、主数据、附加数据。
数据流的同步以及帧头信息的读取MP3数据流的同步以帧为单位,每一帧的帧头都包含同步信息。
这个同步信息是连续的12比特的‘1’组成。
MP3音频解码过程中的第一步就是使解码器与输入数据流同步。
在启动解码器后,可以通过搜索数据流中的12比特长的同步字来完成。
在取得同步以后跟着的数据就是帧头信息,包括采样率、填充位、比特率等信息。
主数据的读取在MP3编码过程中使用了比特池技术,所以当前帧的主数据不一定全部都在当前帧中,在解码过程中,必须结合主数据开始指针的值来确定主数据的开始位置。
主数据包含的数据有缩放因子、哈夫曼数据及附加数据。
这些字段在主数据中有固定的格式。
1.7.5哈弗曼解码流程
哈夫曼解码和反量化在MP3编码过程中,根据心理声学模型的输出,对离散余弦变换的输出样本以粒度为单位进行的量化和分配,再对量化的结果进行哈夫曼编码。
量化和编码主要是通过循环迭代完成的,循环模块分为三层来描述,最高层为帧循环,它调用外层迭代循环,而外层迭代循环又调用内层迭代循环。
但在解码过程中,哈夫曼解码和反量化过程是分开实现的。
每个粒度组的频率线都是用不同的哈夫曼表来进行编码的,因此在解码过程中,需要采用不同的解码方法。
反量化频谱过程就是基于所得到的哈夫曼解码数据,根据逆量化全缩放公式和帧边信息,对于不同的窗类型采用不同的公式以恢复576个频率线的真实值。
1.7.6立体声处理
反量化过程中得出的频谱值不是按相同顺序排列的。
在编码的MDCT过程中,对于长窗产生的频谱值先按子带然后按频率排列;对于短窗,产生的频谱值按子带、窗、频率的顺序排列。
为了提供哈夫曼编码效率,短窗中的数据被重新排列,按照子带、频率、窗的顺序排列。
解码时,重排序及时将短窗中的频谱值重新排列。
同样,在编码的MDCT过程中,为了得到更好的频域特性,对长窗对应每个子带进行了去混叠处理,为了得到正确的音频信号,在解码时必须对长窗对应的子带进行混叠重建。
逆向离散余弦变换逆向离散余弦变换主要是使用逆向离散余弦变换的公式,对反量化得出的信号进行变换。
逆向离散余弦变换的计算十分复杂,为了提高效率,可以对计算做一些优化。
频率反转和子带合成频率反转是对逆向离散余弦变换的输出值中的奇数号子带(0到31号子带中的1,3,5,...,31)中的奇数号样本值(每个子带中的0到17号样本值的1,3,5,...,17号样本值)进行反相处理,用来补偿编码时为提高离散余弦变换效率而进行的频率反转。
子带合成滤波器将32个带宽相等的子带中的频域信号反变换成时域信号。
子带合成是逆向离散余弦变换后的一个通道中32个子带的样值,经过一系列的计算还原出32个PCM数字音频信号的过程。
子带合成过程先将32个子带样值进行逆向离散余弦变换,生成64个中间值,将这64个中间值转入到一个长为1024点的类似先进先出FIFO的缓存,再在这1024个值中抽取一半,构成一个512个值的矢量,再进行加窗运算,最后将加窗结果进行叠加生成32个时域输出。
1.8重排序
重排序的目的在于把哈夫曼解码之后的短块的每个尺度因子带3个窗,每个窗sfbwidth(尺度因子带宽度)个采样的顺序整理成为每个子带三个窗,每个窗六个采样xr[sb][window][freq_line]的顺序。
1.8.1处理流程
重排序处理流程图
1.8.2混淆缩减
对于长块,在进入IMDCT之前应当先进行混淆缩减。
其算法思想是用蝶形算法进行相邻块相邻频率线的调整。
如图:
混淆缩减算法图
其计算公式如下:
其中ci可由ISO1172.3tableB.9查得
计算流程如下(pascal 描述):
Forsb=1to32do
Fori=0to7do
Xar[18sb-i-1]=xr[18sb–i-1]cs[i]–xr[18sb+i]ca[i]
Xar[18sb+i]=xr[18sb+i]cs[i]+xr[18sb-i-1]ca[i]
Endfor
Endfor
1.9IMDCT覆盖叠加
MDCT的目的在于进行时域到频域的转换,减少信号的相关性,使得信号的压缩可以更加高效地完成,而它的反变换IMDCT的目的在于将信号还原为没有变换之前的数值,使频域值向时域值过渡。
其公式如下:
在进行了IMDCT变换之后,需对频率信号进行加窗、覆盖、叠加。
1.9.1加窗:
长块:
开始块:
结束块:
短块的每个窗口分别计算:
1.9.2叠加:
将每一块变换出来的值的前半部分与前一块的后半部分相加,并把后半部分保留来和下一块的前半部分相加。
如下公式:
resulti=zi+sifori=0to17
si=zi+18fori=0to17
1.9.3Szu-WeiLee的快速算法
Szu-WeiLee的IMDCT快速算法是针对非2的n次幂个点的IMDCT快速算法。
他的主要步骤如下:
1将N点MDCT化为N/2点DCT-IV
2将N/2点DCT-IV化为N/2点SDCT-II
3将N/2点SDCT-II化为2个相同的N/4点SDCT-II
4计算SDCT-II(9点)
在本程序中,因为对短块使用这个快速算法并没有带来较大的速度改善,故只对长块使用此快速算法,相较于直接运算的648次乘和612次加来,它只用43次乘和115次加。
1.10频率反转
在IMDCT之后,进入合成多相滤波之前必须进行频率反转补偿以校正多相滤波器组的频率反转。
方法是将奇数号子带的奇数个采样值乘以-1.
1.11合成多相滤波
合成多相滤波的目的是将频域信号转化为时域信号。
其原理流程如下:
合成多相滤波算法图
上图流程可简述如下:
5将从32个子带抽来的32个sample值通过一个矩阵运算算出64个中间值
6将这64个中间值放入一个长度为1024的FIFO缓冲区(这个缓冲区初始化为0)。
7从这个缓冲区中每连续的128个值中取头尾各32个值,合为64个值。
完成后组成512值的向量U
8加窗,即将Ui与窗口系数Di相乘,得到另一512值向量W
9最后将这512值向量W每连续的32个值中顺次取一个值,一次共取得512/32=16个值相加。
完成后一共取得32个最终的时域信号值。
1.1.2ByeongGiLee的dct快速算法
ByeongGiLee的DCT快速算法是用于2的n次幂个点的dct快速算法。
它用于N点的DCT时仅需(N/2)*log2N次乘法和小于3·*(N/2)*log2N)次加法。
其基本思想是,将N个点的DCT转化为两个N/2个点的DCT的和。
进一步分解,即重复这个过程,减少乘法数量。
由于向量Vi的运算是一个类似于DCT的变换,故使用了此快