介绍
fmod是一款非常优秀的c++开源框架,这次就通过这个框架来实现仿QQ的变声效果,变声效果有6种,正常,萝莉,大叔,惊悚,搞怪,空灵。关于更多的效果自己感兴趣再去探索,套路大致相同。
项目效果图及其原理
项目采用Fmod开源库,一个非常简单通用的音频引擎,对原始声音进行音效的处理即可做出变声的效果,下面是变声音频的处理
- 原声:直接播放音频文件
- 萝莉:对音频提高八度
- 大叔:对音频减低八度
- 惊悚:增加音频的颤音
- 搞笑:增加音频的播放速度
- 空灵:增加音频的回音
运行
如果能将上次的fmod的示例程序在Android studio中跑起来了,这次运行也没有多大的问题。
本次使用的工具是 android studio 2.3.3,
步骤
1.下载fmod
到fmod的官网注册下载相应的fmod的Android版本。解压。得到如下
这次要用到的是api/lowlevel包下的inc下的文件和lib下的库
2.新建Android项目
通过as新建Android项目,比如这次我的项目名是QQVoice_change
然后将api/lowlevel下包的lib包下的 armeabi,x86文件及其文件下的.so库,fmod.jar 拷贝到项目的libs目录下。
将api/lowlevel包下的inc文件及其文件拷贝到项目的cpp目录下拷贝完成后如图所示
不用忘了拷过去之后要将fmod.jar编译到项目中。
3.修改build.gradle和CMakeLists.txt
很多人在android studio编译c/c++文件动态库,都死在了这一步,这一步需要有gradle和Cmake编程的基础才能真正的搞明白。这一步如果弄错会发现一编译会发生很多错误。
修改Builde.gradle
1、假如build.gradle
中没有配置ndk{ }
。那么当编译器在编译的时候将会编译所有平台的so库。而这里只导入了armeabi
和x86
的so文件,那么在编译其他的平台的so时,将找不到其他平台so文件而报错。因此需要在build.gradle
中配置ndk{ }
。
如果不在build.gradle
中配置ndk{ }
,那么就需要导入所有平台的so库。
在这个例子中只导入了armeabi
和x86
的so文件,如果直接编译将会报错。所以要在build.gradle
添加如下代码:
ndk {
abiFilters "armeabi","x86"
}
2.这里将so文件配置在了libs文件夹下,因此要在build.gradle
中配置:
sourceSets.main {
jniLibs.srcDirs = ['libs']
jni.srcDirs = []
}
修改后的build.gradle内容如下
android {
compileSdkVersion 26
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "com.gxl.change"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
ndk {
abiFilters "armeabi","x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets.main {
jniLibs.srcDirs = ['libs']
jni.srcDirs = []
}
}
修改CMakeLists.txt
由于这里编译需要fmod.so和fmodL.so,我们实现变声的cpp代码就放在native-lib.cpp中,生成的变声.so名称为changeVoice,所以CMakeLists.txt内容如下
# 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)
# 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.
#-----------------------------------------
find_library( log-lib
log )
set(my_lib_path ${CMAKE_SOURCE_DIR}/libs)
# 添加三方的so库
add_library(libfmod
SHARED
IMPORTED )
# 指名第三方库的绝对路径
set_target_properties( libfmod
PROPERTIES IMPORTED_LOCATION
${my_lib_path}/${ANDROID_ABI}/libfmod.so )
add_library(libfmodL
SHARED
IMPORTED )
set_target_properties( libfmodL
PROPERTIES IMPORTED_LOCATION
${my_lib_path}/${ANDROID_ABI}/libfmodL.so )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
#--------------------------------
add_library( # Sets the name of the library.
changeVoice
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-l