Android开发,jni,ndk开发,调用fmod音频库,音效引擎库

文章目录

Android开发,jni,ndk开发,调用fmod音频库,音效引擎库

1.fmod介绍

https://www.fmod.com/

手机cpu架构指令

2.cmake

作用:把fmod的代码导入到动态库中

导入头文件:

导入库文件:

java 复制代码
    // Used to load the 'native-lib' library on application startup.
    static {
//        System.loadLibrary("native-lib");
        // libnative-lib.so 包含fmod。才能调用fmod,把fmod集成到libnative-lib.so动态库里面就可以调用了
        //apk lib平台libnative-lib.so里面的代码
        System.loadLibrary("native-lib");
    }

cmakelists.txt

java 复制代码
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)
#批量导入所有的cpp文件
file(GLOB allCPP *.c *.h *.cpp)

#导入头文件
include_directories(inc) #相对CMakeLists的路径

#导入库文件,c++环境变量
#CMAKE_SOURCE_DIR CMakeLists的路径
#CMAKE_ANDROID_ARCH 获取手机的四大平台

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}")


# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             native-lib #//libnative-lib.so的生成

             # Sets the library as a shared library.
             SHARED #//动态库

             # Provides a relative path to your source file(s).
             native-lib.cpp #//源文件
            ${allCPP}
        )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
#日志打印的库
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 )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

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

链接库

java 复制代码
        externalNativeBuild {
            cmake {
//                cppFlags ""
            abiFilters "armeabi-v7a"
            }
        }

只处理armeabi-v7a平台,ndk下面这个是会把so库编译进apk里

复制代码
ndk{
    
    abiFilters "armeabi-v7a"
}

3.C++代码实践

资源目录

java代码

java 复制代码
public class MainActivity extends AppCompatActivity {

   libnative-lib.so 动态库    libnative-lib.a 静态库
    static {
        // libnative-lib.so 必须包含fmod代码。我们才能调用fmod
        System.loadLibrary("native-lib");
    }
    private String path;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        path = "file:///android_asset/test.mp3";
        FMOD.init(this); 
    }

    
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_kongling:
                voiceChangeNative(MODE_KONGLING, path);
                break;
        }
    }
    
    private native void voiceChangeNative(int mode, String path);
    public native String stringFromJNI();
    //jni调用的一个方法
    private void playerEnd(String msg) {
        Toast.makeText(this, "" +msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        FMOD.close(); 
    }

}

导入头文件,可以在fmod官方库获取

hpp后缀 C++,ndk,

声音

Demo JNI

c 复制代码
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_voiceChangeNative(JNIEnv *env, jobject thiz, jint mode,
                                                              jstring path) {
    char * testString = "结束";

    //c语言字符串
    const char *path1 = env->GetStringUTFChars(path, NULL);

    //fmod引擎系统指针
    System *system1 = nullptr;

    //音效指针
    Sound *sound = nullptr;

    //音轨指针
    Channel *channel = nullptr;

    //数字信号处理指针
    DSP *dsp = nullptr;

    System_Create(&system1);
    //初始化
    system1->init(20, FMOD_INIT_NORMAL, 0);
    //创建声音音轨
    system1->createSound(path1, FMOD_DEFAULT, 0, &sound);

    system1->playSound(sound, 0, false, &channel);

    switch (mode) {
        case com_example_myapplication_MainActivity_MODE_NORMAL:
            testString = "MODE_NORMAL 播放结束";
            break;
            case com_example_myapplication_MainActivity_MODE_GAOGUAI:
            testString = "MODE_GAOGUAI 播放结束";
            //音轨中获取频率
            float mFrequency;
            channel->getFrequency(&mFrequency);
            // 修改 帧率
            channel->setFrequency(mFrequency * 1.9f);
            break;
        case com_example_myapplication_MainActivity_MODE_LUOLI:
            testString = "MODE_LUOLI 播放完毕";
            //Dsp pitch,创建音调
            system1->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            //设置音调
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 2.0f);

            // 设置音效到音轨里面
            channel->addDSP(0, dsp);
            break;
    }
    //监听
    bool isPlay = 1;
    while (isPlay){

        channel->isPlaying(&isPlay);
        usleep(1000 * 1000);
    }


    //
    sound->release();
    system1->close();
    system1->release();
    env->ReleaseStringUTFChars(path, path1);

    //通知java层的playerEnd函数
    jclass mainCls = env->GetObjectClass(thiz);
    jmethodID endMethod = env->GetMethodID(mainCls, "playerEnd", "(Ljava/lang/String;)V");
    jstring value = env->NewStringUTF(testString);
    env->CallVoidMethod(thiz, endMethod, value);
}
相关推荐
AC赳赳老秦44 分钟前
OpenClaw+Power Apps 实战:自动生成 Power Apps 应用、连接 Excel 数据源
大数据·开发语言·python·serverless·excel·deepseek·openclaw
茉莉玫瑰花茶2 小时前
综合案例 - AI 智能租房助手 [ 5 ]
服务器·数据库·人工智能·python·ai
文艺倾年2 小时前
【强化学习】强化学习基本概念,20W字总结(一)
人工智能·python·语言模型·自然语言处理·面试·职场和发展·大模型
宸丶一2 小时前
Day 13:持久化记忆 - 让 Agent 拥有长期记忆
jvm·python·ai
潇凝子潇3 小时前
chrome插件-给音视频添加倍速播放控制功能
音视频·chrome devtools
BreezeDove3 小时前
【Android】AS项目自动连接mumu模拟器配置
android
码云骑士3 小时前
13-列表append的底层真相(上)-listobject源码中的预分配策略
开发语言·python
浦信仿真大讲堂3 小时前
达索系统SIMULIA Abaqus 2026接触和约束的增强新功能介绍
人工智能·python·算法·仿真软件·达索软件
sweetone3 小时前
SONY老式磁带随身听wm-fx193 之摩机过程(提升重低音音效,改耳放)
经验分享·音视频
xufengzhu3 小时前
第三方 Python 库 Loguru 的进阶实战
python·loguru