Skip to main content

FLAC Detective — lossy transcodes hiding inside lossless files: MP3, AAC, Vorbis, Opus

🎵 FLAC Detective

A lossy file renamed to .flac looks lossless, weighs lossless, and fools every player you own. It can't fool the arithmetic the encoder left behind — and this reads it for you.

MP3, AAC, Vorbis and — partially — Opus, through three independent kinds of evidence. A conviction needs two of them to agree.

PyPI version PyPI Downloads CI Docs License: MIT

Find the fake FLACs in your music library.

A lossy codec throws away the top of the spectrum and never gives it back. FLAC Detective reads each file, spots the fingerprints that loss leaves behind, and tells you which files are real and which are fakes.

pip install flac-detective       # needs Python 3.10+
flac-detective /path/to/music    # scan a file or a whole folder

Every file gets a verdict, like a traffic light:

✅ AUTHENTIC      real lossless         → keep it
❓ WARNING        borderline            → give it a listen
⚠️  SUSPICIOUS     probably a transcode  → likely a fake
❌ FAKE_CERTAIN   definitely a fake     → replace it

The scan only reads your files — it never changes anything.

🟢 New to all this?Start Here — the 5-minute beginner's guide No command line, no jargon. From "what is this?" to "I checked my music".


📊 See why a file was flagged

Add --format html and you get a single self-contained page: a triage table sorted worst-first, plus a spectrum plot for every flagged file. The MP3 "cliff" — a sharp drop well below the real ceiling — is right there for the eye, with the detected cutoff marked.

FLAC Detective HTML report — triage table and per-file spectrum cliffs

Three transcodes at different MP3 bitrates show the wall falling at different frequencies (96 kbps ~11 kHz, 128 kbps ~16 kHz, 160 kbps ~17.5 kHz); the authentic file runs full-range.


🔍 How it works

An MP3 re-saved as FLAC is lossless as a container, but the audio already passed through a lossy codec — and that leaves fingerprints. The clearest is the spectral cliff: MP3 discards everything above a bitrate-dependent frequency, so the spectrum falls off a wall where a real recording keeps going.

FLAC Detective scores each file with 10 heuristic rules built around that idea (cutoff frequency, MP3-bitrate signatures, silent-passage energy) plus protection rules so genuine vinyl rips, cassette transfers and naturally quiet recordings aren't flagged. An optional CNN sharpens borderline verdicts, and a frame-alignment rule reads the fingerprint MDCT quantisation leaves behind — the one signal that survives at 256–320 kbps, where the spectral cliff has nothing left to show. The rules sum to a 0–150 score:

Verdict Score What to do
AUTHENTIC ≤ 30 keep it
WARNING 31–54 borderline — check manually
⚠️ SUSPICIOUS 55–85 likely a transcode
FAKE_CERTAIN ≥ 86 definitely transcoded

The guiding principle is "protect authentic files first": a false alarm on real music is worse than missing a borderline fake. Treat AUTHENTIC as "no evidence of transcoding", not a guarantee.

→ Every rule explained: Technical Details.


⚙️ Usage

flac-detective /path/to/music              # scan a folder
flac-detective                             # interactive (prompts for a path)

flac-detective /music --format csv  -o triage.csv   # spreadsheet, worst-first
flac-detective /music --format html -o report.html  # visual report (see above)
flac-detective /music --deep                        # catch high-bitrate AAC/Opus/Vorbis (slower)
flac-detective /music --advanced                    # show the plumbing: scores, cutoff, per-rule detail

By default the output is easy mode — a plain-language verdict and a recommended action per file ("Almost certainly a fake — the sound stops dead at ~16 kHz, the wall of a 128 kbps MP3. → Replace it."). Add --advanced for the scores, cutoff frequencies and per-rule reasoning. The desktop GUI has the same Advanced toggle.

Analyses FLAC, WAV, ALAC (.m4a) and APE (.ape) — codec-agnostic, and a lossy .m4a is correctly rejected (the real codec is probed, never trusted by extension).

→ Full guide & every flag: User Guide.

🖥️ Prefer a window to a command line?

pip install "flac-detective[gui]"
flac-detective-gui

A desktop app (PySide6): choose a folder or drag it in, watch the progress bar, then triage a sortable, colour-coded verdict table — click any file to see its spectrum with the detected cutoff marked and the reasons for its verdict. Export to HTML/CSV/JSON.

🎚️ It also catches fake hi-res

Beyond lossy-as-lossless, FLAC Detective flags files sold as high-resolution that aren't: 44.1/48 kHz upsampled to 96/192 kHz (a hard spectral cliff with digital silence above it), and 16-bit audio padded into a 24-bit container. This is a separate axis from the transcode verdict — reported as hires_verdict (GENUINE_HIRES / UPSAMPLED / PADDED_DEPTH / …) in the CSV report, the GUI and the Python API. A genuine 96 kHz recording that simply rolls off early reads GENUINE_HIRES, not a false alarm.

Install options & upgrading
pip install flac-detective                 # base
pip install "flac-detective[ml]"           # + optional CNN (Rule 12)
pip install "flac-detective[gui]"          # + desktop GUI (flac-detective-gui)
docker pull ghcr.io/guillain-rdcde/flac_detective:latest   # or Docker (amd64 + arm64)

pip install does not upgrade an existing install — use -U to get the latest release:

pip install -U flac-detective
flac-detective --version
Use it from Python or beets

Python API:

from flac_detective import FLACAnalyzer

result = FLACAnalyzer().analyze_file("song.flac")
print(result["verdict"])   # AUTHENTIC, WARNING, SUSPICIOUS, or FAKE_CERTAIN

beets plugin — triage transcodes without leaving your workflow:

pip install "flac-detective[beets]"
# in config.yaml:  plugins: flacdetective

beet flacdetective                          # analyse & tag the whole library
beet ls flacdetective_verdict:FAKE_CERTAIN  # list the certain fakes

Stores flacdetective_verdict and flacdetective_score on each item; an optional auto: yes analyses files as they're imported.


🤖 The ML side: a case study worth reading

Rule 12's model went through a real R&D saga, written up as a learning resource: a false-positive audit over 11 234 real FLACs, four instructive dead-ends, a debunked "AUC 0.99" caught by cross-validation, and a twist where a "fundamental limit" turned out to be an artifact of listening in mono — fixed by going stereo. Real-world specificity on 11 234 authentic FLACs climbed from 80 % to 95 %.

📖 Read the ML detective story →


📚 More


Licensed under the MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flac_detective-1.11.2.tar.gz (15.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flac_detective-1.11.2-py3-none-any.whl (15.5 MB view details)

Uploaded Python 3

File details

Details for the file flac_detective-1.11.2.tar.gz.

File metadata

  • Download URL: flac_detective-1.11.2.tar.gz
  • Upload date:
  • Size: 15.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for flac_detective-1.11.2.tar.gz
Algorithm Hash digest
SHA256 cb666e144d031592f4e3badcf12baac5b79d6520173810c5b744feb4621cb16b
MD5 3e6aec461915eb2c422c85de039864da
BLAKE2b-256 21c25dec117c37ccae564d5bdb90d1b23b3e6b9f250565b513e476070e0bd7ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for flac_detective-1.11.2.tar.gz:

Publisher: release.yml on Guillain-RDCDE/FLAC_Detective

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flac_detective-1.11.2-py3-none-any.whl.

File metadata

  • Download URL: flac_detective-1.11.2-py3-none-any.whl
  • Upload date:
  • Size: 15.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for flac_detective-1.11.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2586068571b1d647ed1179bd268f6575722653bac5c7ae0e3e37ab20a394d364
MD5 31a2a83dabf0a868255913ee63fa789d
BLAKE2b-256 631125a36b87eb7e97216c0f5574548449b7ccf522e829b7949341333613a99a

See more details on using hashes here.

Provenance

The following attestation bundles were made for flac_detective-1.11.2-py3-none-any.whl:

Publisher: release.yml on Guillain-RDCDE/FLAC_Detective

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.13.8

2 files

1.13.0

2 files

1.12.0

2 files

1.11.4

2 files

1.11.3

2 files

This release

1.11.2 This release

2 files

1.11.0

2 files

1.10.1

2 files

1.10.0

2 files

1.9.0

2 files

1.8.0

2 files

1.7.0

2 files

1.6.1

2 files

1.6.0

2 files

1.5.0

2 files

1.4.0

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.1

2 files

1.0.0

2 files

0.16.1

2 files

0.16.0

2 files

0.15.3

2 files

0.15.2

2 files

0.15.1

2 files

0.15.0

2 files

0.14.1

2 files

0.14.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.1

2 files

0.10.0

2 files

0.9.11

2 files

0.9.7

2 files

0.9.6

2 files

0.9.5

2 files

0.9.1

2 files

0.9.0

2 files

0.8.0

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.8

2 files

0.6.7

2 files

0.6.6

2 files

0.6.5

2 files

0.6.4

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page