Unity3D 录音, 压缩, 保存, 读取, 实时检测音量

    unity 录音功能主要通过,Microphone这个类来完成。使用这个类自然可以跨平台,不用调用平台本地代码处理。

     

		private static AudioClip clip; 

		private static int maxRecordTime = 10;
		private static int samplingRate  = 12000;

		public static bool TryStartRecording()
		{
			try
			{
				Microphone.End(null);
				clip = Microphone.Start(null, false, maxRecordTime, samplingRate);
			}
			catch(Exception e)
			{
				return false;
			}

			return true;
		}

    Start开始录音,name默认不写就是寻找默认设备。samplingRate是采样率长度,越长音质越好,录音文件越大。Start之前调用End是为了结束可能正在进行的录音。


    

		public static void EndRecording(out int length, out AudioClip outClip)
		{
			int lastPos = Microphone.GetPosition(null);

			if (Microphone.IsRecording(null))
			{
				length = lastPos / samplingRate;
			}
			else
			{
				length = maxRecordTime;
			}

			Microphone.End(null);

			if (length < 1.0f)
			{
				outClip = null;
				return;
			}

			outClip = clip;
		}


    结束的时候,计算音频数据的长度,返回长度和clip对象,做进一步处理。拿到,clip文件就可以利用AudioSource播放了。如果,我们需要保存和读取这个音频文件我们就需要使用clip的SetData和GetData文件。


    

        public static byte[] GetData(this AudioClip clip)
        {
             var data = new float[clip.samples * clip.channels];

            clip.GetData(data, 0);

            byte[] bytes = new byte[data.Length * 4];
            Buffer.BlockCopy(data, 0, bytes, 0, bytes.Length);

	            return SVZip.ConvertBytesZlib(bytes, Ionic.Zlib.CompressionMode.Compress);
        } 

        public static void SetData(this AudioClip clip, byte[] bytes)
        {
	            bytes = SVZip.ConvertBytesZlib(bytes, Ionic.Zlib.CompressionMode.Decompress);

            float[] data = new float[bytes.Length / 4];
            Buffer.BlockCopy(bytes, 0, data, 0, data.Length);

            clip.SetData(data, 0);
        }

    public static byte[] ConvertBytesZlib(byte[] data, CompressionMode compressionMode)
    {
        CompressionMode mode = compressionMode;
        if (mode != CompressionMode.Compress)
        {
            if (mode != CompressionMode.Decompress)
            {
                throw new NotImplementedException();
            }
            return ZlibStream.UncompressBuffer(data);
        }
        return ZlibStream.CompressBuffer(data);
    }

    GetData会获得一个float数组,里面是采样音频数据。我们需要把它转换byte数据保存文件,利用BlockCopy内存拷贝,并且使用了Zlib压缩算法对最终的byte数据压缩。GetData的时候,先解压在逆向把byte数据转换为flaot数据,返回给clip,就拿到了可以播放的clip对象了。

    

    使用SetData的clip需要我们调用AudioClip.Create方法创建出来,所以录音的时候,我们需要拿到原始clip的frequency和LengthSamples属性,传入给create方法。


    当clip的数据可以转换成byte数据的时候,我们就可以使用读写文件的方法保存和读取了。另外,既然我们有了音频数据,我们可以做一些操作修改音调添加魔音处理等这样的功能。


==================================================================================


    还有一个功能需求,就是在录音的过程中。如何显示录的声音的大小,同时显示一个音量大小的动画呢。其,核心的思路是,音频数据是float的0-1范围内的数据。就是音量大小的比例。我们可以把0-1的范围,分为若干个区间,来表示音量的大小。那么,我们有两个方案,来录音的时候实时获取这个sample数据。


    第一,就是使用协程,不断的检测Microphone.IsRecording是否在录音中,然后利用Microphone.GetPosition获得当前的进度,往前计算一段sample数据,找出一个平均值来代表这段时间的音量大小。


   第二,就是使用clip的回调接口PCMReaderCallback,在录到数据的时候会回调这个函数,参数中可以拿到当前的一段的sample数据。同样的找出一个平均值来代表当前的音量。




  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值