1、实现功能前的准备

这是我学习NDK的一个练手项目。虽然最后实现的结果并不是非常专业,但是确实能改变声音的音色,这是非常适合NDK新手的项目。

1.1、主要原理

通过修改声音的属性来实现声音音色的变化。

1.2、依赖的三方库

fmod,专业的音频工具。
下载地址:https://www.fmod.com/download

不过需要登陆之后才能下载而且下载速度可能会有点慢。这里准备了一份百度云的地址:
https://pan.baidu.com/s/1eTJuWUm

2、实现功能

如果需要实现这个功能,需要掌握NDK的基本知识,比如CMakeLists的配置、native方法的实现、以及C语言的基础。

2.1、导入三方的工具

解压下载的压缩包。然后找到如下路径:api/lowlevel里面有三个文件夹:
* examples:示例代码
* inc:源文件
* lib:打包好的so动态库和jar

用AndroidStudio新建NDK项目之后,将inc和lib导入。

libs中添加so库和jar。

这里涉及到两个容易出现错误的知识点:

1、假如build.gradle中没有配置ndk{ }。那么当编译器在编译的时候将会编译所有平台的so库。而这里只导入了armeabix86的so文件,那么在编译其他的平台的so时,将找不到其他平台so文件而报错。因此需要在build.gradle中配置ndk{ }
如果不在build.gradle中配置ndk{ },那么就需要导入所有平台的so库。

在这个例子中只导入了armeabix86的so文件,如果直接编译将会报错。所以要在build.gradle添加如下代码:

ndk {abiFilters "armeabi","x86"}

2、这里将so文件配置在了libs文件夹下,因此要在build.gradle中配置:

    sourceSets.main {jniLibs.srcDirs = ['libs']jni.srcDirs = []}

CMakeLists.txt的配置
配置CMakeLists的时候要仔细配置,不要将路径写错。

# 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)find_library( log-liblog )set(my_lib_path ${CMAKE_SOURCE_DIR}/libs)# 添加三方的so库
add_library(libfmodSHAREDIMPORTED )
# 指名第三方库的绝对路径
set_target_properties( libfmodPROPERTIES IMPORTED_LOCATION${my_lib_path}/${ANDROID_ABI}/libfmod.so )# 添加三方的so库
add_library(libfmodLSHAREDIMPORTED )# 指名第三方库的绝对路径
set_target_properties( libfmodLPROPERTIES IMPORTED_LOCATION${my_lib_path}/${ANDROID_ABI}/libfmodL.so )set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")# 添加我们需要写代码的路径
add_library(changeVoiceSHAREDsrc/main/cpp/changeVoice.cpp )# 导入路径,为了让编译时能够寻找到这个文件夹
include_directories(src/main/cpp/inc)# 链接好三个路径
target_link_libraries( changeVoicelibfmodlibfmodL${log-lib} )

如果三方库导入完毕,不要先急于写代码,先build看看是否能通过吧。

2.2、编写native方法,实现主要逻辑

编写native方法,加载动态库。这里需要加载在CMakeLists.txt配置的三个动态库:

target_link_libraries( changeVoicelibfmodlibfmodL${log-lib} )
public class VoiceTools {public static native void  changeVoice(String path,int mode);static {System.loadLibrary("changeVoice");System.loadLibrary("fmod");System.loadLibrary("fmodL");}
}

将native方法生成.h文件,includefmod.hpp实现逻辑。
这里会通过改变声音的通道来修改音色:
1、降低音调,实现“大叔”效果;
2、升高音调,实现“萝莉”效果;
3、加快声音的速度,实现“搞怪”效果;
4、设置声音颤抖和降低声音速度,实现“惊悚”的效果;
5、设置声音的重复,实现“空灵”的效果;

JNICALL
JNIEXPORT void JNICALL Java_com_mg_axechen_changevoice_VoiceTools_changeVoice(JNIEnv *jniEnv, jclass jclass, jstring jstring, jint mode) {// 初始化fmodFMOD::System *system;FMOD::System_Create(&system);Sound *sound;// 通道(声音是由多种音效组成)Channel *channel;// 音频DSP *pDSP;// 速度float frequency;system->init(32, FMOD_INIT_NORMAL, NULL);// 将 jstring转为 charconst char *path = jniEnv->GetStringUTFChars(jstring, NULL);system->createSound(path, FMOD_DEFAULT, NULL, &sound);try {switch (mode) {case MODE_NORMAL:LOGI("%s", "正常");system->playSound(sound, NULL, false, &channel);break;case MODE_DASHU:LOGI("%s", "大叔");// 设置音调,调低音调system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &pDSP);pDSP->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.7);system->playSound(sound, NULL, false, &channel);channel->addDSP(0, pDSP);break;case MODE_LUOLI:LOGI("%s", "萝莉");// 设置音调,调高音调system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &pDSP);pDSP->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 3);system->playSound(sound, NULL, false, &channel);channel->addDSP(0, pDSP);break;case MODE_GAOGUAI:LOGI("%s", "搞怪");system->createDSPByType(FMOD_DSP_TYPE_NORMALIZE, &pDSP);system->playSound(sound, NULL, false, &channel);channel->addDSP(0, pDSP);// 获取速度并加速channel->getFrequency(&frequency);frequency = frequency * 1.6;channel->setFrequency(frequency);break;case MODE_JINGSONG:// FMOD_DSP_TYPE_TREMOLO 颤抖LOGI("%s", "惊悚");// 设置颤抖system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &pDSP);// 设置颤抖的频率pDSP->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.8);system->playSound(sound, NULL, false, &channel);channel->addDSP(0, pDSP);channel->getFrequency(&frequency);frequency = frequency * 0.5;channel->setFrequency(frequency);break;case MODE_KONGLING:LOGI("%s", "空灵");// 设置重复system->createDSPByType(FMOD_DSP_TYPE_ECHO, &pDSP);// 设置重复的重复延迟pDSP->setParameterFloat(FMOD_DSP_ECHO_DELAY, 300);pDSP->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 20);system->playSound(sound, NULL, false, &channel);channel->addDSP(0, pDSP);break;}system->update();bool isPlaying = true;// 需要等待,等声音全部播放完成// 检查是否播放完成while (isPlaying) {channel->isPlaying(&isPlaying);usleep(1000);}} catch (...) {LOGE("%s", "error");goto end;}// 回收内存end:system->close();system->release();jniEnv->ReleaseStringUTFChars(jstring, path);
}

以上参考来自:
https://www.jianshu.com/p/9d1a3429badc

最后附上界面和源码:

源码地址:https://github.com/AxeChen/ChangeVoice

原文来自简书:
https://www.jianshu.com/p/dbee203db243
作者:我自己。

NDK开发—仿QQ变声器相关推荐

  1. 仿QQ变声功能的实现

    Android ndk开发之QQ变声 要做出QQ变声的效果,用Android系统自带的MediaPlayer是无法实现的,只能另想他法了.听说汤姆猫是用SoundTouch实现的,而QQ是用FMOD实 ...

  2. 自学体验使用fmod 以及 仿QQ变声 fmod

    模块一 体验使用fmod 到 https://www.fmod.com/download 上下载fmod android版本的 这里我们用的是别人生成的so库 libfmod.so库 libfmodL ...

  3. android fmod,Android利用Fmod仿QQ变声音效

    看到QQ一些变声音效,这些声音效果可以采用SoundTouch,Fmod去处理.这篇文章我们用Fmod去实现变声音效的处理.fmod官网https://www.fmod.com/,fmod Ex 声音 ...

  4. NDK开发(四):仿QQ变声

    效果 相关资料:fmod官网https://www.fmod.com/download下载需要的资源库 构建项目 首先构建支持C++的android工程,将需要的c库考入工程 这里只需要inc文件下的 ...

  5. NDK JNI 变声器实现

    Android NDK 导入 C库的开发流程学习:通过使用fmod的C库,实现变声器功能. 导入库文件 1)复制fmod的C库到cpp目录下 2)复制fmod的so库到jniLibs目录下 3)复制f ...

  6. jQuery仿QQ音乐播放器

    本文通过Html+CSS+jQuery开发仿QQ版的音乐播放器,是前端技术的综合应用,所用素材来源于网络,仅供学习分享使用,如有不足之处,还请指正. 涉及知识点 在本例中用到的知识点如下,按jQuer ...

  7. 【毕业设计/Matlab系列】基于MATLAB语言的实时变声器系统

    Date:2022.5.5 文章目录 前言 1.算法原理 2.实现效果 2.1.男声变女声 2.2.女声变男声 2.3.男声变大叔声 3.部分matlab代码实现 前言 在大学毕业设计中,要求实现一个 ...

  8. 【AI实时变声器,声音甜甜的小姐姐背后竟是抠脚大汉】

    前言 这是一款基于AI算法的实时变声器,如果你不懂AI也没事,直接使用我提供的一键安装包 链接:https://pan.baidu.com/s/1f3X6JdBVOgeTNPf0B3CRKg 提取码: ...

  9. CycleGAN-VC2音色转换,打造属于你自己的变声器

    一.理论部分 1.音色与音调的区别 音调反映了声音大波的频率特征,而大波可以分解为不同频率的小波.不同乐器之间因为小波的叠加方式不同,导致大波的形状也不同,所以即使有相同的音调,他们的音色也不相同. ...

最新文章

  1. linux配置中心自动化,centos下搭建git服务 基于git服务配置自动化部署 遇到的Linux知识补充...
  2. Filter过滤不了Action的问题
  3. Spring @Value批注
  4. nginx php fpm 日志,nginx下php-fpm不记录php报错日志怎么办?
  5. java使用计算器完成加法、减法运算
  6. android js 回调函数,JS回调函数简单易懂的入门实例分析
  7. 互联网赚钱要有自己的核心思想,我为自己的分秒挣赚软件网创事业代言
  8. https://www.cnblogs.com/h2zZhou/p/5440271.html
  9. 苹果id是什么格式的_可以修改微信号了,怎样起一个好看又好记的微信号ID?...
  10. Devops之制品库平台nexus实践
  11. 聚焦场景 共建生态 加速AI落地——2018中国人工智能应用与生态峰会成功举办
  12. 沈阳学计算机Excel,沈阳excel培训点
  13. SMP与AMP体系结构
  14. [附源码]java毕业设计网络身份认证技术及方法
  15. selenium2(webdriver)的“兄弟姐妹”
  16. Android App 设置系统时间,语言和时区、系统重启
  17. 第七章(1.2)图像处理——人脸识别技术发展及实用方案设计
  18. 3.3.3 消费者拉取线程
  19. python原神抽卡模拟
  20. 【王道OJ】每日上传一个王道OJ代码

热门文章

  1. 上海大数据研究中心专委会成立
  2. Normalized Object Coordinate Space for Category-Level 6D Object Pose and Size Estimation学习笔记
  3. Linux 下 Memcached 缓存服务器安装配置
  4. js给二维码加个图片
  5. tried to access field com.mysql.cj.CharsetMapping.COLLATION_INDEX_TO_COLLATION_NAME from class io.de
  6. 零起步学习 电源知识及技术
  7. 第九周 计算存款利息和本息合计
  8. 我的世界linux版账号,我的世界免费正版号
  9. 做一个很难的小程序是怎样的体验(一)
  10. python 爬虫 小电影 不会告诉网址_想看电影不知道看啥,python爬虫告诉你!