Question

The WebAudio API allows me to create an AnalyserNode which can give me access to the FFT-calculated spectrum of a set of audio samples (in either an unsigned byte array or float array -1 to 1). I am hoping I can use these values to calculate overall power (RMS) for that same set of samples.

I don't suppose it is as simple as taking the 32 window values, adding them up and dividing by 32. (A sine wave at 0dB would only fill up one window with some of the neighboring windows lit up slightly, whereas white noise at 0dB would fill up all the windows.) Is it possible to figure out the RMS value from the FFT/DFT output?

The reason I want to do this is that I need to build an efficient RMS meter. While I have access to the raw samples, processing them to even find a peak every buffer is too much overhead. The browser runs its FFT in native code, and is much more efficient than trying to do all these calculations in JavaScript. If I can calculate RMS from 32 FFT windows, that would be much more efficient.

Was it helpful?

Solution 2

Yeah is possible find RMS values from FFT, you need be sure that AnalyserNote not apply any Window (hanning, blackman, kaiser, etc) on the signal !

Two simple ways to get the same result:

RMS1 = summ of squared absulute FFOutput divided by length of samples

RMS2 = summ of absulute FFOutput squared divided by length of samples divided again by length of sample

I tested here I create a sine wave db = 50 at 450 hertz

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))

The Results for it are:

rms1 =  4.9976e+04
rms2 =  4.9976e+04
dblevel1 =  46.988
dblevel2 =  46.988

OTHER TIPS

For what it's worth -- I've got an app calculating RMS on anywhere from 12 to 20 tracks in a requestAnimationFrame loop that uses getByteTimeDomainData() and it's plenty fast. Between those calculations and drawing the results as meters on a <canvas> every 16.7ms, I consistently get 60fps in Chrome and Firefox.

Modern JS engines are pretty good at doing math reasonably quickly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top