unity3D学习之音频播放 、实时变声简化版-audio菜鸟笔记5

news/2024/10/29 7:21:45/

这是基于soundtouch写的一个实时变声的C#脚本,因为是调试版,所以可能会有BUG


核心代码:

private void OnAudioFilterRead(float[] data, int channels){if (isRecording){//根据data,一段段处理变声soundTouch.PutSamples(data, data.Length);float[] tempsample_after = new float[data.Length];soundTouch.ReceiveSamples(tempsample_after, data.Length);for (int i = 0; i < data.Length; i++){data[i] = tempsample_after[i];}}}

关于OnAudioFilterRead的问题,有兴趣的同学可以去看看它的API,我在这里就不多说了


下面直接代码:

using SoundTouch;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;#if SOUNDTOUCH_INTEGER_SAMPLES
using TSampleType = System.Int16;
using TLongSampleType = System.Int64;
#else
using TSampleType = System.Single;
using TLongSampleType = System.Double;
#endifpublic class ClipChangeTest : MonoBehaviour {public AudioSource audioSource;//滑动条public Slider slider1;public Slider slider2;public Slider slider3;//输入框public InputField inputField1;public InputField inputField2;public InputField inputField3;public InputField inputField_modelName;private float tmpTempo;private float tmpPitch;private float tmpRate;private float temp_ischange1;private float temp_ischange2;private bool isRecording = false;private bool isChange_pitch = false;SoundTouch soundTouch = new SoundTouch();// Use this for initializationvoid Start (){slider1.minValue = -12f;slider1.maxValue = 12f;slider2.minValue = 0f;slider2.maxValue = 6f;slider3.minValue = 0f;slider3.maxValue = 6f;slider1.value = 0f;slider2.value = 1f;slider3.value = 1f;}// Update is called once per framevoid Update () {if (!isChange_pitch){if (slider3.value != temp_ischange2){slider2.value = 1f / slider3.value;temp_ischange1 = slider2.value;temp_ischange2 = slider3.value;}else if (slider2.value != temp_ischange1){slider3.value = 1f / slider2.value;temp_ischange1 = slider2.value;temp_ischange2 = slider3.value;}if (inputField1.isFocused){slider1.value = float.Parse(inputField1.text);}else if(inputField2.isFocused){slider2.value = float.Parse(inputField2.text);}else if (inputField3.isFocused){slider3.value = float.Parse(inputField3.text);}else{inputField1.text = slider1.value.ToString();inputField2.text = slider2.value.ToString();inputField3.text = slider3.value.ToString();}tmpPitch = slider1.value;tmpTempo = slider2.value;tmpRate = slider3.value;}}public void Mic_test(){if (Microphone.devices.Length == 0){Debug.LogWarning("找不到麦克风!");}Microphone.End(null);audioSource.clip = Microphone.Start(null, false, 100, 44100);//实时变声调整(初始化)isChange_pitch = true;soundTouch.SetTempo(tmpTempo);soundTouch.SetPitchSemiTones(tmpPitch);//噪音相对大一点soundTouch.SetRate(tmpRate);soundTouch.SetSampleRate(44100);soundTouch.SetChannels(1);soundTouch.SetSetting(SettingId.UseQuickseek, 0);soundTouch.SetSetting(SettingId.UseAntiAliasFilter, 0);soundTouch.SetSetting(SettingId.SequenceDurationMs, 40);soundTouch.SetSetting(SettingId.SeekwindowDurationMs, 15);soundTouch.SetSetting(SettingId.OverlapDurationMs, 8);isRecording = true;while (Microphone.GetPosition(null) <= 0) { }audioSource.Play();}//保存声音public void Save_test(){soundTouch.Flush();float[] saveClip_befor = new float[audioSource.timeSamples];audioSource.Stop();audioSource.clip.GetData(saveClip_befor, 0);//变声处理soundTouch.SetTempo(tmpTempo);soundTouch.SetPitchSemiTones(tmpPitch);soundTouch.SetRate(tmpRate);soundTouch.SetSampleRate(44100);soundTouch.SetChannels(1);soundTouch.SetSetting(SettingId.UseQuickseek, 0);soundTouch.SetSetting(SettingId.UseAntiAliasFilter, 0);soundTouch.SetSetting(SettingId.SequenceDurationMs, 40);soundTouch.SetSetting(SettingId.SeekwindowDurationMs, 15);soundTouch.SetSetting(SettingId.OverlapDurationMs, 8);soundTouch.PutSamples(saveClip_befor, saveClip_befor.Length);//获取变声后的数据并保存float[] saveClip_after = new float[saveClip_befor.Length];soundTouch.ReceiveSamples(saveClip_after, saveClip_befor.Length);soundTouch.Flush();audioSource.clip = AudioClip.Create("changedClip", saveClip_befor.Length, 1, 44100,false);audioSource.clip.SetData(saveClip_after, 0);SavWav.Save("test1", audioSource.clip);isChange_pitch = false;}//实时变声private void OnAudioFilterRead(float[] data, int channels){if (isRecording){//根据data,一段段处理变声soundTouch.PutSamples(data, data.Length);float[] tempsample_after = new float[data.Length];soundTouch.ReceiveSamples(tempsample_after, data.Length);for (int i = 0; i < data.Length; i++){data[i] = tempsample_after[i];}}}//控制录音时是否有声音public void ChangeController(){if (audioSource.volume == 0){audioSource.volume = 1;}else{audioSource.volume = 0;}}//测试所用//回放public void replay(){isChange_pitch = false;isRecording = true;//实时变声调整(初始化)soundTouch.SetTempo(tmpTempo);soundTouch.SetPitchSemiTones(tmpPitch);//噪音相对大一点soundTouch.SetRate(tmpRate);soundTouch.SetSampleRate(44100);soundTouch.SetChannels(1);soundTouch.SetSetting(SettingId.UseQuickseek, 0);soundTouch.SetSetting(SettingId.UseAntiAliasFilter, 0);soundTouch.SetSetting(SettingId.SequenceDurationMs, 40);soundTouch.SetSetting(SettingId.SeekwindowDurationMs, 15);soundTouch.SetSetting(SettingId.OverlapDurationMs, 8);audioSource.Play();}//保存不同的音色public void Save_changedata(){if (!File.Exists(Application.dataPath + "/Assets/Resources/speech_model.txt")){File.Create(Application.dataPath + "/Assets/Resources/speech_model.txt");Debug.LogWarning("创建文件");}FileStream fileStream = new FileStream(Application.dataPath + "/Assets/Resources/speech_model.txt",FileMode.Append);StreamWriter streamWriter = new StreamWriter(fileStream);streamWriter.Write(inputField_modelName.text + ": ");streamWriter.Write(" pitch:" + tmpPitch);streamWriter.Write(" tempo:" + tmpTempo);streamWriter.Write(" rate:" + tmpRate);streamWriter.WriteLine();streamWriter.Close();Debug.Log("保存音色数据成功!");}}

项目下载链接: http://download.csdn.net/download/weifut/9966784


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

相关文章

用matlab实现女声变男声步骤,男变女声、女变男声、如何实现变声效果?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 在移动直播中, 声音是主播和观众互动的重要途径之一, 为了丰富直播的内容,大家都会想要在声音上做一些文章, 在采集录音的基础上玩一些花样。比如演唱类的直播间中, 主播伴随着背景音乐演唱。这时有些主播就会希望能够给自己声音增…

用MATLAB设计一个超简单的变声GUI界面

由于并非专业变声制作&#xff0c;所以原理上只是进行了对时间轴的压缩或拉伸&#xff08;浅层的频率变换&#xff09;和振幅的变化&#xff0c;没有对音频文件进行滤波啊什么的深入处理。只适合娱乐而已。&#xff08;哈哈~~~&#xff09; 实现效果&#xff1a; 每种…

Android变声(SoundTouch)

前言&#xff1a;既然说是为变声这个功能而做&#xff0c;就我自己所了解的&#xff0c;原生中应该只有ffmpag&#xff0c;或者soundtouch可以实习,而这两种都涉及到NDK开发&#xff0c;这就有点难受了&#xff0c;当时公司是用的腾讯推广的变声器&#xff0c;后来因为老总发话…

自然语言处理从入门到应用——预训练模型总览:两大任务类型

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 相关文章&#xff1a; 预训练模型总览&#xff1a;从宏观视角了解预训练模型 预训练模型总览&#xff1a;词嵌入的两大范式 预训练模型总览&#xff1a;两大任务类型 预训练模型总览&#xff1a;预训练模型的拓展 …

鲸鱼算法WOA优化VMD参数,最小包络熵、样本熵、信息熵、排列熵(适应度函数可自行选择,一键修改)包含MATLAB源代码...

鲸鱼优化算法(Whale optimization algorithm, WOA)是Mirjalili根据座头鲸的捕食行为而提出来的&#xff0c;算法对座头鲸的狩猎行为进行模仿&#xff0c;通过对猎物的寻找&#xff0c;然后攻击进行觅食&#xff0c;以此来达到优化的目的&#xff0c;已有很多学者将算法用于实际…

探索iPadOS 17的亮点特性:值得关注的新功能揭秘

探索iPadOS 17的亮点特性&#xff1a;值得关注的新功能揭秘 看完在WWDC23上作为久违的“OneMoreThing”亮相的令人兴奋的AppleVisionPro后&#xff0c;是时候看看同样作为重要角色出现在发布会上的iPadOS了。与iOS一样&#xff0c;iPadOS也来到了17时代。除了一年后同步iOS16的…

并发编程ReentrantReadWriteLock 和 StampLock详解

并发编程ReentrantReadWriteLock 和 StampLock详解 1. 为什么需要读写锁&#xff1f;1.1 读写锁介绍1.2 2. 如何设计一把读写锁&#xff1f;重点&#xff1a;如何保证读写互斥&#xff1f;如何维护两个状态&#xff1f;如果要实现可重入&#xff0c;如何做&#xff1f;写锁读锁…

关于Win7企业版激活

今天遇到一个朋友的来电&#xff0c;客户希望预装Win7企业版&#xff0c;但始终无法破解。 其实我们往往忽略了一个问题&#xff0c;激活方式。 如果我们要使用企业版的&#xff0c;那么我们可以在公司加域然后由服务器自动激活&#xff0c;或者我们可以手动将IP地址指定为公司…