Loudness is the check most likely to surprise you, because it’s the one on a WaveLens report that can disagree with the others: a file can pass every other check and still read a different loudness, and by default that disagreement doesn’t fail the verdict.
What BS.1770 actually measures
BS.1770 isn’t a peak meter and it isn’t RMS — it’s the ITU-R standard broadcasters use for delivery specs. It applies a K-weighting filter, which weights frequencies roughly the way the ear does, and averages the result over the whole program, ignoring silence. The output is a single number in LUFS (loudness units relative to full scale) meant to track perceived loudness far better than a raw amplitude measurement does.
wavelens measures this on both the reference and the DUT. The Loudness card shows integrated loudness, loudness range, true peak, sample peak, and the loudest momentary and short-term readings for each file, with the difference between them. The integrated difference is judged against a tolerance of 0.5 LU by default.
Reference Only: shown, but not gating
By default the Loudness card is badged Reference Only. The reading is always there, and it doesn’t change the Overall Verdict, because a lossy codec or a processing chain can shift loudness or raise the true peak on purpose. WaveLens also compares the DUT’s true peak, an estimate of the waveform between samples, with the reference’s: the DUT may exceed it by at most 0.5 dB, so an identical copy always passes however loud the reference is. A fixed ceiling such as -1.0 dBTP is available through the config for delivery checks.
Add --loudness to make a Loudness failure count toward the verdict, or --no-loudness to skip the check for content without a meaningful loudness target.
A real example
Take a 1 kHz tone at -20 dBFS and compare it with the same tone 0.8 dB quieter:
$ wavelens analyze --ref tone_1khz.wav --dut tone_quieter.wav --out report.html
wrote report.html (overall: PASS)
The integrated loudness reads -23.0 LUFS for the reference and -23.8 LUFS for the DUT: a difference of -0.80 LU, past the 0.5 LU tolerance. Level Fidelity passes (its tolerance is about 1 dB) and so does Spectral Fidelity (1 dB), because a 0.8 dB difference is inside both. The Overall Verdict is PASS, and the Loudness card says Reference Only. Run the same comparison with --loudness and the verdict becomes FAIL.
That is the point of the check: it notices a whole-file level change the sample-by-sample checks tolerate, and leaves it to you to decide whether it should block anything.
Why a normalization step is the usual suspect
The most common cause of a Loudness difference isn’t distortion or a bad encode — it’s a delivery-chain step that adjusted overall level on purpose. A loudness normalization pass, a broadcast chain applying makeup gain, or a platform-specific loudness target (streaming services each have their own) can all move a file’s integrated loudness outside your reference’s tolerance while leaving every other check clean.
That’s not necessarily a bug in your pipeline — sometimes it’s the pipeline doing exactly what it was told to do. The report tells you it happened; deciding whether it should have happened is still a human call.
Where the check has blind spots
Loudness is a whole-file, integrated measurement — there’s no single “worst sample” the way there is for Bit-Exactness or Distortion, because the whole point is that it’s averaged over time. That has two consequences worth knowing:
- A file can pass Loudness and still have a problem in one section. A three-minute program with one badly clipped ten-second passage can land close enough to the reference’s integrated loudness for the check to pass — the clipping would show up in Artifact Detection or Distortion instead, not here.
- A file can fail Loudness while sounding fine. If your reference and DUT differ by a deliberate, known gain offset — say, a broadcast delivery spec that targets a different LUFS than your internal reference — that’s a real, correct difference, and the fix is adjusting your comparison, not chasing a phantom bug.
Reading it alongside Level Fidelity
Loudness and Level Fidelity look related but answer different questions. Level Fidelity tracks the DUT’s level against the reference sample by sample and fails when it drifts past its tolerance — built to catch a mismatched gain stage, an unintended normalize or a sustained level glitch as a local event. Loudness reports the integrated, perceptual result over the whole file. The 0.8 dB example above passes one and flags the other. In the other direction, a gain glitch lasting a few dozen milliseconds can trip Level Fidelity (it fails on a run of over-tolerance samples lasting at least 20 ms by default) without moving the integrated LUFS enough to matter.
If you’re triaging a report and only Loudness is marked, start by asking whether something in the chain was supposed to change overall level before you assume it’s a regression.
See it for yourself.
WaveLens compares a reference file against a processed copy and shows you exactly where they diverge — down to the sample — not just whether they still sound the same. One command, one report you can point at.