android fmod,Android利用Fmod仿QQ变声音效
发布日期:2021-06-24 15:58:25 浏览次数:2 分类:技术文章

本文共 7732 字,大约阅读时间需要 25 分钟。

看到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,解压出来的文件夹如下

ce042be6fa57

fmod_dir.png我们要用到core下的东西,将core文件下的inc与lib文件拷贝到项目中。

ce042be6fa57

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 音频播放。

转载地址:https://blog.csdn.net/weixin_33682804/article/details/117604465 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:signature=29c90d1a8d382ff261d00a931708390a,发烧音响功放(顶级Hi-End音响发烧器材介绍)...
下一篇:lifull home android,‎App Store 上的“LIFULL HOME'S”

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月19日 17时41分29秒