unity3D學習之音訊播放 、實時變聲簡化版-audio菜鳥筆記5
阿新 • • 發佈:2019-02-04
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; #endif public 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 initialization void 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 frame void 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("儲存音色資料成功!"); } }