Garden Language
Text-based syntax for creating Pure Data patches. Write readable code, transpile to .pd files for MidiGarden.
Example Patches
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 |