本文介绍了符合ISO/IEC 11172-3(MPEG 1 Audio codec Layer I, Layer II and Layer III audio specifications) 或 ISO/IEC 13818-3(BC Audio Codec)的音频编码原理。通过madlib解码库进行实现。1、程序系统结构mp3解码流程图 其中同步及差错检查包括了头解码模块 2、主控模块主控模块的主要任务是操作输入输出缓冲区,调用其它各模块协同工作。 3、同步及差错检测同步及差错检测模块主要用于找出数据帧在比特流中的位置,并对以此位置开始的帧头、CRC校验码及帧边信息进行解码,这些解码的结果用于后继的尺度因子解码模块和哈夫曼解码模块。Mpeg1 layer 3的流的主数据格式见下图: 主数据的组织结构图
3.1 帧同步帧同步目的在于找出帧头在比特流中的位置,ISO 1172-3规定,MPEG1 的帧头为12比特的“1111 1111 1111”,且相邻的两个帧头隔有等间距的字节数,这个字节数可由下式算出: 3.2 头信息解码头信息解码目的是找出这一帧的特征信息,如采样率,是否受保护,是否有填充位等。头信息见下图: 帧头信息结构图 其长度为4 字节,数据结构如下: 3.3 帧边信息解码帧边信息解码的主要目的在于找出解这帧的各个参数,包括主数据开始位置,尺度因子长度等。帧边信息如下图所示: 帧边信息(side_infomation)表 3.4 main_data_beginmain_data_begin(主数据开始)是一个偏移值,指出主数据是在同步字之前多少个字节开始。需要注意的是,1.帧头不一定是一帧的开始,帧头CRC校验字和帧边信息在帧数据中是滑动的。2.这个数值忽略帧头和帧边信息的存在,如果main_data_begin = 0, 则主数据从帧边信息的下一个字节开始。 参见下图: 同步示意图 3.5 block_typeblock_type指出如下三种块类型: 3.6 big_values, count1每一个粒度组的频谱都是用不同的哈夫曼表来进行编码的。编码时,把整个从0 到奈奎斯特频率的频率范围(共576个频率线)分成几个区域,然后再用不同的表编码。划分过程是根据最大的量化值来完成的,它假设较高频率的值有较低的幅度或者根本不需要编码。从高频开始,一对一对的计算量化值等于“0”的数目,此数目记为“rzero”。然后4个一组地计算绝对值不超过“1”的量化值(也就是说,其中只可能有-1,0 和+1共3 个可能的量化级别)的数目,记为“count1”,在此区域只应用了4 个哈夫曼编码表。最后,剩下的偶数个值的对数记为“big values”, 在此区域只应用了32 个哈夫曼编码表。在此范围里的最大绝对值限制为8191。此后,为增强哈夫曼编码性能,进一步划分了频谱。也就是说,对big values的区域(姑且称为大值区)再细化,目的是为了得到更好的错误顽健性和更好的编码效率。在不同的区域内应用了不同的哈夫曼编码表。具体使用哪一个表由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值区和零值区分布图 3.7 处理流程4、缩放因子(scale factor)解码缩放因子用于对哈夫曼解码数据进行逆量化的样点重构。根据帧边信息中的scalefactor_compress 和标准中的对应表格来确定的slen1和slen2 对缩放因子进行解码,即直接从主数据块中读取缩放因子信息并存入表scalefac_l[gr][ch][sfb]和scalefac_s[gr][ch][sfb]中。对第2 粒度组解码时,若为长块,则必须考虑尺度因子选择信息。 4.1 尺度因子带(scalefactor-band)在mpeg layer 3中576条频率线根据人耳的听觉特性被分成多个组,每个组对应若干个尺度因子,这些组就叫做尺度因子带,每个长窗有21个尺度因子带而每个短窗有12个尺度因子带。 4.2 scfsiscfsi(尺度因子选择信息)用于指出是否将粒度组1的尺度因子用于粒度组2。如果为0表示不用,则在比特流中需读取粒度组2的尺度因子。 4.3 处理流程
缩放因子解码流程图 5、哈夫曼解码哈夫曼编码是一种变长编码,在mp3哈夫曼编码中,高频的一串零值不编码,不超过1的下一个区域使用四维哈夫曼编码,其余的大值区域采用二维哈夫曼编码,而且可选择地分为三个亚区,每个有独立选择的哈夫曼码表。通过每个亚区单独的自适应码表,增强编码效率,而且同时降低了对传输误码的敏感度。 5.1 处理流程6、逆量化6.1 逆量化公式逆量化由下面公式算出: 长窗模式: is[i] :由huffman编码构造的频率线 sbg :subblock_gain scalefac_multiplier := (scalefac_scale + 1) / 2 其它值均可在帧边信息中找到。 7、联合立体声转换7.1 强度立体声转换在强度立体声模式中,左声道传的是幅值,右声道的scalefactor传的是立体声的位置is_pos。需要转换的频率线有一个低边界,这个低边界是由右声道的zero_part决定的,并且使用右声道的尺度因子来作为is_pos。 左声道: 右声道: 7.2 M_S立体声转换在M_S立体声模式中,传送的是规格化的中间/旁边声道的信息 其中Mi是channel[0]的值,Si是channel[1]的值 7.3 处理流程强度立体声模式: MS_STEREO因公式单一,较易理解,故流程图略去。 8、重排序重排序的目的在于把哈夫曼解码之后的短块的每个尺度因子带3个窗,每个窗sfbwidth(尺度因子带宽度)个采样的顺序整理成为每个子带三个窗,每个窗六个采样xr[sb][window][freq_line]的顺序。 8.1 处理流程
重排序处理流程图 混淆缩减对于长块,在进入IMDCT之前应当先进行混淆缩减。其算法思想是用蝶形算法进行相邻块相邻频率线的调整。如图: 混淆缩减算法图
其中ci可由ISO 1172.3 table B.9查得 计算流程如下(pascal 描述): For sb = 1 to 32 do For i = 0 to 7 do 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] End for End for 10、IMDCT覆盖叠加MDCT的目的在于进行时域到频域的转换,减少信号的相关性,使得信号的压缩可以更加高效地完成,而它的反变换IMDCT的目的在于将信号还原为没有变换之前的数值,使频域值向时域值过渡。 在进行了IMDCT变换之后,需对频率信号进行加窗、覆盖、叠加。 10.1 加窗:长块: 开始块: 结束块: 短块的每个窗口分别计算: 10.2 叠加:将每一块变换出来的值的前半部分与前一块的后半部分相加,并把后半部分保留来和下一块的前半部分相加。如下公式: 10.3 Szu-Wei Lee的快速算法Szu-Wei Lee的IMDCT快速算法是针对非2的n次幂个点的IMDCT快速算法。他的主要步骤如下:
在本程序中,因为对短块使用这个快速算法并没有带来较大的速度改善,故只对长块使用此快速算法,相较于直接运算的648次乘和612次加来,它只用43次乘和115次加。 11、频率反转在IMDCT之后,进入合成多相滤波之前必须进行频率反转补偿以校正多相滤波器组的频率反转。方法是将奇数号子带的奇数个采样值乘以-1. 12、合成多相滤波合成多相滤波的目的是将频域信号转化为时域信号。其原理流程如下: 合成多相滤波算法图
Byeong Gi Lee的dct快速算法Byeong Gi Lee的DCT快速算法是用于2的n次幂个点的dct快速算法。它用于N点的DCT时仅需(N/2) * log2N次乘法和小于3·*(N/2)*log2 N ) 次加法。 其基本思想是,将N个点的DCT转化为两个N/2个点的DCT的和。进一步分解,即重复这个过程,减少乘法数量。 术语说明MPEG:Motion Picture Expert Group 参考文献
|
联系客服