This is a learning project, no professional solution.
A tool for automatically discovering, labeling, and clustering large collections of audio samples. The tagger extracts acoustic features, runs clustering, and provides a rich web interface for manual review, tagging, UMAP visualization, and natural language semantic search.
- Discovery: Fast concurrent scanning of large sample libraries (stat checks, metadata extraction).
- Labeling Pipeline: Extracts neural embeddings using PANNs (CNN14) and applies fast folder heuristics.
- Machine Learning: Trains a custom logistic regression classifier head on human judgments and applies it across the whole database.
- Semantic Search: Uses CLAP text-to-audio models for natural language queries like "warm analog bass" or "vinyl breakbeat."
- Web UI: Includes an interactive UMAP projection map, built-in media player, search results with inline rating, and task management.
- REAPER Integration: A dockable in-DAW panel (
reaper/) for CLAP semantic search — preview hits and insert them at the edit cursor without leaving the DAW.
You can install the package in editable mode:
pip install -e .- PANNs (CNN14) — downloaded automatically on the first
sample-tagger labelrun to~/panns_data/(~300 MB, fetched from Zenodo by panns_inference). No manual step. - CLAP — manual download required: get
music_audioset_epoch_15_esc_90.14.pt(~2 GB) from the LAION-CLAP checkpoint collection and place it at~/clap_ckpt/music_audioset_epoch_15_esc_90.14.pt. Loaded via LAION-AI/CLAP (HTSAT-base, no fusion).
The stages below build on each other; run them in order for a new library.
All commands default to ./samples.db (--db to override); the editable
taxonomy and ML parameters live in labels.db next to it.
sample-tagger discover <path_to_samples>Fast stat/metadata scan; registers every audio file. Resumable — re-run it after adding new packs.
sample-tagger label -j 4Decodes each file and writes duration, oneshot/loop detection, BPM/key,
path-based instrument priors, and 2048-d PANNs (CNN14) embeddings — the
acoustic features everything downstream (similarity, map, classifier) uses.
First run downloads the CNN14 checkpoint (~300 MB) to ~/panns_data/.
Budget ~1 GB RAM per worker; this is the slow pass (hours for six-figure
libraries, especially on network/FUSE mounts).
sample-tagger-ml clap-embed samples.db --fullEmbeds every file with CLAP and exports the sidecars (samples.clap.npy /
.paths) that power text search and the concat feature set. Also a long
full-library decode pass. Requires the CLAP checkpoint in ~/clap_ckpt/
(see Models).
sample-tagger-web # http://localhost:8765UMAP map (/map — run "Update map" once to project), text search, review
queue, settings. Everything below can be driven from here.
The classifier trains on your labels, so it needs some truth first:
- On the map or review page, click a label to set the dominant instrument; shift+click toggles additional labels (multi-label sets are the training truth, top-1 columns are projections of them).
- The taxonomy is editable in-app (
labels.dbis the source of truth); labeling rules live indocs/taxonomy.md. - A few hundred labels spread across classes is enough for a first model; quality beats quantity — see the propagation caveat below.
Use the gold panel on the review page to sample candidates and freeze a
held-out validation slice. Frozen files are excluded from training and give
you an honest macro-F1 per run (stored in the metrics table), so you can
tell whether more labeling/retraining actually helps.
sample-tagger-ml pipeline samples.db # = export → train → predictExports features + labels, trains one-vs-rest logistic regressions on the
embeddings (per-class calibrated thresholds), and writes predictions back to
the DB (model_labels set + model_instrument/model_conf top-1). Also
launchable from the web UI. Individual steps are available as
sample-tagger-ml export|train|predict, and clap-eval benchmarks CLAP
zero-shot against the trained head on the gold set.
ML parameters live in the ml_params table of labels.db (values are
JSON-encoded). The most important one is the feature set:
# panns (default) | clap | concat — concat[PANNs|CLAP] scores best
sqlite3 labels.db "UPDATE ml_params SET value='\"concat\"' WHERE key='feature_model'"concat requires steps 2 and 3 to be complete.
Retraining is cheap (minutes, no audio decoding). Loop:
- Review page → "disagree" queue surfaces samples where the model and heuristics conflict — label the ones the model gets wrong.
sample-tagger-ml pipeline samples.db- Compare gold macro-F1 against the previous run.
Caveat from experience: bulk-propagating labels across confusable class boundaries (snare vs clap, synth vs pad) injects correlated noise and can lower the score — prefer fewer, certain, hand-checked labels.
sample-tagger sim "path/or/filename-substring.wav" -k 20To view the map, search semantically, manually review classifications, and control the pipeline:
# Start the web UI server on port 8765
sample-tagger-webreaper/sampletagger_search.lua is a ReaScript that talks to the running web
server: type a query ("dusty vinyl breakbeat"), click a hit to preview it
(optionally loudness-normalized), double-click to insert it at the edit cursor.
Also does acoustic "more like this" (Similar), pagination, and client-side
instrument/type/duration filters.
Requirements on the DAW machine: ReaImGui
and SWS (both via ReaPack), plus curl in
PATH (ships with Windows 10+/macOS).
Setup:
- Copy the
reaper/folder to the DAW machine (both.luafiles must stay together). - REAPER → Actions → New action → Load ReaScript →
sampletagger_search.lua, then dock the window. - Click ⚙ and set the server URL. File access:
download(default) — samples are fetched over HTTP into<REAPER resource>/SampleTagger/cache/.direct— if the DAW machine has the same sample library mounted, set the remote/local prefixes (e.g./home/user/pcloud/DAW/Samples→P:\DAW\Samples) and inserts reference the mount directly.
Config persists in <REAPER resource>/SampleTagger/config.json. Note: the first
search after a server restart takes a few seconds while the CLAP model loads.

