08.Eclipse下Ndk开发(使用fmod实现QQ变声功能)
(创建于2017/12/30)
1.编写native
package org.fmod.example;public class EffectUtils {//音效的类型public static final int MODE_NORMAL = 0;public static final int MODE_LUOLI = 1;public static final int MODE_DASHU = 2;public static final int MODE_JINGSONG = 3;public static final int MODE_GAOGUAI = 4;public static final int MODE_KONGLING = 5;/*** 音效处理* @param path* @param type*/public native static void fix(String path,int type);static{System.loadLibrary("fmodL");System.loadLibrary("fmod");System.loadLibrary("qq_voice");}
}
2.进入src目录下,使用命令行生成头文件
javah 包名+类名
3.创建项目根目录下jni文件夹,将头文件拷贝进去
4.下载fmod源码,复制api中lowlevel中的inc中的头文件到jni目录下
5.复制fmod jar包到根目录下libs文件夹并添加依赖
6.复制需要的api平台的so文件到jni目录下
7.修改报错的地方,比如头文件的路径等问题
8.Android Tools -> Add native support 添加本地支持(在此之前,确认你的项目中已经配置了ndk相关的头文件目录支持,参考前边的笔记),填写你要生成的
so库的文件名,确认和loadLibrary中加载的(如qq_voice)保持一致
9.配置mk文件:
Android.mk
LOCAL_PATH := $(call my-dir)//编译libfmod.so
include $(CLEAR_VARS)
LOCAL_MODULE := fmod
LOCAL_SRC_FILES := libfmod.so
include $(PREBUILT_SHARED_LIBRARY)//编译libfmodL.so
include $(CLEAR_VARS)
LOCAL_MODULE := fmodL
LOCAL_SRC_FILES := libfmodL.so
include $(PREBUILT_SHARED_LIBRARY)//编译我们自己写的c代码为so文件,并添加上边编译的so支持
include $(CLEAR_VARS)
LOCAL_MODULE := qq_voice
LOCAL_SRC_FILES := effect_fix.cpp
LOCAL_SHARED_LIBRARIES := fmod fmodL
//添加log支持
LOCAL_LDLIBS := -llog
//添加c++异常类支持
LOCAL_CPP_FEATURES := exceptions
include $(BUILD_SHARED_LIBRARY)
Application.mk
##支持C++异常处理,标准莫板块(针对string.h等头文件的处理,去掉了common.c之后,这个不再需要了,但是保留也没问题)
APP_STL := gnustl_static
10.不断的build project,直到所有异常解决编译成功
部分源码:
effect_fix.cpp
#include "org_fmod_example_EffectUtils.h"
#include "inc/fmod.hpp"
#include <stdlib.h>
#include <unistd.h>
#include <android/log.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"renzhenming",FORMAT,##__VA_ARGS__)
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"renzhenming",FORMAT,##__VA_ARGS__)#define MODE_NORMAL 0
#define MODE_LUOLI 1
#define MODE_DASHU 2
#define MODE_JINGSONG 3
#define MODE_GAOGUAI 4
#define MODE_KONGLING 5using namespace FMOD;JNIEXPORT void JNICALL Java_org_fmod_example_EffectUtils_fix(JNIEnv *env, jclass jcls, jstring path_jstr, jint type){System *system;FMOD_RESULT result;Sound *sound;Channel *channel;DSP *dsp;float frequency = 0;bool isPlaying = true;const char *media_path = env->GetStringUTFChars(path_jstr,NULL);try {//初始化result = System_Create(&system);result = system->init(32, FMOD_INIT_NORMAL, NULL);//创建声音//这里进坑了,写作下边的样子是无法播放的,正确的方式是第二行 因为sound如果是null,那么,播放的时候的sound也就是null,怎么播放呢//result = system->createSound(media_path, FMOD_DEFAULT, 0, NULL);LOGI("%s",media_path);system->createSound(media_path, FMOD_DEFAULT, NULL, &sound);switch(type){case MODE_NORMAL://原生播放result = system->playSound(sound, 0, false, &channel);break;case MODE_LUOLI://dsp -- 音效//FMOD_DSP_TYPE_PITCHSHIFT 提升或者降低音调用的一种音效system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT,&dsp);//设置音调的参数dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,2);//播放(播放和添加channel的顺序必须是先播放,再添加,否则音效无法生效)//猜测原因//playSound之后并不是立即播放,而是在system->update();之后开始播放,//playSound的作用是创造了一个sound载体一个channel载体,然后在这个载体基础上添加一系列的效果,所以,只能现有载体//效果才有放置的位置,所以需要先play再添加result = system->playSound(sound, 0, false, &channel);//添加到channelchannel->addDSP(0,dsp);break;case MODE_DASHU://dsp -- 音效//FMOD_DSP_TYPE_PITCHSHIFT 提升或者降低音调用的一种音效system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT,&dsp);//设置音调的参数dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,0.6);//播放(播放和添加channel的顺序必须是先播放,再添加,否则音效无法生效)result = system->playSound(sound, 0, false, &channel);//添加到channelchannel->addDSP(0,dsp);break;case MODE_GAOGUAI://提高说话的速度result = system->playSound(sound, 0, false, &channel);channel->getFrequency(&frequency);\frequency = frequency*1.5;channel->setFrequency(frequency);break;case MODE_KONGLING:system->createDSPByType(FMOD_DSP_TYPE_ECHO,&dsp);dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY,300);dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK,2);result = system->playSound(sound, 0, false, &channel);channel->addDSP(0,dsp);break;case MODE_JINGSONG://紧张system->createDSPByType(FMOD_DSP_TYPE_ECHO,&dsp);dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW,0.5);result = system->playSound(sound, 0, false, &channel);channel->addDSP(0,dsp);break;default:break;}while(isPlaying){channel->isPlaying(&isPlaying);//<unistd.h>//单位微秒,不断的睡眠保证声音播放完成之后再释放资源usleep(1000*1000);}LOGI("%s","播放完成");system->update();} catch(...){LOGE("%s","发生异常");goto end;}goto end;end:env->ReleaseStringUTFChars(path_jstr,media_path);result = sound->release();system->close();system->release();
}
QQActivity.java
package org.fmod.example;import java.io.File;import com.renzhenming.qq_voice.R;import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;public class QQActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);org.fmod.FMOD.init(this);setContentView(R.layout.activity_main);}public void mFix(View view){String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar + "singing.wav";Log.d("renzhenming", path);switch (view.getId()) {case R.id.btn_record:EffectUtils.fix(path, EffectUtils.MODE_NORMAL);Log.d("renzhenming", "MODE_NORMAL");break;case R.id.btn_luoli:EffectUtils.fix(path, EffectUtils.MODE_LUOLI);Log.d("renzhenming", "MODE_LUOLI");break;case R.id.btn_dashu:EffectUtils.fix(path, EffectUtils.MODE_DASHU);Log.d("renzhenming", "MODE_DASHU");break;case R.id.btn_jingsong:EffectUtils.fix(path, EffectUtils.MODE_JINGSONG);break; case R.id.btn_gaoguai:EffectUtils.fix(path, EffectUtils.MODE_GAOGUAI);break; case R.id.btn_kongling:EffectUtils.fix(path, EffectUtils.MODE_KONGLING);break; default:break;}}@Overrideprotected void onDestroy(){ org.fmod.FMOD.close(); super.onDestroy();}
}
EffectUtils.java
package org.fmod.example;public class EffectUtils {//音效的类型public static final int MODE_NORMAL = 0;public static final int MODE_LUOLI = 1;public static final int MODE_DASHU = 2;public static final int MODE_JINGSONG = 3;public static final int MODE_GAOGUAI = 4;public static final int MODE_KONGLING = 5;/*** 音效处理* @param path* @param type*/public native static void fix(String path,int type);static{System.loadLibrary("fmodL");System.loadLibrary("fmod");System.loadLibrary("qq_voice");}
}
程序运行界面
08.Eclipse下Ndk开发(使用fmod实现QQ变声功能)相关推荐
- Eclipse下NDK开发与调试
Eclipse下NDK开发 一.关于NDK: NDK全称:Native Development Kit. 1.NDK是一系列工具的集合. NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动 ...
- android fmod,Android利用Fmod仿QQ变声音效
看到QQ一些变声音效,这些声音效果可以采用SoundTouch,Fmod去处理.这篇文章我们用Fmod去实现变声音效的处理.fmod官网https://www.fmod.com/,fmod Ex 声音 ...
- 26.Android Studio下Ndk开发(ffmpeg导入Android studio以cmake方式编译的过程)
Android studio 2.2开始支持cmake的方式进行jni开发,我在另一篇10.Eclipse下Ndk开发(ffmpeg解码)中写过Eclipse下编译ffmpeg的过程,但是现在几乎没有 ...
- Android下NDK开发环境搭建
Android下NDK开发环境搭建 1. AndroidNDK安装与配置 1.1 NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP部 ...
- android fmod,Android ndk开发:fmod语音学习(二)
在上一篇文章中,介绍以及搭建了FMOD的Android示例,这篇文章是在上一篇文章的基础上写的.所以建议首先读一下我的这篇文章. 本文使用FMOD来实现变声效果,直接使用<Android ndk ...
- eclipse下web开发中缓存问题
eclipse下web开发中缓存问题 原创 2016年04月06日 17:27:14 标签: eclipse / 缓存 / web开发 2351 问题描述:对web文件无论怎么修改,甚至删除,最后都会 ...
- 自学体验使用fmod 以及 仿QQ变声 fmod
模块一 体验使用fmod 到 https://www.fmod.com/download 上下载fmod android版本的 这里我们用的是别人生成的so库 libfmod.so库 libfmodL ...
- 安卓eclipse 的ndk开发
谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK提供 ...
- android studio下NDK开发
2019独角兽企业重金招聘Python工程师标准>>> 1.NDK 的下载 和 配置 NDK 下载地址 : https://developer.android.com/ndk/ind ...
最新文章
- 27.3. source code
- seci-log1.02日志分析软件版本升级了
- 在Linux上编写并运行Python文件
- MySQL主主复制 外键_MySQL 组复制介绍
- cassandra使用心得_使用Cassandra和Nutch爬网
- 横竖屏切换时候Activity的生命周期的总结
- 打开黑色_垃圾桶里的黑色塑料袋,打开一看,倒吸一口气!
- python正则匹配html标签_Python爬虫常用正则表达式及HTML网页标签分析总结
- 使用LoRa技术进行智慧城市转型
- putty提示Network error:Software caused connection abort
- WebSocket 对象简介
- 2018.12.18
- delphi OleVariant转换RecordSet
- 项目日报模板_韶州中学项目建设正酣 ,计划明年9月投入使用
- 大一高数求极限的方法小结
- micropython控制舵机_玩转micro:bit-用BXY控制小舵机、360舵机和带驱动N20电机
- c语言最小公倍数最简单求法,c语言最小公倍数与最大公约数的求法集锦
- 赛门铁克并购 Blue Coat 的益处显现
- 华硕美版路由器RT-AC1200G+解决无线信号弱问题
- 使用Unity制作VR全景图片清晰度的问题!!!