(創(chuàng)建于2017/12/30)
1.編寫(xiě)native
package org.fmod.example;public class EffectUtils {//音效的類(lèi)型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.進(jìn)入src目錄下,使用命令行生成頭文件
javah 包名+類(lèi)名
3.創(chuàng)建項(xiàng)目根目錄下jni文件夾,將頭文件拷貝進(jìn)去 4.下載fmod源碼,復(fù)制api中l(wèi)owlevel中的inc中的頭文件到j(luò)ni目錄下 5.復(fù)制fmod jar包到根目錄下libs文件夾并添加依賴(lài) 6.復(fù)制需要的api平臺(tái)的so文件到j(luò)ni目錄下 7.修改報(bào)錯(cuò)的地方,比如頭文件的路徑等問(wèn)題 8.Android Tools -> Add native support 添加本地支持(在此之前,確認(rèn)你的項(xiàng)目中已經(jīng)配置了ndk相關(guān)的頭文件目錄支持,參考前邊的筆記),填寫(xiě)你要生成的 so庫(kù)的文件名,確認(rèn)和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)//編譯我們自己寫(xiě)的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++異常類(lèi)支持
LOCAL_CPP_FEATURES := exceptions
include $(BUILD_SHARED_LIBRARY)
Application.mk
##支持C++異常處理,標(biāo)準(zhǔn)莫板塊(針對(duì)string.h等頭文件的處理,去掉了common.c之后,這個(gè)不再需要了,但是保留也沒(méi)問(wèn)題)
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);//創(chuàng)建聲音//這里進(jìn)坑了,寫(xiě)作下邊的樣子是無(wú)法播放的,正確的方式是第二行 因?yàn)閟ound如果是null,那么,播放的時(shí)候的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 提升或者降低音調(diào)用的一種音效system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT,&dsp);//設(shè)置音調(diào)的參數(shù)dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,2);//播放(播放和添加channel的順序必須是先播放,再添加,否則音效無(wú)法生效)//猜測(cè)原因//playSound之后并不是立即播放,而是在system->update();之后開(kāi)始播放,//playSound的作用是創(chuàng)造了一個(gè)sound載體一個(gè)channel載體,然后在這個(gè)載體基礎(chǔ)上添加一系列的效果,所以,只能現(xiàn)有載體//效果才有放置的位置,所以需要先play再添加result = system->playSound(sound, 0, false, &channel);//添加到channelchannel->addDSP(0,dsp);break;case MODE_DASHU://dsp -- 音效//FMOD_DSP_TYPE_PITCHSHIFT 提升或者降低音調(diào)用的一種音效system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT,&dsp);//設(shè)置音調(diào)的參數(shù)dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,0.6);//播放(播放和添加channel的順序必須是先播放,再添加,否則音效無(wú)法生效)result = system->playSound(sound, 0, false, &channel);//添加到channelchannel->addDSP(0,dsp);break;case MODE_GAOGUAI://提高說(shuō)話(huà)的速度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","發(fā)生異常");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 {//音效的類(lèi)型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");}
}
程序運(yùn)行界面
18404062.png
總結(jié)
以上是生活随笔 為你收集整理的08.Eclipse下Ndk开发(使用fmod实现QQ变声功能) 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。