sublevel
# Sublevel
A reference-matching mix analyst for Ableton Live, exposed over MCP, backed by
a corpus of 798 analyzed electronic tracks.
Mixing low end without accurate monitoring is guessing. Everything below about
150Hz is inaudible on laptop speakers and misrepresented on consumer
headphones. Sublevel replaces the ear with measurement where measurement
works, and says how confident it is by placing every number against records
you actually listen to.
## What makes it trustworthy
There is not a single invented threshold in this repo. A mix is not "thin"
because a diff crossed -3dB; it is thin because it sits below p10 of tracks in
its own genre. Every claim carries its percentile so it can be checked.
```
sub vs body: you -3.42dB (p8), reference 3.92dB (p82), -7.34dB.
Kick has punch but no weight underneath it.
```
The corpus is scoped by genre, because the genres genuinely differ - House
carries about 2dB less sub relative to kick body than Tech House or Minimal,
and that is not a rounding artifact.
## Status
Built and verified: measurement core, 798-track corpus, genre-scoped
calibration, reference finding, headless Vital patch design, the diff-to-device
translation layer, and the MCP server (11 tools).
Needs you, once, in Live: select **AbletonMCP** as a Control Surface
(Preferences > Link, Tempo & MIDI; Input and Output both None) and restart
Live. The Remote Script is already installed.
## Setup
```bash
python3.13 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest
```
The MCP server is registered for this project in `.mcp.json` (`python -m sublevel mcp`). See `ARCHITECTURE.md` for the v2 layout and the tool contracts.
## Rebuilding the calibration
```bash
python -m sublevel.corpus extract ~/Downloads/beatport_tracks_* --out calibration/corpus.json
python -m sublevel.calibration build calibration/corpus.json
python -m sublevel.calibration show calibration/thresholds.json --genre "Tech House"
```
Extraction is resumable and keyed by content hash, so re-running skips what is
already analyzed. 798 tracks takes about 14 minutes on 5 workers.
## MCP tools
The agent-facing surface (`python -m sublevel mcp`). Long operations return
a job id; poll with `job`.
| tool | what it does |
|---|---|
| `session` | the open set: tracks, chains, target, budget, bypass state, jobs |
| `set_target` | genre / reference / artist / favorites / file; acceptance bands from the drop of finished records |
| `measure`, `compare`, `readiness` | loop-aligned capture; distance and gaps to the target; the club floor |
| `map_mix`, `mixmap` | which track owns which band |
| `plan`, `apply`, `iterate`, `verify` | pure plan, guarded write, the loop; goals `lowend` and `club_ready` |
| `undo`, `revert_all`, `ab`, `rate`, `history` | the undo stack, the A/B bypass, what it sounded like, the change log |
| `monitor` | read-only readout every N bars while you play |
| `mastering_check` | what the master's limiter and compressors are contributing |
| `find_kicks`, `find_bass_patches`, `place_sample` | the sample library and preset bank against the target's kick and bass |
| `design_bass`, `deliver_patch` | design a bass toward the reference (Vital offline, or a rack in Live in place) and put it on the bass track |
| `detect_key`, `read_notes`, `write_bassline`, `automate` | the key, a clip's notes, a bassline under the kick, clip automation |
| `find_references`, `add_reference`, `finishline` | the corpus and the named library |
## Sound design
`.vital` presets are plain JSON with human-named parameters, and `pedalboard`
renders Vital offline, so the measurement engine doubles as a fitness function:
write a patch, render a note, measure, adjust - about 200 candidates a minute,
entirely headless, with only the winner going into Live. Targeting a real
tech-house bass preset from Vital's init patch converges in ~25 seconds.
Corpus percentiles are deliberately not used here. They describe finished,
mastered records; a solo'd bass patch judged against them would produce
nonsense with a confident percentile attached.
## Safety
Sublevel writes to Live through exactly one path, `Engine.apply`, and every
write is measured before and after. A move is kept only if the objective
improved without costing kick punch, crest, mono compatibility or headroom;
otherwise it is put back. Every kept and reverted move is appended to
`calibration/changes.jsonl` with device, parameter, old value, new value, the
reason, the proposal it came from and the verdict. `undo`, `revert_all` and
the `ab` bypass are always available.
Two notes on the Ableton bridge:
- The Remote Script Live runs is the upstream ableton-mcp script, patched and
vendored at `src/sublevel/live/remote_script/`. Upstream binds to
`0.0.0.0`; the vendored copy binds to `127.0.0.1`.
- The third-party `ableton` MCP server in `.mcp.json` has telemetry that
records the originating prompt and an opt-in dataset upload. It is
registered with `DISABLE_TELEMETRY=1`; consent is yours to give.
## What it does not do
It does not judge groove, sound design, arrangement, or whether a record is
good. It speaks with confidence about sub, weight, punch, width and dynamics -
the parts monitoring problems hide - and reports midrange as context rather
than instruction, because most midrange problems are masking and arrangement,
where the fix is removing a layer and no analyzer can tell you that.
## Notes on the corpus
All 798 tracks are 320kbps MP3. That is transparent in the bottom two octaves,
so sub, punch, dynamics and mono correlation are trustworthy. It is not
transparent at the extremes: codec reconstruction overshoots sample peaks
(every track in this corpus reads above 0dBTP), and everything is lowpassed
around 20kHz. `true_peak_db` and the `high` band are marked `advisory`
wherever they surface, and are never presented as calibrated fact.
TDQS
Scored across 36 tools
Tools are grouped into clear functional clusters—reference, measurement, mixing moves, and job control—and most have distinct resource-action purposes. The measurement family (measure/compare/verify/monitor) and revert family (undo/revert_all/ab) could be confused, but their scopes are different enough that a careful agent should select correctly.
Most actions use an imperative verb_target pattern and information tools are named as plain nouns (session, history, samples, mixmap), which is a consistent semantic convention. A few bare verbs or abbreviations like ab, job, and rate break the pattern slightly, but the all-snake_case style keeps it predictable.
At 36 tools, this is well beyond the 25-tool 'too many' threshold, making the surface heavy even for a broad DAW-assistant domain. Several tools could be consolidated into grouped subcommands—especially the measurement, reference, and job-related tools—without losing clarity.
The set covers the full workflow: references and target selection, measurement and comparison, planning/apply/iterate, undo and history, plus creative helpers like bassline writing, patch design, and project scaffolding. Minor gaps like reference-library removal/editing exist, but core workflows are complete with no dead ends.