KO
|
EN
gitlite — search
Search
#nodejs
#javascript
#php
#hacktoberfest
#wordpress
#android
#python
#csharp
#wordpress-plugin
#java
#require
#scala
NDKVoice
★ 50
Open GitHub ↗
【博客】AndroidStudio+CMake实现QQ变声效果
Download README (.md)
Explore Similar Repositories
angular-universal-express-firebase
:
A packaged Cloud Function to serve Angular Universal apps.
caffe-sal
:
Amulet and UCF methods for Saliency Detection
gff3sort
:
GFF3sort: A Perl Script to sort gff3 files and produce suitable results for tabix tools
How-to-configure-SSL-for-FileBeat-and-Logstash-step-by-step
:
How to configure SSL for FileBeat and Logstash step by step (Create CA, CSRs, Certificates, etc)
BethanysPieShop
:
Sample code for Pluralsight course Building an Enterprise ASP.NET Core MVC app
// repository documentation
Was this content helpful?
★ 0
(0 ratings)
Select Rating:
★
★
★
★
★
Submit Feedback
Recent Feedback
×
Download README
Do you want to download the
README.md
file for
NDKVoice
?
Download (.md)
[toc] ## 项目演示  ## 源码下载 Github:https://github.com/AndroidHensen/NDKVoice ## 环境配置 1. 你的Android Studio在SDKManager中下载好ndk-build和cmake 2. 通过fmod的官网,在DownLoad页面中,找到Android平台的源码进行下载,这里需要注意使用VPN或者联系客服 ## 项目开始 1、创建一个新的项目,勾选包含C++  2、勾选C++11和C++的依赖库  3、找到下载好的fmod目录下,在api/lowlevel/lib中,将所有文件拷贝到你的项目的libs目录下  4、让项目添加对fmod.jar包的支持,fmod.jar右键Add As Libs  5、找到下载好的fmod目录下,在api/lowlevel/inc中,将所有文件拷贝到你的项目的cpp(jni folder)目录下  拷贝好后如下图  6、准备好一个音频文件放到assets文件夹中  7、配置app的gradle文件中的cmake和ndk ``` android { compileSdkVersion 25 buildToolsVersion "25.0.3" defaultConfig { applicationId "com.handsome.ndkvoice" minSdkVersion 16 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags "-std=c++11 -frtti -fexceptions" abiFilters "armeabi","arm64-v8a","armeabi-v7a","x86" } } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets.main { jniLibs.srcDirs = ['libs'] jni.srcDirs = [] } externalNativeBuild { cmake { path "CMakeLists.txt" } } } ``` ## 代码编写 1、我们创建一个Utils类,编写我们的fmod变声处理 ``` public class Utils { //音效类型 public static final int MODE_NORMAL = 0; public static final int MODE_LUOLI = 1; public static final int MODE_DASHU = 2; public static final int MODE_JINGSONG = 3; public static final int MODE_GAOGUAI = 4; public static final int MODE_KONGLING = 5; /** * 音效处理传2个值 * * @param path 音频文件路径 * @param type 音频文件类型 */ public native static void fix(String path, int type); static { System.loadLibrary("fmodL"); System.loadLibrary("fmod"); System.loadLibrary("sound"); } } ``` 2、通过终端,javah我们的文件  3、将创建好的.h文件放进我们的cpp目录下,并创建sound.cpp  4、编写sound.cpp代码 ``` #include "inc/fmod.hpp" #include <stdlib.h> #include <unistd.h> #include "com_handsome_ndkvoice_Utils.h" #include <jni.h> #include <android/log.h> #define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"zph",FORMAT,##__VA_ARGS__); #define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"zph",FORMAT,##__VA_ARGS__); #define MODE_NORMAL 0 #define MODE_LUOLI 1 #define MODE_DASHU 2 #define MODE_JINGSONG 3 #define MODE_GAOGUAI 4 #define MODE_KONGLING 5 using namespace FMOD; JNIEXPORT void JNICALL Java_com_handsome_ndkvoice_Utils_fix(JNIEnv *env, jclass jcls, jstring path_jstr, jint type) { //声音引擎 System *system; //声音 Sound *sound; //数字处理(音效) DSP *dsp; //正在播放 bool playing = true; //音乐轨道 Channel *channel; //播放速度 float frequency = 0; //音频地址 const char* path_cstr = env->GetStringUTFChars(path_jstr, NULL); System_Create(&system); system->init(32, FMOD_INIT_NORMAL, NULL); try { //创建声音 system->createSound(path_cstr, FMOD_DEFAULT, NULL, &sound); switch (type) { case MODE_NORMAL: //原生播放 system->playSound(sound, 0, false, &channel); break; case MODE_LUOLI: //提升或者降低音调的一种音效 system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp); //设置音调的参数 dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 1.8); //添加进到channel,添加进轨道 system->playSound(sound, 0, false, &channel); channel->addDSP(0, dsp); break; case MODE_DASHU: system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp); dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.8); system->playSound(sound, 0, false, &channel); channel->addDSP(0, dsp); break; case MODE_JINGSONG: system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp); dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.8); system->playSound(sound, 0, false, &channel); channel->addDSP(0, dsp); break; case MODE_GAOGUAI: //提高说话的速度 system->playSound(sound, 0, false, &channel); channel->getFrequency(&frequency); frequency = frequency * 2; channel->setFrequency(frequency); break; case MODE_KONGLING: system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp); dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 300); dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 20); system->playSound(sound, 0, false, &channel); channel->addDSP(0, dsp); break; } } catch (...) { LOGE("%s", "发生异常"); goto end; } system->update(); //单位是微妙 //每秒钟判断下是否是播放 while (playing) { channel->isPlaying(&playing); usleep(1000); } goto end; //释放资源 end: env->ReleaseStringUTFChars(path_jstr, path_cstr); sound->release(); system->close(); system->release(); } ``` 5、配置cmake文件 ``` cmake_minimum_required(VERSION 3.4.1) find_library( # Sets the name of the path variable. log-lib log ) set(distribution_DIR ${CMAKE_SOURCE_DIR}/libs) add_library( fmod SHARED IMPORTED ) set_target_properties( fmod PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/${ANDROID_ABI}/libfmod.so ) add_library( fmodL SHARED IMPORTED ) set_target_properties( fmodL PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/${ANDROID_ABI}/libfmodL.so ) add_library( sound SHARED src/main/cpp/sound.cpp ) include_directories(src/main/cpp/inc) target_link_libraries( sound fmod fmodL ${log-lib} ) ``` 6、编写我们的Activity,对每个类型处理点击事件并调用本地方法 ``` public class MainActivity extends AppCompatActivity implements View.OnClickListener { private ExecutorService fixedThreadPool; private PlayerThread playerThread; private String path = "file:///android_asset/hensen.mp3"; private int type; private LinearLayout normal, luoli, dashu, jingsong, gaoguai, kongling; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); normal = (LinearLayout) findViewById(R.id.normal); luoli = (LinearLayout) findViewById(R.id.luoli); dashu = (LinearLayout) findViewById(R.id.dashu); jingsong = (LinearLayout) findViewById(R.id.jingsong); gaoguai = (LinearLayout) findViewById(R.id.gaoguai); kongling = (LinearLayout) findViewById(R.id.kongling); normal.setOnClickListener(this); luoli.setOnClickListener(this); dashu.setOnClickListener(this); jingsong.setOnClickListener(this); gaoguai.setOnClickListener(this); kongling.setOnClickListener(this); fixedThreadPool = Executors.newFixedThreadPool(1); FMOD.init(this); } class PlayerThread implements Runnable { @Override public void run() { Utils.fix(path, type); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.normal: type = Utils.MODE_NORMAL; break; case R.id.luoli: type = Utils.MODE_LUOLI; break; case R.id.dashu: type = Utils.MODE_DASHU; break; case R.id.jingsong: type = Utils.MODE_JINGSONG; break; case R.id.gaoguai: type = Utils.MODE_GAOGUAI; break; case R.id.kongling: type = Utils.MODE_KONGLING; break; } playerThread = new PlayerThread(); fixedThreadPool.execute(playerThread); } @Override protected void onDestroy() { super.onDestroy(); FMOD.close(); } } ``` ## 过程分析 * cmake文件的分析 * 变声类型的分析 * 实现变声代码过程的分析 ### cmake文件分析 1、声明cmake版本 ``` cmake_minimum_required(VERSION 3.4.1) ``` 2、设置一个路径变量,指向我们的libs目录,也就是fmod.jar和so库的目录 ``` set(distribution_DIR ${CMAKE_SOURCE_DIR}/libs) ``` 3、添加我们需要的fmod、fmodL、sound的库 ``` add_library( fmod SHARED IMPORTED ) set_target_properties( fmod PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/${ANDROID_ABI}/libfmod.so ) add_library( fmodL SHARED IMPORTED ) set_target_properties( fmodL PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/${ANDROID_ABI}/libfmodL.so ) add_library( sound SHARED src/main/cpp/sound.cpp ) ``` 这里是通过我们刚才设置的libs目录下,和对应的Gradle设置的架构进行匹配,找到libfmod.so文件 ``` ${distribution_DIR}/${ANDROID_ABI}/libfmod.so ``` Gradle设置的架构在这个地方  ### 变声类型的分析 * 原声:直接播放音频文件 * 萝莉:对音频提高八度 * 大叔:对音频减低八度 * 惊悚:增加音频的颤音 * 搞笑:增加音频的播放速度 * 空灵:增加音频的回音 ### 实现变声代码过程的分析 这里的实现主要是阅读fmod下载的例子,播放声音的代码和增加音效的代码来编写的  大概的流程 1. 创建fmod的系统:System_Create(&system); 2. 系统进行初始化:system->init(32, FMOD_INIT_NORMAL, NULL); 3. 创建音频:system->createSound(path_cstr, FMOD_DEFAULT, NULL, &sound); 4. 创建不同类型的音效:system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp); 5. 播放声音:system->playSound(sound, 0, false, &channel); 6. 将音效加入声音中:channel->addDSP(0, dsp); 7. 关闭资源:end部分