FMOD 集成指南

作者:Reyn

前提

FMOD是为游戏开发者准备的音频引擎,比起 Cocos2d-x 内置的SimpleAudioEngine,其专业能力超出SimpleAudioEngine好几个量级。长期以来,我们内部使用的一直是SimpleAudioEngine,期间出现过音频无法播放、丢失等问题,为解决SimpleAudioEngine的硬伤,我们决定使用FMOD替换掉SimpleAudioEngine。这篇文章就旨在讲解FMOD集成的过程。

方案

本次集成基于开源方案cocos2d-x-fmod,然而由于cocos2d-x-fmod集成的 api 过于简陋,没有发挥出fmod应有的强大,比如:设置音量缺失、不区分音乐和音效、不提供重播功能等,因此我在其基础上新增了很多 API 以适应项目的需要,并尽量向SimpleAudioEngine提供的 API 看齐。API 的扩展在此处不是重点,下面重点说明集成的过程。

一、代码集成

  1. 拉取 cocos2d-x-fmod
  2. fmod目录复制到frameworks⁩/cocos2d-x⁩/external
  3. lua_fmod_auto.cpplua_fmod_auto.hpp复制到frameworks⁩/cocos2d-x⁩/cocos/scripting/lua-binding/manual (这里是一个坑,虽然它是 auto,但实际上是 manual,因此把它丢到 manual 下)
  4. 修改frameworks/cocos2d-x/cocos/scripting/lua-bindings/manual/CCLuaStack.cpp cpp ... #include "fmod/lua_fmod_auto.hpp" ... // 2.register bool LuaStack::init(void) { ... register_all_cocos2dx_fmod(_state); ... return true; }

二、Windows 集成

  1. FMODAudioEngine.cppFMODAudioEngine.h添加到libcocos2d工程
  2. lua_fmod_auto.cpplua_fmod_auto.hpp添加到libluacocos2d工程
  3. 配置 fmod 的附加库目录
  4. 添加 fmod 的附加依赖项
  5. 编译,成功后需要将fmodL.dll动态库复制到生成目录,否则程序会提示fmodL.dll而运行不起来

三、Android 集成

  1. fmod.jar复制到app/libs目录下,并修改app/build.gradle将其添加为库:
// fmod
implementation files('libs\\fmod.jar')
  1. 修改AppActivity.java
    ...
    static
    {
        //加载fmodL动态库
        System.loadLibrary("fmodL");
    }
    ...
    protected void onCreate(Bundle savedInstanceState) {
    ...
    // 初始化fmod
    org.fmod.FMOD.init(this);
    ...
    }
    ···
    protected void onDestroy() {
        ···
        org.fmod.FMOD.close();
        ···
        super.onDestroy();
    }
    ···
  1. 修改cocos/Android.mk:
    ···
    LOCAL_STATIC_LIBRARIES += fmod_static
    ···
    $(call import-module,fmod/prebuilt/android)
  1. 修改cocos/scripting/lua-bindings/proj.android/Android.mk:
    ···
    LOCAL_SRC_FILES += ../manual/fmod/lua_fmod_auto.cpp

    LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../../external/lua/tolua \
    ···
                        $(LOCAL_PATH)/../manual/fmod \
                        $(LOCAL_PATH)/../../../../external/fmod \
    ···
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../../external/lua/tolua \
    ···
                        $(LOCAL_PATH)/../manual/fmod \
                        $(LOCAL_PATH)/../../../../external/fmod \
    ···