仿QQ语言变声功能

news/2024/12/29 17:54:07/

仿QQ语言变声功能

这次写的是QQ语言变声功能,这个功能想必大家都使用过,那么这个功能是怎么实现的呢?
在开发中一边触及和语音,视频,算法等等都和c/c++相关,我们这里也是使用的NDK,链接第三方动态库,生成我们自己的库文件。

先来讲讲第三方的动态库,我们这里使用的FMOD音频引擎提供给android的api和动态库。我们可以到官网下载:
FMOD,因为下载需要注册,但是我天朝的。。。,需要vnp,所以这边也提供了下载地址:FMOD android下的开发

想看下效果图:

这里写图片描述

我么进入正题:

1.从fmod开发包中,引入动态库和jar包,头文件

这里写图片描述

2.编写CMakeLists.txt文件

cmake_minimum_required(VERSION 3.4.1)set(distribution_dir ../../../../libs )find_library(   log-liblog )add_library(    fmodSHAREDIMPORTED )set_target_properties(  fmodPROPERTIES IMPORTED_LOCATION${distribution_dir}/${ANDROID_ABI}/libfmod.so)add_library(    fmodLSHAREDIMPORTED )set_target_properties(  fmodLPROPERTIES IMPORTED_LOCATION${distribution_dir}/${ANDROID_ABI}/libfmodL.so)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")add_library(    stonevoicerSHAREDsrc/main/cpp/StoneVoicer.cpp )include_directories(src/main/cpp/inc)target_link_libraries(  stonevoicerfmodfmodL${log-lib} )

3.build.gradle中添加配置信息

 ndk{abiFilters "armeabi","x86","armeabi-v7a","arm64-v8a"}
sourceSets {main {jniLibs.srcDirs = ['libs']}
}

4.编写java代码

MainActivity:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);requestPermission();FMOD.init(this);}private void  requestPermission(){if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);}if(ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 200);}}public void mFix(View v) {//音频路径可以去获取麦克风的数据,我这里写死了String path = "file:///android_asset/xiaoxin.wav";switch (v.getId()) {case R.id.btn_normal:VoicerUtil.fix(path, VoicerUtil.MODE_NORMAL);break;case R.id.btn_luoli:VoicerUtil.fix(path, VoicerUtil.MODE_LUOLI);break;case R.id.btn_dashu:VoicerUtil.fix(path, VoicerUtil.MODE_DASHU);break;case R.id.btn_jingsong:VoicerUtil.fix(path, VoicerUtil.MODE_JINGSONG);break;case R.id.btn_gaoguai:VoicerUtil.fix(path, VoicerUtil.MODE_GAOGUAI);break;case R.id.btn_kongling:VoicerUtil.fix(path, VoicerUtil.MODE_KONGLING);break;default:break;}}@Overrideprotected void onDestroy() {super.onDestroy();FMOD.close();}
}

VoicerUtil:

public class VoicerUtil {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("fmod");System.loadLibrary("fmodL");System.loadLibrary("stonevoicer");}
}

5.生成头文件

我这边使用的是javah来生成的:

javah -classpath . -jni github.com.stonevoicer.VoicerUtil

然后将头文件移动到cpp文件夹下:

这里写图片描述

6.编写c++代码

#include <jni.h>
#include <string>
#include <stdlib.h>
#include "github_com_stonevoicer_VoicerUtil.h"
#include <fmod.hpp>
#include <unistd.h>#include <android/log.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"zph",FORMAT,##__VA_ARGS__);
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"zph",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_github_com_stonevoicer_VoicerUtil_fix(JNIEnv *env, jclass jcls, jstring path_jstr, jint mode){LOGI("%s", "===>start");System * system;Sound *sound;DSP *dsp;Channel *channel;float frequency;bool isplaying= true;System_Create(&system);system->init(32,FMOD_INIT_NORMAL,NULL);const char* path_cstr = env->GetStringUTFChars(path_jstr,NULL);try {system->createSound(path_cstr,FMOD_DEFAULT,NULL,&sound);switch (mode){case MODE_NORMAL:LOGI("%s", path_cstr);system->playSound(sound, 0, false, &channel);LOGI("%s", "fix normal");break;case MODE_LUOLI://dsp->音效//dsp 提升或者降低音调的一种音效system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,8.0);system->playSound(sound, 0, false, &channel);channel->addDSP(0, dsp);break;case MODE_DASHU:system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH,0.8);system->playSound(sound, 0, false, &channel);channel->addDSP(0, dsp);break;case MODE_JINGSONG:system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp);dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 5);system->playSound(sound, 0, false, &channel);channel->addDSP(0, dsp);break;case MODE_GAOGUAI://提高说话的速度system->playSound(sound, 0, false, &channel);channel->getFrequency(&frequency);frequency = frequency * 2;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, 20);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);}goto end;end:env->ReleaseStringUTFChars(path_jstr, path_cstr);sound->release();system->close();system->release();}

下面给出项目地址:StoneVoicer-Demo


http://www.ppmy.cn/news/544977.html

相关文章

【有手就行】使用你自己的声音做语音合成

【有手就行】使用你自己的声音做语音合成 厌倦了前篇一律的TTS音色了吗&#xff1f;打开短视频听来听去就是那几个声音&#xff0c;快来试试使用你自己的声音来做语音合成吧&#xff01;本教程非常简单&#xff0c;只需要你能够上传自己的音频数据就可以(建议10句以上&#xf…

仿QQ变声功能的实现

Android ndk开发之QQ变声 要做出QQ变声的效果&#xff0c;用Android系统自带的MediaPlayer是无法实现的&#xff0c;只能另想他法了。听说汤姆猫是用SoundTouch实现的&#xff0c;而QQ是用FMOD实现的&#xff0c;就根据网上的教程&#xff0c;自己捣鼓ndk好几天&#xff0c;终…

java实现变声器--变声萝莉

编写java变声器需要做的前期准备 安装 ffmgeg 下载地址 Releases BtbN/FFmpeg-Builds GitHub win系统下载 ffmpeg-N-103272-g7bba0dd638-win64-gpl.zip 配置环境变量到 bin目录 新建maven程序加入两个引用 <!-- https://mvnrepository.com/artifact/com.github.st-h/…

matlab调制变声,MATLAB变声程序代码

% ct1 clear all,close all, clc; % 定义常数 FL 80; % 帧长 WL 240; % 窗长 P 10; % 预测系数个数 [s,fs] wavread(sunday_2.wav); % 载入语音s s s/max(s); %归一化 L length(s); % 读入语音长度 FN floor(L/FL)-2; % 计算帧数 % 预测和重建滤波器 exc zeros(L,1); %…

Android 端音频变声方案

音频变声实质上是通过调整 PCM 数据的音调、节拍等属性&#xff0c;实现听感上的变化。如果是 mp3、aac 等压缩音频&#xff0c;则需提前解码成 PCM 数据&#xff0c;Android 端可以通过 MediaExtractor 及 MediaCodec 解码得到 PCM&#xff0c;但调整音调、节拍仅靠 Android a…

实时语音变声技术原理解析:“大叔变小萝莉”

游戏社交化是近年来游戏行业发展的重要趋势&#xff0c;如何提高游戏的社交属性已成为各大游戏厂商游戏策划的重要组成部分。游戏中玩家的互动形式也不再止于语音聊天&#xff0c;有了更为高阶的需求&#xff0c;比如&#xff1a;玩家在“吃鸡”的时候&#xff0c;会通过外带的…

MATLAB变声器程序

clear;clc; [s,fs,] audioread(‘61.m4a’); % 载入语音s s(1:3000)s(1:3000)randn(3000,1)*eps; s s/max(s); %归一化 L length(s); % 读入语音长度 figure(1); subplot(211);plot(s);title(‘原始语音信号波形’) subplot(212);plot(abs(s));title(‘原始语音信号频谱’) …

光变声

为何变&#xff1f; 今年智能车竞赛中的信标组的导引信号发生了改变&#xff0c;由原来的光&#xff0c;变成了声&#xff08;还有射频信号&#xff09;&#xff0c;除了传承智能车竞赛赛题永远在变化的传统&#xff0c;还有阻断…&#xff08;此处省略三千字&#xff09;。 …