File Hashes Miss Audio Identity
The same recording changes bytes the moment it's transcoded, retagged, renamed, or rewrapped in a new container. A cryptographic hash then treats one song as unrelated files.
audiocatalog calls the proven fpcalc binary, stores duration and raw Chromaprint fingerprints in SQLite, gates implausible duration pairs, and ranks likely acoustic duplicates.
Keep the Library Local
Directory indexing and matching run without uploading music or needing an API key. The CLI handles real files, while the API and workbench expose the comparison contract for inspection.
The Demo
Four catalog entries produce six pair comparisons, and exactly one crosses the threshold: differently named WAV and MP3 exports of the same recording, at 99.48% similarity.
Chromaprint is built for near-identical audio, not cover songs, remixes, or sample detection. Every candidate stays a review decision.
The Score Wasn't a Fixed-Width Metric, and the Demo Hid It
Chromaprint fingerprints are arrays of fixed 32-bit words. The similarity function normalized each word's bit difference by how many bits that particular number needed, not by the 32 bits every word actually occupies. That made the score depend on the numeric magnitude of the values, which has nothing to do with how two recordings sound.
The demo fixture hid it. Real fpcalc words come back in the hundreds of millions, about 30 bits; the hand-written fixture used values under 65,536, 8 to 16 bits. Under the old normalization, unrelated tracks scored 38 to 46%, and the published "real separation, not a near-miss" framing came from that bug plus unrealistic fixture values. With the correct fixed-32-bit metric they score 70 to 74%.
Auditing this page, I stopped arguing from fixtures and used real audio. ffmpeg renders a track, transcodes it to a 128 kbps MP3, and fpcalc fingerprints both. The export scores 1.0000 against its source. A different recording scores 0.7748. The 0.92 threshold separates them cleanly, a lossy re-encode survives fingerprinting intact, which is the whole point over file hashing, and unrelated tracks genuinely sit near 0.77 rather than near zero. That's now a committed test, and CI installs ffmpeg and Chromaprint to run it on Python 3.10 through 3.13.
Implementation Basis
Built on the open-source Chromaprint acoustic fingerprinting algorithm and its fpcalc command-line implementation. Read the Chromaprint documentation.
Try It
Needs fpcalc (Chromaprint) on your PATH:
git clone https://github.com/ahmeddoghri/audiocatalog && cd audiocatalog
pip install -e .
audiocatalog demo # four entries, one duplicate pair
audiocatalog index ~/Music catalog.db # fingerprint your own library
python -m unittest tests.test_real_audio -v # render, transcode, fingerprint, compare
audiocatalog serve # workbench on :8090