热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

UnityAudioSource与MicroPhone以及AudioClip之间的关系。下面是一个声音,长度为7秒钟,声音的实际数据本质是由采样点组成的的列表,一秒钟内的采样点数就是采样频率,下

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

 


推荐阅读
author-avatar
迷失在黑暗中的我_136
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有