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