1.简介

在QQ中我们使用到的一个功能就是变声,QQ是使用FMOD实现的,那么同样的我们也使用FMOD让自己的应用可以变音

2.FMOD简介

fmod Ex 声音系统是为游戏开发者准备的革命性音频引擎,有时候我们下载FMOD可能不是太方便下载,我已将他下载好了放在百度云盘中:

链接:https://pan.baidu.com/s/1TW3ctQd0o5bOVCx5gKL0hA 密码:x2o4

下载下来后解压我们看到解压目录如下:

3.搭建项目

在开始之前,最好已经了解了NDK开发的基本知识,需要下载好ndk并配置好,我用的Android studio版本是2.3.2,所以安装了cmake。

新建项目,输入项目名称,勾选包含支持c++

一直next最后一步勾选c++支持如下:

点击finish项目就创建完成了。

4.项目配置

4.1 将api\lowlevel\lib的文件复制到项目lib文件夹下

并且将fmod.jar引入进入,项目中如下图所示:

4.2将api/lowlevl/inc目录下的文件复制到你项目中的cpp目录下

复制后如下图:

4.3 准备好将要变声的mp3文件,放到assets目录下,如果没有就新建一个,在这里我下载的mp3文件是大家耳熟能详的敢问路在何方,这样听起来效果更加明显。

4.4 在app下的build.gradle下,添加jnilib指向的文件夹

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

5.代码编写

配置好后,就可以编写代码了,(这里Android版本不同或者其他按照第四部可能会出现其他的各种问题,大家可以可以和我一起交流,至于2.3之前的版本ndk对应的是.mk文件并不是cmake)

5.1新建一个工具类ChangeUtils,声明声音对应的类型,以QQ为例分为正常、大叔、萝莉等6中音效,定义改变声音的方法,传入声音路径和声音类型,代码如下:

public class ChangeUtils {//定义音效类型常量public static final  int zhengchang = 0;//正常public static final int luoli = 1;//萝莉public static final int dashu = 2;//大叔public static final int jingsong = 3;//惊悚public static final int gaoguai = 4;//搞怪public static final int kongling = 5;//空灵/**** @param path* @param type*/public native static void change(String path, int type);static {System.loadLibrary("fmodL");System.loadLibrary("fmod");System.loadLibrary("sound");}
}

5.2生成对应的头文件

我们使用javah命令生成工具类对应的头文件

上面报错是因为在代码注释中有中文,所以我们可以给javah添加utf8,就不报错误了,命令如下:

执行成功后就生成了对应的头文件:

5.3将生成的头文件复制到cpp目录下,并在cpp目录下新建voice.cpp文件

我们可以根据下载实例中的下述文件编写voice的代码(个人能力有限,不造轮子)

voice.cpp的代码如下:

#include "inc/fmod.hpp"
#include <stdlib.h>
#include <unistd.h>
#include  "hlq_utils_ChangeUtils.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_hlq_utils_ChangeUtils_change(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.4配置cmake文件,声明cmake版本,设置一个路径变量,指向我们的libs目录,也就是fmod.jar和so库的目录

添加我们需要的fmod、fmodL、sound的库

我的cmake文件如下:

cmake_minimum_required(VERSION 3.4.1)find_library( # Sets the name of the path variable.log-liblog )set(distribution_DIR ${CMAKE_SOURCE_DIR}/libs)add_library( fmodSHAREDIMPORTED )
set_target_properties( fmodPROPERTIES IMPORTED_LOCATION${distribution_DIR}/${ANDROID_ABI}/libfmod.so )
add_library( fmodLSHAREDIMPORTED )
set_target_properties( fmodLPROPERTIES IMPORTED_LOCATION${distribution_DIR}/${ANDROID_ABI}/libfmodL.so )
add_library( soundSHAREDsrc/main/cpp/voice.cpp )include_directories(src/main/cpp/inc)target_link_libraries( sound fmod fmodL${log-lib} )

5.5 最后一步

终于到了最后一步,那就是在页面放上几个按钮,给按钮添加监听事件,不同监听事件对应音效不同

在Activity中初始化FMOD

FMOD.init(this);

结合工具类设置工具类型

class PlayerThread implements Runnable {@Overridepublic void run() {ChangeUtils.change(path, type);}
}
playerThread = new PlayerThread();
fixedThreadPool.execute(playerThread);

这样就完成了变声效果,需要注意的事,点击播放后,需要重新退出才可以切换声音效果,感兴趣的可以自行扩展成语音对讲那种。

6.总结

  • 原声:直接播放音频文件
  • 萝莉:对音频提高八度
  • 大叔:对音频减低八度
  • 惊悚:增加音频的颤音
  • 搞笑:增加音频的播放速度
  • 空灵:增加音频的回音

源码地址:https://github.com/huanglinqing123/ChangeVoice/tree/master

欢迎start和issue

欢迎关注技术公众号,微信号搜索ColorfulCode 代码男人

分享技术文章,投稿分享,不限技术种类,不限技术深度,让更多人因为分享而受益。

Android 开发之 QQ变声功能实现相关推荐

  1. 仿QQ变声功能的实现

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

  2. Android开发之QQ空间效果(QQ空间下拉图片放大,松手后回弹)

    Android开发之QQ空间效果(QQ空间下拉图片放大,松手后回弹) 腾讯QQ空间的下拉图片放大,松手后回弹的效果带来的视觉差异效果让许多移动开发者心动不已,经本人一段时间的研究,终于实现了该视差效果 ...

  3. Android开发之Navigationdrawer导航抽屉功能的实现(源代码分享)

    导航抽屉(navigationdrawer)是一个从屏幕左边滑入的面板,用于显示应用的主要导航项目.用户可以通过在屏幕左边缘滑入或者触摸操作栏的应用图标打开导航抽屉.导航抽屉覆盖在内容之上,但不覆盖操 ...

  4. 08.Eclipse下Ndk开发(使用fmod实现QQ变声功能)

    (创建于2017/12/30) 1.编写native package org.fmod.example;public class EffectUtils {//音效的类型public static f ...

  5. 仿QQ语音变声功能实现

    版权声明:转载必须注明本文转自张鹏辉的博客: http://blog.csdn.net/qingtiangg 大家好,这是我从业以来第一篇博客,给大家拜个晚年,祝大家鸡年大吉,幸福美满.事业有成.好了 ...

  6. Android监听作用,Android开发之CheckBox的简单使用与监听功能示例

    本文实例讲述了Android开发之CheckBox的简单使用与监听功能.分享给大家供大家参考,具体如下: activity_main.xml android:layout_width="ma ...

  7. android 图库分析,Android开发之ImageSwitcher相册功能实例分析

    本文实例讲述了Android开发之ImageSwitcher相册功能.分享给大家供大家参考,具体如下: 简介: 1.ImageSwitcher是viewSwitcher的子类,所以ImageSwitc ...

  8. Android开发之仿QQ表情实现(上)

    大家晚上好,,小鹿又来了..最近小鹿特别忙,忙到没时间发表博客了(注:以下内容过于简单请大家不要喷,仅提供初学者学习) 今天发表两篇文章,分别是讲解模拟QQ表情的实现,先给大家看效果图,,,, 开始了 ...

  9. Android开发之TextView高级应用

    Android开发之TextView高级应用 我们平时使用TextView往往让它作为一个显示文字的容器,但TextView的功能并不局限于此.以下就和大家分享一下TextView的一些使用技巧. A ...

最新文章

  1. pushpop指令的操作数必须是字操作数_指令格式
  2. 360浏览器卸载_有恃无恐“弹弹弹”,安全卫士360自己就是最大的流氓“弹窗王”!...
  3. 严选前端全栈工程师学习笔记
  4. Linux是不是共享软件,linux – 是否有可能在应用程序之间共享Cuda上下文?
  5. linux更改python版本链接
  6. 每周一荐:foobar2000, 奇幻人生, 一个Flash小游戏
  7. How to resolve empty table CRMATAB issue in ERP gt_crmtab[]
  8. linux之找出两个文件里面相同的数据
  9. HDU - 2204 Eddy‘s爱好(尚未完全解决)
  10. Ubuntu网络连接未托管的解决办法
  11. 【英语学习】【WOTD】disavow 释义/词源/示例
  12. Java面试之锁-可重入锁和递归锁
  13. [UE4]响应鼠标点击
  14. svg的transform-matrix详解
  15. 【PHP面向对象(OOP)编程入门教程】20.PHP5接口技术(interface)
  16. 【简易设计模式07】适配器模式
  17. 使用Canvas合成多张图片和文字为一张图片
  18. 微信支付宝免签约支付方案
  19. docker部署finebi 帆软
  20. 输入法半角和全角的快捷转换_搜狗输入法经常用到的冷门小技巧,复制文章空白行取消方法...

热门文章

  1. 用python实现将pdf转化为有声读物
  2. HFSS学习笔记(一)基础篇 操作界面简介和使用前的准备工作
  3. .Net Core中使用NEST简单操作Elasticsearch
  4. 计算机的二进制的位数为8位,16位,32位,64位
  5. linux下的命令行词典
  6. 码农买房 - 卖出房子的流程记录
  7. 一个陌生女人的来信——茨威格
  8. Windows Server 2012 R2 -DNS服务器辅助区域(VMware workstation环境)
  9. iPhone如何添加邮箱
  10. 从 wepy 到 uniapp 变形记