CoProducer Measure a mix
Studio console and headphones

Reference · 21 August 2026 · 7 min

How to use a reference track when mixing: match the loudness first, then compare

NoDAW Labs · Lacquer Vol. 02

To use a reference track well, turn it down to the same loudness as your mix before you compare anything. A louder track almost always sounds better, so an unmatched A/B tells you nothing. Once they’re matched, compare tonal balance, how loud the vocal sits and how big the low end is. Copy the balance. Don’t copy the reference’s peak level, because plenty of commercial masters are hotter than streaming will ever play them.

“Make it sound like that song” is the most common note in music, and the hardest one to act on by ear. You flip to the reference, it sounds huge, you flip back, your mix sounds small, and you start adding EQ and limiting until something breaks. Most of that frustration is a measuring problem, and it’s easy to fix.

What is a reference track for?

A reference is a finished song you trust, used as a ruler. It tells you where your mix sits on the things you’ve stopped hearing after hours in the session: how bright the top end is, how much low end there is compared with everything else, and how forward the vocal sits.

It isn’t a template. Your song has a different key, arrangement and singer, so matching it number for number would be strange even if you could do it. What you want is to be in the same neighbourhood on the big things, so nothing about your mix sounds wrong next to it on a playlist.

Pick one or two references in the same genre and tempo range, released recently enough that they reflect how records in your lane sound now. Get the best file you can: a purchased WAV, FLAC or high-bitrate download. A stream has already been turned up or down and run through a codec, which is a whole topic of its own (don’t match a streamed reference).

Why does the reference always sound better?

Because it’s louder. When two versions of the same thing are a couple of dB apart, we tend to hear the louder one as fuller, brighter and more exciting. That’s simply how our hearing works at different levels; the equal-loudness contours show that our sensitivity to bass and treble changes with level. So a reference that’s 5 dB hotter than your mix wins every blind test before you’ve listened for anything specific. It’s the same trap as mixing at a different volume every day.

The fix is to measure both in integrated LUFS (loudness units relative to full scale, measured the ITU-R BS.1770 way) and turn the reference down by the difference. Then switch between them quickly, a few seconds each, at the same spot in the song. Now whatever difference you hear is a real difference.

How do I compare my mix to a reference by the numbers?

Here’s a small script that does the measuring and writes a level-matched copy of the reference for you. It needs Python 3, NumPy and FFmpeg. It reads loudness, loudness range and true peak with FFmpeg’s ebur128 filter, then compares tonal balance in six bands. Each band is shown relative to that file’s own total energy, so it doesn’t matter which file is louder.

#!/usr/bin/env python3
"""ref_compare.py: compare your mix with a reference track by the numbers, at matched loudness.
Usage: python3 ref_compare.py MIX REFERENCE [--write-matched]
Prints integrated loudness, loudness range (LRA), true peak and peak-to-loudness ratio (PLR) for both
(FFmpeg ebur128, ITU-R BS.1770 / EBU Tech 3342), then tonal balance per band relative to each file's
own total, so the comparison doesn't depend on which one is louder. With --write-matched it writes
reference_matched.wav: the reference turned down (or up) to your mix's loudness, for honest A/B listening.
Your files are only read. Needs: Python 3, NumPy, FFmpeg on PATH."""
import re, subprocess, sys
import numpy as np

BANDS = [("sub", 20, 60), ("bass", 60, 250), ("lowmid", 250, 800), ("mid", 800, 2500), ("pres", 2500, 6000), ("air", 6000, 18000)]

def meter(path):
    err = subprocess.run(["ffmpeg", "-hide_banner", "-nostats", "-i", path, "-af", "ebur128=peak=true", "-f", "null", "-"],
                         capture_output=True, text=True).stderr
    g = lambda pat: float(re.findall(pat, err)[-1])
    return dict(I=g(r"I:\s+(-?[\d.]+) LUFS"), LRA=g(r"LRA:\s+([\d.]+) LU"), TP=g(r"Peak:\s+(-?[\d.]+) dBFS"))

def balance(path):
    raw = subprocess.run(["ffmpeg", "-v", "error", "-i", path, "-f", "f32le", "-ac", "1", "-ar", "48000", "-"],
                         capture_output=True, check=True).stdout
    x = np.frombuffer(raw, np.float32).astype(np.float64)
    P = np.abs(np.fft.rfft(x)) ** 2; f = np.fft.rfftfreq(len(x), 1 / 48000)
    tot = P[(f >= 20) & (f < 18000)].sum()
    return [10 * np.log10(P[(f >= lo) & (f < hi)].sum() / tot + 1e-12) for _, lo, hi in BANDS]

def main(mix, ref, write=False):
    a, b = meter(mix), meter(ref)
    for d in (a, b): d["PLR"] = d["TP"] - d["I"]
    print(f"{'':12}{'LUFS':>8}{'LRA LU':>8}{'TP dBTP':>9}{'PLR dB':>8}")
    for name, d in (("your mix", a), ("reference", b)):
        print(f"{name:12}{d['I']:8.1f}{d['LRA']:8.1f}{d['TP']:+9.1f}{d['PLR']:8.1f}")
    gain = a["I"] - b["I"]
    print(f"\nreference is {-gain:+.1f} LU vs your mix. To A/B fairly, play it at {gain:+.1f} dB.")
    if b["TP"] > -1.0:
        print(f"reference true peak {b['TP']:+.1f} dBTP is over -1 dBTP: copy its balance, not its peak.")
    need = b["I"] - a["I"]
    print(f"matching its loudness would push your mix {need:+.1f} dB: true peak {a['TP'] + need:+.1f} dBTP before any limiting")
    print(f"\ntonal balance, dB relative to each file's total (loudness-independent)")
    ba, bb = balance(mix), balance(ref)
    print(f"{'band':8}{'Hz':>12}{'mix':>8}{'ref':>8}{'diff':>8}")
    for (n, lo, hi), x, y in zip(BANDS, ba, bb):
        flag = "  <-- look here" if abs(x - y) >= 3 else ""
        print(f"{n:8}{f'{lo}-{hi}':>12}{x:8.1f}{y:8.1f}{x - y:+8.1f}{flag}")
    if write:
        subprocess.run(["ffmpeg", "-v", "error", "-y", "-i", ref, "-af", f"volume={gain:.2f}dB", "-c:a", "pcm_f32le", "reference_matched.wav"], check=True)
        print(f"\nwrote reference_matched.wav ({gain:+.1f} dB, 32-bit float so nothing clips)")

if __name__ == "__main__":
    args = [x for x in sys.argv[1:] if not x.startswith("--")]
    main(*args, write="--write-matched" in sys.argv)

To show it working without anybody’s real song, we generated two synthetic 30-second beats at 140 BPM. The “reference” is bright and driven hard into a simple limiter, the way plenty of commercial masters are. “Your mix” is the same kind of beat, darker, with a low shelf boosting the bottom and no limiter. This is what the script printed:

$ python3 ref_compare.py refs/mix.wav refs/reference.wav --write-matched
                LUFS  LRA LU  TP dBTP  PLR dB
your mix       -14.0     0.2     -3.6    10.4
reference       -8.6     0.3     +1.6    10.2

reference is +5.4 LU vs your mix. To A/B fairly, play it at -5.4 dB.
reference true peak +1.6 dBTP is over -1 dBTP: copy its balance, not its peak.
matching its loudness would push your mix +5.4 dB: true peak +1.8 dBTP before any limiting

tonal balance, dB relative to each file's total (loudness-independent)
band              Hz     mix     ref    diff
sub            20-60    -0.8    -1.0    +0.1
bass          60-250    -7.8    -7.7    -0.1
lowmid       250-800   -23.0   -18.6    -4.4  <-- look here
mid         800-2500   -28.3   -23.3    -5.0  <-- look here
pres       2500-6000   -29.4   -25.0    -4.3  <-- look here
air       6000-18000   -25.3   -21.0    -4.4  <-- look here

wrote reference_matched.wav (-5.4 dB, 32-bit float so nothing clips)

How do I read the comparison?

Start at the top. The reference is 5.4 LU louder than the mix. Before you change a single EQ band, that alone explains why it sounded bigger. The script wrote reference_matched.wav, the reference turned down 5.4 dB to −14.0 LUFS, the same as your mix. Use that file for listening.

Next, the reference’s true peak. Its highest sample sits at −0.1 dBFS, which looks safe on a normal peak meter, but its true peak is +1.6 dBTP. True peak estimates the level of the real waveform between the samples, which is what a converter or a lossy encoder has to reproduce. Spotify’s guidance asks for masters below −1 dBTP, and below −2 dBTP for masters louder than −14 LUFS. This reference fails both. That’s fine for a reference you listen to, but it’s not something to copy (more on why in true peak is what codecs clip).

The last line of the top section shows what happens if you try anyway. Pushing your mix up 5.4 dB to match the reference’s loudness would put your true peak at +1.8 dBTP before any limiter touched it. You’d need several dB of limiting just to make it legal, and you’d be squashing your song to match a number that streaming will turn down again.

Then the tonal balance table. The sub and bass rows match within a dB, but everything from 250 Hz up sits 4 to 5 dB lower in your mix than in the reference. Because each column is relative to its own total, that doesn’t mean your mids are quiet in absolute terms. It means the low end is taking too big a share of the mix. That’s the classic home-studio balance problem, and it’s why a mix can sound dull and small next to a reference at the same loudness.

What should I copy from a reference, and what should I leave alone?

Copy the relationships, because those survive every playback system:

Leave these alone:

What’s a good reference workflow in the session?

  1. Put the reference on its own track routed straight to the output, so your mix bus processing doesn’t touch it.
  2. Measure both and turn the reference down to your mix’s integrated loudness. Re-check whenever your mix level changes a lot.
  3. Loop the same section of both songs, usually the first chorus, and switch every few seconds.
  4. Write down the one or two biggest differences. Fix those, bounce, and measure again.
  5. Stop referencing once the big things match. Past that point you’re mixing someone else’s song.

That last step matters. References are best used for a few minutes at the start of a session and again at the end, not as a constant comparison that keeps you second-guessing.

How do I use a reference track when mixing?
Pick one or two finished songs in the same lane as yours, get the best files you can, and drop them into your session on their own track that skips your mix bus. Turn the reference down until it measures the same integrated LUFS as your mix, then flip between them for a few seconds at a time. Compare tonal balance, how loud the vocal sits and how big the low end is. Don’t chase its peak level.
Should I match the LUFS of my reference track?
Match it for listening, not for your master. Turn the reference down to your mix’s loudness so you can compare fairly. Many commercial references are mastered louder than streaming plays them back, and some have true peaks over 0 dBTP. Copy the balance and keep your own master under −1 dBTP.
Why does my mix sound worse than the reference?
Often it’s just quieter. A track that’s a few dB louder usually sounds fuller and brighter to us, so an unmatched A/B is rigged before you start. Level-match first. If it still sounds worse, look at the biggest tonal balance difference, which is usually too much low end or a buried midrange.
Can I use a YouTube or Spotify rip as a reference?
It works for rough balance, but the levels are wrong. A streamed or ripped file has been turned down or up by the platform and run through a lossy codec, so its loudness and peaks no longer match the master. Buy or download a lossless file when you can, and measure both on the same meter.

A free one-pager

The checklist we run before every release.

Loudness, true peak, mono, tails, export settings and the metadata basics, on one page. Leave your email and it opens straight away, or read it here first. No email needed for that.