Human writes the score, machine executes the mix — a programmatic DJ mixing engine.
Repo: cyborgdj
Links: Two Libraries Out of a Grown Tool — the extraction and its lessons (2026-10-22), dj-render — the render library CyborgDJ’s engine became (2026-10-22), dj-score — the analysis library, Eyes and Ears for LLMs — the translator goals (G1–G6) whose text surface this engine executes, DJ Set 1, Set Mastering, Camelot From YouTube, Programmatic DJ Mixing Tools, The Cyborg Model, DJ EQ Blending Technique, Multi-Genre & Wide-BPM Mixing, DJ Blend Tool Test Plan, dj-score — shared analysis library; replaces the forked scripts/{spectral_collision,export_rekordbox,analyze_track}.py and the stale camelot/ copy, CyborgDJ as Controller — decided 2026-10-21: CyborgDJ becomes the controller; dj-score is its tool surface
A programmatic DJ mixing engine that reads structured JSON specs and produces continuous mixed audio. Creative decisions (track selection, transition design, EQ strategy) stay with the human; mechanical execution (beat-matching, time-stretching, crossfading, rendering) is automated.
The mix lives in a JSON spec file — change a bar number, re-render, listen, repeat.
Cleaned up by the dj-score migration’s step 7 audit (the repo’s AUDIT.md). The repo holds
code only: tracks live in the shared, local-only music library (../music); mix projects (specs, renders, notes)
live in music/CyborgProjects/<project>/ (Preach = DJ Set 1b, Loud, dinka-giga-mix, EZ). Superseded scripts are
archived locally. Open: every spec renders on camelot’s contaminated tempogram BPMs (up to 0.86% off the
measured tempo), compensated by hand-set downbeats; switching the renderer to the library’s comb grid changes the
audio, so it waits on listening tests (a Foss A/B: “a little cleaner”) and an objective verify step.
| Library | Role |
|---|---|
| soundfile (+ ffmpeg for MP3) | Audio I/O |
| pyrubberband (Rubber Band CLI) | Time-stretching |
| scipy | EQ, filtering, first-downbeat onsets |
| numpy | Array math for mixing and crossfades |
CyborgDJ is now the controller over two libraries: dj-score measures and dj-render renders (split out 2026-10-22, because the dependencies differ: the renderer needs no librosa, analysis needs no Rubber Band). The repo keeps the CLI and controller-side scripts; the MCP layer is to sit over both libraries (controller design).
| Feature | Spec key | Notes |
|---|---|---|
| Crossfade curves | fade_type, fade_power |
linear, equal_power, exp, s_curve |
| Fader automation | automation.outgoing/incoming |
[[bar, value], ...] breakpoints |
| Per-band EQ automation | automation.outgoing_low/mid/high, incoming_low/mid/high |
Independent gain envelopes per frequency band. See EQ Blending Research |
| 3-band EQ ramp | eq_3band_outgoing/incoming |
Start/end gains per band with power curve |
| Parametric EQ | eq_outgoing/incoming |
Highpass, lowpass, shelf, peak filters |
| Tempo ramp | tempo_ramp |
Gradual BPM matching across overlap |
| Decoupled fader | fade_offset_bars, fade_bars |
EQ spans full overlap, fader moves in sub-region |
| Outgoing hold | outgoing_hold |
Keep outgoing at full volume, slam cut |
Per-band EQ automation subsumes fader automation, 3-band EQ ramp, decoupled fader, and outgoing hold into a single general model. When EQ lanes are present, legacy features are ignored with a warning. See the implementation results for practical findings.
Part of the full cyborg DJ workflow: