仿QQ变声功能的实现

Android ndk开发之QQ变声

要做出QQ变声的效果,用Android系统自带的MediaPlayer是无法实现的,只能另想他法了。听说汤姆猫是用SoundTouch实现的,而QQ是用FMOD实现的,就根据网上的教程,自己捣鼓ndk好几天,终于实现了,但是效果不是很理想。
FMOD是老外为游戏开发者准备的革命性音频引擎,说它支持很多功能,包括音效的处理,声道变化,音调等,,去fmod官网下载,首先得先注册一个账户,国内用户注册不了,需要才能注册,下载后解压,把需要的c文件放到jni目录下如图:配置Android.mk,写个native方法用来播放音频。中间会遇到各种问题,这里就不一一列举了,下面贴出源码。
仿QQ变声功能的实现_第1张图片

  • 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 fmodL

include $(BUILD_SHARED_LIBRARY)

  • voicer.cpp
#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代写

java安卓程序代做,安卓程序代做,专业程序代写,有需要请加QQ: 2103752102

我的淘宝店铺

你可能感兴趣的:(android)