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