win mobile 5播放mp3音乐的方法(1)--libmad库的移植篇

鉴客

win mobile 5播放mp3音乐的方法(1)--libmad库的移植篇

鉴客 发表于 10-23 09:28 1年前, 0 回/140阅

【珠海】 11月25日(周日下午)OSC 源创会 我要报名?

win mobile 5上面播放mp3似乎已经有了可以依赖于win mobile提供的
multi-media播放器的调用方法。这种显而易见的方法,我认为缺少一些
主动性,只能微软怎么做,咱就怎么做。如果想做出个性化的软件或者
播放器,或者实现在线边下载边播放的方案就很困难了。对于从moto的
linux移植到win mobile的5mbox而言,我更熟悉传统的一些的处理mp3文件
的方案。
基本的思路是:先把mp3文件读取到缓冲区,然后解码,解成pcm码流,然后
下一步是把pcm码流送给系统的播放接口开始播放。
mp3文件读取自然没有什么问题,不需要多说。如果有心提高播放效率的话,
可以考虑加入一个线程后台读取,把mp3的二进制数据直接读入一个二进制
队列里面,然后解码器再从队列中读取块数据进行解码。经过我在多普达p800
真机上测试,这一步由于是二进制文件的顺序读取,如果不是网络应用
(例如:边下载边播放的那种),是可以忽略不计的,对mp3的解码没有
什么大的影响。
总体来说,解码的速度,应该是整个程序的瓶颈(实际上也确实如此)。
于是乎目光转向了libmad这个开源的mp3解码器。很多linux下面优秀的mp3
播放器都是基于这个解码器做得。
我用来移植的libmad的版本是0.14.2的这个版本(在version.h文件里面有定义)
1# define MAD_VERSION_MAJOR 0
2# define MAD_VERSION_MINOR 14
3# define MAD_VERSION_PATCH 2
4# define MAD_VERSION_EXTRA " (beta)"

但是在config.h里面写的是:
#define VERSION "0.14.2b"
不管了,大概是这个样子的。

具体的移植过程主要有如下几点:
(1)mad.h的嵌入汇编问题
打开mad.h会发现这是一个很大的头文件,一般我们在c++中编写头文件的时候
都是采用总的一个文件a.h,在a.h中include了若干个头文件。这样可以希望在
编译的时候,把cpp编译成.o或者.obj文件,然后链接。
这里的mad.h看上去就是把各个头文件的内容都直接拷贝到这个文件中,我想可
能是它要使用汇编优化的原因吧,有的.o不是由对应的.c编译出来的,而是通
过.S编译出来的,可以有选择的链接,当然也不一定对,不管它了。
这里面需要注意的是fix.h中的关于FPM_xxxx的定义,它涉及到一系列的嵌入式
汇编语句。我查看了一下,多数都是linux平台下面的gcc格式的嵌入式汇编格式
我尝试过用cygwin或者mingw编译汇编的文件,然后放到目录下跟win32的obj文件
一起链接是可以的,但是太麻烦了。
所以在这里,我还是希望能够用vs2005的编译器直接编译,这样就需要在:
# if defined(FPM_FLOAT)
前面加入#define FPM_DEFAULT,使得代码看上去是这样的:
#define FPM_DEFAULT
# if defined(FPM_FLOAT)
....
在mad.h和fix.h两个文件中都要加。这样宏就会自动选择default的形式来编译了
采用c语言的普通移位运算来做一些操作。这相比于汇编代码自然效率低了不少。
经过我在win mobile 5的机器上实际测试的结果来看,效率是有所降低,但是
不是致命的,是可以接受并通过一些其它方面的优化措施加以补救的。
(2)把所有的.c文件都改为.cpp文件,这是例牌了。
然后把所有的.h文件#ifndef xxxx, #define xxxx后面都加入:
01#ifdef __cplusplus
02extern "C" {
03#endif 
04xxxxxxxxxxxx
05xxxxxxxxxxxx
06....代码
07xxxxxxxxxxxx
08xxxxxxxxxxxx
09#ifdef __cplusplus
10}
11#endif

这里面特别需要说明的是mad.h文件,里面包含了很多个头文件的定义,
需要耐心的加入上面的那些定义。

(3)类型定义方面的错误
这个错误是非常让人郁闷的,修改起来也需要非常大的耐心才行,我们来看下面的定义:
1struct A {
2struct B {
3struct C {
4....
5} xxx ; 
6....
7} xxxx ; 
8} ;


在c语言中,没有所谓名字空间的概念,上述定义是可以直接引用的:
struct A xxx ;
struct B xxx ;
struct C xxx ;
这样的声明在c语言中是完全合法的,但是到了c++中,就不再合法,如果要定义的话必须用如下
方法:
struct A xxxx ;
struct A::B xxx ;
struct A::B::C xxx ;
采用这样的方法才行,理解这一点,对于成功移植layer3.cpp尤为重要,这个文件中是有一个嵌套
的结构体定义(可能还有别的,我只是用这个来举个例子):

01struct sideinfo {
02unsigned int main_data_begin;
03unsigned int private_bits;
04unsigned char scfsi[2];
05struct granule {
06struct channel {
07/* from side info */
08unsigned short part2_3_length;
09unsigned short big_values;
10unsigned short global_gain;
11unsigned short scalefac_compress;
12unsigned char flags;
13unsigned char block_type;
14unsigned char table_select[3];
15unsigned char subblock_gain[3];
16unsigned char region0_count;
17unsigned char region1_count;
18/* from main_data */
19unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */
20} ch[2];
21} gr[2];
22};


这里面,对于这个sideinfo里面包含的结构体的定义,就需要像我上面提到的那样嵌套的定义才可以。
struct sideinfo xxxx ;
struct sideinfo::granule xxxx ;
struct sideinfo::granule::channel xxxx ;
呵呵,这样做才能把原先说是数据类型没有定义的部分都变成已经定义的部分。

(4)常规的类型转换问题
例如在bit.cpp中定义的:
unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len)
作者为了方便,直接定义为unsigned long类型的,而在具体使用中经过c++编译器编译以后,就会爆出
无法进行类型转换的warning或者error,需要手工强制类型转换为(unsigned char)mad_bit_read(xxxx)
就可以了。
这样的情况还会发生在enum类型的数据赋值上面,在c语言中,我们通常认为enum就是int数值,所以
libmad的作者也是如此考虑的(在c++语法中,这一点是不同的),很多enum类型返回值都让作者弄成是
int,这样也会出现类型转换的错误,只要细心一些,灵活运用强制类型转换应该就可以解决这个问题。
(5)一些设置文件的修改
例如config.h,可以把如下linux相关部分定义去掉
//#define HAVE_ERRNO_H 1
//#define HAVE_FCNTL_H 1
//#define HAVE_SYS_TYPES_H 1
多试几次,就可以完成libmad的移植工作,经过在多普达p800上的测试,可以流畅地播放mp3文件。
上面这些是手工移植的大体总结,下面我把移植好的,可以在win mobile 5.x上直接运行的libmad
的源代码公布出来,希望能够对后来者有所帮助,可以省下时间做更加有意义的事情。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据中王者MySql作为系统的数据,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值