Unity 声音与录音与麦克风实时播放

时间:2019-06-17
本文章向大家介绍Unity 声音与录音与麦克风实时播放,主要包括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函数中每隔一段时间进行处理。

原文地址:https://www.cnblogs.com/xiaoahui/p/11037671.html