<Excerpt in index | 首页摘要>
利用SoundTouch降低音调 实现变声(变男、变女)
<The rest of contents | 余下全文>
写在前面
soundtouch是一个c library 所以我们需要用到jni
你需要有jni的基础知识
本篇文章只介绍如何编译、使用它
不做它的代码分析
你需要准备好ndk/sdk 并且配置好环境变量
前提
之前有一篇文章介绍如何模仿qq魔声
fmod 功能更为强大,但是同样的有些方面缺陷也很大。
fmod是一个音频播放处理框架
从名字上就应该能知道它是在播放的时候处理对音频做手脚。
其实如果变声只是在app内部流通 可以采用多端传递音频原生文件+变声参数
各端播放的时候做处理即可。
我们这边希望能够做到音频分享到微信直接播放,必须将音频文件传递给微信,而且微信播放音频的过程我们无法干预 所以fmod是不适于这个场景的。
soundtouch应势而出
soundtouch是一个音频处理库
soundtouch 的功能不是很强大 主要可以调整的参数只有2个:音速、音调
对我们来说实现上是足够了,因为声音变男、变女只需要做变男(降低音调) 变女(提高音调)就可以实现。
下载、编译 源码
写这篇文章的时候,soundtouch的最新版本是2.0
下载下来它 并解压
源码需要修改2个地方才能保证编译通过
1:soundtouch根目录/source/Android-lib/jni/Application.mk
在里面加入这句话
1 | APP_ALLOW_MISSING_DEPS := true |
2:soundtouch根目录/source/SoundTouch/BPMDetect.cpp
打开搜索fabs (238行)
修改为abs
进入 soundtouch根目录/source/Android-lib/jni 目录
打开终端(windows在当前目录打开命令行)
输入ndk-build (需要下载并且配置ndk环境变量)
然后就成功的生成了我们需要的so文件 (在soundtouch根目录/source/Android-lib/libs 目录下)
打开我们的项目
将所有的so copy至我们的项目的jniLibs目录下(如果是配置so的导入路径 你配置的哪里粘贴到哪里去)
然后copy soundtouch根目录/source/Android-lib/src/net/surina/soundtouch/SoundTouch.java 到你的项目里面 注意 这个文件的包名不能变
如果需要该这个 那你还需要去修改jni里面的soundtouch-jni.cpp 然后重新buildso
使用
变声,注意需要运行在子线程中,因为是耗时操作
1 | SoundTouch st = new SoundTouch(); |
解释一下
tempo是音速,取值0.01 - 1 这个我们不用管1.0f即可
pitch 是音调 这个就是我们的重点了, 大于0 是变女生,小于0是变男声
具体的效果需要和产品去调整
我们调整出来的是比较合适的值是
男声:-10
女声:+10
inFileName : 要转换的文件全路径 必须为wav格式
outFileName:转换之后保存的文件全路径 必须为wav格式
因为soundtouch只支持wav的处理
我们多端传输使用的是aac,所以需要转换格式,这里推荐一个转换格式的库:
非常强大的一个工具库 支持的格式有
1 | AAC |
转换使用也非常的方便 傻瓜化的那种 这里就不介绍了