赵羽佳,罗红杰,吕 强
(武汉轻工大学电气与电子工程学院,湖北武汉430023)
WMA和MP3格式作为国内知名的音频压缩格式,以其良好的特性在很多领域得到了广泛的应用。由于WMA算法没有公开,除了微软公司提供解码程序外,FFmpeg项目组用逆向工程的方法开发出了WMA解码,Mplayer用的就是这个解码,但是将该解码程序移植到mini2440开发板后,解码效果不理想。mini2440开发板采用专业稳定的CPU内核电源芯片和复位芯片来保证系统运行时的稳定性[1]。它是一款真正低价实用的ARM9开发板,性价比高,采用Samsung S3C2440为微处理器。下面就以mini2440为开发板,对Mplayer中的WMA解码程序进行优化。
优化设计的多媒体播放器是基于嵌入式Linux而设计的,嵌入式linux是裁剪修改版的linux操作系统,它由一个Kernel(内核)以及一些根据需要而定制的系统模块组成,Kernel一般只有几百kB,即便加上其它必须的应用程序和模块,所需的存储空间也很小[2]。具有多线程、多任务、源码开放等优点。
开发嵌入式Linux的运行环境是开发板,开发环境是宿主机。宿主机(Host)是一台通用计算机,它通过以太网接口或者串口与目标机通信[3]。宿主机的软硬件资源比较丰富,能够大大提高嵌入式应用软件的开发速度和效率。目标板(Target)是应用程序实际运行的平台,或者是能够替代实际运行环境的仿真系统。软硬件资源通常都比较有限[4]。本文的宿主机采用Windows 7操作系统并安装了VMware虚拟机、目标板是mini2440开发板,并采用串口通信进行开发。
Linux内核:Red Hat4.5.1-4。编译工具:gcc4.5.1。交叉编译工具:arm-linux-gcc3.4.1。
硬件平台:普通 PC机。运行环境:arm-linuxgcc(版本:4.5.1)。图形用户界面平台:Qt/Embedded 2.3.7。硬件平台:mini2440 开发板。
1.2.1 引导加载程序
在PC机中系统加电时运行的第一段代码就是引导加载程序,PC机中的引导加载程序由BIOS和OS Loader组成,PC机中的BIOS主要任务是初始化电脑设备,它将第一个检索到的硬盘上MBR中的内容读到系统RAM中,接着由OS Loader来完成第二级引导加载操作[5]。由OS Loader负责将所要引导的操作系统的内核映象从硬盘上读到系统RAM中,然后跳转到内核的入口点上。但是在Linux嵌入式系统中,一般没有BIOS程序,因而将由Boot-Loader来完成系统的加载过程。
1.2.2 交叉编译开发环境建立
交叉编译就是一台机器中执行的程序不是在本机器编译生成,而是由另一台的机器编译生成。一般把前者称为目标机,后者称为宿主机[6]。在嵌入式系统中,开发板就是目标机,而PC机就是宿主机。在PC机上编译好可以在开发板上运行的程序后,通过串口线或网线将程序下载到开发板,然后通过PC机上的超级终端来控制开发板中程序的运行。交叉编译开发模型如图1所示。
图1 交叉编译开发模型
嵌入式交叉编译环境的建立过程如下。
1)下载预先编译好的交叉开发环境到根目录下。
2)执行如下命令安装:tar xzvf arm-linux-gcc-4.3.2.tar.gz-C。
3)生成的编译工具在目录/user/local/arm/4.3.2/bin下。
4)添加环境变量:进入/etc/profile,添加export PATH=/user/local/arm/4.3.2/bin:$PATH。
5)验证编译环境是否建立成功:输入命令#armlinux-gcc-v,如果看到版本信息,表示建立成功。
下载 MPlayer-1.0rc2.tar.bz2 和 libmad-0.15.1b.tar.gz文件,通过 configure配置完成后,执行make命令完成编译。这里注意,MPlayer 1.0已经把大部分解码库都自带了,但是自带的音频库在S32440下效果非常不好,换成使用libmad效果不错[7]。在配置信息中要加上--disable-mp3lib不配置mp3lib。
虽然MPlayer提供了WMA解码程序,但MPlayer提供的WMA解码程序运算量大,移植到本硬件平台后,解码效率不能满足设计要求。因此需要对MPlayer中的WMA开源解码程序进行优化设计,从而使WMA解码程序在2440中的解码效率得到提高。本文选用浮点转定点的方法和快速除法进行WMA解码器的优化。
S3C2440不具有浮点运算单元(FPU),在实现浮点运算时需要用软件模拟的方法来实现,然而WMA的解码过程需要大量的浮点运算[8]。浮点运算存储格式特殊,在进行浮点运算的时候要用到复杂的操作,这种方式效率不高,运算量大。然而定点运算就相对简单一些,本文的优化方法之一就是浮点转定点运算。
2.1.1 浮点转定点分析
在计算机内部表示小数时,小数的小数点位置是可变的。而对于定点数而言,小数点的位置就是固定的。如C语言中float类型的数就是浮点数。基于IEEE754的浮点数包括3种:单精度浮点数、双精度浮点数和扩展精度浮点数,本文只讨论前两者。单精度浮点数在计算机中占4个字节,用32位二进制描述,其中符号位S占1个位、指数位E占8位、尾数位M占23位,如图2所示。
图2 单精度存储格式
双精度浮点数在计算机中占8个字节,用64位二进制描述,同样包含3个构成字段,其中符号位S占1位、指数位E占11位、尾数位M占52位。对其进行重新编号。其中0—51位代表52位尾数,52—62位代表11位的指数,最高位代表符号。
通过内联函数或宏定义来实现浮点转定点运算,一般情况下转换后的定点数为int型,有32位,低16位为尾数部分,高16位为整数部分。如果两个定点数都带有16位尾数,那么这两个定点数相乘,结果会带有32位尾数,这时需要将结果右移16位。如果浮点数转定点数时超过了定点数的取值范围时,将不进行转换。如果没有超过定点数的范围则进行转换,如图3所示。
图3 32位定点数相乘过程处理
2.1.2 用定点运算优化解码函数
在具体优化的过程中,首先要对程序的工作流程进行分析。找出解码过程中耗时最长的程序段进行优化,直到解码时间低于某个值为止。MPlayer解码WMA文件是通过调用FFMPEG的开源编解码库libaVcodec来实现的。MPlayer主程序调用WMA解码函数过程如图4所示。
图4 WMA主要解码函数及其关系
通过调试代码,发现在解码每帧时,函数wma_decode_block()都会被循环调用多次,并且每次调用的耗时都很长,所以这个函数就是我们最先要优化的代码[9]。测量解码时间需要在mplayer的主函数main.c中设置一个打印函数对其进行时间测试,发现函数fft_calc(&s→fft,z)耗时最长,进而读这个函数的实现代码发现,z是个浮点数,且在计算中有大量涉及浮点计算的循环,这样浮点转定点的优化方法就有了用武之地了。把z先转化为定点数再传给fft_calc(&s→ fft,z)函数,结果运算速度果然明显提高了。如表1所示,这里采用4个音频文件,file1.wma、file2.wma 是比特率为 48 kbps,采样率为44 kHz,长度为 20 s的 WMA 文件。file3.wma、file4.wma 是比特率为 48 kbps,采样率为 44 kHz,长度为20 s的WMA文件。
表1 优化前后解码耗时对比
WMA解码器经过优化后,计算速度提高了43.78%,在S3C2440上解码音频文件基本上达到实时播放的要求。
采用浮点运算转定点运算来优化解码函数,其中浮点转定点是优化的关键,优化过程中选择解码过程中耗时最长的程序段进行优化。交叉编译环境的建立和mplayer的移植也很重要。通过优化解码,解码速度提高了43.78%,使嵌入式开发板也能较好地播放WMA文件。
[1]毛德操,胡希明.嵌入式系统:采用公开源代码和StrongARM/XScale处理器[M].浙江:浙江大学出版社,2003:45-48.
[2]王正万.嵌入式Linux下基于ARM9的媒体播放的设计[J].电子设计工程,2010(12):135-137.
[3]马龙华,彭哲.基于Scilab的ARM.Linux嵌入式计算及应用[M].北京:科学出版社,2008:44-52.
[4]Andrew N Sloss,Dominic Symes,Chris Wirght.ARM嵌入式系统开发.软件设计与优化[M].沈建华译.北京:北京航空航天大学出版社,2005:14-37.
[5]Diomidis Spinellis.代码阅读方法与实践[M].赵学良译.北京:清华大学出版社,2004.
[6]李凡.Qt/Embedded在嵌入式Linux系统下的移植与应用[J].黑龙江科技信息,2008,27:79-80.
[7]Srinvas M,Patnaik L M.Adaptive probability of crossover and mutation in genetic algorithms[J].IEEE Trans on SMC,1994,24(4):656-667.
[8]段玉倩,贺家李.遗传算法及其改进[J].电力系统及其自动化学报,1998,10(1):39-52.
[9]MPlayer.The online documentation of MPlayer[EB/OL].(2008-04-01)http://www.mplayerhq.hu/DOCS/HTML-single/en/MPlayer.thml.