Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mastercheck

A command-line tool that measures the signal characteristics of audio masters using FFmpeg. It analyzes loudness, peak levels, dynamic range, DC offset, stereo correlation, and more — then presents the results with plain-language interpretation.

mastercheck never modifies your audio files. It is strictly read-only.

Built for recording and mastering engineers who want a quick, reliable second opinion on a master before delivery — or anyone who wants to understand what's going on inside an audio file.

Requirements

  • Python 3.11 or newer
  • FFmpeg and FFprobe on your PATH

Install FFmpeg:

Platform Command
macOS brew install ffmpeg
Debian / Ubuntu sudo apt install ffmpeg
Windows winget install Gyan.FFmpeg

Installation

pip install -e .
mastercheck --version

No third-party Python packages are required — mastercheck uses only the standard library.

You can also run it directly without installing:

python3 mastercheck.py song.wav

Usage

# Analyze a single file
mastercheck song.wav

# Analyze multiple files
mastercheck song1.wav song2.aif

# Analyze all WAVs in a directory
mastercheck *.wav

# Filenames with spaces or special characters
mastercheck "Untitled_2 #01.aif"

# Compare against a custom loudness target (default is -14 LUFS)
mastercheck --target-lufs -16 song.flac

# JSON output (for scripting or piping)
mastercheck --json song.wav

# CSV output (for spreadsheets or batch reports)
mastercheck --csv *.wav > report.csv

# Show FFmpeg commands and raw parsed data
mastercheck --verbose song.m4a

--target-lufs changes only the displayed comparison; it never alters audio.

ANSI color is emitted only to an interactive terminal and is disabled when the NO_COLOR environment variable is set.

Exit codes

Code Meaning
0 All files analyzed successfully
1 One or more files could not be analyzed
2 FFmpeg or FFprobe not found

Measurements that are unavailable in your FFmpeg build appear as N/A and do not cause a nonzero exit.

Understanding the output

Example (invented values)

mastercheck — Example Master.wav
  Path                       Example Master.wav
  Codec / container          PCM signed 24-bit / WAV / WAVE
  Sample format              48,000 Hz / 24-bit
  Channels                   2 / stereo
  Duration / size            03:42.180 / 61.03 MiB
  Integrated loudness        -12.40 LUFS
  Loudness range             5.80 LU
  True peak                  -0.70 dBTP
  Maximum sample peak        -1.10 dBFS
  RMS level                  -15.60 dBFS
  Crest factor               14.50 dB
  Peak / clipped count       3 / 0
  Samples >= 0 dBFS          No
  Channel imbalance          0.20 dB
  Stereo correlation (mean)  0.742
  Headroom to -1 dBTP        -0.30 dB
  Headroom to -2 dBTP        -1.30 dB
  Est. LUFS at -1 dBTP       -12.70 LUFS
  Difference from -14.0      1.60 LU
  DC offset
    Ch 1: linear 0.00001200, approx. -98.42 dBFS
    Ch 2: linear -0.00000900, approx. -100.92 dBFS
  Interpretation
    • Integrated loudness is 1.6 LU above the -14.0 LUFS target.
    • True peak is above -1.0 dBTP.
    • No meaningful DC offset was detected at the 0.001 linear threshold.
    • No samples reaching 0 dBFS were detected.
    • By broad mastering norms this falls within a typical wide range.
    • These measurements describe signal characteristics, not whether the master is good or bad.

How to read each measurement

Integrated loudness (LUFS)

The overall perceived loudness of the entire file, measured per ITU-R BS.1770. This is the single most important number for delivery compliance.

Context Typical target
Streaming (Spotify, Apple Music, YouTube) -14 LUFS
Broadcast (EBU R128) -23 LUFS
Broadcast (ATSC A/85, US) -24 LKFS
CD / loud modern masters -9 to -6 LUFS
Classical / acoustic / jazz -18 to -14 LUFS

If your master is significantly louder than the platform target, the platform will turn it down — and it may sound worse than if you'd mastered to that target in the first place.

Loudness range (LU)

How much the loudness varies over the course of the file. A higher LRA means more dynamic contrast.

Range Character
< 4 LU Heavily compressed / limited
4–8 LU Typical for pop, rock, electronic
8–15 LU Dynamic; common in jazz, classical, acoustic
> 15 LU Very wide dynamic range

True peak (dBTP)

The estimated maximum inter-sample peak after reconstruction. This matters because digital-to-analog converters can produce peaks between the discrete samples, causing distortion even when no individual sample hits 0 dBFS.

Guideline
Streaming delivery Keep at or below -1.0 dBTP
Broadcast (EBU R128) Keep at or below -1.0 dBTP
Broadcast (ATSC A/85) Keep at or below -2.0 dBTP

If true peak exceeds your ceiling, you need a true-peak limiter, not just a sample-peak limiter.

Maximum sample peak (dBFS)

The highest instantaneous sample value in the file. Unlike true peak, this only looks at the actual sample values and can miss inter-sample peaks.

  • 0.0 dBFS = the sample is at full digital scale.
  • A value above 0 dBFS is possible with floating-point formats and means the signal exceeds full scale.

RMS level (dBFS)

The average signal power. Combined with sample peak, this gives you crest factor.

Crest factor (dB)

The difference between the maximum sample peak and the RMS level: peak dBFS - RMS dBFS.

Range Character
< 6 dB Extremely compressed — brickwalled
6–10 dB Moderate compression, typical for loud masters
10–18 dB Healthy dynamics
> 18 dB Very dynamic or sparse (classical, solo instruments)

A low crest factor means the loud parts and the average level are close together — the file has been compressed or limited heavily.

Peak / clipped count

  • Peak count is how many times the measured peak value occurred in the file.
  • Clipped count is how many samples were at or above full scale (when reported by your FFmpeg build).

A nonzero clipped count doesn't prove audible clipping — full-scale samples can occur without audible distortion — but it's worth investigating.

Samples >= 0 dBFS

Whether any decoded sample reached digital full scale. "Yes" means at least one sample hit 0 dBFS. This is an indication to inspect, not proof of a problem.

Channel imbalance (dB)

The RMS difference between the loudest and quietest channel. In a well-balanced stereo master, this should be small (typically under 1–2 dB). A large imbalance might indicate a panning issue or a problem with the source.

Stereo correlation (mean)

The average phase relationship between the left and right channels (stereo files only).

Value Meaning
+1.0 Perfectly correlated (mono-compatible)
0.0 Uncorrelated (wide stereo, may lose content in mono)
Negative Out of phase (will cancel in mono — usually a problem)

Most well-produced stereo masters land between 0.3 and 0.9. Values near zero or below suggest phase issues that will cause problems on mono playback systems.

Headroom to -1 / -2 dBTP

How much gain you could add (positive) or would need to remove (negative) to bring the true peak to exactly -1 or -2 dBTP. A negative number means the file is already over that ceiling.

Est. LUFS at -1 dBTP

An estimate of what the integrated loudness would be if you applied simple linear gain to bring the true peak to -1 dBTP. This is not a second loudness measurement — it's arithmetic. But it tells you roughly where the file would land if you adjusted the level to meet a -1 dBTP ceiling.

Difference from target

How far the integrated loudness is from your comparison target (default -14 LUFS, adjustable with --target-lufs). Positive means louder than target; negative means quieter.

DC offset

A constant voltage offset in the signal. Most well-recorded audio has negligible DC offset (below 0.001 linear / roughly -60 dBFS). A significant DC offset wastes headroom and can cause clicks at edit points. If you see values above the 0.001 threshold, consider applying a high-pass filter or DC removal before mastering.

Interpretation section

mastercheck provides a plain-language summary at the bottom of each report. These notes use intentionally broad, conservative thresholds. They describe what the signal looks like — they do not judge whether the master is good or bad.

Measurement notes and limitations

  • Loudness is measured via FFmpeg's loudnorm=print_format=json filter. Results depend on your FFmpeg build's loudness implementation.
  • Sample statistics come from astats=metadata=1:reset=0. Field names vary between FFmpeg versions; the parser accepts common variants and reports N/A for absent fields.
  • Bit depth is shown only for PCM/lossless codecs. It is deliberately suppressed for lossy codecs (MP3, AAC, etc.) where the concept is misleading.
  • Crest factor is a file-level engineering estimate, not a perceptual loudness metric.
  • DC offset in dBFS is an approximation: 20 × log10(|linear offset|). Zero offset has no finite dB representation and displays N/A.
  • "Samples >= 0 dBFS" relies on decoded peak/clipped-sample fields. Floating-point sources can exceed 0 dBFS; integer decoders typically saturate. A full-scale sample is an indication to inspect, not proof of audible clipping.
  • Stereo correlation is the arithmetic mean of aphasemeter frame metadata — approximate, unweighted, and stereo-only.
  • Headroom is signed. A negative value means attenuation would be needed. The estimated LUFS at -1 dBTP is simple arithmetic, not a second loudness measurement.
  • Interpretation thresholds are intentionally broad and conservative. They characterize the signal, not the artistic or technical quality of a master.

Supported formats

Any format your FFmpeg build can decode: WAV, AIFF, FLAC, MP3, AAC, M4A, OGG, Opus, WMA, and many more.

Tests

python3 -m unittest discover -v

Unit tests mock FFmpeg subprocess calls. One integration test generates and analyzes a short sine tone — it automatically skips when FFmpeg/FFprobe are not available.

License

MIT

About

A conservative FFmpeg-powered command-line audio master analyzer

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages