first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
# @suaveplan/audio-fingerprint - Python-tier high-accuracy audio fingerprinting service (librosa chromagram + scipy 2D peak detection + constellation hashing + Jaccard matching), exposed as a FastAPI REST API, with a typed TypeScript HTTP client (PythonAudioService) for browser/Node consumers.
High-accuracy audio fingerprinting service. The package is dual-runtime: a Python FastAPI backend (`src/fingerprint.py` + `src/api/app.py`) implements chromagram-based Shazam-style fingerprinting on top of librosa and scipy, and a TypeScript HTTP client (`src/client/python-audio-service.ts`) exposes that service to browser and Node consumers. It is the high-accuracy backend behind the browser-tier `@suaveplan/react-audio-fingerprint` React surface.
<!-- begin:auto-docs -->
## Documentation tree
- [api](./src/api/app.md) — `api/app.py` wraps the `AudioFingerprinter` core into a FastAPI HTTP service. It is the network surface the TypeScript…
- [app](./src/api/app.md) — `api/app.py` wraps the `AudioFingerprinter` core into a FastAPI HTTP service. It is the network surface the TypeScript…
- [client](./src/client/python-audio-service.md) — `PythonAudioService` is the typed HTTP client TypeScript and browser callers use to talk to the Python-tier audio finge…
- [python-audio-service](./src/client/python-audio-service.md) — `PythonAudioService` is the typed HTTP client TypeScript and browser callers use to talk to the Python-tier audio finge…
- [fingerprint](./src/fingerprint.md) — The `AudioFingerprinter` class is the Python core of `@suaveplan/audio-fingerprint`. It implements the full Shazam-styl…
<!-- end:auto-docs -->
## Install
```bash
# TypeScript client side
bun add @suaveplan/audio-fingerprint
# Python service side (creates the suaveplan-audio-fingerprint micromamba env)
cd packages/media/audio/audio-fingerprint
micromamba create -f environment.yml -y
```
## Quick start
```bash
# Start the FastAPI service on port 8000
micromamba run -n suaveplan-audio-fingerprint \
uvicorn src.api.app:app --host 0.0.0.0 --port 8000
```
```ts
import { PythonAudioService } from "@suaveplan/audio-fingerprint";
const client = new PythonAudioService({ baseUrl: "http://localhost:8000" });
const health = await client.healthCheck();
const fingerprint = await client.fingerprint({ file: someAudioFile });
const match = await client.match({
query_file: clipFile,
reference_file: corpusFile,
min_matches: 20,
});
```
## Architecture
The package is split into two runtimes that share the wire format documented in `src/types/audio-fingerprint.types.ts`:
- **Python tier** — `src/fingerprint.py` implements the `AudioFingerprinter` class (chromagram extraction via librosa, 2D peak detection via `scipy.ndimage.maximum_filter`, constellation-map hashing, Jaccard matching with median time-offset estimation). `src/api/app.py` wraps it in a FastAPI service with `GET /`, `POST /fingerprint`, and `POST /match` endpoints, plus CORS for `localhost:3000` and `localhost:5173`.
- **TypeScript tier** — `src/client/python-audio-service.ts` is the typed HTTP client. It depends only on the platform `fetch`, `FormData`, and `AbortController` APIs and runs unchanged in browsers and modern Node runtimes.
## Algorithm
1. **Audio loading** — mono downmix and resample to 22050 Hz (configurable).
2. **STFT** — `n_fft=2048`, `hop_length=512` (configurable).
3. **Chromagram** — 12-bin pitch-class profile (configurable) via `librosa.feature.chroma_stft`.
4. **Peak detection** — 2D local maxima on the normalised chromagram using a `(3, 5)` neighbourhood maximum filter; peaks below `peak_threshold` are discarded.
5. **Constellation map** — each peak is paired with the next `fan_value` peaks in time-sorted order.
6. **Hashing** — each pair becomes a `(hash(f1, f2, dt), t1, dt)` tuple.
7. **Matching** — set intersection on hashes, Jaccard similarity for confidence, median per-hash time offset for alignment.
## Modules
- [`src/fingerprint.py`](./src/fingerprint.py) — `AudioFingerprinter` core. Docs: [`src/fingerprint.md`](./src/fingerprint.md).
- [`src/api/app.py`](./src/api/app.py) — FastAPI service. Docs: [`src/api/app.md`](./src/api/app.md).
- [`src/client/python-audio-service.ts`](./src/client/python-audio-service.ts) — typed HTTP client. Docs: [`src/client/python-audio-service.md`](./src/client/python-audio-service.md).
- [`src/types/audio-fingerprint.types.ts`](./src/types/audio-fingerprint.types.ts) — wire-format type definitions (re-exported from `@suaveplan/audio-fingerprint/types`).
## Testing
```bash
# TypeScript bridge tests + 100/100/100/100 istanbul coverage
bunx turbo test:coverage --filter=@suaveplan/audio-fingerprint
# Python service tests + 100% line+branch pytest coverage
cd packages/media/audio/audio-fingerprint
micromamba run -n suaveplan-audio-fingerprint pytest
```
Both gates hard-fail below 100% coverage. The Python test suite is not currently wired into `turbo`; it must be invoked standalone via `micromamba`. See for the rationale and the proposed follow-up to wire a `turbo` task once the broader Python tooling story lands.
## See also
- `@suaveplan/react-audio-fingerprint` — the React 19 sibling that runs the browser-tier fingerprinter and, via this package's `python-backend` integration, consults this service for high-accuracy matching.
- `@suaveplan/audio-analysis-spectrum` — the universal FFT/spectrogram primitives the browser-tier fingerprinter is built on.