Unity 聲音與錄音與麥克風實時播放

Unity AudioSource與MicroPhone以及AudioClip之間的關係。ios

下面是一個聲音,長度爲7秒鐘,聲音的實際數據本質是由採樣點組成的的列表,一秒鐘內的採樣點數就是採樣頻率,下面的採樣頻率是10,正常實際中是44100,根據需求設置;AudioSource播放聲音時,設置其TimeSamples的意思就是從聲音的第timeSamples個採樣點位置開始播放,所以設置聲音的播放的偏移位置的方式是設置timeSamples或者設置time。播放時timeSamples並非一直固定的,跟隨時間逐個指向每一個對應的採樣點的索引值。函數

接下來是設置麥克風的,麥克風的原理就是首先定義一個Clip,開始錄音以後,就不斷的將錄音採樣點值賦予clip的相對應的採樣點,這點和Audiosource的timeSamples相同,區別是二者的操做相反,當前採樣點的位置能夠用MicroPhone的GetPosition()得到。所以若是想要像KTV那樣實時的播放錄音,就是讓audiosource播放的時候,timeSamples的值恰好等於當前採樣點的值,或者延遲不大的一段採樣點距離(好吧,我這麼幹了,但是不知道爲何噪音很嚴重,有待研究,而且timeSamples的值不能大於當前錄音採樣點的值,否則沒有聲音(傻瓜都能想到爲何))。spa

下面是實時播放的代碼。code

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MicroPhoneTest : MonoBehaviour
{
    public AudioSource aud;

    bool isHaveMicroPhone;
    string device;
    public Text text;

    //Debug Text
    public Text clipLength;//記錄音頻文件的長度
    public Text devicePosition;//設備音頻的位置
    public Text audioTime;//記錄音頻的時間
    public Text audioSampleTime;//

    
    // Start is called before the first frame update
    void Start()
    {
        aud = GetComponent<AudioSource>();
        string[] devices = Microphone.devices;

        if (devices.Length > 0)
        {
            isHaveMicroPhone = true;
            device = devices[0];
            text.text = devices[0];
        }
        else
        {
            isHaveMicroPhone = false;
            text.text = "沒有獲取到麥克風";
        }
    }

    //開始錄音按鈕
    public void OnclickButton()
    {
        if (!isHaveMicroPhone) return;

        aud.clip = Microphone.Start(device, true, 10, 10000);
        //aud.Play();
        //aud.timeSamples = Microphone.GetPosition(device);
        //aud.timeSamples = 0;
        Debug.Log("開始錄音");
    }

    //開始播放按鈕
    public void OnPlay()
    {
        aud.Play();
        aud.timeSamples = Microphone.GetPosition(device);//這裏設置了以後就會近乎實時同步

        int min;
        int max;
        Microphone.GetDeviceCaps(device, out min,out max);
        //aud.timeSamples = 0;
        Debug.Log("開始播放"+min+" "+max);
    }




    private void Update()
    {
        //clipLength.text = "     clipLength:" + aud.clip.length;
        //devicePosition.text = " devicePosition:" + Microphone.GetPosition(device);
        //audioTime.text = "      audioTime:" + aud.time;
        //audioSampleTime.text = "audioSampleTime:" + aud.timeSamples;

        //Debug.Log("     clipLength:" + aud.clip.length);
        //Debug.Log(" devicePosition:" + Microphone.GetPosition(device));
        //Debug.Log("      audioTime:" + aud.time);
        //Debug.Log("audioSampleTime:" + aud.timeSamples);

        //aud.timeSamples = Microphone.GetPosition(device);
    }
}

 

 

注意,實時錄音播放後,可能會出現播放的採樣點與錄音的採樣點的值愈來愈大的問題,所以可能須要在update函數中每隔一段時間進行處理。blog

相關文章
相關標籤/搜索