# 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. ![FLAC Detective HTML report — triage table and per-file spectrum cliffs](https://raw.githubusercontent.com/Guillain-RDCDE/FLAC_Detective/main/assets/html_report_demo.png) *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)**