栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Android NDK导入C库示例

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android NDK导入C库示例

以导入fmod为例

    fmod官网:https://www.fmod.com/

创建一个空项目



配置ndk路径



下载fmod

fmod的API下载:https://www.fmod.com/download#ue4integration

头文件:apicoreinc下
库文件:apicorelib下

导入fmod的头文件

把inc整个目录(头文件:apicoreinc)拷贝到项目的 appsrcmaincpp 下

批量导入源文件

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

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

批量导入:

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

导入fmod的库文件

在目录 appsrcmain 下创建 jniLibs 目录

将fmod文件中的apicorelib下的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:xxxxxxAndroidSdkndk20.0.5594570platformsandroid-23arch-arm64usrlibliblog.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中 apicorelibfmod.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);


在目录 appsrcmainjava 下执行: javah com.example.fmod_test.MainActivity
将头文件放到 appsrcmaincpp 下
导入fmod的头文件

实现文件 native-lib.cpp
#include 
#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,不知道什么原因!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/303335.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号