Bit-Exactness asks whether every sample in the DUT equals the matching sample in the reference. It compares the decoded audio, not the file around it — so when two files that look identical fail, the samples really are different, even if by an amount nobody could hear.
What doesn’t matter: the container
A WAV file carries more than audio: LIST and bext chunks, cue points, timecode, padding bytes, header fields. WaveLens reads the audio samples out of each file and compares those, so none of that changes a Bit-Exactness result. Two files with identical samples pass even if a DAW stamped a different timestamp into each, or one of them was re-saved with its chunks in a different order. (If you want to know whether two files are byte-identical, a checksum answers that. Bit-Exactness answers whether the audio is.)
Time offset doesn’t matter either. WaveLens aligns the two files before any check runs, so extra silence at the start of the DUT doesn’t push every sample out of step.
What does matter: the samples themselves
- Bit-depth conversion. Going from 24-bit to 16-bit rounds every sample onto a coarser grid. The result sounds the same, but almost no sample keeps its exact value.
- Dither. Any tool that requantizes — even a resave through certain audio applications — may add dither by default: a tiny, intentional noise floor that avoids quantization artifacts. It is a real, measurable difference, not a bug, and it fails Bit-Exactness every time.
- Sample-format changes. Integer to floating point and back is not always lossless. When either file is floating point, Bit-Exactness measures the size of a difference in 24-bit steps.
- Any gain change, however small. A normalize pass or a 0.1 dB trim changes every sample.
- Resampling. Even a round trip to another sample rate and back rarely returns the original values.
A real example
Take one 1 kHz tone and generate it twice, once at 24-bit and once at 16-bit (with wavgen, a free tool that ships separately), then compare the two:
$ wavgen --mode tone --tone 1000:-20 --samplerate 48000 --bitdepth 24 --duration 5 -o tone_24bit.wav
$ wavgen --mode tone --tone 1000:-20 --samplerate 48000 --bitdepth 16 --duration 5 -o tone_16bit.wav
$ wavelens analyze --ref tone_24bit.wav --dut tone_16bit.wav --out report.html
wrote report.html (overall: PASS)
Bit-Exactness · 230,000 of 240,000 samples differ — the 16-bit samples sit on a coarser grid than the 24-bit ones, so nearly every value is off by a rounding step.
Spectral Fidelity, Level Fidelity, Artifact Detection, Distortion and Loudness all pass (the integrated loudness reads -23.0 LUFS on both sides), and the Overall Verdict is PASS, because Bit-Exactness doesn’t gate the verdict unless you ask it to.
Telling a real problem from an expected difference
None of this makes Bit-Exactness a bad check. It is doing exactly what it should: telling you the samples aren’t identical. The mistake is treating that FAIL, on its own, as evidence of an audible problem. Two things help you triage:
- Look at the other checks. If Spectral Fidelity, Level Fidelity, Artifact Detection, Distortion and Loudness are clean and only Bit-Exactness is marked, the most likely explanation is one of the causes above. If Artifact Detection or Spectral Fidelity is marked too, something happened to the audio itself.
- Look at how widespread the difference is. A conversion, dither or small gain change touches almost every sample, as in the example above. A defect confined to one part of the file, such as a dropout, shows up as differences in just that stretch.
See Bit-Exact vs. “close enough” for when the strict check is actually the one you want, and reach for --bitaccuracy (see Bit-Exactness vs. Bit Accuracy) when you want a measured “how close,” not just a strict yes/no.
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.