# How to get the volume level from PCM audio data?

I have a decoded PCM audio data obtained from the Web Audio API.

I'd like to generate a chart that represents the volume level (perceived by humans) over time.

volume|
level|    ******
|   *      *                           **
|  *        *                         *  **
|**          *      ***              *
|             ** * *   *            *
+---------------*-*-----************------+--- time
0                                        30s
audio is             and quiet
loud here            here


Here is my current approach, given I have an audio composed of 6 channels.

To calculate the volume level at time T:

1. For every channel, calculate the RMS value of 200ms window (44100 * 0.2 = 8820 samples, in my case). Time T will be in the middle of the window (ignore the edges).

2. Calculate the average of the 6 values obtained in step #1.

I get something like this:

Is this a reasonable approach to get the volume level?

Would translating RMS to dB (step #3: Calculate 20*Log_10(step #2)) produce a more accurate chart?

What would be some appropriate methods for smoothing / noise removal?

• Why would you ignore the negative samples? They're being squared by the RMS calculation. – jaket Jan 3 '18 at 5:37
• @jaket Good point! No good reason for ignoring the negative samples. Question updated. – Misha Moroshko Jan 3 '18 at 6:59
• 200 ms are relatively large windows. I'd suggest using smaller windows and averaging only 2-3 windows. Overlapping windows would also improve accuracy. – dsp_user Jan 3 '18 at 8:57
• Additionally, you maybe want to look at weighting filters link if you are interested in perceived loudness – user6522399 Jan 4 '18 at 10:09
• You can't really chart the perceived loudness this way. First of all, you only get relative loudness from your audio file - you cannot say how loud the original sound really was. Second, peception of loudness depends on the frequency content. The human ear responds less well to low and high frequencies than it does to the typical voice frequencies. There are response curves that you can use to mimic the response of human hearing. I've forgotten the name of the standard, but look for "Psophometric weighting." – JRE Jan 4 '18 at 11:59

There are two separate issues behind your question: the duration of the measurement and the algorithm used to do the actual metering. In the audio jargon, the term used for the perceived level measurement is loudness metering.

# Time duration

The first issue you need to tackle is the length of the window used to do the metering. Usually, in audio they can be divided in three classes:

• Momentary, which gives a loudness level that varies quickly over time (usually a few hundreds of milliseconds)
• Short term, which winows of a few seconds
• Integrated, which gives a loudness level on the whole audio file from beginning to end

The actual values for the lengths of the windows varies from the specification, but this EBU tech note specifies a duration of 400 ms for momentary, 3 s for short-term and the whole duration of the file for integrated, of course. Moreover, if you do live tracking of the metering, there is the issue of the refresh rate of the measurement as well, but you may want to set this aside in your case. Finally, it may be useful to note that a rectangular window is used, contrarily to other cases in audio (short-term fourier transform for instance).

# Loudness metering

To accurately represent the perceived level, you will need something more complex than a simple RMS measurement. Various methods have been developed over time, from the simple A-weighting mentioned in the comments (which is just filtering before computing the RMS value), to the LUFS (Loudness Units relative to Full Scale) measurement specified in the ITU-R BS.1770-4 recommendation. The latter is a complex algorithm, but it provides methods for measuring perceived loudness in a multi-channel audio file, which is your case.