Custom LUFS Meter

Over the past week I’ve been making a LUFS meter (Loudness Units Full-Scale), following the calculations of the ITU-R BS.1770-2 technology guide. LUFS are used as an alternative measurement to RMS, that helped put an end to the loudness wars.

This process was a good exercise in object-orientated programming; because of the way the calculations are done, it’s good to keep nuggets of information assigned to object classes.

 

Let me give a quick overview of the way the calculations work:

First, the audio is filtered (EQ’d). You can use FIR or IIR for this, but it’s widely accepted that IIR is a lot cheaper on your CPU and the change of phase it produces does not affect the result. The filtering puts a low-cut and high-shelf on the spectrum, and is meant to roughly model the way the head-ear system affects audio.

After filtering, the audio is split into windows 400ms long, overlapping by 75% (=100ms), and the mean-square is calculated. Note this is not the root-mean-square (RMS, which is still a popular measurement for audio volume), but can still be thought of as a ‘power’ measurement.

Once each window has been measured for power, the conversion to loudness is done. This is where keeping the power comes in useful. To measure the integrated loudness (a measurement indicating the overall loudness throughout the audio), each of the frames goes through a 2-stage gating process, whereby frames under a certain loudness are rejected, and the power of the frame are not included in the average. You average the power rather than the loudness, because loudness can’t be averaged in a linear way (as it’s a logarithmic scale). It’s particularly important to get these calculations in the right order, as managing multi-channel audio can become quite cumbersome and confusing with so many similar variables, and so many different ways they can be combined. This confusion may be perpetrated (or indeed caused) by a potential order of operations error in the maths of the reference manual.

After that, it’s mostly fun and games of calculating other loudness measurements like loudness range, and histograms, and anything else you fancy.

 

I’ve added an interesting new measurement; something I’m calling angular distribution. This takes into account the angle of the monitors in a modelled environment (all can be a user-defined variable), and calculates on average where the audio is ‘coming from’. This is actually quite easy, only needing to convert the polar magnitude for each channel in a time frame to cartesian coordinates, and sum them.

You can see in the example below, that one of the EBU Test Files supplied has a bias to the left overall; especially towards the end.

Loudness envelopes in LUFS in the top section, with balance envelopes along the bottom. Histograms of each are aligned and scaled the same on the left. The angular distribution is on the bottom right, and displays the distribution and average of power, along with the position and channels that can be specified by the user.

 

In this 5.1 surround sound test file, you can see the angular distribution as it moves around L/R and F/B. More channels appear in the graph, plus the LFE marker. (LFE is not used in the measurement of loudness, but it’s good to indicate that it’s there.)

 

A close up of a 5.1 test file distribution.

This new measure, Spacial Distribution is designed to let mixers know if they have a bias – either in a section or overall – to the L/R, or F/B. It’s derived from the Short-Term Loudness measurement (with a window length of 3 seconds) – the same as Loudness Range (LRA) – so it should be considered reasonably stable.
%d bloggers like this: