Skip to content

About

Browser-based MIDI-to-Strudel converter with readable notation, key detection, quantization, track splitting, and playback.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Repository files navigation

midi-strudel

i got too obsessed with Epic: The Musical and wanted to see the melodies as strudel code.

that was honestly the whole spark for this. i was on a high from Epic, discovered strudel, and really wanted to look at those melodies in this code-shaped notation instead of just a piano roll.

then vibe coding made it very easy to keep poking at it. it stopped being a one-off experiment and slowly became a fun little tool for turning midi into strudel-ish code so i could study melodies, inspect patterns, and hear them back in a different way.

along the way it also became a useful excuse to play with gemini, claude, and gpt as ai dev tools and see what kind of workflow they were actually good for.

what strudel is

strudel is a browser-based live coding environment for music. instead of a piano roll, you describe repeating patterns and cycles in code.

what this project is doing

this project takes a midi file, parses the tracks, and turns them into strudel-ish code you can read, tweak, and send into the repl without starting from scratch.

the notation idea here came out of me trying to figure out how to represent melody, harmony, overlap, rests, and timing in a way that felt usable for this converter.

so this app is not trying to be a perfect or official representation of strudel syntax theory. it is more like: i had a notation idea, kept iterating on it, and built a tool around that idea so i could feed midi in and get something musical and readable back out.

very briefly, some of the notation ideas in here work like this:

  • C4@0.5 means play C4 for half a cycle
  • ~ means rest
  • {C4, E4, G4} is being used for overlapping / stacked material
  • relative mode turns notes into scale degrees like 0 2 4 instead of raw note names

if you want the deeper background:

For the current beat-group and phrase-library renderer, see structured notation. It also explains how structural weights differ from note gates; the historical examples above describe the earlier notation experiments.

what you can do with it

  • drop in a .mid or .midi file
  • detect tempo, time signature, drum tracks, and a likely key
  • convert MIDI tracks into one phrase library with compact Strudel arrangements
  • switch between absolute note names and relative scale degrees
  • adjust playback, formatting, visuals, and per-track mapping
  • preview the result in the embedded strudel player
  • open the generated code in strudel and keep messing with it there

local development

npm install
npm run dev

the dev server runs on http://localhost:3000.

if you want to run the checks:

npm test
npm run build
npm run typecheck
npm run lint

agent-facing CLI

Install dependencies from a clean checkout, then invoke the converter without a browser or prompts:

npm ci
npm run --silent convert -- path/to/song.mid

The command writes only its requested result to stdout, so agents can safely redirect or parse it. Errors go to stderr and return a nonzero exit status. Non-fatal conversion diagnostics also go to stderr as one deterministic line per affected MIDI note, while conversion still succeeds.

Choose one of three stable output formats:

# Plain Strudel code (the default)
npm run --silent convert -- song.mid --format code

# Versioned JSON with source metadata, effective config, track summaries, diagnostics, code, and URL
npm run --silent convert -- song.mid --format json

# An openable strudel.cc URL containing the same encoded code payload as the web app
npm run --silent convert -- song.mid --format url

# Adjust line wrapping without changing musical timing
npm run --silent convert -- song.mid --measures-per-line 2

The schema-v1 JSON object includes a diagnostics array. This is an additive, backward-compatible field; each dropped percussion entry contains a stable diagnostic code, severity, MIDI note number, event count, and message.

Conversion flags include --bpm, --notation absolute|relative, --measures-per-line (alias --items-per-line), --control-syntax chained|colon, --sound, --auto-mapping / --no-auto-mapping, and --velocity / --no-velocity. Timing within 10 ms of the beat grid is snapped automatically (exact to the ear), so there are no quantize flags. Run npm run --silent convert -- --help for the complete contract.

All conversions use structured notation, combining subdivisions, relative weights, note gates, and exact phrase reuse automatically. The retired --rendering, --timing, and --duration-precision flags now return an explanatory error; remove them from existing commands. Saved browser projects migrate these settings away while retaining their MIDI notes and other preferences.

About

Browser-based MIDI-to-Strudel converter with readable notation, key detection, quantization, track splitting, and playback.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages