# FLAC_Detective — reference
[← Back to the README](https://github.com/Guillain-RDCDE/FLAC_Detective#readme)
---
## 📊 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.

*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 **12 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.
**What the numbers describe.** Every accuracy figure this project publishes was measured on
*direct* transcodes — lossy audio re-encoded straight to FLAC, nothing in between. Transcodes
that passed through a **mastering chain** before reaching a disc (levels, limiting, press —
what wild compilations actually sell) are a different population: on 34 owner-attested wild
MP3-sourced tracks, v1.11.4 signaled **8.8 %**, v1.12.0 — after repairing four admission
gates that had been calibrated on lab material — signaled **50.0 %**, and v1.13.0 — after
feeding the depth instrument to the cells the container check consults — signals **70.6 %**
and convicts its first two, both owner-attested fakes corroborated by independent evidence
families. **False convictions remain zero across every version and population**, which is
the half of the design that held throughout. Every number here was pre-registered before its
measurement and scored on hash-verified bytes; the remaining gap is real, measured, and
being worked on rather than blurred.
→ Every rule explained: **[Technical Details](technical-details.md)**.
---
## ⚙️ Usage
```bash
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 # also high-bitrate MP3 and Apple AAC (slower)
flac-detective /music --advanced # show the plumbing: scores, cutoff, per-rule detail
flac-detective /music --progress-events - # stage-by-stage progress as NDJSON, for another program
```
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](user-guide.md)**.
### 🖥️ Prefer a window to a command line?
```bash
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 or 32-bit container. This
is a separate axis from the transcode verdict — reported as `hires_verdict`
(`GENUINE_HIRES` / `UPSAMPLED` / `PADDED_DEPTH` / …) in the text report, 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. 32-bit integer FLAC (FLAC 1.4+) is analysed too.
Install options & upgrading
```bash
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. Since v2.4.0 the tool does it for
you when asked (it checks PyPI once a day and tells you when a newer release exists):
```bash
flac-detective --update # or answer "y" when a run ends with the notice; GUI: the Install button
pip install -U flac-detective # the same thing by hand
flac-detective --version
```
Use it from Python or beets
**Python API:**
```python
from flac_detective import FLACAnalyzer
result = FLACAnalyzer().analyze_file("song.flac")
print(result["verdict"]) # AUTHENTIC, WARNING, SUSPICIOUS, or FAKE_CERTAIN
```
**[beets](https://beets.io) plugin** — triage transcodes without leaving your workflow:
```bash
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 →](https://github.com/Guillain-RDCDE/FLAC_Detective/blob/main/ml/README.md)**