Local-first layered mashup engine. The rule that names it: the composer is never allowed to touch raw file slices. Material enters through an audition (the ear crate) or it does not exist. Everything downstream is gated: varispeed-only deck discipline, deterministic compatibility graph, turnover contract, pre-render and post-render quality gates, runtime ledger with per-stage receipts. No fallback render is allowed.
- Prerequisite: Python 3 plus
ffmpegandffprobeonPATH. - Windows (first time):
START_HERE.cmdinstalls dependencies, builds, and launches. - Windows (desktop icon): run
Create-Desktop-Shortcut.cmdonce for an "EarCrate" desktop icon. The icon runsLaunch-EarCrate.cmd, the fast path that skips reinstalling dependencies. - Dev:
python -m earcrate - Single file:
python build/make_singlefile.pythenpython dist/earcrate.py
EarCrate exposes a language-agnostic provider protocol for external MIR, ML, DSP, rights, transport, and review tools. Providers receive one content-addressed request on stdin, emit one evidence result on stdout, and write derived files only beneath a negotiated artifact directory. They may propose observations, candidates, measurements, refusals, derived artifacts, or unapplied review patches; they may not silently write canonical musical state.
python -m earcrate floor capability
python -m earcrate floor gaps
python -m earcrate floor scaffold build/reference-floor-provider
python -m earcrate floor conformance \
build/reference-floor-provider/reference.floor-provider.json \
build/reference-floor-provider/request.json \
build/reference-floor-conformance --repeat 2
See docs/OPEN_MUSIC_EVIDENCE_FLOOR.md and docs/FLOOR_PROVIDER_PROTOCOL_V1.md.
Signal sanity is not musical acceptance. A builder may create a source-derived or generated candidate, but a different evaluator must qualify its signal, a human must accept the music, and a rights policy must admit the intended use before release.
python -m earcrate floor release-capability
python -m earcrate floor release-adapt-recurrence receipt.json build/release-floor
python -m earcrate floor release-review-template build/release-floor/release_candidate.json human_review.json
python -m earcrate floor release-gate build/release-floor/release_candidate.json release_gate.json \
--signal-evaluation build/release-floor/signal_evaluation.json \
--human-review human_review.json \
--custody passed --reproducibility passed
See docs/RELEASE_CANDIDATE_REVIEW_GATE.md.
MIDI enters through a source-independent, content-hashed event ledger. Mido is used as the Standard MIDI File codec, while EarCrate retains every absolute tick, track-local event order, tempo event, controller, program change, pitch bend, note message, and meta message as its own canonical data.
python -m earcrate midi inspect "arrangement.mid"
python -m earcrate midi ledger "arrangement.mid" "arrangement.ledger.json"
python -m earcrate midi roundtrip "arrangement.mid" "arrangement.roundtrip.mid"
python -m earcrate midi render "arrangement.mid" "arrangement.neutral.wav" --stems-dir "neutral-stems"
The neutral renderer deliberately uses simple tones. It executes tempo changes,
sustain, volume, expression, pan, and pitch bend. Each full render writes three
independently hashed records beside the WAV: the exact render program, an
event-level execution ledger, and the final render receipt. Every selected note
is classified as fully executed, truncated, or refused. A full render is rejected
unless every selected note is fully executed. Diagnostic renders created with
--max-seconds retain all partial and refused outcomes instead of reporting false
completion.
Optional per-track stems use the same master scale, so their numerical sum must reproduce the full render within the gate tolerance. Declared track count does not determine audio rendering cost. Only note events, control curves, active voices, and occupied tracks are materialized.
Basic Pitch is an optional note-observation provider for isolated stems. It is measurement only: EarCrate retains authority over the accepted beat grid, quantization, arrangement, and sample binding.
pip install "basic-pitch>=0.4,<0.5"
python -m earcrate midi transcribe "bass-stem.wav" "bass.notes.json" --provider basic-pitch
The provider hashes the installed model bytes and raw model outputs into the observation receipt. No Basic Pitch model is bundled by EarCrate.
EarCrate can turn a finished MIDI performance into an exact shopping list for replacement material. A demand manifest groups notes by track, channel, and program, then records note and velocity coverage, gate duration, polyphony, controller use, pitch bend, General MIDI family, role hints, and every source event that must remain accounted for.
The direct approved-library flow is dry-run first. It searches only the current approved EarAtoms for the chosen profile and writes nothing:
python -m earcrate rack-from-crate "arrangement.mid" --profile girl_talk_v1
When the proposal is complete, --apply decodes the selected source regions,
seals exact rack revisions, compiles SFZ instruments, binds every MIDI event,
and can render the substituted arrangement immediately:
python -m earcrate rack-from-crate "arrangement.mid" \
--profile girl_talk_v1 \
--apply \
--output "crate-build" \
--render "crate-build/substituted.wav" \
--stems-dir "crate-build/stems"
Search produces candidate receipts instead of changing execution semantics. Each receipt records role fit, timbral fit, key and transposition distance, duration coverage, loopability, quality terms, and the exact approved atom. Rejected atoms are excluded. Missing coverage remains unresolved and prevents an applied build or render. There is no runtime sample fallback.
The lower-level rack commands remain available for manual or external search systems:
python -m earcrate midi demand "arrangement.mid" "arrangement.demand.json"
python -m earcrate midi rack-template "bass.rack.draft.json" --mode pitched --rack-id crate-bass --name "Crate Bass"
# Edit the draft to point at an approved sample or EarAtom slice.
python -m earcrate midi rack-seal "bass.rack.draft.json" "bass.rack.json"
python -m earcrate midi bind "arrangement.mid" "arrangement.binding.json" "bass.rack.json" "drums.rack.json"
python -m earcrate midi render-rack "arrangement.mid" "arrangement.binding.json" "arrangement.crate.wav" --rack "bass.rack.json" --rack "drums.rack.json" --stems-dir "crate-stems"
python -m earcrate midi sfz "bass.rack.json" "bass.sfz"
A sealed RackRevision identifies the exact source file, decoded PCM slice,
key and velocity zone, root note, loop, trigger behavior, tuning, gain, pan, and
envelope. Binding compiles an event-level map from every MIDI note to one exact
rack zone. A missing key range, velocity layer, duration, rack, sample, or source
identity remains an explicit unresolved or refused event. Rendering cannot
silently substitute another sample.
The in-process rack renderer is the proof backend. It performs variable-rate sample playback, pitch bend, looping with optional crossfade, one-shot and gated voices, velocity and channel controls, exact source revalidation, per-track stems, and event-level execution receipts. SFZ is generated as portable object code for external samplers; the EarCrate rack and binding ledgers remain the source of truth.
The live engine treats MIDI as an exact teaching and execution language rather
than the final product. It compiles arrangement patterns into a LiveMaterialAtlas,
maintains a hashed LiveSetState, plans over a receding horizon, commits only the
next phrase, and replans after controls or state changes.
Four numerical persona policies ship with the runtime: club, girl_talk,
pretty_lights, and minimal. They control phrase and horizon lengths, energy,
density, risk, layer limits, source turnover, role priorities, technique weights,
and objective weights. Persona changes remain pending until a phrase boundary
that is legal for both policies.
The typed technique registry currently includes blend, hard cut, loop extension, drop to floor, foreground swap, tease, layer building, breakdown, echo out, drum rebuild, sample chop, and layer accumulation. Every selected technique has preconditions, exact selected layers, lowering commands, objective terms, ranked alternatives, and an execution outcome.
A complete scheduled set can be planned and proved through neutral instruments:
python -m earcrate live capability
python -m earcrate live atlas "source-performance.mid" "live-atlas.json"
python -m earcrate live session "source-performance.mid" "live-build" \
--bars 64 \
--persona pretty_lights \
--controls "controls.json" \
--neutral-render
For interactive operation, keep the state as an immutable JSON revision. Apply a control or commit one legal phrase at a time:
python -m earcrate live state-init \
"live-atlas.json" \
"state.000.json" \
--persona club
python -m earcrate live control \
"state.000.json" \
"state.requested.json" \
--command set_persona \
--value '"pretty_lights"'
python -m earcrate live step \
"live-atlas.json" \
"state.requested.json" \
"step-001"
Controls may switch persona, enable, disable, or force a technique, change energy, density, risk, or layer limits, hold and release the current material, and skip source patterns. The next phrase is replanned from the exact current state; the earlier performance and previous decisions are never rewritten.
The expensive private-library search can be moved completely out of the live path. The configured-library command reads the approved EarAtom pool, performs the slow multi-zone search once, materializes exact sample slices, seals racks, and optionally writes SFZ:
python -m earcrate live crate-compile-library \
"source-performance.mid" \
"compiled-live-crate" \
--profile girl_talk_v1 \
--max-transpose 18
A portable alternative accepts an explicit approved-atom JSON export:
python -m earcrate live crate-compile \
"source-performance.mid" \
"approved-atoms.json" \
"compiled-live-crate" \
--profile girl_talk_v1 \
--max-transpose 18
Later sessions use only the sealed crate and execute with zero full-library scans:
python -m earcrate live crate-session \
"compiled-live-crate/live-crate-atlas.json" \
"live-show" \
--bars 128 \
--persona pretty_lights \
--controls "controls.json" \
--render \
--stems
crate-session plans on CPU, revalidates the compiled sample identities, binds
the generated performance to those racks, and renders without rescanning the
library. Its CPU execution receipt reports the command count, peak active layers,
and zero pattern or material scans during execution.
The device callback is deliberately smaller than the planner. A non-audio thread applies controls, plans the next phrase, binds it to the sealed racks, decodes or loads the required samples, and prepares stereo float PCM. The callback may only swap a queued phrase buffer and copy prepared frames. It may not plan, search the library, decode samples, or bind events.
Prepare one exact phrase and its next state:
python -m earcrate live-audio capability
python -m earcrate live-audio phrase \
"compiled-live-crate/live-crate-atlas.json" \
"state.requested.json" \
"prepared-phrase-001" \
--controls "next-controls.json"
The phrase directory contains the WAV, next state, engine step, MIDI,
MIDI-lowering ledger, binding, render program, event execution ledger, and phrase
receipt. The in-memory LiveAudioCallback consumes prepared buffers in fixed
blocks and records explicit underruns. LiveSoundDevicePlayer is an optional
thin host around the sounddevice package. Core planning, tests, and offline
crate compilation do not require that package or an audio device.
python tests/run_gates.pypython VERIFY_PACKAGE.pybuilds and self-tests the single-file package and drives its packaged MIDI, rack, reference, live, and live-audio command surfaces.python scripts/oss_audit.pyvalidates code and model governance ledgers.
CI retains the complete gate ledger and package-verifier ledger as artifacts on both successful and failed runs. Treat a red run as a merge blocker. The gate runner prints the current executable count, so documentation does not preserve a stale historical number.
Descends from the Jukebreaker GT line (v0.5.x deck discipline, v0.6.x
fail-fast harvest / turnover contract / keyless percussion, v0.7.x modular
rebuild). Full history is in CHANGELOG.md. Legacy workspaces are adopted in
place: an existing jukebreaker.sqlite is used without migration.
Sources (audio) never enter this repository.
PolyForm Noncommercial 1.0.0. It is free for personal and noncommercial use;
commercial use requires a written license from the copyright holder. See
LICENSE.md, which also notes that music rights are separate from software rights.