Making a VU meter

I'm asking this, not to find out if there's a better way, but to stimulate
discussion of new API features that would make it easier and more
efficient. (Though if you know of a better way under the current spec, I'd
be glad to hear it.)

In my case, I'm interested in implementing an on-screen VU meter that
"looks right" to an average user. It doesn't need to be mathematically
correct in any way.

The most obvious way is to use a ScriptProcessorNode to compute a
sum-of-squares of each successive buffer, and scale the result
appropriately. Optional improvements would be to apply a filter first
(remove DC, give more weight to the more audible frequencies) and to apply
a window function to each buffer.

I don't want to do that because of the inefficiency of ScriptProcessorNode.
So here's what I'm doing instead:

I square the signal by feeding it to a gain node and also to the gain
node's gain parameter. Then I lowpass filter it with a biquad filter. Then
I use a ScriptProcessorNode to grab just one sample from it each time I
need a value. (Maybe using an AnalyserNode to get time domain data would be
better, though I think how that works may be underspecified.)

Obviously it's not optimal, but it seems to work pretty well. I probably
should filter the signal a bit first, but I haven't bothered.

A slightly different problem would be if you wanted a real peak-to-peak
meter, so the user would know how close the signal was to clipping. I think
the only way to do that currently would be to do it all in a
ScriptProcessorNode.

I expect both will be needed pretty frequently in web audio apps. So should
there be a special feature for this? Or more general-purpose features that
make them easier to implement? Or am I missing an already-existing way?

One general-purpose feature that would make it relatively easy would be if
Float32Array had vector operations like "sum of squares" and "find
maximum/minimum value". I'm sort of surprised that it doesn't.

Received on Wednesday, 13 August 2014 00:02:59 UTC