webAudio在声音源头和扬声器之间可以增加很多过滤器,其中有一个叫做AnalyserNode的,它可以用来分析声波,利用FFT(快速傅立叶)将声音进行分解,来达到直观查看声波变化,先来看看效果:

webAudio之AnalyserNode分析声波 gif webAudio之AnalyserNode分析声波

webAudio之AnalyserNode

前面的文章讲过webAudio是怎么玩的,如何利用webAudio去播放声音,如果你还不知道,可以看看 初识webAudio这篇文章,里面讲解了webAudio播放声音的一般套路。

background Layer 1 声音源 过滤处理器 扬声器

上图就是webAudio播放声音的一般套路,注意的是过滤处理器是可以多个链接在一起的,而且这个过滤处理器也是多种多样的,今天的主角是AnalyserNode,它可以将声音利用FFT将声波分解。

声音的本质就是波的震动,而波的形态也是多种多样的,下面是一些常见的波的形态:

Waveform examples Examples of some waveforms. Sine Square Triangle Sawtooth

我们来直观的看看声音的震动效果:

webAudio之AnalyserNode分析声波 gif webAudio之AnalyserNode分析声波

我们可以发现,如果在没有声音的时候,是水平的,如果开始有声音了,就会有波形开始移动,声音的大小,音调的高低等因素会产生不同的波形,声音越频繁,波形相应的也会越密集。

单单看声波图像是不够的,因为两个不同音调的声音在声波图像上看都是一连串波,可能波形有一点点不同,这样是很难看出它们到底在哪里有区别,这个时候我们就要对声波进行分解。

数学家发现,所有的声波都可以表示成a1*sin(x)+a2*sin(x/2)+a3*sin(x/3)....的形式,也就是说任何声波都可以表示成多个简单波的叠加效果:

上图中红色的就是我们的声波,我们将它进行分解,分解成很多个简单波的叠加效果,那么得到的蓝色线条投影就是a1,a2,a3...数列,也就是组成这个波的具体合成参数。

那么这样拆分有什么意义呢?这样可以把任何的声音按照相同的规则进行拆分,那么对于不同的波而言,就只是哪些a1,a2,a3...数列不同而已了。假如两段声音只有一个调不一样,从波形上几乎看不出区别,但是如果分解的话,就可以发现这两个分解波的参数大部分相同,只有一两个参数不同而已,这样可以更直观的分析声音。

分解得到具体表达式参数数列是利用FFT,大概流程就是对一段声波采样,例如采样数(fftSize)为128,就是将一段波上采取128个点,然后将波分解成128个小波形,利用FFT计算,会得到128个参数(a1,a2....a128),其中有一半的为0(偶数下标的为0),真实数据为64个(frequencyBinCount)。

代码难点

第一步就是从声源链接分析器链接扬声器了,这个简单,关键代码如下:

analyser的fftSize一般是2的倍数,例如128,256,512,1024等,这个是由于FFT计算特性所决定的,这个数值越大,说明对波分解的越详细,越彻底。

frequencyBinCount就是指分解后的那些参数的个数,这个个数为fftSize的一半。

background Layer 1 255 -30 -100

maxDecibels,minDecibels是干嘛?因为真实计算得到那些参数都是负数,而且跨度比较大(如上图),因此为了方便展示,利用maxDecibels,minDecibels将计算得到的参数投影到0-255之间。

smoothingTimeConstant则是控制获取的参数变化速度,如果smoothingTimeConstant很小,那么数值变化幅度很大,看起来很乱,如果很大(0到1之间),变化幅度就比较小。具体的大家可以调试一下就知道了。

关键绘制代码如下 :

这里的getByteFrequencyData()是获取计算后的参数数列,个数为fftSize/2;getByteTimeDomainData()获取的是声波的采样数据,个数为fftSize。

DEMO下载

点击下载 [0积分]一共下载0

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字