Android ndk开发之QQ变声
要做出QQ变声的效果,用Android系统自带的MediaPlayer是无法实现的,只能另想他法了。听说汤姆猫是用SoundTouch实现的,而QQ是用FMOD实现的,就根据网上的教程,自己捣鼓ndk好几天,终于实现了,但是效果不是很理想。
FMOD是老外为游戏开发者准备的革命性音频引擎,说它支持很多功能,包括音效的处理,声道变化,音调等,,去fmod官网下载,首先得先注册一个账户,国内用户注册不了,需要翻墙才能注册,下载后解压,把需要的c文件放到jni目录下如图:配置Android.mk,写个native方法用来播放音频。中间会遇到各种问题,这里就不一一列举了,下面贴出源码。
- 1.本地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);}
- Android.mk
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 fmodLinclude $(BUILD_SHARED_LIBRARY)
- voicer.cpp
#include "com_daqiang_voicer_TestNdk.h"
#include <stdlib.h>
#include "jni.h"
#include <fmod.hpp>
#include <android/log.h>
#include <unistd.h>//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; //是否正在播放,默认为trueDSP *dsp; //音效try {//初始化System_Create(&system);//maxchannels:最多使用的频道数 这里32system->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代写
java安卓程序代做,安卓程序代做,专业程序代写,有需要请加QQ: 2103752102
我的淘宝店铺