Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6.5 KiB
@suaveplan/react-audio-fingerprint - React 19 surface for client-side audio fingerprinting (Shazam-style constellation algorithm) and identity matching. Consumes FFT/spectrogram primitives from @suaveplan/audio-analysis-spectrum so the audio family has a single FFT implementation. Universal fingerprint + matcher cores; React hook + accessible component on top.
React 19 surface for client-side audio fingerprinting and identity matching.
The package implements the classic Shazam-style constellation algorithm
(2D-peak detection + pair hashing + time-offset histogram matching) on top of
the FFT/spectrogram primitives from
@suaveplan/audio-analysis-spectrum
— there is exactly one FFT implementation across the audio family.
Documentation tree
- local-backend —
LocalBackendis the default implementation of theFingerprintBackendcontract that hooks and components depend on.…- local-backend —
LocalBackendis the default implementation of theFingerprintBackendcontract that hooks and components depend on.…
- local-backend —
- fingerprint-match-display —
<FingerprintMatchDisplay>renders the output ofFingerprintMatcher.matchas an accessible ranked list. Each row sho…- fingerprint-match-display —
<FingerprintMatchDisplay>renders the output ofFingerprintMatcher.matchas an accessible ranked list. Each row sho…
- fingerprint-match-display —
- memory-corpus —
MemoryCorpusis the defaultCorpusimplementation: aMap<string, Fingerprint>wrapped with aPromise-returning…- memory-corpus —
MemoryCorpusis the defaultCorpusimplementation: aMap<string, Fingerprint>wrapped with aPromise-returning…
- memory-corpus —
- error-codes — This module declares every error code that
@suaveplan/react-audio-fingerprintcan throw. Each code is registered thro…- error-codes — This module declares every error code that
@suaveplan/react-audio-fingerprintcan throw. Each code is registered thro…
- error-codes — This module declares every error code that
- audio-fingerprinter —
AudioFingerprinteris the entry point that turns anAudioDocumentinto a deterministic constellation fingerprint. I…- audio-fingerprinter —
AudioFingerprinteris the entry point that turns anAudioDocumentinto a deterministic constellation fingerprint. I…
- audio-fingerprinter —
- constellation — The constellation module converts a list of spectrogram peaks into a stable, hashable fingerprint by pairing each ancho…
- constellation — The constellation module converts a list of spectrogram peaks into a stable, hashable fingerprint by pairing each ancho…
- fingerprint-matcher —
FingerprintMatcherscores a query fingerprint against a corpus of candidate fingerprints using the classic Shazam tim…- fingerprint-matcher —
FingerprintMatcherscores a query fingerprint against a corpus of candidate fingerprints using the classic Shazam tim…
- fingerprint-matcher —
- peak-detector — The peak detector consumes a spectrogram (a sequence of FFT magnitude frames produced by `@suaveplan/audio-analysis-spe…
- peak-detector — The peak detector consumes a spectrogram (a sequence of FFT magnitude frames produced by `@suaveplan/audio-analysis-spe…
- use-audio-fingerprint —
useAudioFingerprint(source, options?)drives aFingerprintBackendoff a React-managedAudioDocumentand returns t…- use-audio-fingerprint —
useAudioFingerprint(source, options?)drives aFingerprintBackendoff a React-managedAudioDocumentand returns t…
- use-audio-fingerprint —
- test-setup — This file is loaded by
vitest.config.tsviasetupFilesso every test in the package runs against a consistent jest-…
Status
bootstrap landing — initial slice focused on:
- Six error codes via
defineCodes("REACT_AUDIO_FINGERPRINT", …). peak-detector,constellation,audio-fingerprinter.fingerprint-matcher(time-offset histogramming).memory-corpus(Map-backed, async-shaped, subscribable).local-backend(defaultFingerprintBackendrunning in-process).useAudioFingerprinthook (driver with abort + progress).<FingerprintMatchDisplay>component + stories.
Deferred to follow-up: IndexedDbCorpus, <AudioFingerprintUploader>,
<FingerprintVisualizer>, python-backend, __benchmarks__, integration +
purity + property + bundle-size tests.
Quick Start
import { decode } from "@suaveplan/audio-engine-browser/decode";
import {
LocalBackend,
MemoryCorpus,
FingerprintMatchDisplay,
useAudioFingerprint,
} from "@suaveplan/react-audio-fingerprint";
function MatchSurface({ file }: { file: File }) {
const [doc, setDoc] = useState<AudioDocument | undefined>(undefined);
useEffect(() => {
decode(file).then(setDoc);
}, [file]);
const { state, fingerprint } = useAudioFingerprint(doc);
return state === "done"
? <FingerprintMatchDisplay results={[]} />
: <progress />;
}
Algorithm
AudioFingerprinter composes three deterministic stages:
- Spectrogram (delegated to
@suaveplan/audio-analysis-spectrum). - 2D peak detection (
peak-detector) — local-max sweep above thenoiseFloor, capped atpeaksPerFrameper frame. - Constellation pair hashing (
constellation) — 32-bit packedbinA[12] | binB[12] | dt[8]over each anchor'sfanoutnext peaks inside atargetZoneSecwindow.
Matching is identical to the original Wang (2003) paper: build a 10 ms-wide
histogram of (candidateOffset − queryOffset) per shared hash, return the
heaviest bin's count as the score and its midpoint as the alignment offset.
License
MIT — see LICENSE at the repo root.