要做出QQ变声的效果,用Android系统自带的MediaPlayer是无法实现的,只能另想他法了。听说汤姆猫是用SoundTouch实现的,而QQ是用FMOD实现的,就根据网上的教程,自己捣鼓ndk好几天,终于实现了,但是效果不是很理想。
FMOD是老外为游戏开发者准备的革命性音频引擎,说它支持很多功能,包括音效的处理,声道变化,音调等,,去fmod官网下载,首先得先注册一个账户,国内用户注册不了,需要才能注册,下载后解压,把需要的c文件放到jni目录下如图:配置Android.mk,写个native方法用来播放音频。中间会遇到各种问题,这里就不一一列举了,下面贴出源码。
public class TestNdk {
static {
System.loadLibrary("fmod");
System.loadLibrary("fmodL");
System.loadLibrary("voicer");
}
public static final int MODE_NORMAL = 0;
public static final int MODE_LUOLI = 1;
public static final int MODE_DASHU = 2;
/**
* 音效处理
* @param path sd卡上音频路径
* @param mode 音效模式
*/
public static native void fix(String path, int mode);
}
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := fmod
LOCAL_SRC_FILES := libfmod.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := fmodL
LOCAL_SRC_FILES := libfmodL.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := voicer
LOCAL_SRC_FILES := voicer.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)/inc
LOCAL_LDLIBS := -llog
LOCAL_CPP_FEATURES :=exceptions
LOCAL_SHARED_LIBRARIES := fmod fmodL
include $(BUILD_SHARED_LIBRARY)
#include "com_daqiang_voicer_TestNdk.h"
#include
#include "jni.h"
#include
#include
#include //unix 标准头文件,这里用到了sleep函数
using namespace FMOD;
//宏定义
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"daqiang",FORMAT,##__VA_ARGS__)
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"daqiang",FORMAT,##__VA_ARGS__)
#define MODE_NORMAL 0
#define MODE_LUOLI 1
#define MODE_DASHU 2
/*
* Class: com_daqiang_json_voicer_TestNdk
* Method: fix
* Signature: (Ljava/lang/String;I)V
*/
JNIEXPORT void JNICALL Java_com_daqiang_voicer_TestNdk_fix(JNIEnv *env,
jclass jcls, jstring path, jint mode) {
System *system;
Sound *sound;
void *extradriverdata; //Driver specific data that can be passed to the output plugin. For example the filename for the wav writer plugin. See FMOD_OUTPUTTYPE for what each output mode might take here. Optional. Specify 0 or NULL to ignore.
Channel *channel;
bool isPlaying = true; //是否正在播放,默认为true
DSP *dsp; //音效
try {
//初始化
System_Create(&system);
//maxchannels:最多使用的频道数 这里32
system->init(32, FMOD_INIT_NORMAL, extradriverdata);
//要播放声音,先创建声音
const char* path_cstr = env->GetStringUTFChars(path, NULL);
system->createSound(path_cstr, FMOD_DEFAULT, NULL, &sound);
LOGI("路径:%s", path_cstr);
switch (mode) {
case MODE_NORMAL: //正常
system->playSound(sound, 0, false, &channel);
break;
case MODE_LUOLI: //萝莉
//音效
system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
//指定音效的参数 (Type:float) - Pitch value. 0.5 to 2.0. Default = 1.0. 0.5 = one octave down, 2.0 = one octave up. 1.0 does not change the pitch.
dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 2);
system->playSound(sound, 0, false, &channel);
channel->addDSP(0, dsp);
break;
case MODE_DASHU: //大叔
//音效
system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
//指定音效的参数 (Type:float) - Pitch value. 0.5 to 2.0. Default = 1.0. 0.5 = one octave down, 2.0 = one octave up. 1.0 does not change the pitch.
dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.5);
system->playSound(sound, 0, false, &channel);
channel->addDSP(0, dsp);
break;
}
} catch (...) {
LOGE("%s", "异常");
goto end;
}
//更新,没有更新是不会播放声音的
system->update();
//播放声音异步,如果没有播放完,
// 等待播放完成
while (isPlaying) {
channel->isPlaying(&isPlaying);
//休眠,单位:微秒
usleep(1000 * 1000); //1秒
}
end:
LOGI("%s", "播放结束");
system->close();
system->release();
}
android studio 3.0 重新编译了代码:源码下载地址地址(只是简单的界面,几个按钮,音效处理):https://download.csdn.net/download/u014389362/10753612
java安卓程序代做,安卓程序代做,专业程序代写,有需要请加QQ: 2103752102
我的淘宝店铺