1. 程式人生 > >unity3D學習之音訊播放 、實時變聲簡化版-audio菜鳥筆記5

unity3D學習之音訊播放 、實時變聲簡化版-audio菜鳥筆記5

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("儲存音色資料成功!");
    }

}