14
$\begingroup$

I'm trying to calculate the loudness of an audio track I have stored in a buffer. The buffer contains PCM data of the signal and I want to get how 'loud' it is by using Root Mean Squared. I assume I can do this in the time-domain instead of having to switch to the frequency domain. What would be the pseudo-code for doing this?

Would I simply sample for one second (audio[0] - audio[44099], audio[44099] - audio[88199] etc..) and calculate the RMS of those values? So, for example, would I do this:

$$RMS = \sqrt{\frac{\text{audio}[0]^2 + \text{audio}[1]^2 + \text{audio}[2]^2.....\text{audio}[44099]^2}{44100}}$$

for each second?

$\endgroup$
  • 1
    $\begingroup$ There's a missing bracket in the expression above - I'd add it myself but edits need to be at least 6 characters apparently... $\endgroup$ – Paul R Sep 22 '11 at 7:39
  • 3
    $\begingroup$ @PaulR - You can add an <!-- html comment --> to work around the character restriction in the rare case that an otherwise perfect post has a tiny but very important error. This need occurs very rarely: there's usually more than 6 characters of improvement to be done. For example, when there are missing brackets, it's usually better to use the \sqrt{} and \frac{}{} constructs in TeX. $\endgroup$ – Kevin Vermeer Sep 22 '11 at 12:12
  • 1
    $\begingroup$ @Kevin: thanks for the tip - I will use your HTML comment suggestion in future. $\endgroup$ – Paul R Sep 22 '11 at 12:15
  • $\begingroup$ @PaulR - This has been discussed before: The restriction is intentional, designed to prevent incomplete or pointless edits (see a defense here), but has its opponents (see discussion here). $\endgroup$ – Kevin Vermeer Sep 22 '11 at 12:24
  • 4
    $\begingroup$ Note that RMS alone doesn't tell you loudness. Extremely low or high frequencies sound lower in volume than 3 kHz of the same RMS value. An A-weighting filter will give you a more accurate estimation. gist.github.com/148112 $\endgroup$ – endolith Sep 22 '11 at 14:26
12
$\begingroup$

Another thing is that the RMS value is not very well correlated with perceived loudness. You might want to consider calling it level or volume instead. There is something called equal loudness contours which quantifies how sensitive the ear is to one particular frquency compared to another frequency, see the Wikipedia article. These curves are level dependent. For instance, the ear is very sensitive to a 1kHz tone compared to a 100Hz tone, as shown in this image (horizontal axis is frequency in Hz):

equal loudness contours

One of the relative simple things you can do is to filter your PCM data with an inverted equal loudness curve. Or you can apply the standard A weighting, see the Wikipedia Weighting Filter article. Then you can compute the RMS value of the output of the equal loudness weighted filter.

$\endgroup$
  • $\begingroup$ I'm unclear how to go from the quesitoner's code to this. The question's example is summing the squares of the audio samples. The answer is talking about applying filter to frequencies so it seems like "filter your PCM data with an inverted equal loudness curve" isn't sufficient. You first have to have the value for each frequency, then you can figure how to apply the curve right? But that's a big step left out. $\endgroup$ – gman Feb 25 at 13:14
  • $\begingroup$ @gman The idea is to preprocess the audio with a filter and then use the result as in the question (RMS computation). I'm not 100% sure what you mean. Are you unsure how to do the filtering or perhaps the filter design? $\endgroup$ – niaren Feb 27 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.