android SDL系列讲解(十三) 播放音乐库 SDL_mixer教程


项目外包项目信息更新:
qq抢红包,因为评估时间问题,没有对接下来。
一个网页开发项目,已经内部消耗掉了。

机会总是稍纵即逝,有兴趣探讨技术,以及项目事宜,可以联系代码GG微信:
code_gg_boy


SDL系列讲解(一) 简介
SDL系列讲解(二) 环境搭建
SDL系列讲解(三) 工具安装
SDL是什么,能干什么,为什么我们要学习它?
SDL系列讲解(四) demo讲解
SDL系列讲解(五) 调试c代码
SDL系列讲解(六) SDL_Activity流程
SDL系列讲解(七) SDL_image教程SDL系列讲解(八) SDL_ttf教程
SDL系列讲解(九) 异常退出分析
SDL系列讲解(十) 按键处理流程
SDL系列讲解(十一) SDL_QUIT流程
SDL系列讲解(十二)创建窗口流程


项目合作

下周发布一个游戏移植过程,敬请期待。 android学习过程的所有疑惑,可以留言,代码GG知无不言言无不尽,会答疑解惑。

前言

讲解完了图片,文字,这节我们来看下怎么播放声音。
SDL默认是可以播放wav以及pcm格式的音乐,但是使用起来比较麻烦,所以官网给我们提供了一个三方库SDL_mixer,用来支援更多的音频格式,比如mp3,midi以及ogg,关于flac无损音乐,后续有个移植过程,但是编译出来使用的时候,发现速度跟不上,有卡顿现象,有兴趣的可以去研究下。在本节的最后,会提供flac的编译方法。

下载SDL_mixer库

来到 http://www.libsdl.org/projects/SDL_mixer/ ,下载这里的SDL2_mixer-2.0.1.zip


下载下来,我们放置到jni目录,改名字为SDL2_mixer。



配置SDL_mixer库

修改app\src\main\jni下面的Android.mk,新增两行加入
include src/main/jni/SDL2_mixer/external/libmikmod-3.1.12/Android.mk
include src/main/jni/SDL2_mixer/external/smpeg2-2.0.0/Android.mk
目的在于,将SDL2_mixer里面包含的开源库编译进来。然后开始编译,爆出一个错误


修改成assert(audio->timestamp >= (double*)0); 再次编译。

然后修改android-project/app/src/main/jni/src/Android.mk
LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_ttf


LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_ttf SDL2_mixer

将我们的SDL2_mixer包含进来。

验证播放音乐

下载一首歌曲,这里下载薛之谦的《动物世界》,放置在项目的assets目录下。


然后在我们的main.c的main方法里面加入
//初始化mix,MP3格式if (Mix_Init(MIX_INIT_MP3) < 0) { printf("Mix_Init: %s\n", SDL_GetError()); return 1;}//打开设备if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096) < 0) { printf("Mix_OpenAudio: %s\n", SDL_GetError()); return 1;}Mix_Music *music = Mix_LoadMUS("dongwu.mp3");Mix_PlayMusic(music, SDL_TRUE);

在退出的地方,加入



然后编译,运行app,观看效果。然而你所遇到的是个bug,apk异常退出啦。


可以看到,这里是解包的大小引起,本身三方库就是解决编解码的问题,然而编解码出现问题,可以去修复,同时也可以使用其他替代,这里我们用SDL提供的第二个库libmad进行解码mp3格式。
移植libmod 库

第一步,下载git for window
打开 http://rj.baidu.com/soft/detail/30195.html?ald 进行下载即可。
关于Git

Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

安装Git

主界面:


我们只需要一直下一步即可,不用管其他的操作,使用默认的即可。
安装后,我们点击电脑左下方的window图标,选择所有应用,选择git目录,选择git Bash

选择点开git Bash之后,界面为:

然后我们使用cd /d 进入d盘,然后使用
git clone https://gitorious.org/rowboat/external-libmad.git 将libmad模块抓下来。


等待下载完成,然后我们进入d盘下,将下载好的目录,复制到我们项目的app\src\main\jni\SDL2_mixer\external目录下,并且改名为libmad


然后我们修改app\src\main\jni下面的Android .mk ,加入一行:
include src/main/jni/SDL2_mixer/external/libmad/Android.mk
然后我们修改app\src\main\jni\SDL2_mixer下面的Android.mk

LOCAL_C_INCLUDES := $(LOCAL_PATH)LOCAL_CFLAGS := -DWAV_MUSIC
后面加入:



同时把本文件的
SUPPORT_MP3_SMPEG ?= true 修改成
SUPPORT_MP3_SMPEG ?= false
去掉smpeg的默认解码mp3,使用mad库进行解码。
进入app\src\main\jni\SDL2_mixer\external\libmad 修改这里的Android.mk

具体为:

删除第一行的
ifeq ($(strip $(BUILD_WITH_GST)),true)
和最后一行的

endif
然后修改:

LOCAL_CFLAGS := -DHAVE_CONFIG_H -DFPM_DEFAULT
修改为:
LOCAL_CFLAGS :=-DHAVE_CONFIG_H -DFPM_ARM -ffast-math -O3
这里主要的是FPM_ARM,让编译arm指令集。

如果编译过程报错:
Error:error: invalid instruction mnemonic 'smull'
我们需要修改
ndk { abiFilters "armeabi", "armeabi-v7a", "x86" }
这里的armeabi 需要去掉,同时我们去掉x86,去掉armeabi是因为低版本的arm没有smull指令,去掉x86是因为我们手机是arm平台,为了我们快速编译apk,就先去掉它。
延伸flac无损解码库编译

不做更详细的讲解,这里将我的操作过程展示一下。因为我们一般使用的mp3 wav格式,当前已经完美支持,所以flac放在有兴趣研究的人,这里作为抛砖一下。
http://downloads.xiph.org/releases/flac/flac-1.3.2.tar.xz 下载flac库。
然后我们需要ubuntu 等linux环境,解压,进入目录,然后使用:
./configure --help 进行查看都有哪些命令,然后进行配置,配置参数里面的CC CXX这些路径,需要自己修改对应自己的真正arm编译链的位置。

./configure
--prefix=/home/andy/share/flac/cross_install --enable-cross-compile --build=i386-pc-linux-gnu --host=arm-linux --target=arm-linux --enable-ogg --disable-3dnow --disable-oggtest --disable-asm-optimizations --disable-xmms-plugin --disable-sse --disable-cpplibs --disable-shared --disable-id3libtest \CC=/home/user/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc \CXX=/home/user/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ \AR=/home/user/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar \LD=/home/user/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld \RANLIB=/home/user/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ranlib \STRIP=/home/user/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip \CFLAGS="-I/home/user/Android/Sdk/ndk-bundle/platforms/android-24/arch-arm/usr/include -I/media/user/big/sdl/android-project/app/src/main/jni/SDL2_mixer/external/libogg-1.3.1/include" \CXXFLAGS="-I/home/user/Android/Sdk/ndk-bundle/platforms/android-24/arch-arm/usr/include -I/media/user/big/sdl/android-project/app/src/main/jni/SDL2_mixer/external/libogg-1.3.1/include" \LDFLAGS=--sysroot=/home/user/Android/Sdk/ndk-bundle/platforms/android-24/arch-arm

配置通过后,我们使用make 即可完成编译,如果想看编译的具体参数等信息,可以使用make --just-print 进行只输出命令,不做实质编译,用来学习编译过程,最好不过啦。

编译过后,会出来一个libFLAC-static.a 静态库,然后我们在我们的项目jni目录下创建libs目录加入这个库:libs/libFLAC.a (改成这个名字)

在SDL2_mixer目录下的Android .mk 加入:

编译之后,这是我们可以播放flac格式的音乐了。

问题
flac编译出来,可以播放音乐,但是比较卡,具体此问题,留作疑问。

推荐阅读更多精彩内容