本文介绍了符合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解码流程图
其中同步及差错检查包括了头解码模块
在主控模块开始运行后,主控模块将比特流的数据缓冲区交给同步及差错检查模块,此模块包含两个功能,即头信息解码及帧边信息解码,根据它们的信息进行尺度因子解码及哈夫曼解码,得出的结果经过逆量化,立体声解码,混淆缩减,IMDCT,频率反转,合成多相滤波这几个模块之后,得出左右声道的PCM码流,再由主控模块将其放入输出缓冲区输出到声音播放设备。
2、主控模块
主控模块的主要任务是操作输入输出缓冲区,调用其它各模块协同工作。
其中,输入输出缓冲区均由DSP控制模块提供接口。
输入缓冲区中放的数据为原始mp3压缩数据流,DSP控制模块每次给出大于最大可能帧长度的一块缓冲区,这块缓冲区与上次解帧完后的数据(必然小于一帧)连接在一起,构成新的缓冲区。
输出缓冲区中将存放的数据为解码出来的PCM数据,代表了声音的振幅。它由一块固定长度的缓冲区构成,通过调用DSP控制模块的接口函数,得到头指针,在完成输出缓冲区的填充后,调用中断处理输出至I2S接口所连接的音频ADC芯片(立体声音频DAC和DirectDrive耳机放大器)输出模拟声音。
3、同步及差错检测
同步及差错检测模块主要用于找出数据帧在比特流中的位置,并对以此位置开始的帧头、CRC校验码及帧边信息进行解码,这些解码的结果用于后继的尺度因子解码模块和哈夫曼解码模块。Mpeg1 layer 3的流的主数据格式见下图:
主数据的组织结构图
其中granule0和granule1表示在一帧里面的粒度组1和粒度组2,channel0和channel1表示在一个粒度组里面的两个通道,scalefactor为尺度因子quantized value为量化后的哈夫曼编码值,它分为big values大值区和count1 1值区
CRC校验:表达式为X16+X15+X2+1
3.1 帧同步
帧同步目的在于找出帧头在比特流中的位置,ISO 1172-3规定,MPEG1 的帧头为12比特的“1111 1111 1111”,且相邻的两个帧头隔有等间距的字节数,这个字节数可由下式算出:
N= 144 * 比特率 / 采样率
如果这个式子的结果不是整数,那么就需要用到一个叫填充位的参数,表示间距为N +1。
3.2 头信息解码
头信息解码目的是找出这一帧的特征信息,如采样率,是否受保护,是否有填充位等。头信息见下图:
帧头信息结构图
其长度为4 字节,数据结构如下:
typedef struct tagHeader {
unsigned int sync : 11 ; / / 同步信息
unsigned int version : 2 ; / / 版本
unsigned int layer : 2 ; / / 层
unsigned int error2protection : 1 ; / / CRC校正
unsigned int bit2rate2index : 4 ; / / 位率索引
unsigned int sample2rate2index : 2 ; / / 采样率索引
unsigned int padding : 1 ; / / 空白字<