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函数中每隔一段时间进行处理。