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


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

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

接下來是設置麥克風的,麥克風的原理就是首先定義一個Clip,開始錄音之后,就不斷的將錄音采樣點值賦予clip的相對應的采樣點,這點和Audiosource的timeSamples相同,區別是兩者的操作相反,當前采樣點的位置可以用MicroPhone的GetPosition()獲得。因此如果想要像KTV那樣實時的播放錄音,就是讓audiosource播放的時候,timeSamples的值剛好等於當前采樣點的值,或者延遲不大的一段采樣點距離(好吧,我這么干了,可是不知道為什么噪音很嚴重,有待研究,並且timeSamples的值不能大於當前錄音采樣點的值,不然沒有聲音(傻瓜都能想到為什么))。好吧,今日附貼,與公司大佬討論了一下之后終於明白了,原來噪音出現的原因是我播出來的聲音又實時的被錄進去了,從而出現類似回音的效果,所以最好戴上耳機錄音。

下面是實時播放的代碼。

 

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函數中每隔一段時間進行處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM