Unity学习日记-Unity音频处理,自定义滤波函数OnAudioFilterRead

来源:互联网 发布:常用会计软件 编辑:程序博客网 时间:2024/06/07 01:06

Unity 的现有的资料中,音频处理部分真是少得可怜,每走一步都感觉自己是先驱(虽然应该并不是)。


前几天一边学Unity 的基本知识,同时也扫荡了一下Unity 中与音频相关的API。我要做的事情是使用HRTF 对音频进行实时的处理,制造具有方位感的音频,之前提到过HRTF 本质上就是一个滤波器,主要的困难在于,这个滤波器是要进行实时的刷新的,在不同的时间点,这个滤波器是会变化的。

我的思路有两种,理想的办法是直接通过Unity 在不同的时候让声音经过不同的滤波器,这样比较省事,不需要操作播放器的底层。万一找不到有关的API ,就要使用比较坏的方法,手动对音频进行分帧,有必要的话还要对硬件开刀,这种方法我自己也不太有把握,走投无路的话,也得硬着头皮上了。


扫荡Unity docs 后的收获:

http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAudioFilterRead.html

同时找到了一篇参考文章:

http://stackoverflow.com/questions/30654493/using-onaudiofilterread-with-playonawake


这是好可以写一个实时调整音量的小Demo 。

using UnityEngine;using System.Collections;//确认attach的物件包含AudioSource组件[RequireComponent(typeof(AudioSource))]public class AudioTest : MonoBehaviour {//gain是音量的权重,0f是静音,1f是正常播放的音量public float gain = 1f;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {}// This custom filter controls the gain by filtering the samples by multiplying each sample with a <i>gain</i> parameter.  void OnAudioFilterRead(float[] data, int channels){Debug.Log (">> data.Length = " + data.Length + "\n>> channels = " + channels);for (int i = 0; i < data.Length; ++i) {data [i] = data[i]*gain;Debug.Log (">> i = " + i);}}}
因为还不知道data 和data[i] 分别指的什么,所以我Debug了一下。

从结果可以看出来,data 其实是音频文件的一帧,包含2048个点,而data[i] 是对这一帧音频的遍历,这也告诉我们OnAudioFilterRead 这个函数是每一帧调用一次,简直福音。不过Debug data[i] 的时候,脚本就会放不出声音,可能是资源消耗太大?毕竟一帧就要调用2048次,可能系统有些吃不消。注释掉它就可以正常的播放,正常的调节音量了。另外我也不太明白右下角绿色框框中的数字是什么含义,猜测是和播放的流畅程度有关。

Debug之后我们可以明白OnAudioFilterRead的作用了,得到AudioSource的播放帧(默认2048点)并存入data 中,时域上我们可以利用data[i] 进行遍历并修改每个任意点的值。频域上应该可以对data 做卷积(还没测试)。

现在的我对于HRTF的音频处理大致心里有数了,首先需要一个public 的数组,用于储存各个位置的HRIR,然后在每一帧的时候,将对应位置的HRIR 和data 进行卷积(真希望卷积不会对性能影响太大)。


PS:还有一个新发现,Unity 有一个音频的SDK:Native Audio Plugin SDK

http://docs.unity3d.com/Manual/AudioMixerNativeAudioPlugin.html

目前性能不知,功能也没研究,留着今后再看。










0 0