基于ARM平台的MP3软解码算法研究与实现
摘要:为了减少功耗与降低成本,根据ARM芯片对C语言良好支持的特点,在深度剖析MP3解码算法、分析C语言在ARM芯片上编程的优化方法的基础上,通过软件形式实现MP3音频解码器,便一些无硬件解码器支持的ARM嵌入式系统完成MP3解码任务,从而实现基于ARM的嵌入式系统的MP3软解码器,可以有效地降低系统功耗,提高解码效率,更好地扩展和增强便携嵌入式系统多媒体功能。
关键词:MP3解码;ARM嵌入式系统;嵌入式多媒体;霍夫曼编码
随着便携式嵌入式系统的发展,嵌入式多媒体技术正在影响并改变着人们的日常生活,多媒体音频编码解码技术也越来越受到关注和重视。笔者提出了一种MP3音频解码通过软件方式在嵌入式系统上实现的解决方案。该方案以目前比较高效的MP3解码算法为基础,灵活的取代了基于DSP的硬件解码方案,在低消耗处理器资源的前提下,实现能与硬件解码相媲美的效果。从而节省了研发或购买DSP芯片的费用,还可以方便快捷的兼容MPEG新提出的解码标准,这是该方案最重要的现实意义。
目前国外在MP3软解码方面的研究有两大成果,一个是开源MP3解码项目mpg123,一个是开源嵌入式MP3解码库libmad。这两个开源项目中使用的解码算法参考了很多国际学术论文。前者被广泛用于播放器软件,例如Mplaver,千千静听等;后者则更加适用于嵌入式系统,已经被成功移植到Symbian手机系统上。
1 MP3解码算法分析
MP3解码主要包括以下过程:预处理(Preprocessing)、霍夫曼编码(Huffman decoding)、反量化(Requantization)、重排列(Reorder ing)、立体声解码(Stereo decoding)、混迭消除(Alias reduction)、反离散余弦变换(IMDCT transform)、频域转换(Frequency invers ion)、子带合成滤波(Synthesis filterbank),最后生成声卡可以直接读取的PCM采样。MP3解码流程具体如图1所示。
为了在ARM处理器下快速稳定的运行解码器,除了浮点转化为定点的策略,还要根据硬件特点进一步进行程序优化:首先减小运算强度,利用位移操作代替乘除运算,通常需要乘除以2的幂次方都可以用左右移n位来完成,比如3×8等价于33;利用乘法代替乘方运算,ARM核中内建有乘法器,因此可以通过乘法运算来代替调用C库函数乘方运算以节约函数调用开销;利用与运算代替求余运算。通常and指令比%操作效率要高;使用内联函数,ARM下支持C语言inline关键字,这时的函数直接在调用处代码展开,省去了函数调用开销,不过它的缺点是代码量增加;使用寄存器变量,CPU对寄存器的存取要比对内存的存取快得多,因此为变量分配一个寄存器,将有助于代码的优化和运行效率的提高。
避免除法,ARM指令集中没有除法指令,其除法是通过调用C库函数实现,一个32位的除法通常需要20~140个时钟周期。因此,除法是程序效率的瓶颈,应尽量避免使用。用查表法代替计算,在CPU资源紧张而内存资源富裕的情况下,可以用空间来换取运行速度,例如在反离散余弦变换算法中需要频繁的计算正弦和余弦函数值,可以预先将函数值计算出来以常量放到内存里,需要计算时直接通过内存地址提取需要的值。
3 解码器结构设计与实现
在对现有算法进行研究的基础上,笔者设计出一个性能优良、结构灵活、可移植性强的MP3软解码器。解码器主要包括以下模块:解码器引擎初始化,缓冲区输入输出控制,帧解码模块,注销解码器引擎等。
3.1 解码器引擎初始化
用MP3文件初始化解码器,初始化过程中,解码器读取每一帧的帧头信息而不对数据进行解码,快速计算出该文件的播放时间,并根据文件大小以秒或分钟为单位内建解码位置索引。解码位置索引的目的是为了快速的根据时间定位待解码数据在文件中的位置。
数据流缓存提供的功能有以下几点:
初始化:该功能申请堆中的一块内存,用于以后存放缓存数据。
注销:负责释放初始化时申请的内存。
写入数据:向缓存的当前写入位置后写入指定大小的数据。
跳过指定大小数据:将当前读取位置移动到指定位置。
获取错误信息:返回操作过程中产生的错误信息。
帧同步:将读取位置跳转到下一帧开始位置。该操作的主要算法是每次读取缓存11个比特,若这些比特全为1,则把其当做下一帧的开始位置。通过研究可知,该种算法并不能准确判断下一帧的开始,但这种算法不进行帧头解码,也不会漏掉数据。从时间和空间上讲,都是一种比较好的选择。
解码引擎以帧为解码单位,每次输出一帧的解码输出结构,结构中包括pcm数据、长度、采样率、声道数,播放时间等信息。
3.3 帧解码模块
该模块为解码引擎核心模块,按照顺序完成预处理、霍夫曼编码、反量化、重排列、立体声解码、混迭消除、反离散余弦变换、频域转换、子带合成滤波,最后生成声卡可以直接读取的PCM采样。
- 浅析如何学习基于ARM平台的嵌入式系统(12-02)
- 嵌入式ARM平台调试方法的讨论(11-21)
- 建立ARM平台上的交叉调试器gdb和gdbserver(11-11)
- ARM平台上实现Linux PPP拨号(11-11)
- 为ARM平台添加rzsz指令(11-11)
- ARM平台NEON指令的编译和优化(11-10)