Android NDK的使用实例——fmod example

Android NDK的使用实例——fmod example_第1张图片
image

概述

这次记录的是NDK的使用实例,使用 fmod 来处理变声。有着上一次 Android NDK的使用实例——增量更新实战 的实践经验,一开始还想着不会特别麻烦。实战以后才发现,连demo也不是简单导入就能够跑起来的,为此也踩了不少坑。这次先记录下如何成功跑起官方的demo。

fmod是什么?这是fmod的官网 https://www.fmod.com。fmod是音效引擎游戏开发革命引擎。很多著名游戏如魔兽都使用到该音效引擎,游戏开发引擎Cocos2D、Unity3D更是直接内置封装了这个库。正如Android也在Library层内置封装了OpenGL ES、SQLite等优秀的库。像fmod这种优秀的C/C++库,有了NDK的支持,自然也可以应用到Android应用程序中,开发类似于QQ变声等功能。

下载官方文件

官网注册后,下载api解压后打开,看到下图所示。这里有一些文档,其实我们只是想要跑Android的demo的话,只需要看到 api/lowlevel 低版本的api里面就能看我们熟悉的一些文件,比如 example/org.fmod.example/MainActivity、libfmod.so库、fmod.jar包等。

Android NDK的使用实例——fmod example_第2张图片
image

如何使用

如何运行这个demo?也查找了很多资料,看了很多文档,而且这种问题简单通俗的资料也不多。文末有参考博客。这里其实是运行了一个播放声音的demo,点击不同的按钮就播放不同的声音。UI操作如下:

Android NDK的使用实例——fmod example_第3张图片
image

新建一个C++ support工程,这里还是使用CMake的方式。既然这里要使用的功能就是播放声音,看下载的文件发现有个 play_sound.cpp 的类,copy进来,编译,随之发现引用到的其他几个头文件、源文件也是需要一起copy进来。最终的软件工程目录是这样的。

Android NDK的使用实例——fmod example_第4张图片
image

需要注意的地方

1、添加权限


2、修改 include 路径

因为我们直接copy了整个 inc 文件夹,有几个文件 play_sound.cpp、common.cpp、common.h 就需要修改 include 的路径了

#include "inc/fmod.hpp"
#include "inc/fmod_errors.h"
3、修改JNI方法定义

这里的MainActivity的包名最好保证是 org.fmod.example,要么就到
common_platform.cpp 里面修改相应的方法名,按照JNI的命名规范。

extern "C"
{

jstring Java_org_fmod_example_MainActivity_getButtonLabel(JNIEnv *env, jobject thiz, jint index)
{
    return env->NewStringUTF(Common_BtnStr((Common_Button)index));
}

void Java_org_fmod_example_MainActivity_buttonDown(JNIEnv *env, jobject thiz, jint index)
{
    gDownButtons |= (1 << index);
}

......

void Java_org_fmod_example_MainActivity_main(JNIEnv *env, jobject thiz)
{
    gJNIEnv = env;
    gMainActivityObject = thiz;

    FMOD_Main();
}

} /* extern "C" */

预编译so库

修改 CMakeLists.txt,这个才是这次记录的重点。因为fmod的很多源代码并没有全部开源出来,很多都是以so库的形式存在fmod.so、fmodL.so里面,因此,我们需要预编译这些so库,不然无法编译通过。

# 设置构建这个so库所需要的最小CMake版本
cmake_minimum_required(VERSION 3.4.1)

# 设置一个变量path_project,后面预编译so库的时候会使用到
set(path_project /document/workandroid/NdkTest6_fmod)

# 添加默认需要生成的so库
add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             # 这里最好把相关的cpp源文件都添加进来
             src/main/cpp/play_sound.cpp
             src/main/cpp/common.cpp
             src/main/cpp/common_platform.cpp
             src/main/cpp/native-lib.cpp )

# 注意:这里添加两个需要预编译的so库fmod.so、fmodL.so,也就是上面的cpp源文件的部分源代码
# 是在so库里面,并没有全部开源出来,我们要先预编译so库,才能编译通过
add_library(
    fmod
    SHARED
    IMPORTED )

# 设置预编译的so库的路径,这里要使用绝对路径,不然会链接错误,
# 测试了使用相对路径编译通过,但运行崩溃。
set_target_properties(
    fmod
    PROPERTIES IMPORTED_LOCATION
    ${path_project}/app/src/main/jniLibs/${ANDROID_ABI}/libfmod.so )

add_library(
    fmodL
    SHARED
    IMPORTED )
set_target_properties(
    fmodL
    PROPERTIES IMPORTED_LOCATION
    ${path_project}/app/src/main/jniLibs/${ANDROID_ABI}/libfmodL.so )

# 找到Android内置的log库,用于打印log
find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# 这里需要把预编译的so库,链接到默认生成的native-lib.so库中
# 后续System.loadLibrary("native-lib")就可以包含预编译的so库了。
target_link_libraries( # Specifies the target library.
                       native-lib
                       fmod
                       fmodL

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

注意:在MainActivity中只需要

System.loadLibrary("native-lib");

就可以,因为在 CMakeLists.txt 已经将预编译的fmod.so、fmodL.so链接到该so库中了。
构建通过,运行demo。

总结

这里再理一下整个过程。首先要知道的是,这个demo提供的是一个播放声音方法。所以需要引入 play_sound.cpp,以及相对应的其他cpp文件、jar包。然后需要将这些文件构建成so库,而构建这个so库要需要其他的so库fmod.so、fmodL.so,这就是涉及到CMake的使用,如何预编译其他依赖的so库。将相关的so库,头文件,源文件都准备好之后,通过CMake构建脚本,就可以构建出目标的so库 native-lib.so,然后就可以执行播放声音了。

下一次将要使用这个库来制作变声效果。

Demo代码已上传至我的 GitHub

感谢

FMOD
Android NDK开发之旅25--NDK--模仿QQ变声特效
Android Studio NDK开发(九):变声特效

你可能感兴趣的:(Android NDK的使用实例——fmod example)