Android-NDK 接入Fmod库,变声操作
生活随笔
收集整理的這篇文章主要介紹了
Android-NDK 接入Fmod库,变声操作
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
fmod是音效引擎庫,游戲引擎cocos2d、unity3d 等都是默認集成了 fmod 來做音效。
fmod官網
1.下載Fmod資源
可以在官網下載,也可以直接訪問百度云盤下載:
鏈接:https://pan.baidu.com/s/1Ypqlgk8WWacstURNMw2ETw
提取碼:pkom
2.接入Fmod
-
在main路徑下新建jniLibs文件夾,增加需要的架構庫,根據項目來選擇。并講libfmod.so、libfmodL.so這兩個so庫拷貝到相應的路徑下面。
- arm64-v8a:新手機使用的這個架構,微信項目只支持這個,支付寶用的armeabi-v7a。
- armeabi
- armeabi-v7a :游戲類項目,可只選armeabi-v7a,優勢具有輕量級的DSP數字信號處理能力。
- x86 :模擬器以及WindowPhone手機使用的這個架構
-
在libs路徑下面增加fmod.jar包,并在gradle中配置依賴
- implementation fileTree(include: ['*.jar'], dir: 'libs') :依賴所有libs路徑下的jar包。
- implementation files('libs\\fmod.jar') :單獨依賴此jar包。
-
在build.gradle中配置
- externalNativeBuild {cmake {abiFilters "armeabi-v7a" //指定編譯用的CPU架構庫} }
- ndk {abiFilters("armeabi-v7a") //配置最終打包到apk中的包含的CPU架構 }
-
引入頭文件inc,講inc文件夾全部拷貝到cpp路徑下面。
-
配置CMakeLists.txt文件
- # 最低支持的CMake版本 cmake_minimum_required(VERSION 3.18.1)
- include_directories("inc") #導入頭文件,因為inc跟CMakeLists.txt文件同級所以直接寫inc就行。
- #指定編譯的庫的名稱、類型、以及需要加入的源文件,如果cpp源文件有多個,直接在括號里邊添加即可。 add_library(#庫名字msvoicechange# 庫類型 動態還是靜態SHARED# 添加的源文件native-lib.cpp)多個cpp源文件的時候,也可以通過統一引用file(GLOB allCPP *.c *.h *.cpp) ${allCPP} 直接添加這個就可以
- #給fmod.so設置環境變量,這樣就可以依賴到fmod的動態庫了 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}")
- #這個find_library 其實就是查找 liblog.so 庫,并將路徑緩存給變量 log-lib,以后直接使用這個變量就行,如果設計多個使用,可以提高效率。 下面是這個so庫的路徑 #D:\tools\Android\Sdk\ndk\21.4.7075529\platforms\android-24\arch-arm64\usr\lib\liblog.so find_library(#變量名稱log-lib#庫名 liblog.so 找的是這個庫 log)
- #進行鏈接操作 target_link_libraries( # Specifies the target library.msvoicechangefmod #需要將so 鏈接到msvoicechange 里邊 注意這里的名稱前面的lib默認會加這里不能寫 #so也是一樣fmodL${log-lib})
3.編寫Android上層頁面代碼
加載編譯生成的so庫,采用靜態代碼塊的方式添加。
companion object {init {System.loadLibrary("msvoicechange")} }在onCreate方法里邊,添加初始化的操作,一般的都會有這樣的操作。
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)FMOD.init(this);}在onDestroy,添加關閉的操作
override fun onDestroy() {super.onDestroy()FMOD.close(); }定義natvie方法
/*** path:音頻文件的路徑* mode:變聲的類型:原聲、蘿莉、大叔等*/external fun voiceChangeNative(mode: Int, path: String)4.編寫cpp部分
#include "fmod.hpp" //有hpp后綴的引用這個,這個是最新版本,加強版本 #include <unistd.h> #include <string>//增加命名空間 using namespace std; using namespace FMOD;extern "C" JNIEXPORT void JNICALL Java_com_meishe_msvoicechange_MainActivity_voiceChangeNative(JNIEnv *env, jobject thiz, jint mode,jstring path) {const char *toast_content = "播放完畢";//c++只能使用c或者c++的內容 并能用JNI的數據,所以需要轉//JNI的方法參數,只能使用JNI的類型,所以也需要轉//得到傳進來的音頻路徑const char *audioPath = env->GetStringUTFChars(path, NULL);//fmod 的音效引擎System *system = 0;//fmod 的聲音Sound *sound = 0;//fmod 的音軌Channel *channel = 0;//digital signal process 數字信號處理DSP *dsp = 0;//c 的初始化方式xxx(system) 一般都是需要傳遞指針的,因為需要對地址進行賦值操作,,指針就是地址System_Create(&system);//初始化system->init(32, FMOD_INIT_NORMAL, NULL);//創建聲音system->createSound(audioPath, FMOD_DEFAULT, 0, &sound);//播放聲音system->playSound(sound, 0, false, &channel);switch (mode) {case com_meishe_msvoicechange_MainActivity_MODE_NORMAL:toast_content = "原聲-->播放完畢";break;case com_meishe_msvoicechange_MainActivity_MODE_LUOLI:// 蘿莉 音調高//創建dsp pitch 音調調節 默認是1 小于1音調低 大于1音調高 0.5-2(合理的調節區間)system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT,&dsp);//設置pitch音調=2.0dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,2.0f);//添加一個音效進去channel->addDSP(0,dsp);toast_content = "蘿莉:播放完畢";break;case com_meishe_msvoicechange_MainActivity_MODE_DASHU://大叔 音調低system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT,&dsp);dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,0.7f);channel->addDSP(0,dsp);toast_content = "大叔:播放完畢";break;case com_meishe_msvoicechange_MainActivity_MODE_JINGSONG://驚悚 多個音頻軌道 拼接處理//音調較低system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT,&dsp);dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,0.7f);channel->addDSP(0,dsp);//echo 回聲system->createDSPByType(FMOD_DSP_TYPE_ECHO,&dsp);dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY,500);dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK,35);channel->addDSP(1,dsp);// 顫抖 Tremolo frequency:頻率 skew :傾斜system->createDSPByType(FMOD_DSP_TYPE_TREMOLO,&dsp);dsp->setParameterFloat(FMOD_DSP_TREMOLO_FREQUENCY,0.8);dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW,0.8);channel->addDSP(2,dsp);toast_content = "驚悚:播放完畢";break;case com_meishe_msvoicechange_MainActivity_MODE_GAOGUAI://搞怪 頻率快float frequency;channel->getFrequency(&frequency);channel->setFrequency(frequency*1.5);toast_content = "搞怪:播放完畢";break;case com_meishe_msvoicechange_MainActivity_MODE_KONGLING://空靈system->createDSPByType(FMOD_DSP_TYPE_ECHO,&dsp);dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY,200);//衰減 50 默認 0就沒了dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK,10);channel->addDSP(0,dsp);toast_content = "空靈:播放完畢";break;}bool isPlay= true;while (isPlay){channel->isPlaying(&isPlay);usleep(1000*1000); //單位是微秒}//進行資源釋放sound->release();system->close();system->release();env->ReleaseStringUTFChars(path,audioPath);//回調java方法,提示用戶播放完畢jclass _activityClazz = env->GetObjectClass(thiz);jmethodID _toastId = env->GetMethodID(_activityClazz, "playerEnd", "(Ljava/lang/String;)V");jstring _toastJString = env->NewStringUTF(toast_content);env->CallVoidMethod(thiz, _toastId, _toastJString);}System:fmod 的音效引擎
Sound:聲音
Channel:音軌
DSP:數字信號處理
- pitch:對音調的調節,音調高了一般是蘿莉 音調低了就是大叔,默認是1 調節區間(0.5-2)
- echo:回聲,空靈會使用這個
- Tremolo:這個是顫抖
這樣就完成了對Fmod庫的依賴,并使用庫中的方法做了調音的效果。
源碼地址
總結
以上是生活随笔為你收集整理的Android-NDK 接入Fmod库,变声操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python面试题总结(4)--数据类型
- 下一篇: Android 开发中常用的库