GitHub - astralisone/Selecta · GitHub
Skip to content
astralisonePublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Track2Mix

Which of your tracks actually mixes with this one?

DJ library intelligence for Rekordbox, Traktor and Serato. Track2Mix reads your collection (or scans a folder of music), decodes every track on your own machine, scores it for energy, and then — given any anchor track — hands you the harmonically and rhythmically compatible shortlist, ranked. Export it as an M3U8 for Rekordbox, an NML playlist for Traktor, or a Serato crate.

Runs entirely offline. No account, no upload, no server.

Two ways in

  • CLI (track2mix) — import a library or scan a folder, query the resulting DB, export Rekordbox / Traktor / Serato playlists from the shell.
  • GUI (track2mix-tauri) — Import / scan a Rekordbox XML, Traktor collection, Serato library or crate, or any folder; search and filter the analysed library, click a track to get harmonically / BPM-compatible suggestions, tick the ones you want, and Export playlist for Rekordbox (M3U8), Traktor (NML) or Serato (crate). Imports go into the open database.

Run the GUI in development:

bun install        # first time
bun tauri dev

The GUI auto-opens ./library.db from the project root if it exists; otherwise click Open DB in the title bar.

A release build installs the CLI as track2mix; the examples below use cargo run so they work from a checkout.

What this proves (or disproves)

  1. Rekordbox XML is parseable and round-trippable. If this chokes on your real library, the whole product is in trouble.
  2. Pure-Rust audio decoding handles your formats. MP3, FLAC, WAV, AIFF, M4A via Symphonia.
  3. Feature extraction is fast enough. Target: < 2 seconds per track on an M-series Mac, parallelized.
  4. The computed energy values correlate with your ear. This is the real test. If a liquid roller and a neurofunk banger score the same, the features are too coarse.

Usage

# Rekordbox: File → Export Collection in xml format
cargo run --release -- analyze --xml ~/rekordbox.xml --limit 500

# Real-world Rekordbox libraries contain a lot of streaming / stale /
# moved entries — do a fast coverage check before committing to a
# long full-library run:
cargo run --release -- analyze --xml ~/rekordbox.xml --dry-run

# If a directory moved (files still there, just at a new path), remap it:
cargo run --release -- analyze --xml ~/rekordbox.xml \
    --path-map '/Volumes/OldName/music=/Volumes/NewName/music' \
    --skip-analyzed

Other sources

analyze takes exactly one source:

Flag Source
--xml rekordbox.xml Rekordbox: File → Export Collection in xml format
--nml collection.nml Traktor: the collection file (~/Documents/Native Instruments/Traktor x.y/collection.nml) or an exported .nml playlist
--serato ~/Music/_Serato_ Serato: the _Serato_ folder, its database V2 file, or a single .crate
--dir ~/Music Any folder, scanned recursively. Title, artist, genre, BPM and key come from the files' tags, falling back to Artist - Title.ext file names
cargo run --release -- analyze --dir ~/Music/DnB --skip-analyzed
cargo run --release -- analyze --nml ~/Documents/Native\ Instruments/Traktor\ 3.11.1/collection.nml
cargo run --release -- analyze --serato ~/Music/_Serato_

Sources can be mixed in one database. Tracks are matched by file path, so a file imported from Rekordbox and again from a folder scan stays one row (later imports refresh its metadata and features).

Notes:

  • --skip-analyzed makes re-runs cheap — only newly-resolved tracks get decoded.
  • Tracks with paths like /v4/catalog/tracks/... are Beatport streaming entries, not local files; they are dropped and reported in the coverage summary.

Then explore the library without touching SQL:

# Top / bottom N by any extracted feature, optionally filtered by genre.
cargo run --release -- top --by energy --limit 20
cargo run --release -- top --by energy --genre liquid --asc

# Harmonically + BPM-compatible neighbours around a reference track.
# Matches Camelot / classical / open-key notation in the Rekordbox "Tonality" field.
cargo run --release -- compat "circles around" --bpm-tol 3
cargo run --release -- compat "my favourite track" --any-key   # BPM-only

# Snapshot of what's in the database.
cargo run --release -- stats

Every subcommand accepts --db /path/to/library.db if you keep multiple libraries.

Exporting to Rekordbox, Traktor or Serato

top --export, compat --export and the export subcommand pick the format from the file extension:

Extension App Import it with
.m3u8 Rekordbox (and most others) File → Import Playlist
.nml Traktor — carries BPM, key and genre right-click Playlists → Import Playlist
.crate Serato — must be saved in _Serato_/Subcrates restart Serato; the crate appears
cargo run --release -- compat "circles around" --export ~/Desktop/circles.nml
cargo run --release -- export ~/Music/_Serato_/Subcrates/Liquid.crate --sub-genre liquid
cargo run --release -- export ~/Desktop/everything.m3u8

Serato crates can only hold files on the same drive as their _Serato_ folder; tracks on other drives are skipped and listed. Traktor addresses boot-disk files by volume name, detected automatically on macOS — pass --traktor-volume if you export elsewhere for a Mac whose disk isn't called "Macintosh HD".

Direct SQL still works if you want ad-hoc queries:

sqlite3 library.db "SELECT name, artist, bpm, tonality, energy FROM tracks ORDER BY energy DESC LIMIT 20"

The validation checklist

Run against 500 of your own tracks, then:

  • Speed. Total time under 10 minutes? Per-track under 2 seconds on release build?
  • Coverage. How many tracks failed? If > 5%, investigate why (moved files, exotic formats, encrypted M4A from iTunes).
  • Energy sanity. Sort by energy descending. Top 20 should be your hardest tracks. Bottom 20 should be your intros/ambient/deep tracks. If it's random noise, the weights in features.rs need retuning.
  • Genre coherence. Group by genre, plot energy distribution. Liquid DnB should cluster lower than neurofunk. Tech house should cluster mid. If genres overlap completely, features aren't discriminating.
  • Harmonic mixing sanity check. Pick a track you know mixes well with X. Query for tracks in compatible keys (same Camelot number, ±1, relative major/minor) within ±3 BPM. Do the suggestions actually mix?

Known limitations vs. a shippable v1

  • Linear resampling. Fine for MIR, not for audio playback. Swap rubato if you ever play back.
  • Onset detection is a simple flux-spike heuristic. For real use, port a proper algorithm (complex domain or superflux). Aubio has a well-tested one.
  • No key detection. We trust the key from your DJ app (or the file's tags for folder scans). If you want to verify or re-detect, that's a chromagram + key profile correlation — another 100 lines.
  • No embedding generation yet. Once features look good, the next step is composing a text profile per track (metadata + feature descriptors like "dense, bright, dynamic") and embedding it.
  • Energy weights are hand-tuned. For a real product, collect labels (users rating sets they built) and learn the weights.

What comes next if this works

  1. Write a Rekordbox XML playlist (with cue points) in addition to M3U8, proving the round-trip.
  2. Add text embedding generation via the OpenAI or Voyage API, store vectors in a sibling vectors table using sqlite-vec.
  3. Build a tiny TUI that takes a natural-language prompt and returns a candidate playlist.
  4. Port to Tauri v2 as a sidecar binary or compile the analyzer as a library and call it from the Rust backend directly.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages