WebAudio API允许我create an AnalyserNode,这可以让我访问一组音频样本的FFT计算频谱(无符号字节数组或浮点数组-1
到{{1} }})。我希望我可以使用这些值来计算同一组样本的总功率(RMS)。
我不认为它就像取32个窗口值一样简单,将它们相加并除以32.(0dB的正弦波只会填满一个窗口,其中一些相邻的窗口会略微亮起,而0dB处的白噪声会填满所有窗口。)是否有可能从FFT / DFT输出中找出RMS值?
我想这样做的原因是我需要构建一个高效的RMS表。虽然我可以访问原始样本,但处理它们甚至找到一个峰值,每个缓冲区的开销都太大了。浏览器以本机代码运行其FFT,并且比尝试在JavaScript中执行所有这些计算更有效。如果我可以从32个FFT窗口计算出RMS,那将会更有效率。
答案 0 :(得分:3)
对于它的价值 - 我有一个应用程序在requestAnimationFrame
循环中使用getByteTimeDomainData()
在12到20个轨道上的任何地方计算RMS,而且速度非常快。在这些计算之间以及每16.7毫秒<canvas>
上以米为单位绘制结果,我在Chrome和Firefox中始终获得60fps。
现代JS引擎非常擅长快速合理地完成数学运算。
答案 1 :(得分:1)
是的,有可能从FFT中找到RMS值,你需要确保AnalyserNote不对信号应用任何Window(hanning,blackman,kaiser等)!
获得相同结果的两种简单方法:
RMS1 =平方的绝对FFOutput的平方除以样本的长度
RMS2 =绝对FFOutput平方的总和除以样本长度除以样本长度
我在这里测试我在450赫兹创建一个正弦波db = 50
dbimput = 50;
t = [ 0 : 1 : 10000];
f = 450;
Fs = 44100;
data =10^(dbimput/20)*sin(2*pi*f/Fs*t)';
FFTDATA = fft(data);
rms1 = sum(abs(FFTDATA /length(data)).^2)
rms2 = sum(abs(FFTDATA .^2) / length(data)) / (length(data) )
dblevel1 = 20 * log10(sqrt(rms1))
dblevel2 = 20 * log10(sqrt(rms2))
结果如下:
rms1 = 4.9976e+04
rms2 = 4.9976e+04
dblevel1 = 46.988
dblevel2 = 46.988