Android NDK导入C库示例(fmod)

以导入fmod为例

    fmod官网:https://www.fmod.com/
    fmod包下载:https://share.weiyun.com/1KtqEUlA
        (头文件:api\lowlevel\inc下、库文件:api\lowlevel\lib下)

创建一个空项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

配置ndk路径

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

导入fmod的头文件

把inc整个目录(头文件:api\lowlevel\inc)拷贝到项目的 \app\src\main\cpp 下

include_directories("inc")

在这里插入图片描述

批量导入源文件

默认是只导入native-lib.cpp,可以继续追加一些源文件,但避免遗漏,批量导入

add_library(
        native-lib
        SHARED
        native-lib.cpp)

批量导入:

file(GLOB allCPP *.c *.h *.cpp)
add_library(
        native-lib
        SHARED
        ${allCPP})

在这里插入图片描述

导入fmod的库文件

在目录 \app\src\main 下创建 jniLibs 目录

将fmod文件中的api\lowlevel\lib 下的cpu架构拷贝到jniLibs目录下

# 导入库文件
# CMAKE_SOURCE_DIR 等于 CMakeLists.txt所在的地址目录
# CMAKE_ANDROID_ARCH_ABI  等于 当前手机的CPU架构
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}")

在这里插入图片描述

链接具体的库

默认是 这样设置了别名再链接,像这里的 log ,对应的就是
C:\xxxxxx\Android\Sdk\ndk\20.0.5594570\platforms\android-23\arch-arm64\usr\lib\liblog.so
即,刚开始配置ndk的路径下的

find_library(
        log-lib
        log)

target_link_libraries(
        native-lib
        ${log-lib})

修改成如下:

target_link_libraries(
        native-lib
        log
        fmod
        fmodL
)

在这里插入图片描述

导入fmod.jar

将fmod中 api\core\lib\fmod.jar导入

// 导入fmod.jar
implementation files("libs\\fmod.jar")

在这里插入图片描述

生成头文件

MainActivity.java

private static final int MODE_NORMAL = 0;
    private static final int MODE_LUOLI = 1;
    private static final int MODE_DASHU = 2;
    private static final int MODE_JINGSONG = 3;
    private static final int MODE_GAOGUAI = 4;
    private static final int MODE_KONGLING = 5;
    String path;
    static {
        System.loadLibrary("native-lib");
    }
    private void playerEnd(String msg){
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
    private native void voiceChange(int mode, String path);

在这里插入图片描述
在目录 app\src\main\java 下执行: javah com.example.fmod_test.MainActivity
将头文件放到 \app\src\main\cpp 下
导入fmod的头文件
在这里插入图片描述

实现文件 native-lib.cpp

#include <unistd.h>
#include "com_example_fmod_test_MainActivity.h"

extern "C" JNIEXPORT void JNICALL Java_com_example_fmod_1test_MainActivity_voiceChange
        (JNIEnv * env, jobject thiz, jint mode, jstring path){
    const char * path_ = env->GetStringUTFChars(path, NULL);

    // FMOD
    FMOD::System * system = 0;      // 音效引擎
    FMOD::Sound * sound = 0;        // 声音
    FMOD::Channel * channel = 0;    // 通道
    FMOD::DSP * dsp = 0;            // DSP digital signal process  数字信号处理

    FMOD::System_Create(&system);                       // 创建系统
    system->init(32,FMOD_INIT_NORMAL, 0);               // 系统的初始化
    system->createSound(path_, FMOD_DEFAULT, 0, &sound);// 创建声音
    system->playSound(sound, 0, false, &channel);       // 播放

    switch (mode) {
        case com_example_fmod_test_MainActivity_MODE_NORMAL:
            break;
        case com_example_fmod_test_MainActivity_MODE_LUOLI:
            system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 2.0f);
            channel->addDSP(0, dsp);
            break;
        case com_example_fmod_test_MainActivity_MODE_DASHU:
            system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.7f);
            channel->addDSP(0, dsp);
            break;
        case com_example_fmod_test_MainActivity_MODE_GAOGUAI:
            float mFrequency;
            channel->getFrequency(&mFrequency);
            channel->setFrequency(mFrequency * 1.5f);
            break;
        case com_example_fmod_test_MainActivity_MODE_KONGLING:
            system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);
            dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 200);
            dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 10);
            channel->addDSP(0, dsp);
            break;
        case com_example_fmod_test_MainActivity_MODE_JINGSONG:
            system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.7f);
            channel->addDSP(0, dsp);

            system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);
            dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 200);
            dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 10);
            channel->addDSP(1, dsp);

            system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp);
            dsp->setParameterFloat(FMOD_DSP_TREMOLO_FREQUENCY, 20);
            dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.8f);
            channel->addDSP(2, dsp);
            break;
    }

    bool isPlayer = true;
    while (isPlayer) {
        channel->isPlaying(&isPlayer);
        usleep(1000 * 1000);
    }

    // 释放
    sound->release();
    system->close();
    system->release();
    env->ReleaseStringUTFChars(path, path_);

    // 调用java的方法
    jclass cls = env->GetObjectClass(thiz);
    jmethodID playerEndMethod = env->GetMethodID(cls, "playerEnd", "(Ljava/lang/String;)V");
    jstring msg = env->NewStringUTF("播放完毕");
    env->CallVoidMethod(thiz, playerEndMethod, msg);
}

遗留问题:通过 fmod 播放完mp3文件后,会延迟一段时间isPlaying才返回false,不知道什么原因!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值