I like music — especially electronic music. Over the years I’ve accumulated synthesizers, drum machines, and other MIDI-controlled devices. Since I’m a programmer, I want to write programs that control these devices to make music.
There are good systems for this. Tidal Cycles and Strudel, ChucK, SuperCollider, and many others each have their strengths. I’ve tried quite a few and had fun making music with them, but none of them totally clicked. They didn’t match my mental model for creating music.
So I built my own. This post is about what I wanted and how warp’s design follows from those goals.
Declarative, not functional
Tidal Cycles is built on Haskell. Strudel is functional JavaScript. I never jived with functional programming, and procedural doesn’t fit either. To me, a song is a description — a set of tracks with patterns, not a pipeline of function calls. That description maps naturally to YAML: structured, readable, and flat. Warp programs are YAML documents.
song:
tempo: 108
root: A2
phrases:
main:
progression: rising_sun
tracks: [arp, bass, drums]
tracks:
arp:
instrument: percussive_organ
n: "1 3 5 8"
cycle: 1/2 bar
bass:
instrument: synth_bass_1
n: "1 1 _ 1"
octave: -1
gate: 100%
drums:
instrument: gm_drums
n: "bd ~ sd ~"
Not live-coding
I enjoy watching people live-code a piece of music. It’s impressive. But it isn’t how I work, and a language that puts live-coding front and center tends to prioritize terseness and typeability over readability. Warp favors clear, readable programs over compact ones. You edit a document, press play, and hear it. If you change the document while it’s playing, warp picks up the changes — but the design doesn’t revolve around typing speed.
MIDI-first
I have great-sounding hardware and software synths that make interesting sounds. I have a DAW with effects chains. I don’t need to create sound from scratch — I need to control the instruments I already have. Warp generates MIDI events: note-on, note-off, velocity, CC messages. What turns those events into sound is up to me. A built-in General MIDI soundfont plays in the browser so programs work without any external setup, but the real target is my own gear.
Melody, harmony, and progressions
Many live-coding environments are strongest at dance music where the beat is the primary element and melody is secondary. I’m interested in more melodic music — arpeggiated chord changes, countermelodies, harmonic motion — but I don’t have a deep music theory background.
Warp has built-in support for chords, scales, named progressions, and
automatic voice leading. You can write progression: Am F C G and
every track that uses scale degrees gets those chord changes without
spelling out each note. The goal is to make it easy to create
melodic, harmonically grounded music without requiring theory
knowledge up front.
Full-featured
The language is small enough to learn in an afternoon, but it covers a lot of ground — polyrhythms, arpeggios, ratchets, CC automation, progressions, scales, chords, templates, transforms, modulators and more. The pieces combine so you can build up complex arrangements without the language itself being complex.
Patterns from Tidal, without the confusion
Tidal’s mini-notation is a powerful way to express rhythm. Subdivisions, Euclidean patterns, alternation, random choice — I can encode complex rhythmic ideas in a short string. Warp adopts this mini-notation because it works.
I could never keep Tidal’s pattern-combining semantics straight in my head. The rule that structure comes from the left-hand pattern is flexible, but when I layered several patterns I’d lose track of which side was carrying the structure and get surprised by the result.
Warp simplifies this. Structure always comes from the n pattern, never from anything else. This helps me better understand what is going on in any track.
Repeatable
A warp program can use random elements — random note choice, random
velocity offsets, probability gates. But the same program always
produces the same output, on any machine, in any browser. Randomness
is seeded deterministically from the program text. If you share a
.yaml file, the other person hears exactly what you heard.
Runs in the browser
No install, no dependencies, no build step. Open the editor in a browser, paste a program, press play. The built-in GM soundfont means every program makes sound immediately. For Chrome users, MIDI output routes to external hardware or a DAW with one click.
Visual playback
While a program plays, the editor animates a visualization that shows which notes are firing, which bar the song is in, and how patterns interact. This helps when debugging a rhythm or understanding how a modulator shapes a phrase over time.
The name
The name comes from Web Arpeggiator — the first version was just a browser page that arpeggiated chords over MIDI. The scope grew, but the name stuck. It also nods to Tidal Cycles creator Alex McLean’s observations about the connection between music and weaving — repeating patterns interlocking across time, which is what warp programs do.
Try it
I made warp for myself, but if any of the above resonates with how you think about music, give it a try. Open the editor, paste one of the examples, and press play. If something is broken or missing, I’d like to hear about it — file an issue or send me a note.