Expand description
The acoustic fingerprint of a file: what the audio is, not what it says.
§Why this exists
Every other identifier in this program comes out of the tags, and a badly
tagged file therefore cannot be identified at all: track03.mp3 with no
title and no artist is invisible to MusicBrainz, because there is nothing
to ask about. A fingerprint is computed from the decoded audio, so it
answers for a file whose tags say nothing, and it disagrees with a file
whose tags say the wrong thing.
§It is computed, not fetched — and stored beside the checksum
A fingerprint is Aède’s own conclusion about the bytes, like
crate::audit::integrity and unlike anything in sources.json: nobody
told us, we worked it out. So it lives on crate::model::AudioFile and
is carried across a rescan by the same size-and-mtime rule the integrity
verdict uses. What AcoustID answers when shown one is a different
thing entirely, and goes in the attributed layer where every other
source’s claim goes.
§Two ways to compute one, and why ffmpeg comes first
Chromaprint is the algorithm; there are two ordinary ways to run it.
- ffmpeg, when it was built with
--enable-chromaprint. Debian and Ubuntu build it that way, so on those machines this is no new dependency at all — Aède already requires ffmpeg forspectrumandcopy --compress. fpcalc, the tool Chromaprint itself ships. Canonical, and the one AcoustID’s own documentation names.
Homebrew’s ffmpeg does not have chromaprint, which this module’s first
version claimed it did — a guess written as a fact, corrected by a reader
pasting the configuration: line of a fresh brew install ffmpeg. On
macOS the answer is brew install chromaprint, and it is a small package.
The lesson is not about ffmpeg: a build option is a property of somebody
else’s packaging decision, and this program has no business asserting one
it has not seen. So the availability check asks the muxer list rather
than reading a version string, and the message names both ways out with
the right one first for each platform.
The two agree on the whole input, not just a preview. fpcalc normally
processes only the first 120 seconds; -length 0 removes that limit, matching
ffmpeg’s complete-input path. On a short file its ordinary default agrees
with ffmpeg -algorithm 1, byte for byte. fpcalc -algorithm 1 is a
different algorithm and answers something else — the measurement is beside
the ALGORITHM constant below.
ffmpeg is tried first because it is more likely to be there already; the fallback exists because “built with chromaprint” is not a promise anyone made. Neither is linked or vendored, exactly as ffmpeg is not: a checkout with neither installed builds, passes its tests, and says plainly what is missing.
§The duration is part of the question
AcoustID is asked for a fingerprint and a length, and refuses without
both — the length is how it tells a full track from an excerpt that
fingerprints alike. fpcalc prints it; ffmpeg’s muxer does not, so the
caller supplies it from the catalog, which read it out of the file’s own
header at scan time.
Structs§
- Fingerprint
- What one file’s audio amounts to, for a service that identifies audio.
Enums§
- By
- Which program produced a fingerprint, for a message to name.
Functions§
- find
- Whether either program is available, and which.
- missing
- What to tell somebody who has neither program, worded so they can act.
- of
- Computes the fingerprint of one file.
- read_
ffmpeg - Reads what ffmpeg’s chromaprint muxer wrote to its output.
- read_
fpcalc - Reads
fpcalc’s two lines:DURATION=andFINGERPRINT=.