当前位置: 首页 > news >正文

成都b2c外贸网站建设昆明seo网站管理

成都b2c外贸网站建设,昆明seo网站管理,php开发,wordpress添加图片不显示Android NDK 导入 C库的开发流程学习;通过使用fmod的C库,实现变声器功能。导入库文件1)复制fmod的C库到cpp目录下2)复制fmod的so库到jniLibs目录下3)复制fmod的jar库到libs目录下4)将声音文件复制到assets目…

Android NDK 导入 C库的开发流程学习;通过使用fmod的C库,实现变声器功能。

  1. 导入库文件

1)复制fmod的C库到cpp目录下

2)复制fmod的so库到jniLibs目录下

3)复制fmod的jar库到libs目录下

4)将声音文件复制到assets目录下

fmod库文件资源:https://wwgl.lanzout.com/ilXHP0pn7f4f

  1. 打开CMakeLists.txt导入fmod库文件

cmake_minimum_required(VERSION 3.10.2) # 最低支持的CMake版本project("whine")# TODO 第一步 导入头文件(fmod库)
include_directories("inc")# 批量导入所有文件
file(GLOB allCPP *.c *.h *.cpp)add_library(native-lib # 打包出来库的名称 libnative-lib.soSHARED # 动态库${allCPP} # 添加所有库文件
)# TODO 第二步 导入库文件(fmod库)
# ${CMAKE_CXX_FLAGS} 原先的CMake环境 +
# -L${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI} 加上新的fmod库的路径
# CMAKE_SOURCE_DIR == CMakeLists.txt所在的路径
# /../ 回退到cpp目录
# jniLibs/ 进入jniLibs目录
# ${CMAKE_ANDROID_ARCH_ABI} 使用当前手机CPU系统结构对应的库 如:arm64-v8a
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}")find_library(log-liblog # 自动寻找log库
)# TODO 第三步 链接具体的库,到 libnative-lib.so总库
target_link_libraries(native-lib${log-lib}fmod # 具体的库 链接到 libnative-lib.so里面去fmodL # 具体的库 链接到 libnative-lib.so里面去
)
  1. 打开build.gradle,指定CPU架构和依赖fmod的jar包

defaultConfig {// TODO 第四步externalNativeBuild {cmake {// cppFlags "" // 默认五大平台// 指定CPU架构,Cmake的本地库, 例如:native-lib ---> arm64-v8aabiFilters "arm64-v8a"}}// TODO 第五步// 指定CPU架构,打入APK lib/CPU平台ndk {abiFilters "arm64-v8a"}
}dependencies {// TODO 第六步:依赖fmod的jar包implementation files("libs\\fmod.jar");
}
  1. 准备工作完成,开始编写Activity代码

1)定义变声模式

/*** 定义变声模式* 0 正常; 1 萝莉; 2 大叔; 3 惊悚; 4 搞怪; 5 回声;*/
private static final int MODE_NORMAL = 0;
private static final int MODE_LUOLI = 1;
private static final int MODE_DASHU = 2;
private static final int MODE_JINGSONG = 3;
private static final int MODE_GAOGUAI = 4;
private static final int MODE_KONGLING = 5;

2)加载编译后的lib库

static {System.loadLibrary("native-lib");
}

3)初始化fmod.jar库,并在页面关闭的时候释放

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);FMOD.init(this);
}@Override
protected void onDestroy() {super.onDestroy();FMOD.close();
}

4)编写变声native层方法和变声结束后提供native调用的方法

public native void voiceChangeNative(int modeNormal, String path);private void playerEnd(String msg) {isPlaying = false;runOnUiThread(() -> Toast.makeText(this, msg, Toast.LENGTH_SHORT).show());
}

5)Activity完整代码

package com.whine;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.Toast;import org.fmod.FMOD;/*** TODO Android NDK 导入 C库,开发流程 之 变声器*/
public class MainActivity extends AppCompatActivity {/*** 定义变声模式* 0 正常; 1 萝莉; 2 大叔; 3 惊悚; 4 搞怪; 5 回声;*/private static final int MODE_NORMAL = 0;private static final int MODE_LUOLI = 1;private static final int MODE_DASHU = 2;private static final int MODE_JINGSONG = 3;private static final int MODE_GAOGUAI = 4;private static final int MODE_KONGLING = 5;/*** 声音路径*/private String soundPath;private boolean isPlaying = false;static {System.loadLibrary("native-lib");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// TODO 第七步 初始化FMOD库FMOD.init(this);initData();}private void initData() {soundPath = "file:///android_asset/sound.mp3";}// 点击事件public void onFix(View view) {switch (view.getId()) {case R.id.btn_normal:voiceChange(MODE_NORMAL, soundPath); // 真实开发中,必须子线程  JNI线程(很多坑)break;case R.id.btn_luoli:voiceChange(MODE_LUOLI, soundPath);break;case R.id.btn_dashu:voiceChange(MODE_DASHU, soundPath);break;case R.id.btn_jingsong:voiceChange(MODE_JINGSONG, soundPath);break;case R.id.btn_gaoguai:voiceChange(MODE_GAOGUAI, soundPath);break;case R.id.btn_kongling:voiceChange(MODE_KONGLING, soundPath);break;}}@Overrideprotected void onDestroy() {super.onDestroy();FMOD.close();}private void voiceChange(int modeNormal, String path) {if (isPlaying) {Toast.makeText(this, "正在播放,请稍后!", Toast.LENGTH_SHORT).show();return;}isPlaying = true;new Thread(() -> voiceChangeNative(modeNormal, path)).start();}/*** 给C++(native)层调用的函数* JNI 调用 Java函数的时候,忽略掉 私有、公开 等** @param msg*/private void playerEnd(String msg) {isPlaying = false;runOnUiThread(() -> Toast.makeText(this, msg, Toast.LENGTH_SHORT).show());}/*** 变声native层方法** @param modeNormal* @param path*/public native void voiceChangeNative(int modeNormal, String path);
}
  1. 编写native层头文件(声明文件)

1)导入需要使用到的头文件

#include <jni.h>
#include <fmod.hpp>
#include <string>
#include <android/log.h>

2)定义log宏

#define TAG "NDK"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)

3)定义变声模式宏

#undef com_whine_MainActivity_MODE_NORMAL
#define com_whine_MainActivity_MODE_NORMAL 0L
#undef com_whine_MainActivity_MODE_LUOLI
#define com_whine_MainActivity_MODE_LUOLI 1L
#undef com_whine_MainActivity_MODE_DASHU
#define com_whine_MainActivity_MODE_DASHU 2L
#undef com_whine_MainActivity_MODE_JINGSONG
#define com_whine_MainActivity_MODE_JINGSONG 3L
#undef com_whine_MainActivity_MODE_GAOGUAI
#define com_whine_MainActivity_MODE_GAOGUAI 4L
#undef com_whine_MainActivity_MODE_KONGLING
#define com_whine_MainActivity_MODE_KONGLING 5L

4)头文件完整代码

// TODO 第八步 编写头文件(声明文件)
#include <jni.h>
// 导入FMOD的头文件
#include <fmod.hpp>
#include <string>
// 导入log库
#include <android/log.h>extern "C" {// log宏
#define TAG "NDK"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)// 创建变声模式宏
#undef com_whine_MainActivity_MODE_NORMAL
#define com_whine_MainActivity_MODE_NORMAL 0L
#undef com_whine_MainActivity_MODE_LUOLI
#define com_whine_MainActivity_MODE_LUOLI 1L
#undef com_whine_MainActivity_MODE_DASHU
#define com_whine_MainActivity_MODE_DASHU 2L
#undef com_whine_MainActivity_MODE_JINGSONG
#define com_whine_MainActivity_MODE_JINGSONG 3L
#undef com_whine_MainActivity_MODE_GAOGUAI
#define com_whine_MainActivity_MODE_GAOGUAI 4L
#undef com_whine_MainActivity_MODE_KONGLING
#define com_whine_MainActivity_MODE_KONGLING 5L
JNIEXPORT void JNICALL Java_com_whine_MainActivity_voiceChangeNative(JNIEnv *, jobject, jint, jstring);
}
  1. 编写native层实现文件

1)转换Java层传递的声音路径jstring -> char *

const char *pathChar = env->GetStringUTFChars(path, NULL);

2)定义和初始化音效引擎系统

// 定义音效引擎系统 指针
System *system = 0;
// 声音
Sound *sound = 0;
// 音轨
Channel *channel = 0;
// 数字信号处理  指针
DSP *dsp = 0;
// 创建系统
System_Create(&system);
// 初始化系统 参数1:最大音轨数,参数2:系统初始化标记,参数3:额外数据
system->init(32, FMOD_INIT_NORMAL, 0);
// 创建声音  参数1:路径,  参数2:声音初始化标记, 参数3:额外数据, 参数4:声音指针
system->createSound(pathChar, FMOD_DEFAULT, 0, &sound);
// 播放声音,并赋值通道 参数1:声音,参数2:分组音轨,参数3:控制,参数4:通道
system->playSound(sound, 0, false, &channel);

3)判断变声模式,调节音效

switch (mode_normal) {case com_whine_MainActivity_MODE_NORMAL:resultChar = "原生,播放完毕!";break;case com_whine_MainActivity_MODE_LUOLI:resultChar = "萝莉,播放完毕!";// 音调高 -- 萝莉 2.0// 1.创建DSP类型的Pitch 音调条件system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);// 2.设置Pitch音调调节2.0dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 3.0f);// 3.添加音效进去 第一个音轨channel->addDSP(0, dsp);break;case com_whine_MainActivity_MODE_DASHU:resultChar = "大叔,播放完毕!";// 音调低 -- 大叔 0.7// 1.创建DSP类型的Pitch 音调条件system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);// 2.设置Pitch音调调节0.7dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.7f);// 3.添加音效进去 第一个音轨channel->addDSP(0, dsp);break;case com_whine_MainActivity_MODE_GAOGUAI:resultChar = "搞怪小黄人,播放完毕!";// 小黄人声音 频率快// 1.从音轨拿 当前 频率float frequency;channel->getFrequency(&frequency);// 2.加快频率加快  小黄人的声音channel->setFrequency(frequency * 1.5f);break;case com_whine_MainActivity_MODE_JINGSONG:resultChar = "惊悚,播放完毕!";// 惊悚音效:特点:很多声音的拼接// TODO 1.音调低// 音调低 -- 大叔 0.7// 1.创建DSP类型的Pitchsystem->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);// 2.设置Pitch音调调节0.7dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.7f);// 3.添加音效进去 第一个音轨channel->addDSP(0, dsp);// TODO 2.回声// 回音 ECHO// 1.创建DSP类型的ECHOsystem->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);// 2.设置回音 延时 to 5000.  Default = 500.dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 200);// 3.设置回音 衰减度 Default = 50   0 完全衰减了dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 10);// 4.添加音效进去 第二个音轨channel->addDSP(1, dsp);// TODO 3.颤抖// Tremolo 颤抖音// 1.创建DSP类型的Tremolosystem->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp);// 2.设置颤抖 正常 5,非常颤抖 20dsp->setParameterFloat(FMOD_DSP_TREMOLO_FREQUENCY, 20);// 3.dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.8f);// 4.第三个音轨channel->addDSP(2, dsp);break;case com_whine_MainActivity_MODE_KONGLING:resultChar = "空灵,播放完毕!";// 回音 ECHO// 1.创建DSP类型的ECHO 音调条件system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);// 2.设置回音 延时 to 5000.  Default = 500.dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 200);// 3.设置回音 衰减度 Default = 50   0 完全衰减了dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 10);// 4.添加音效进去 第一个音轨channel->addDSP(0, dsp);break;
}

4)检测声音是否播放完毕

bool isPlay = true;
while (isPlay) {// 如果真的播放完成了,音轨是知道的,内部会修改isPlayer=falsechannel->isPlaying(&isPlay);// 休眠100mSusleep(100 * 1000);
}

5)回收C层资源

sound->release();
system->close();
system->release();
env->ReleaseStringUTFChars(path, pathChar);

6)播放完毕,通知java层(调用Java层的播放完成方法)

jclass jClazz = env->GetObjectClass(thiz);
jmethodID methodId = env->GetMethodID(jClazz, "playerEnd", "(Ljava/lang/String;)V");
jstring value = env->NewStringUTF(resultChar);
env->CallVoidMethod(thiz, methodId, value);

7)实现文件完整代码

#include <unistd.h>
#include "whine.h"using namespace FMOD; // fmod的命名空间extern "C"
JNIEXPORT void JNICALL
Java_com_whine_MainActivity_voiceChangeNative(JNIEnv *env, jobject thiz, jint mode_normal,jstring path) {// 定义一个结果字符串返回char *resultChar = "播放完毕!";// 转换路径jstring -> char *const char *pathChar = env->GetStringUTFChars(path, NULL);// 定义音效引擎系统 指针System *system = 0;// 声音Sound *sound = 0;// 音轨Channel *channel = 0;// 数字信号处理  指针DSP *dsp = 0;// 创建系统System_Create(&system);// 初始化系统 参数1:最大音轨数,参数2:系统初始化标记,参数3:额外数据system->init(32, FMOD_INIT_NORMAL, 0);// 创建声音  参数1:路径,  参数2:声音初始化标记, 参数3:额外数据, 参数4:声音指针system->createSound(pathChar, FMOD_DEFAULT, 0, &sound);// 播放声音,并赋值通道 参数1:声音,参数2:分组音轨,参数3:控制,参数4:通道system->playSound(sound, 0, false, &channel);LOGI("init done");// 判断模式,增加特效switch (mode_normal) {case com_whine_MainActivity_MODE_NORMAL:resultChar = "原生,播放完毕!";break;case com_whine_MainActivity_MODE_LUOLI:resultChar = "萝莉,播放完毕!";// 音调高 -- 萝莉 2.0// 1.创建DSP类型的Pitch 音调条件system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);// 2.设置Pitch音调调节2.0dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 3.0f);// 3.添加音效进去 第一个音轨channel->addDSP(0, dsp);break;case com_whine_MainActivity_MODE_DASHU:resultChar = "大叔,播放完毕!";// 音调低 -- 大叔 0.7// 1.创建DSP类型的Pitch 音调条件system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);// 2.设置Pitch音调调节0.7dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.7f);// 3.添加音效进去 第一个音轨channel->addDSP(0, dsp);break;case com_whine_MainActivity_MODE_GAOGUAI:resultChar = "搞怪小黄人,播放完毕!";// 小黄人声音 频率快// 1.从音轨拿 当前 频率float frequency;channel->getFrequency(&frequency);// 2.加快频率加快  小黄人的声音channel->setFrequency(frequency * 1.5f);break;case com_whine_MainActivity_MODE_JINGSONG:resultChar = "惊悚,播放完毕!";// 惊悚音效:特点:很多声音的拼接// TODO 1.音调低// 音调低 -- 大叔 0.7// 1.创建DSP类型的Pitchsystem->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);// 2.设置Pitch音调调节0.7dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.7f);// 3.添加音效进去 第一个音轨channel->addDSP(0, dsp);// TODO 2.回声// 回音 ECHO// 1.创建DSP类型的ECHOsystem->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);// 2.设置回音 延时 to 5000.  Default = 500.dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 200);// 3.设置回音 衰减度 Default = 50   0 完全衰减了dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 10);// 4.添加音效进去 第二个音轨channel->addDSP(1, dsp);// TODO 3.颤抖// Tremolo 颤抖音// 1.创建DSP类型的Tremolosystem->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp);// 2.设置颤抖 正常 5,非常颤抖 20dsp->setParameterFloat(FMOD_DSP_TREMOLO_FREQUENCY, 20);// 3.dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.8f);// 4.第三个音轨channel->addDSP(2, dsp);break;case com_whine_MainActivity_MODE_KONGLING:resultChar = "空灵,播放完毕!";// 回音 ECHO// 1.创建DSP类型的ECHO 音调条件system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);// 2.设置回音 延时 to 5000.  Default = 500.dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 200);// 3.设置回音 衰减度 Default = 50   0 完全衰减了dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 10);// 4.添加音效进去 第一个音轨channel->addDSP(0, dsp);break;}// 等待播放完毕 再回收bool isPlay = true;while (isPlay) {// 如果真的播放完成了,音轨是知道的,内部会修改isPlayer=falsechannel->isPlaying(&isPlay);// 休眠100mSusleep(100 * 1000);}LOGI("play done");// 回收资源sound->release();system->close();system->release();env->ReleaseStringUTFChars(path, pathChar);// 通知java层jclass jClazz = env->GetObjectClass(thiz);jmethodID methodId = env->GetMethodID(jClazz, "playerEnd", "(Ljava/lang/String;)V");jstring value = env->NewStringUTF(resultChar);env->CallVoidMethod(thiz, methodId, value);
}

http://www.ritt.cn/news/14793.html

相关文章:

  • 郑州做网站外包的公司有哪些宁波seo推广推荐公司
  • h5技术做网站产品软文
  • 2013一汽大众企业网站车主俱乐部建设维护方案互联网运营培训课程
  • 简洁页面心情网站百度爱采购平台官网
  • 做ppt的网站叫什么企业营销策划方案
  • 公司法人查询seo项目培训
  • dramwaver做网站长沙网站包年优化
  • 宁国网站建设站长之家产品介绍
  • 图片二维码生成器在线制作太原关键词优化公司
  • 永康做网站的公司百度一键优化
  • 查看网站架构广告营销平台
  • 2008iis网站属性网站一级域名和二级域名区别
  • 桂林网站制作人才招聘二级域名网站免费建站
  • 网站建设的方式在线教育
  • 沈阳h5建站西安网约车
  • 做推广便宜的网站b站视频推广怎么买
  • 运城网站制作路90肇庆seo按天收费
  • 诚信通网站怎么做百度指数查询官方网
  • 海南省住房和城乡建设厅官网网站首页杭州seo建站
  • 做国珍新时代 网站window优化大师官网
  • 网站没有关键词收录培训网站推广
  • 怎样做浏览的网站不被发现免费seo推广计划
  • 做门户网站服务器选择福州百度seo排名软件
  • 天河wap网站建设公司网站发帖推广平台
  • 网页制作新建站点步骤苏州网络推广服务
  • 大连做网站需要多少钱外贸网络推广
  • 怎么做付费的小说网站百度销售岗位怎么样
  • 网站图片地址怎么做佛山百度提升优化
  • 北京响应式的网站设计1688关键词排名查询
  • 织梦网站优化教程网络推广的基本渠道