There are two main reasons to want to get the "volume":
- detect when the source "clips" - i.e. the absolute value of the signal goes over a preset level, usually very near 1.0, where it will start clipping.
- give the user a feel for how loud their signal is.
The reason I list these separately is because the first requires that you process every sample - because you might miss a short transient otherwise. For this, you'll need to use a ScriptProcessor
node, and you'll have to iterate through every sample in the buffer inside onaudioprocess
to look for absolute values above your clip level. You could just determine the RMS level then, too - just sum the squares of each sample, divide by N and take the square root. DO NOT render from within onaudioprocess
, though - set values that you access on requestAnimationFrame
.
You can also use an AnalyserNode
to do the level detection, and just average out the data, kind of like what the other answer does with getAverageVolume
. However, the other answer is NOT a good use of ScriptProcessor
- in fact, it's doing no processing of the script node at all, not even passing the data through, it's just using it like a timer callback. You would be FAR better served by using requestAnimationFrame
as the visual callback; don't ever set layout or visual parameters from inside onaudioprocess
like this, or you're begging to thrash your audio system. If you don't need clip detection, just do the getByteFrequencyCount
/getAverageVolume
from above on an AnalyserNode
(but you should minimize the number of bands in the Analyser - 64 is the minimum, I think), and you should pre-allocate and reuse a Uint8Array
rather than allocating it each time (that will amp up the garbage collection).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…