Skip to content

About

Measure and hear what a lossy encoder did to your audio

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

CodecDelta

CI Python 3.11+ License: GPL-3.0 Platform: Windows

Measure what a lossy encoder actually did to your audio.

CodecDelta compares two encodes of the same recording — FLAC against Opus, an original against a YouTube rip, MP3 against AAC — and reports how much information was lost, where in the spectrum it went, and whether it is audible. It is also meant to answer the other common question from a single file with no reference: is this FLAC really lossless, or a transcode?

Version 1.0.0. The analysis engine, the desktop window, encoding with a bitrate sweep, shareable reports, blind ABX testing and library scanning work, and the app installs as a regular Windows program. What has not been verified is listed under Status.

Status

Layer State
core/ — ffmpeg discovery, PCM streaming, ffprobe inspection, settings, privacy, ABX statistics working
bitstream/ — Ogg/Opus, Vorbis, FLAC, MP3 container and codec metadata working
dsp/, align/ — sub-sample delay estimation and alignment validity working
coarse alignment, drift/PAL detection, "same recording?" verdict working (engine only)
single-pass comparison: per-band SNR (mid/side), linear vs codec-noise split, measured floor, clock-drift tracking working (engine only)
ERB masking model + NMR, anchor ladder verdict ("equivalent to Opus ~128 kbps"), referenceless lossy-source detection with calibrated thresholds working (engine only)
desktop window: analyze tab (compare, verify, ladder), English/Turkish working — v0.1.0
encode panel: 12 codecs discovered from the ffmpeg build, bitrate / quality / advanced options, never overwrites, encode-then-compare working
HTML report: single self-contained file, charts as inline SVG, light/dark, paths and user names removed and audited before writing working — v0.2.0
ABX blind test: aligned, level-matched, click-free switching (8 ms linear crossfade); fixed-n, sequential and practice modes; results that never read "no difference" working — v0.3.0
library scan: staged reference-free verification of a whole folder, resumable cache, filter, CSV export working — v0.4.0
bitrate sweep: one codec at 96–256 kbps, SNR curve, any point sent to ABX working — v1.0.0
match thresholds calibrated on real pairs (tools/calibrate_match.py) done — v1.0.0
packaging: one-folder Windows build, per-user installer, ffmpeg download script working — v1.0.0
threshold calibration from the user's own files not built (see below)

617 tests, ruff + mypy --strict clean, CI on Windows (including a clean-machine build of the packaged app).

Not verified yet: ABX has not been tried by ear, and playback over Bluetooth (where buffer underruns could spoil a test) has not been measured. The "different master" class in the match calibration is synthetic (EQ + compression): there were no real remaster pairs, so a different master only produces a warning, not a verdict. Library scan speed was measured on a warm disk cache only. setup-ffmpeg.ps1 was checked up to URL resolution and the capability test, not a full download. The packaged app was checked with its smoke test (window, report template, audio output), not with a full analysis inside the built executable. Calibrating the lossy-source thresholds from the user's own files is not built: the margins are narrow (about 120 Hz either side of the 20.75 kHz gate) and an automatic adjustment could add false positives without a way to check it.

Why this repository might be worth reading

The interesting part is not the feature list, it is the evidence trail. Several plausible ideas were implemented, measured, and then removed because the measurement disagreed:

  • FLAC blocksize does not identify an encoder. The same ffmpeg build produced 1024, 4096 and 4608 depending only on how the input was fed. 4096 is the value usually attributed to the reference encoder, so the rule would have mislabelled most modern ffmpeg output.
  • ffmpeg does not write a real LAME tag. The tag is in the right place with correct encoder delay, but every field from +9 to +20 is zero — so the lowpass value it is famous for is simply absent.
  • Reading an ffmpeg pipe with read(n) is 57× slower than readinto on Windows: 117.6 s against 2.1 s for the same 211 MB stream.
  • ffmpeg's default soxr resampler silently walls off the top of the band, which would have made the transcode detector flag clean files.
  • A phase-slope delay estimator failed on 79% of the input class this tool exists for. An adversarial audit measured it across 12,600 synthetic trials plus real music and real codec pairs; it was replaced, and the reasoning is written down rather than lost.
  • Dividing a correlation by the overlap count finds the wrong place half the time. Locating a 4 s excerpt inside a 30 s recording failed on 20 of 40 seeds, with errors up to 32 s. A true Pearson coefficient over the overlap: 40 of 40.
  • Seeking with ffmpeg -ss is not sample-accurate on every format. Measured against a full decode: exact on WAV, FLAC, Ogg Opus and MP3; off by 70–820 samples on M4A/AAC depending on position, a constant −128 on Ogg Vorbis, −48 on WebM Opus. Only measured formats take the fast path.
  • ffmpeg can requantise to 16 bits in the middle of a resampling chain. A 16-bit source round-tripped 44.1→48→44.1 kHz measured 81 dB instead of 148 dB until the chain was forced to floating point.
  • One tonality choice moves the noise-to-mask ratio by 15 dB. On the same near-transparent Opus file the median NMR read +5.8, −9.2 or +0.8 dB depending on how tonality was estimated. No verdict rests on an absolute NMR; the headline comes from a ladder of the user's own reference encoded at known bitrates, which is monotonic and self-validating.
  • The plan's transcode heuristics were partly backwards. On nine CD tracks and 117 transcodes: the CD itself has a steep knee at 19.6 kHz, per-frame cutoff variance runs the opposite way from the plan, and the side channel does not discriminate. What does: the median per-frame cutoff (real ≥ 21.2 kHz, every non-transparent codec ≤ 20.2 kHz).
  • ffmpeg's FLAC encoder takes its block size from the decoder feeding it. An MP3 decoded straight to FLAC gets 47-sample blocks and barely compresses (0.97), which had made compression ratio look like a strong lossy-source signal. It is not.
  • PAL speed-up cannot be measured by alignment anchors — so it is tested instead. Anchors lose lock beyond about 1000 ppm; PAL is 41,667 ppm. But PAL is not a continuous unknown, it is one entry in a short table, and testing each entry recovers it exactly.

These are recorded in docs/DECISIONS.md, with the numbers behind them. docs/SPEC-alignment.md is the contract for the alignment core, written before the code it describes.

What it does

  • Compare two files with automatic sample-accurate alignment (offsets, PAL speed-up, drift, polarity inversion, channel swaps), then a single-pass streaming analysis producing per-band SNR, lowpass cutoff, residual level, and a coherence decomposition separating linear differences (EQ, level, resampling) from real codec noise.
  • Judge audibility against an anchor ladder built from the user's own reference file: "the measured difference is equivalent to Opus at roughly 112 kbps for this track."
  • Verify a single file with no reference: per-frame cutoff statistics, knee sharpness, above-cutoff noise floor, joint-stereo collapse, bit-level entropy and container metadata, reported as readable reasons rather than one opaque score.
  • Encode and compare, with a bitrate ladder, to find how many kbps a particular track needs.
  • A blind ABX test with sample-aligned, level-matched, click-free switching and statistics that never report "no difference" from a failed test.
  • Batch-scan a library for files whose signatures are consistent with a lossy source.

Video files are accepted as input and never have their video decoded — a 20 GB concert MKV costs the same as its audio track alone: probe and decode were verified at 1242× realtime on a real 684 s YouTube m4a.

Install

Download or build CodecDelta-<version>-win64.zip, extract it, and run:

powershell -ExecutionPolicy Bypass -File install.ps1            # Start menu shortcut
powershell -ExecutionPolicy Bypass -File install.ps1 -Desktop   # plus a desktop shortcut

It installs for the current user into %LOCALAPPDATA%\Programs\CodecDelta (no administrator rights). install.ps1 -Uninstall removes it; settings in %APPDATA%\CodecDelta stay unless -Purge is added. If no ffmpeg is found, setup-ffmpeg.ps1 (in the same folder) downloads the BtbN build into %LOCALAPPDATA%\CodecDelta\bin, checks its digest and that it has soxr, and the app finds it on the next start. Alternatively: winget install yt-dlp.FFmpeg.

To build the zip yourself from a development setup: powershell -ExecutionPolicy Bypass -File tools\build.ps1. It ends by starting the built executable with --smoke-test and refuses to zip a build that fails it.

Requirements (development)

  • Windows 10/11
  • Python 3.11+ (developed and tested on 3.14)
  • ffmpeg and ffprobe on the system — discovered automatically
uv venv --python 3.14 .venv
uv pip install -r requirements-dev.txt
.venv\Scripts\python -m app            # open the window
.venv\Scripts\python -m pytest         # run the tests

After setup, CodecDelta.bat starts the window without a console. Drop one or two audio files onto it to load them as reference and test; CodecDelta.bat --console keeps a console open to show errors if the window does not appear.

ffmpeg

CodecDelta does not bundle or redistribute ffmpeg; it locates an ffmpeg already present on the system (its settings folder, a bin folder next to the executable, %LOCALAPPDATA%\CodecDelta\bin, winget, PATH — always requiring ffprobe in the same folder). setup-ffmpeg.ps1 downloads it from its publisher on request. ffmpeg is separately licensed and its own terms govern that binary.

License

GNU General Public License v3.0 or later — see LICENSE.

You may use, study, modify and redistribute this software. If you distribute a modified version, you must release its source under the same licence. Commercial use is permitted; making it closed-source is not.

About

Measure and hear what a lossy encoder did to your audio

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages