Ahmed Doghri Logo Image
Ahmed Doghri

audiocatalog

The filename changed, the recording didn't. audiocatalog fingerprints audio locally and finds the duplicate a hash can't, proven on real files: a 128 kbps MP3 export scores 1.0000 against its source, a different track 0.7748.

audiocatalog acoustic fingerprint duplicate index
audiocatalog working browser demo

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

Tools Used

Python
Chromaprint
fpcalc
SQLite
Audio Fingerprinting
Music Information Retrieval
Hamming Distance
Docker