android fmod,Android利用Fmod仿QQ变声音效
看到QQ一些变声音效,这些声音效果可以采用SoundTouch,Fmod去处理。这篇文章我们用Fmod去实现变声音效的处理。fmod官网https://www.fmod.com/,fmod Ex 声音系统是为游戏提供音频引擎。多路输出,多路输入,支持类型广。
在使用之前了解一些关于声音的概念,一般声音的采样率是44.1khz,就是每秒钟采集44100个sample,一个sample(采样解析度)有8-bit ,16-bit(声音品质好)。声道分为单声道和立体声(多声道),硬件的扬声器只能播放PCM数据,通过对音频的解码(解压缩过程)获取到音频解码数据输送到扬声器播放。
下面我们就来看看Fmod的使用。下载Fmod https://www.fmod.com/download选择Android,解压出来的文件夹如下
fmod_dir.png我们要用到core下的东西,将core文件下的inc与lib文件拷贝到项目中。
fmod_引入.png
CMakeLists.txt的配置
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp)
add_library(libfmod
SHARED
IMPORTED)
set_target_properties(libfmod
PROPERTIES
IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libfmod.so)
find_library( # Sets the name of the path variable.
log-lib
log)
target_link_libraries( # Specifies the target library.
native-lib libfmod
${log-lib})
build.gradle配置
android {
..........
defaultConfig {
..........
externalNativeBuild {
cmake {
cppFlags "-fexceptions"
abiFilters "armeabi","x86","x86_64"
}
}
}
..........
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}
dependencies {
..........
implementation files('libs/fmod.jar')
}
fmod使用前调用 org.fmod.FMOD.init(this);进行FMOD的初始化
/**
* 播放声音
*/
extern "C"
JNIEXPORT void JNICALL
Java_com_youyangbo_fmod_FmodUtils_play(JNIEnv *env, jclass type, jstring path_) {
const char *path = env->GetStringUTFChars(path_, 0);
//创建对象
System *system;
System_Create(&system);
//初始化
void *extradriverdata;
system->init(32, FMOD_INIT_NORMAL, extradriverdata);
//創建一個聲音
Sound *sound;
system->createSound(path, FMOD_DEFAULT, 0, &sound);
//播放声音
Channel *channel = 0;
system->playSound(sound, 0, false, &channel);
system->update();
//是否播放
bool isplaying = true;
//阻塞线程
while (isplaying) {
channel->isPlaying(&isplaying);
usleep(1000*1000);
}
//释放资源
sound->release();
system->close();
system->release();
env->ReleaseStringUTFChars(path_, path);
}
}
到这里我们就可以简单的播放一个声音啦。system->playSound(sound, 0, false, &channel);可以看到我们在播放声音时传了一个Channel这里并没有进行赋值, 在playSound()函数里面会给选择一个闲置的Channel用来播放声音。我们保存Channel就是为了后面对声音的操作。
怎样利用Fmod进行变声,Fmod提供了很多DSP(数字信号处理的一个单元)类型,我们根据不同的类型创建不同的DSP,然后把我们创建好的DSP添加到Channel(音轨)中达到对声音的改变。
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
static {
try {
System.loadLibrary("fmodD");
} catch (UnsatisfiedLinkError e) {
}
try {
System.loadLibrary("fmod");
} catch (UnsatisfiedLinkError e) {
}
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.tv_original).setOnClickListener(this);
findViewById(R.id.tv_lolita).setOnClickListener(this);
findViewById(R.id.tv_dashu).setOnClickListener(this);
findViewById(R.id.tv_thriller).setOnClickListener(this);
findViewById(R.id.tv_gaoguai).setOnClickListener(this);
findViewById(R.id.tv_kong_ling).setOnClickListener(this);
findViewById(R.id.tv_mantuntun).setOnClickListener(this);
org.fmod.FMOD.init(this);
}
public static final String path = "file:///android_asset/el.mp3";
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_original:
FmodUtils.play(path);
break;
case R.id.tv_lolita:
FmodUtils.changeOfVoice(path, FmodUtils.ChangeOfVoice.valueOf("LOLITA").getType());
break;
case R.id.tv_dashu:
FmodUtils.changeOfVoice(path, FmodUtils.ChangeOfVoice.valueOf("DASHU").getType());
break;
case R.id.tv_thriller:
FmodUtils.changeOfVoice(path, FmodUtils.ChangeOfVoice.valueOf("THRILLER").getType());
break;
case R.id.tv_gaoguai:
FmodUtils.changeOfVoice(path, FmodUtils.ChangeOfVoice.valueOf("GAOGUAI").getType());
break;
case R.id.tv_kong_ling:
FmodUtils.changeOfVoice(path, FmodUtils.ChangeOfVoice.valueOf("KONG_LING").getType());
break;
case R.id.tv_mantuntun:
FmodUtils.changeOfVoice(path, FmodUtils.ChangeOfVoice.valueOf("MANTUNTUN").getType());
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//同步FMOD的生命周期
org.fmod.FMOD.close();
}
}
FmodUtils.java
public class FmodUtils {
enum ChangeOfVoice
{
ORIGINAL(0), //原声
LOLITA(1), //萝莉
DASHU(2), //大叔
THRILLER(3), //惊悚
GAOGUAI(4), //搞怪
KONG_LING(5), //空灵
MANTUNTUN(6); //满吞吞
int type;
ChangeOfVoice(int i) {
type = i;
}
public int getType() {
return type;
}
}
public static native void play(String path);
public static native void changeOfVoice(String path, int original);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_youyangbo_fmod_FmodUtils_changeOfVoice(JNIEnv *env, jclass type, jstring path_,
jint effect_type) {
const char *path = env->GetStringUTFChars(path_, 0);
//创建对象
System *system;
System_Create(&system);
//初始化
void *extradriverdata;
system->init(32, FMOD_INIT_NORMAL, extradriverdata);
//創建一個聲音
Sound *sound;
system->createSound(path, FMOD_DEFAULT, 0, &sound);
// FMOD_RESULT F_API createDSPByType (FMOD_DSP_TYPE type, DSP **dsp);
DSP *dsp;
//播放声音
Channel *channel = 0;
system->playSound(sound, 0, false, &channel);
switch (effect_type) {
case ORIGINAL:
break;
case LOLITA:
// FMOD_DSP_TYPE_PITCHSHIFT 对音频提高八度 达到萝莉效果
system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 2.0);
channel->addDSP(0, dsp);
break;
case DASHU:
//降低八度
system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.5);
channel->addDSP(0, dsp);
break;
case THRILLER:
//声音抖动
system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp);
dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.5);
channel->addDSP(0, dsp);
break;
case GAOGUAI:
//加快声音的播放速度
float frequency;
channel->getFrequency(&frequency);
channel->setFrequency(frequency*1.5);
break;
case KONG_LING:
//添加回声
system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);
//声音延迟
dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 300);
//回声次数
dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 3);
channel->addDSP(0, dsp);
break;
case MANTUNTUN:
float frequency_m;
channel->getFrequency(&frequency_m);
channel->setFrequency(frequency_m*0.8);
break;
}
system->update();
//是否播放
bool isplaying = true;
//阻塞线程
while (isplaying) {
channel->isPlaying(&isplaying);
usleep(1000*1000);
}
//释放资源
sound->release();
system->close();
system->release();
env->ReleaseStringUTFChars(path_, path);
}
介绍一下关于DSP的类型
typedef enum
{
FMOD_DSP_TYPE_UNKNOWN, // 不知类型
FMOD_DSP_TYPE_MIXER, //不需要任何输入,并将它们混合在一起
FMOD_DSP_TYPE_OSCILLATOR, //振荡器
FMOD_DSP_TYPE_LOWPASS, //低通滤波
FMOD_DSP_TYPE_ITLOWPASS, //特低通滤波
FMOD_DSP_TYPE_HIGHPASS, //高通滤波
FMOD_DSP_TYPE_ECHO, //回声
FMOD_DSP_TYPE_FADER, //衰减器
FMOD_DSP_TYPE_FLANGE, //轮缘 对声音产生法兰效应
FMOD_DSP_TYPE_DISTORTION, //扭曲
FMOD_DSP_TYPE_NORMALIZE, //归一化
FMOD_DSP_TYPE_LIMITER, //限幅器
FMOD_DSP_TYPE_PARAMEQ, //参数化
FMOD_DSP_TYPE_PITCHSHIFT, //频移
FMOD_DSP_TYPE_CHORUS, //合唱
FMOD_DSP_TYPE_VSTPLUGIN,
FMOD_DSP_TYPE_WINAMPPLUGIN, //温普拉普林
FMOD_DSP_TYPE_ITECHO, //特回声
FMOD_DSP_TYPE_COMPRESSOR, //压缩机
FMOD_DSP_TYPE_SFXREVERB, //SFX混响器
FMOD_DSP_TYPE_LOWPASS_SIMPLE, //低通简单
FMOD_DSP_TYPE_DELAY, //延迟
FMOD_DSP_TYPE_TREMOLO, //颤音
FMOD_DSP_TYPE_LADSPAPLUGIN, //拉斯帕拉金/
FMOD_DSP_TYPE_SEND,
FMOD_DSP_TYPE_RETURN,
FMOD_DSP_TYPE_HIGHPASS_SIMPLE,//高通简单
FMOD_DSP_TYPE_PAN,
FMOD_DSP_TYPE_THREE_EQ, //三重均衡器
FMOD_DSP_TYPE_FFT, //快速傅立叶变换
FMOD_DSP_TYPE_LOUDNESS_METER, //劳氏流量计
FMOD_DSP_TYPE_ENVELOPEFOLLOWER,
FMOD_DSP_TYPE_CONVOLUTIONREVERB, //卷积混响
FMOD_DSP_TYPE_CHANNELMIX, //通道混合
FMOD_DSP_TYPE_TRANSCEIVER,
FMOD_DSP_TYPE_OBJECTPAN,
FMOD_DSP_TYPE_MULTIBAND_EQ, //多频带EQ
FMOD_DSP_TYPE_MAX,
FMOD_DSP_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */
} FMOD_DSP_TYPE;
关于对音频音效的处理上面已经实现QQ变音效果。音频这块的东西后面会在音视频文中具体涉及到,包括音频的编解码,OpenSL ES 音频播放。
android fmod,Android利用Fmod仿QQ变声音效相关推荐
- 自学体验使用fmod 以及 仿QQ变声 fmod
模块一 体验使用fmod 到 https://www.fmod.com/download 上下载fmod android版本的 这里我们用的是别人生成的so库 libfmod.so库 libfmodL ...
- 仿QQ变声功能的实现
Android ndk开发之QQ变声 要做出QQ变声的效果,用Android系统自带的MediaPlayer是无法实现的,只能另想他法了.听说汤姆猫是用SoundTouch实现的,而QQ是用FMOD实 ...
- NDK开发(四):仿QQ变声
效果 相关资料:fmod官网https://www.fmod.com/download下载需要的资源库 构建项目 首先构建支持C++的android工程,将需要的c库考入工程 这里只需要inc文件下的 ...
- NDK开发—仿QQ变声器
1.实现功能前的准备 这是我学习NDK的一个练手项目.虽然最后实现的结果并不是非常专业,但是确实能改变声音的音色,这是非常适合NDK新手的项目. 1.1.主要原理 通过修改声音的属性来实现声音音色的变 ...
- Android插件化的思考——仿QQ一键换肤,思考比实现更重要!
Android插件化的思考--仿QQ一键换肤,思考比实现更重要! 今天群友希望写一个关于插件的Blog,思来想去,插件也不是很懂,只是用大致的思路看看能不能模拟一个,思路还是比较重要的,如果你有兴趣的 ...
- android 仿qq换肤功能,Android插件化的思考——仿QQ一键换肤,思考比实现更重要!.doc...
Android插件化的思考--仿QQ一键换肤,思考比实现更重要! 关于QQ的换肤,他们的实现思路我不是很清楚,但是你可以看一下这张换肤的截图 我们想使用哪个主题就直接下载就好了,这一实现的过程我们大致 ...
- Android 开发之 QQ变声功能实现
1.简介 在QQ中我们使用到的一个功能就是变声,QQ是使用FMOD实现的,那么同样的我们也使用FMOD让自己的应用可以变音 2.FMOD简介 fmod Ex 声音系统是为游戏开发者准备的革命性音频引擎 ...
- Android NDK开发之旅25 NDK 模仿QQ变声特效
###前言 我们这次用到的是fmod这个库,fmod是音效引擎游戏开发革命引擎,著名的游戏开发引擎CosCos2D.U3D都封装了这个库. 学习NDK的目的就是为了让我们的APP能够使用C/C++开源 ...
- NDK开发——Android Studio+CMake实现QQ变声效果
项目演示 Github:https://github.com/AndroidHensen/NDKVoice 项目分析 项目采用Fmod开源库,一个非常简单通用的音频引擎,对原始声音进行音效的处理即可做 ...
最新文章
- 怎样将包含元组的列表转换为字典?
- 控件授权:知道Infragitics是怎么限制别人使用它的控件了。
- 左手技术右手商业 网易智企全新业务版图亮相
- windows文件保护_文件通通用它加密,安全等级提高一个档次
- .NET Core整合log4net以及全局异常捕获实现2
- magento 插件
- 动与静--软件的雕塑艺术
- django render_(django/flask/bottle)多框架python-restful接口包api-shop
- 如何在Ubuntu中重置MySQL Root密码
- html同时用多个css,多类选择器的运用_html/css_WEB-ITnose
- waitpid使用实例
- WinRAR_5.40 绿色!!!无广告
- 物联网终端安全系列(之三) -- 物联网终端安全解决方案概述
- 在Power BI中如何计算同比增长?
- Linux系统中文件颜色分别代表什么?
- 荣耀XIO升级鸿蒙,距断供不到10天 华为大招来了:不止鸿蒙
- php http请求 返回数据包太大 499,http错误码原理及复现 - 499,500,502,504
- Python爬虫实战之五:requests-re多页爬取链家成都地区租房市场信息
- 交换机上的指示灯狂闪
- 苹果屏幕旋转怎么设置_笔记本电脑维修|笔记本电脑屏幕旋转90度怎么复原
热门文章
- 计算机组成原理中的非门表示,计算机组成原理4-数字逻辑2.ppt
- 【NKOJ-1096】母牛回家
- 点积(点乘、数量积、内积)和叉积(叉乘、向量积、外积)
- 计算机组成原理之CPU的功能和组成
- centos6.4拷贝两光盘内容到硬盘并配置本地 yum源
- C++ STL之 queue和deque用法详解
- FLV科普8 FLV音频头信息
- 从李开复换门庭开启的缝隙中窥视——试探Google的几招成功“秘诀”
- c语言 飞机,C语言写的飞机源码
- android cordova,android项目使用cordova