Variations of variations
Declare a theme once. Derive everything else with composable transformations of pitch, time, shape, and accent. Variations can name variations as their source — they compose all the way down.
Zigzag is an AI-assisted audio engineering tool that produces finished tracks from scratch — the full audio stack, composition to waveform. Describe what you want; the AI composes the parts, dials the mix, masters the master, and gives it back as a track ready to release.
Featured render
Every note, mix decision, and effect on this track lives as text in the project tree. Edit a line, re-render, hear the change.
Hear it work
The same engine that rendered the track above gets the fundamentals exactly right. Press play on any one — every pitch is a function of the project, so what you hear is what was written.
The idea under everything here: a line of numbers carries no meaning until it is read through a context — so the same line becomes a melody or a harmony, moves the key, reshapes under the transform algebra, or gates another line.
Two notes a fixed distance apart — the atoms of melody and harmony. The distance is never stored; it emerges from where two degrees land in a scale. Start with the ladder; the complete tour names and plays all 144.
The context a line is read through: the same ascending degrees become major, minor, or any of the seven modes — only the scale beneath them changes.
The same move, stacked into harmony: one voicing read against a scale sets a chord's quality, and a line of degrees spells a whole progression. The notes are stacked, but the quality comes from the context.
One motif, then variations derived from the same line — repeated, reversed, transposed. The source never moves; each variation is just another way of reading it.
The other way sounds relate — not one line read through a context, but several sounds stacked at once. One motif layered against itself, voice by voice, until a single line fills out into a full texture: the concurrent counterpart to playing notes in turn.
The last rung of the ladder: a whole song's structure is one line of numbers read through a short list of sections — so reversing the line reorders the song, the way reversing a melody flips its notes.
An arrangement is a grid — one row per voice, one column per moment. Reading down stacks the voices that sound together; reading across is time. So reversing the grid flips every voice back to front at once, the way reversing a melody flips a single line.
A part is a brick. Take one short phrase and play it at different pitches — a third up, a fifth, an octave — and the single idea climbs into a melody. The sampler's oldest trick, with a whole phrase in place of a note.
One operation turns each pair of cells (a, b) into a three-cell ripple (a, b, a) and shortens them to hold the time — straight twos become rolling threes. On a scale it is a triplet run; on a beat, a galloping shuffle — the same move on both, because both are the same grid underneath.
A long phrase carries one memorable window. A scale keeps trying to fall home, gets snapped back to the top, and finally lands a clean run all the way down — and that closing run, lifted out, stands on its own as a hook; looped, an ostinato. The source never changes; the extract is just another way of reading it, shorter.
Take a plain scale and lift a single note up — only that note moves; every other one stays exactly where it was. Then lift a few the same way and the line turns into a rolling ornament. A surgical edit, one targeted note at a time, the source never rewritten.
The same scale read through four different voices — from a bare sine to a warm detuned chorus. The notes never change; only what sounds them does.
Lines read as rhythm instead of pitch — a beat built up layer by layer, classic patterns, and the click that holds it together.
Production in motion — sidechain pumping, buses chained into buses, two lines fused point for point, and a scale derived from another.
48 examples · scroll for more · more added as the library grows
Structure is data
A song's structure is just a line of numbers — one per section. The same move that turns a line into a scale or a chord progression turns this one into verse, chorus, and bridge. So the shape of a whole song is as editable as a four-note phrase.
Same sections, same instruments — nothing rebuilt. One move on the line and the whole song reshapes. It's the last rung of the same ladder: a single interval, a scale, a chord, a motif — and now the structure of the song itself, all addressable the same way.
The beat is data
A groove is a grid of hits — one row per drum, one column per moment. The same reverse and rotate that reorder a phrase reorder the beat, and the new beat points back at the source — so the original stays the thing you edit.
Same three drums, the same handful of hits — reversed, then turned a beat later. Nothing re-recorded; each is a derived reading of the one grid up top. The beat joins the melody, the chord line, the song's form, and the stack of voices: all reshaped by the same moves, because underneath they're the same grid of numbers.
One move, two worlds
Triplet turns each pair of cells (a, b) into a three-cell ripple (a, b, a) and shortens them to hold the time — straight twos become rolling threes. On a scale that's a triplet run; on a beat, a gallop. One move, because both are the same grid underneath.
The scale and the beat never met the same code path before this — yet one operation pushed both from straight time into triplets, because a run of pitches and a row of drum hits are the same thing underneath: a grid of numbers on a clock. Define a move once and it reaches every dimension at once. That is the whole bet — composition as algebra, not a pile of special cases.
Pull the hook out
A scale keeps trying to fall home and keeps getting snapped back to the top — until one steady run finally makes it all the way down. That closing run is the hook. Keep just that window and it stands on its own; loop it and it drives.
Nothing here was re-written. The hook is the same eight notes that close the phrase — kept, while everything before them is set aside; and the loop is that window said again. A phrase is a row of numbers on a clock, so a window into it is just another reading of the same source: shorter, pointing at the same idea, ready to build on. Pull a piece out, then make something of it.
Move one note
Start with a plain scale. Raise one note — only that note moves; the rest are untouched. Then make the same move on a few notes and the line blooms into an ornament. A surgical edit, one note at a time, never a rewrite.
Nothing was re-written between these. Each is the plain scale with a lift declared on top — pointed at one note, then at a handful. The notes that aren't named never move a hair, which is the whole point: you can reach into a line and color a single note, and know with certainty that everything around it is left exactly as it was. The decoration lives in what you change, not in a new copy of the line.
Voices are a grid
A melody is a line of numbers. Stack a few lines and you have a grid — the voices of a whole arrangement, across is time and down is what sounds together. The same move that flips a melody flips the entire grid: every voice reverses with it.
Same voices, same notes — nothing rebuilt. One move on the grid and every line turns back to front at the same instant. It's the projection idea in two dimensions: across is time, down is the voices that play together, and the whole arrangement is as addressable as a single phrase.
One phrase, many pitches
Write one phrase. Then play it higher — a fourth, a fifth, an octave — and the same idea climbs into a melody, in key the whole way. One part, repitched, is a whole line: the sampler's oldest trick, with a phrase in place of a note.
The phrase never changes — it's one idea. Lifting it in pitch is the only move, and the four copies climb in key — a fourth, a fifth, an octave home — so a single part becomes the tune. The same thing a finished phrase does when it turns into an instrument: composed once, then played at any pitch.
Who this is for
If you want to type a sentence and get back a finished pop song — with vocals you didn’t write, in a key you didn’t pick, on a beat you didn’t choose — there are tools that do that beautifully. Zigzag isn’t trying to be any of them.
Things a prompt-to-song model is great at
If any of those sound like the deal you’re looking for, those are real, well-built products. Genuinely — go try one:
A prompt-to-song toolWe’ll be over here, in the room where every parameter still has a hand on it.
The AI controls every layer of the machine — every bit of every sample of every signal of every channel, all the way up through synthesis, effects, mixing, mastering, arrangement, motifs, rhythms, keys, scales, repetition, harmony, and structure.
You direct at whatever level fits. Hand it a sentence and get a full track; or work down to a per-sample envelope curve. Same surface.
If you want to use a computer to create a sound file — and you care how it's made, every decision yours rather than a model's guess — that's the thread. Not a job title: the actual audio, built deliberately, with AI's leverage at every layer and your hands still on the controls. Today that artifact is a finished WAV you own.
It tends to land with producers, musicians, composers, coders, and sound designers — but the point isn't the role. It's wanting to make the thing, not order it.
What this is
Zigzag is two things. It’s a body of text — human-readable and machine-readable, fully source-control compatible — that compiles, deterministically, into every sample of every signal of every channel of the finished, mastered audio. And it’s a set of tools that make that text easy for an AI to read, reason about, and rewrite as you direct.
Generative models guess.
Zigzag composes.
Text-to-audio models are giant pre-trained weights — you write a prompt, audio comes out, the "what" of the music lives in the model. Zigzag is a project of human-readable text that deterministically renders to audio. Every musical decision is something you can read, diff, and refine.
The render isn’t the artifact.
The project is.
A finished mix is what a binary is to a compiler — a build output. What you keep, share, and iterate on is the directory: the chord progression, the instruments, the arrangement, the mix. Re-renderable, reproducible, content-addressable.
You direct it.
The AI conducts.
Speak in any vocabulary the studio uses — synths, reverb, sidechain compression, intervals, arpeggios, repetition, transposition. The agent is fluent in all of them: engineer, musician, director, conductor, producer, encapsulated. You direct; it writes the project; the engine renders.
It’s not AI making the music.
It’s AI making the program that makes the music.
Every sample of PCM in a render is determined algorithmically — by the patterns you wrote, the modulators you wired, the FX chain and arrangement you composed. The agent’s job isn’t to guess audio; it’s to author the deterministic program whose execution yields the audio. Reproducible. Readable. Refinable line by line.
A DAW for the agent
Synthesizers defined in code. Routing and effects without limit. Event data like MIDI, with monadic composition and transformation of musical ideas. Completely deterministic: every sample of every render is a function of the project — not a guess from a model.
Declare a theme once. Derive everything else with composable transformations of pitch, time, shape, and accent. Variations can name variations as their source — they compose all the way down.
LFOs, envelopes, and automation lanes combine with arithmetic — drive a pad with a slow fade modulated by a rhythmic gate. Knobs are formulas, not single values you have to ride.
Every effect carries a channel side: left, right, or both. A right-side delay yields Haas-style width with no special-casing. Stereo is a property of the chain, not an afterthought.
Classic pump-and-duck compression on any track keyed by any other. A studio-grade multiband splits the signal into bands, compresses each independently, sums them back — house-music glue or transparent mastering on tap.
A spoken clip synthesizes text into audio at render time — inline announcements, click-track callouts, spoken lyrics. Choose a voice from the catalog; swap engines without rewriting the project.
Watch mode re-renders only what changed and hot-reloads playback. Edit a filter cutoff, save, hear it a second later. The development loop you wish your DAW had.
Short room verb. Long hall. Per-track sends, ducked by per-bus FX. The classic mixing topology — declared in plain text, summed inside the engine.
LUFS · true-peak · DR. Per-band stereo width. Onset timing. Anomalies — clip bursts, DC offset, channel asymmetry. The agent reads the report before it touches the mix — and after.
Every clip and intermediate is keyed by content. Identical inputs become an instant cache hit. A render is instant when nothing changed, partial when little did, and never wastes a sample on what you already heard.
The full audio stack
Zigzag isn’t pinned to one layer of the studio. The project contains the music as composition, as arrangement, as event data, as synthesis, as signals, as a mix, as a master, and as the final waveform — all at once, all derived from one source. Because every layer is real and addressable, Zigzag can read from — and write to — any tool that lives anywhere along that stack.
One project; ten descriptions of the same music. A change at the top propagates all the way to the last sample; a change near the bottom never silently disagrees with the score.
WAV in and out, any common sample rate and channel layout, transcoded to whatever your delivery target needs. MIDI in and out, so event data crosses the boundary intact. ABC in and out, so the notation crosses too. Audio is audio; events are events; notation is notation — Zigzag knows the difference and preserves each one.
Bring a project in from the DAW you already use — and pick up where it left off, with the agent on it. Or build the track in Zigzag and hand the project back out to your DAW to finish by hand. Stems, MIDI, arrangement — whatever crosses the boundary, crosses cleanly. Zigzag fits the workflow you already have; it doesn’t ask you to leave it.
The project tree
A Zigzag project is a directory of plain-text source. Show me the project is now a question with an answer. So is what changed? — every commit is a production diary entry, every mix decision a line you can read out loud.
Direction → conducting
People ask "what prompt did you use?" — but that question doesn’t quite fit. You speak in synths and intervals, reverbs and arpeggios. The agent is fluent in all of it — engineer, musician, director, conductor, producer — and writes the project to match. The result isn’t guessed; it’s constructed, decision by decision.
3 matches in the Universe kick-808 #a1f3 80→35 Hz sweep · used in 12 projects kick-808b #7c20 punchier · 90→40 Hz kick-sub #e4d9 pure sub · no transient
step 1 . . . 2 . . . 3 . . . 4 . . . 5 . . . 6 . . . 7 . . . 8 . . . kick x . . . . . . . x . . . . . . . x . . . . . . . x . . . . . . . hat 1 . 6 . 1 . 6 . 1 . 6 . 1 . 6 . 1 . 6 . 1 . 6 . 1 . 6 . 1 . 6 . bass x . . . . . . . x . . . . . . . x . . . . . . . x . . . . . . .
step 1 . . . 2 . . . 3 . . . 4 . . . click 2 . . . 1 . . . 1 . . . 1 . . .
export default ({ note_hz, velocity }) => {
const amp = env({ A: 0.001, D: 0.4, S: 0, R: 0 })
return sin(note_hz).mul(amp).mul(0.32).mul(velocity)
}step 1 . . . 2 . . . 3 . . . 4 . . . kick 2 1 1 1 2 1 1 1 2 1 1 1 2 1 1 1 pad . - = # . - = # . - = # . - = #
spec 20Hz ########====++==--::..::..... 20kHz
step 1 2 3 4 5 6 deg 1 3 5 8 5 3
bar 1 2 3 4 5 6 form 0 1 0 1 0 2 play V C V C V B
step 1 2 3 4 5 6 7 8 rise 1 2 3 4 5 6 7 8 fall 8 7 6 5 4 3 2 1 add 9 9 9 9 9 9 9 9 max 8 7 6 5 5 6 7 8 min 1 2 3 4 4 3 2 1
major W W H W W W H rotated W W W H W W H degrees 0 2 4 6 7 9 11
The Universe
The conversation above is real. The engineer can build an instrument from a single oscillator, one envelope at a time, and you can sit in the chair while it does. That’s a demonstration of reach, not a requirement. Most sessions never touch a raw oscillator. They don’t need to.
Instruments. Patterns. Progressions. Motifs. Rhythms. Kits. Voices. Mastering chains. Every piece is named, versioned, and reachable from any project. When you ask for a banjo, a kick, a half-time shuffle, a I · V · vi · IV in A minor — the agent doesn’t synthesize it from scratch. It finds the piece that already exists and writes it into your project.
Every piece is permanent and addressed by its content. A change makes a new version next to the old one, never in place. A GUI overwrites history; the Universe accumulates it. Your project from a year ago still renders bit-identically a year from now — because every piece it points to is still there, exactly as it was.
Reference someone’s banjo; fork it; tune it; publish your version. A motif you write today is something another project will derive a variation from next week. The Universe is the remix tree the studio always wanted — a living lineage where every piece carries its ancestors with it.
Information wants to be free. Music is just another form of information.
Under the hood
Scroll through the core of the rendering engine. The same handful of ideas that shape a single melody shape an entire mix — numbers over time, read through a context, transformed by total functions, composed along two axes.
A musical event, before it carries any meaning, is a rest or an integer. A scale is seven of them; a chord progression, four. The grid stays small enough to read at a glance — and that legibility is a hard rule, not an accident.
/// A single cell in a line matrix.
pub enum Cell {
Rest,
Value(i32),
}
impl Cell {
pub fn value(self) -> Option<i32> {
match self {
Cell::Value(v) => Some(v),
Cell::Rest => None,
}
}
} The same integer becomes a pitch, a chord degree, a sweep over time — depending on the context you read it through. “Sample a value at this moment” is one function, shared by everything that turns data into sound.
/// A context that yields a `T` at a position of type `P`.
pub trait TimeIndexed<P, T> {
fn at(&self, pos: P) -> T;
}
impl TimeIndexed<f64, i32> for LineSampler {
fn at(&self, pos: f64) -> i32 {
let n = self.cells.len() as i64;
let idx = (pos / self.beats_per_cell).floor() as i64;
self.cells[idx.rem_euclid(n) as usize].unwrap_or(self.default)
}
} Reverse a phrase. Invert it. Transpose it. Snap it to a scale. Each is a total function from one line of numbers to the next — so they compose, stack, and chain without surprises. Twenty-two of them, split by what they touch: the values, or their place in time.
/// A single edit applied to a matrix. Transformations apply in
/// order; each takes a matrix and produces one of the same kind.
pub enum Transformation {
Transpose { by: i32 },
Reverse,
Rotate { by: i32 },
Invert { pivot: i32 },
Quantize { allowed: Vec<i32> },
Palindrome,
Repeat { times: u32 },
Combine { other: String, func: CombineOp },
// … 14 more
} Lay sound after sound, or stack sound onto sound. Sequence and mix — two associative operations, mirror images of each other across time and amplitude. That single pair is the whole grammar of arrangement.
pub enum Source {
// …
/// Lay clips end-to-end, in order — B follows A.
Concat { parts: Vec<String>, gap_seconds: f32 },
/// Layer clips concurrently, summed sample-wise —
/// the amplitude-axis dual of Concat's append.
Mix { parts: Vec<String> },
} Drive one stream through another, cycling to fit. Nine lines, generic over whatever flows through them. Gating, combining, modulation — every one of them is this same shape, written once.
/// Co-indexed projection — the zipWith "brick". Drive `input`
/// through a `ctx` sequence, cycling `ctx` to align.
pub fn project<A: Copy, B: Copy, C>(
input: &[A],
ctx: &[B],
f: impl Fn(A, B) -> C,
) -> Vec<C> {
let n = ctx.len();
input.iter().enumerate().map(|(i, &a)| f(a, ctx[i % n])).collect()
} Determinism falls out of this: every sample of every render is a function of the project — not a guess from a model.
Zigzag is in private beta. New invites every Friday. Tell us a little about you and we’ll get you in.
We’ll only email you about the beta and GA launch. No newsletter, no drip, no growth-hack sequences.