Unity3D使用内部频谱分析方法做音乐视觉特效的原理及说明

发表于2019-03-22
评论0 3.8k浏览
在一些音游项目中,如何将音乐的视觉特效给表现出来呢,正常的是可以借助使用内部频谱分析方法来做。知道这个以后,我们就来介绍下做音乐视觉特效的原理。

先理解几个名词和概念:

声音:一种波动,通过空气分子有节奏的震动进行传递。

声音频率Hz:声音每秒种震动的次数,以赫兹Hz 表示。频率越高,音高越高。

分贝dB:量度两个相同单位之数量比例的单位,可表示声音的强度单位。

人耳可听到的声波频率:每秒振动20次到20000次的范围内,既20赫兹至20000赫兹之间。

采样Sampling:在信号处理程序中,将连续信号(例如声波)降低成离散信号(一系列样本数据)。

采样率Sampling Rate:每秒从连续信号中提取并组成离散信号的采样个数,单位也是赫兹。

快速傅里叶变换FFT:一种算法,可用来转换信号。

窗函数Window Function:在信号处理之中,用来降低信噪比的一种算法。

信噪比:
—噪讯比越高的话,声音的大音量和小音量的音量差会越大(音质猛爆)。
—噪讯比越低的话,声音的大音量和小音量的音量差会越小(音质柔和)。

然后我们看一下Unity内置的这条命令:

AudioSource.GetSpectrumData
—public void GetSpectrumData(float[] samples, int channel, FFTWindow window);

samples:将音频样本数据传送至samples数组,数组大小必须为2的n次方,最小64,最大8192。

channel:一般设置为0。

window:转换信号所用的窗函数,算法越复杂,声音越柔和,但速度更慢。

因此我们先声明一个浮点数组:
public float[] spectrumData=new float[8192];

在Update方法里面使用方法:
thisAudioSource.GetSpectrumData(spectrumData,0,FFTWindow.BlackmanHarris);

那么这个方法传送到浮点数组里的数据是什么呢?

已知了开始部分的概念,我们可以定义几个变量:

一系列采样数据样本: N

采样频率: fs

时间:T

既:

它的倒数称为频率分辨率Frequency Resolution:

频率分辨率越高,转换出来的数据越精确。(下图,同样情况下,低频率分辨率与高频率分辨率的比较)


而我们声明的浮点数数组的大小既是GetSpectrumData这个方法的窗函数转换数据时所用的频率分辨率,而数组中每个浮点数的值既是谱密度,每单位频率波携带的功率,我们知道了频率分辨率df=8196,那么每个浮点数,既谱密度dB表示的的是哪个频率范围,既音高范围的功率呢?

目前数字音乐领域的采样率通常为44100Hz,但通过分析音频文件[MV] FIESTAR() _ Mirror.mp3的频谱,可能是因为通过视频转音频的缘故,基本上16000Hz以上的谱密度都非常低了。

而在Unity内通过分析spectrumData的数值,spectrumData[5500]左右以后的浮点数值与前面有一个断崖似的减少,因此可推断出,GetSpectrumData的采样的最高频率是在20000~23000赫兹之间,既音频文件23000赫兹以上频率的数据都被忽略掉了。

如果继续深入,可研究声波频率与音高的关系,将spectrumData特定范围的浮点数相加即可体现乐曲中各个音高的谱密度,由于人的听觉系统对音高最为敏感,其视觉效果应该会更加理想。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引