question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Equal-loudness contour (ISO 226)

See original GitHub issue

What’s the best way to calculate loudness per frame? And can we make it a function?

TLDR;

Is it this?

S = abs(FFT(y))**2 # power spectrogram
weighting = A_weighting # weighting in dB
weighting = 10**(weighting/10) # weighting for power spectrogram 
S *= weighting # perceptually weighted power spectrogram
S = melspectrogram(S) # perceptual pitch distances
loudness = np.mean(S) # taking mean is ok, because not in dB
loudness = logamplitude(loudness) # convert to dB

Longer Explanation

Say we have a mel spectrogram

y = load(mp3)
S = np.abs(FFT(y)) # magnitude spectrogram
S = S**2 # power spectrogram
S = melspectrogram(S) # convert frequencies to mel scale

We can weight the perceived loudness of frequencies differently this way:

dB = logamplitude(S) 
perceptual_weighting = A_weighting * logamplitude(S)

But for loudness, we don’t want the mean of dB values:

loudness = mean(perceptual_weighting)

because dB adds up like this image

Can we use this equation to add up the dB frequencies to get loudness? It’s more expensive because of extra squaring and division.

OR

Can we weight the power spectrogram instead? Then taking the mean is fine, and we can calculate the dB from there:

perceptual_weighting = A_weighting * power
loudness = logamplitude(mean(perceptual_weighting))

image

But A_weighting is a logarithmic weighting of dBs, so we need to convert it for power spectrograms

weighting = 10**(A_weighting/10) # is this correct?

image

And now we can calculate the mean just fine:

loudness = np.mean(power * weighting)
loudness = logamplitude(loudness) # in db

This is great, because we also want to do weighting before we calculate the mel spectrogram, otherwise we lose frequency precision, which sometimes makes the subbass disappear, as in this example:

image image

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:2
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
keunwoochoicommented, Dec 8, 2016

Is A-weighting good enough for you? Otherwise you can take a look at https://github.com/keunwoochoi/perceptual_weighting, which is a perceptual weighting code based on ISO226. @bmcfee I once was thinking about PR this stuff. What do you think?

1reaction
bmcfeecommented, Dec 13, 2016

You need to square the rows, divide by the square of the reference, take the log10 of that, times 10.

Okay, that’s easy enough as well. Since you have a constant factor of p0**2 in the summation, you can factor it out of the log just like any other reference power.

power = np.abs(S)**2
p_mean = np.sum(power, axis=0, keepdims=True)
p_ref = np.max(power)  # or whatever other reference power you want to use
loudness = librosa.power_to_db(p_mean, ref=p_ref)

If you’re on the 0.4 series, replace the last line by

loudness = librosa.logamplitude(p_mean, ref_power=p_ref)

@bmcfee I once was thinking about PR this stuff. What do you think?

Not sure – what would the PR add exactly? Different weighting curves?

Read more comments on GitHub >

github_iconTop Results From Across the Web

ISO 226:1987 - Normal equal-loudness level contours
Specifies the relations existing between the sound pressure levels and frequencies of pure sinusoidal continuous tones in several conditions.
Read more >
ISO 226 Normal Equal-Loudness-Level Contour Calculator
The ISO 226 standard is the Acoustics Standard for normal equal-loudness-level contours. Normal equal-level-contours are often referred to as ...
Read more >
Normal equal-loudness level contours - ISO 226:2003 Acoustics
An equal-loudness contour is a measure of sound pressure, over the frequency spectrum, for which a listener perceives a constant loudness. The unit...
Read more >
Equal-loudness contour - Wikipedia
An equal-loudness contour is a measure of sound pressure level, over the frequency spectrum, ... The definitive curves are those defined in ISO...
Read more >
ISO 226 Equal-Loudness-Level Contour Signal - MathWorks
Generates a psychoacoustic equal loudness contour (curve) as described in ISO 226. 4.9. (21). 9K Downloads.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found