Garden Language

Text-based syntax for creating Pure Data patches. Write readable code, transpile to .pd files for MidiGarden.

Example Patches

Garden Syntax
Pure Data Output

Why Garden?

Garden makes it easy to create synthesizers for MidiGarden. Write patches in readable text, let the transpiler handle coordinates and connections. Perfect for AI-assisted generation, version control, and sharing patches.

The Workflow

1. Write Garden

Readable syntax with named variables. Use templates for reusable components.

2. Transpile

Convert to Pure Data. Object placement and wiring handled automatically.

3. Load in MidiGarden

Drop .pd files into MidiGarden. Play with touch controls and parameters.

4. Share

Share .garden source files. Others can modify and learn from your patches.

Why Text Over Visual Patching?

AI Generation

LLMs struggle with coordinates. Named variables are natural to generate.

Version Control

Git diffs are readable. No coordinate noise from moving objects.

Templates

Define an envelope once, use it everywhere. No copy-paste errors.

Batch Processing

Transpile whole synth packs. Automate with build scripts.

See the Difference

Garden (Readable)

// MIDI input
note_in = inlet();
pitch, vel = unpack f f(note_in);
note_off, gate = sel 0(vel);

// Synthesis
freq = mtof(pitch);
osc_out = osc~(freq);

// Envelope + output
env = line~(pack 1 5(gate) pack 0 300(gate));
out = *~(osc_out, env);
outlet~(out);
outlet~(out);

Pure Data (Generated)

#N canvas 0 0 800 600 10;
#X obj 180 22 inlet;
#X obj 180 44 unpack f f;
#X obj 180 66 sel 0;
#X obj 180 88 mtof;
#X obj 180 110 osc~;
#X obj 180 132 pack 1 5;
#X obj 180 154 pack 0 300;
#X obj 180 176 line~;
#X obj 180 198 *~;
#X obj 180 220 outlet~;
#X obj 180 242 outlet~;
#X connect 0 0 1 0;
... (plus 10+ connection lines)

Syntax Features

Named Variables

Assign outputs to variables. Reference by name instead of connection indices.

freq = mtof(pitch);
freq_sig = sig~(freq);
osc_out = osc~(freq_sig);

Multiple Outputs

Unpack multi-outlet objects into separate variables.

pitch, velocity = unpack f f(note_in);
note_off, gate = sel 0(velocity);

Message Boxes

The msg keyword creates PD message boxes.

attack_msg = msg 1 50(gate);
release_msg = msg 0 300(note_off);
env = line~(attack_msg release_msg);

Templates

Define reusable code blocks with <NN> placeholder.

def out = gain<NN>(sig, amount) {
  amt_sig = sig~(amount);
  out = *~(sig, amt_sig);
}

output = gain<1>(osc, 0.5);

Quick Reference

What you want Garden syntax Notes
Create an object name = osc~ 440(); Arguments before parens, inputs inside
Connect objects b = osc~(a); Just pass the variable name
Multiple inputs out = *~(sig, amp); Comma-separated for different inlets
Same inlet out = +~(a b); Space-separated = same inlet
Multiple outputs a, b = unpack f f(in); Comma-separated on left side
Message box m = msg 1 50(trigger); Starts with msg
Comment // This is a comment Inline or standalone