Sliding Window Averaging Headaches/Integrated Loudness Measurement

J F's icon

I'm currently building a loudness metering system for a project and pulling my hair out trying to figure what's going wrong. I've written it at data rate and signal rate in codebox in Gen~, but both aren't showing consistently correct values (but do sometimes) and I'm not sure why. Ultimately that tells me either implementation isn't quite right, but I don't know why. It doesn't really matter whether it's at signal rate or data rate, but I'd like to get at least one of them working properly.

I'm following the classifications outlined in BS 1770 (page 6). I've also looked at this code implementation which is open source in hopes it can assist, but I'm not sure where mine is going wrong.

I need to take a 400ms window of the overall audio with a 75% overlap. Then gate twice - once filtering everything below -70, then a second gate that has a relative threshold that's -10 below the average of the first gate.

I know I'm missing something, but not sure what. I believe the issue lies in the sliding window and how I'm handling the sample accumulation/removal of old values as it passes through the two gates. Or maybe it's something else entirely.

I'm hoping someone with more knowledge and fresher eyes can help me figure this out!

Max Patch
Copy patch and select New From Clipboard in Max.

Roman Thilenius's icon

if you are squaring and then use average~ in rms mode, you are squaring twice.

Roman Thilenius's icon

no wait, bipolar is default.

but about the different results, i think that is just the test setup: the windowing is running freely, so when you press "start" again, the signal you analyze is a bit different from last time.

one would have to add some kind of reset function for the averaging as well as for the snapshot~.

the test audio is quite short, you would probably not notice differences in a complete song.

J F's icon

Yeah it's only averaging in bipolar in both implementations. In the case of test window, I did this for posting purposes, but my main testing is in Ableton and nearly all audio is showing close to correct results, but not reliably so. I've been mainly focusing on the Gen~ patch though.

With all meters there is a degree of variability especially with this stuff since the implementation can be varied, but it shouldn't be varying as much as the one I posted, so I'm not sure which part is handled incorrectly.

Roman Thilenius's icon

i am getting a constant -11.3 for program. but the short time has a relatively high variance, which seems unacceptable. try to use 20 loops of that sample instead of one, maybe the result will be better. (i forgot to do it myself before)

oh and in case it applies... snapshot can jitter at very long vectorsizes. this also could be part of the problem since the material (drumloop) has such a high dynamics.

it is lovely how you calculate the filter yourself - like i had to do it 20 years ago in max 4, but you know that biquad would support butterworth topology on the fly?

J F's icon

This sample was just for easy posting, but it doesn't matter what the audio is because it's not consistently taking correct values. It should play through the sample once and produce accurate results regardless of looping (or at least consistent results).

In both cases, is the 400ms window with 75% overlap being handled correctly? I feel like it's not because the gating aspect is pretty straightforward, but the overlap is what is throwing me off.

Roman Thilenius's icon

is the 400ms window with 75% overlap being handled correctly?

never understood this part of the paper either, since it came out. not sure if it is my english or my lack of common math knowledge.

if you take it literally it makes the most sense; four windows of 400ms length, each with 100ms offset to its neighbours.

J F's icon

Attached is updated code. I think the sliding window is handled correctly because it currently accumulates over 400ms, then every time the overlap counter hits 100ms, it calculates the average from the running sum. The issue I'm finding is with this:

This page has excellent test signals to measure the accuracy of LUFS meters in addition to explanations about each. In the case of the below code, everything checks out (seemingly) correctly until the relative threshold test. The signal when dragged into the code should read between -7.7 to -8.2 LUFS as every other meter I have tested does. The code below shows -11.3 which is way off. According to the description for test 5, the relative threshold should be -23.5 thus filtering out everything below that, but it's letting those values in which contributes to the incorrect average for that section. I don't know what aspect is implementing incorrectly for it to be doing that.

PrismSound_QualisAudio_LM5.wav

Max Patch
Copy patch and select New From Clipboard in Max.

Roman Thilenius's icon

a sinewave is for many things not the ideal test material. do you experience similar offsets with other things, too?

J F's icon

Agreed, but in this case taking these signals made for testing LUFS meters has produced verifiable results when comparing other meters to what I’m trying to do. The offsets experienced here are the kind I’m consistently getting. Sometimes it’ll show correct results, but not consistently even though it seems like all the code is set up correctly… pulling my hair out over this cause it all seems relatively straightforward