A Lisp-like pattern language for algorithmic music in Pure Data. Write expressive patterns as S-expressions, evaluate them to lists, and feed them to sequencers.
(euclid (seq 606467) 8) → 60--64--67-See this repo for the complete toolkit
In Pd: Tools → Find externals, then search for and install alien.
Optionally also install alien-theme-plugin for the dark canvas theme
(restart Pd after installing it).
Uses pd-lib-builder. For a complete walkthrough on Linux, macOS, and Windows, see INSTALL.md.
git clone --recurse-submodules https://github.com/m-onz/alien.git
cd alien
make
make install objectsdir=~/Documents/Pd/externalsTo load-test a build, open pkg-tester.pd and check the Pd console for creation
errors — every object should appear with a solid border.
[alien]
Send a pattern, get a list:
(seq 1 2 3) → 1 2 3
[alien kick snare hihat]
- One outlet per voice, plus loop bang
- Send patterns via
[; kick (euclid 4 16)] - Bang to advance step
All operators use prefix notation: (operator arg1 arg2 ...). Patterns nest freely — any argument can be another expression. The - character represents a rest (silence).
| Syntax | Description |
|---|---|
60 | A number (e.g. MIDI note) |
- | A rest (silence) |
60 → 60- → -Build a sequence from values or sub-expressions. This is how you group things together.
(seq 123) → 123
(seq 60-64-67) → 60-64-67
(seq) → (empty)
(seq (seq 12) (seq 34)) → 1234; nested seqs flattenRepeat a value or sequence n times.
(rep value count)
(rep 14) → 1111
(rep (seq 12) 3) → 121212
(rep -4) → ----
(rep (seq 606467) 2) → 606467606467All arithmetic preserves rests — rests pass through unchanged.
(add sequence n)
(add (seq 606264) 12) → 727476; transpose up octave
(add (seq 1-3) 10) → 11-13; rests preserved(sub sequence n)
(sub (seq 727679) 12) → 606467; transpose down octave
(sub (seq 0) 1) → -1; negative values (not rests)
(sub (seq 72-64) 12) → 60-52(mul sequence n)
(mul (seq 123) 2) → 246
(mul (seq 123) 0) → 000
(mul (seq 1-3) 5) → 5-15(modsequence n)
(mod (seq 8910) 7) → 123
(mod (seq 101112) 12) → 10110
(mod (seq 1-5) 3) → 1-2Linearly map values from one range to another.
(scale sequence from_min from_max to_min to_max)
(scale (seq 064127) 01270100) → 050100; MIDI to percent
(scale (seq 0510) 0106072) → 606672; map to MIDI
(scale (seq -5-) 0100100) → -50-; rests preservedConstrain values to a min/max range.
(clamp sequenceminmax)
(clamp (seq 1510) 38) → 358
(clamp (seq 050127) 20100) → 2050100
(clamp (seq 1-10) 38) → 3-8Values that exceed the range wrap around (modulo-style).
(wrap sequenceminmax)
(wrap (seq 05101520) 012) → 051038
(wrap (seq 132537) 012) → 111
(wrap (seq 607284) 6072) → 606060
(wrap (seq 1-5) 010) → 1-5Values that exceed the range bounce (reflect) back.
(fold sequenceminmax)
(fold (seq 05101520) 010) → 051050
(fold (seq 50607080) 5575) → 60607070
(fold (seq 1-8) 010) → 1-8Distribute hits evenly across steps using the Euclidean algorithm.
(euclid hits steps)
(euclid hits steps rotation)
(euclid hits steps rotation hit_value)
(euclid pattern steps)
(euclid pattern steps rotation)
; Basic: distribute hits, outputs 1 for each hit
(euclid 38) → --1--1-1
(euclid 44) → 1111
(euclid 14) → ---1
(euclid 58) → -1-11-11
(euclid 08) → --------; Rotation: shift the pattern
(euclid 382) → 1--1-1--; Hit value: output a specific number instead of 1
(euclid 38036) → --36--36-36
(euclid 44060) → 60606060; Sequence as hits: cycle values across hit positions
(euclid (seq 606467) 8) → --60--64-67
(euclid (seq 363842) 8) → --36--38-42Repeat each element n times (rhythmic subdivision).
(subdiv sequence n)
(subdiv (seq 12) 2) → 1122
(subdiv (seq 123) 3) → 111222333
(subdiv (seq 60-64) 2) → 6060--6464
(subdiv (seq 123) 1) → 123; identity(reversesequence)
(reverse (seq 123)) → 321
(reverse (seq 1-3)) → 3-1Rotate elements to the right by n positions.
(rotate sequence n)
(rotate (seq 1234) 1) → 4123
(rotate (seq 1234) 2) → 3412
(rotate (seq 1234) 0) → 1234; identityWeave two sequences together, alternating elements.
(interleave sequence_a sequence_b)
(interleave (seq 123) (seq ---)) → 1-2-3-
(interleave (seq 1) (seq 2)) → 12
(interleave (seq 12) (seq 102030)) → 11022030Randomly reorder a sequence. Non-deterministic — different result each time.
(shuffle sequence)
(shuffle (seq 1234)) → (random order)Create a palindrome — the sequence followed by itself reversed (without repeating the last element).
(mirror sequence)
(mirror (seq 123)) → 12321
(mirror (seq 12)) → 121
(mirror (seq 60646772)) → 60646772676460
(mirror (seq 1-3)) → 1-3-1(take sequence n)
(take (seq 12345) 3) → 123
(take (seq 123) 5) → 123; clamps to length
(take (seq 123) 0) → (empty)(drop sequence n)
(drop (seq 12345) 2) → 345
(drop (seq 123) 10) → (empty)
(drop (seq 123) 0) → 123; identityExtract elements from index start (inclusive) to end (exclusive).
(slice sequence start end)
(slice (seq 1020304050) 13) → 2030
(slice (seq 1020304050) 02) → 1020
(slice (seq 1020304050) 35) → 4050Take every nth element, starting from the first.
(everysequence n)
(every (seq 123456) 2) → 135
(every (seq 123456) 3) → 14
(every (seq 1234) 1) → 1234; identityStrip all rests from a sequence, keeping only values.
(filter sequence)
(filter (seq 1-2-3)) → 123
(filter (seq ---)) → (empty)
(filter (euclid 38)) → 111Generate a sequence of integers from start to end (inclusive).
(range start end)
(range start end step)
(range 15) → 12345
(range 082) → 02468
(range 0103) → 0369
(range 6072) → 60616263646566676869707172
(range 00) → 0Interpolate linearly between two values over count points.
(ramp start end count)
(ramp 60725) → 6063666972
(ramp 0104) → 03710
(ramp 1003) → 1050; descending
(ramp 003) → 000; flat
(ramp 0127) → 024681012All random operators are non-deterministic — they produce different results on each evaluation.
Randomly select one of its arguments. Each argument can be a value or expression.
(choose arg1 arg2 ...)
(choose 606467) → 60 (or 64, or67)
(choose (seq 12) (seq 34)) → 12 (or34)Generate count random integers. Defaults to MIDI range 0-127.
(rand count)
(rand countminmax)
(rand 4) → (4random values, 0-127)
(rand 46072) → (4random values, 60-72)Each element has a percent% chance of passing through. Failures become rests.
(prob sequence percent)
(prob (seq 1234) 50) → (each has 50% chance)
(prob (seq 1234) 100) → 1234; always
(prob (seq 1234) 0) → ----; neverGenerate a random walk: steps values starting at start, moving by at most max_step each time. Optionally bounded to a min-max range (reflects at boundaries).
(drunk steps max_step start)
(drunk steps max_step start minmax)
(drunk 8260) → (8 values, random walk from 60, ±2 each step)
(drunk 83604872) → (bounded between 48and72)
(drunk 161646068) → (gentle walk in narrow range)Snap each value to the nearest pitch class in a scale. Octave-aware — works correctly across the full MIDI range.
(quantize sequence scale_degrees)
; Common scales as pitch classes (0 = C, 2 = D, etc.)
(quantize (seq 616366) (seq 02457911)) → 606265; C major
(quantize (seq 60) (seq 047)) → 60; C major triad
(quantize (seq 1610) (seq 04711)) → 0711; Cmaj7Generate an arpeggio pattern from a set of notes. Direction: 0 = up, 1 = down, 2 = up-down.
(arp notes direction length)
(arp (seq 606467) 06) → 606467606467; up
(arp (seq 606467) 16) → 676460676460; down
(arp (seq 606467) 28) → 6064676460646764; up-down
(arp (seq 60) 25) → 6060606060; single noteRepeat a pattern to fill a target length.
(cycle sequencelength)
(cycle (seq 123) 8) → 12312312
(cycle (seq 123) 3) → 123; exact fit
(cycle (seq 123) 1) → 1; truncate
(cycle (seq 60-64) 6) → 60-6460-64Progressively reveal more of a pattern. Each iteration shows one more element, with rests filling the remaining slots.
(grow sequence)
(grow (seq 123)) → 1--12-123
(grow (seq 12)) → 1-12
(grow (seq 60646772)) → 60---6064--606467-60646772Keep every nth element, replace the rest with rests.
(gate sequence n)
(gate (seq 123456) 2) → 1-3-5-
(gate (seq 123456) 3) → 1--4--
(gate (seq 123) 1) → 123; identityInsert n-1 rests after each element, stretching the pattern.
(speedsequence n)
(speed (seq 123) 2) → 1-2-3-
(speed (seq 123) 4) → 1---2---3---
(speed (seq 123) 1) → 123; identity
(speed (seq 60) 3) → 60--Use a gate pattern to selectively pass through values from a source. Where the gate has a value, take the next value from the source (cycling). Where the gate has a rest, output a rest.
(mask source gate)
(mask (seq 606467) (euclid 38)) → --60--64-67
(mask (seq 123) (seq 1-1-1)) → 1-2-3
(mask (seq 12) (seq 1111)) → 1212; source cycles
(mask (seq 3638) (euclid 24)) → -36-38Add n rests before the sequence.
(delay sequence n)
(delay (seq 123) 2) → --123
(delay (seq 60) 4) → ----60
(delay (seq 123) 0) → 123; identityPatterns nest freely — any argument can be another expression:
; Arpeggiated euclidean rhythm
(euclid (arp (seq 606467) 04) 16)
; Polyrhythmic interleave
(interleave (euclid 38) (euclid 58))
; Random transposition
(add (shuffle (seq 60646771)) (choose 012))
; Euclidean kick pattern with MIDI note
(euclid 416036)
; Euclidean hi-hats with different sounds
(euclid (seq 424446) 16)
; Distribute MIDI notes over a euclidean rhythm
(mask (seq 60646772) (euclid 416))
; Filtered random walk snapped to scale
(quantize (drunk 163604872) (seq 02457911))
; Gradually reveal a chord
(grow (seq 60646772))
; Reversed ramp as velocity curve
(reverse (ramp 4012716))
; Take a slice of a cycle
(slice (cycle (seq 60646772) 32) 816)
; Gate a range to create dotted rhythm
(gate (range 6075) 3)
; Fold a drunk walk into a narrow range
(fold (drunk 16560) 5570)
; Speed up a euclidean pattern
(speed (euclid 38) 2)
; Mirror an arpeggio
(mirror (arp (seq 60646772) 04))Test patterns without Pd:
./alien_parser '(euclid 5 8)'
./alien_parser '(seq 60 64 67)'
./alien_parser '(euclid 3 8 0 36)'
./alien_parser '(drunk 16 3 60)'
./alien_parser --test # run test suite (223 tests)[; kick (euclid 4 16 0 36)]
[; snare (euclid 2 16 4 38)]
[; hihat (rep 42 16)]
[; lead (quantize (drunk 16 3 60 48 72) (seq 0 2 4 5 7 9 11))]
[; a (euclid 3 8)]
[; b (euclid 5 8)]
[; c (euclid 7 8)]
[; perc (grow (seq 36 38 42 46))]
| Operator | Args | Description |
|---|---|---|
seq | val ... | Sequence of values |
rep | val n | Repeat n times |
add | seq n | Add n to each value |
sub | seq n | Subtract n from each value |
mul | seq n | Multiply each value by n |
mod | seq n | Modulo each value by n |
scale | seq fmin fmax tmin tmax | Map from one range to another |
clamp | seq min max | Constrain to range |
wrap | seq min max | Modular wrap to range |
fold | seq min max | Reflect/fold at range boundaries |
euclid | hits steps [rot [val]] | Euclidean rhythm |
subdiv | seq n | Subdivide each element n times |
reverse | seq | Reverse order |
rotate | seq n | Rotate right by n |
interleave | a b | Alternate elements from two sequences |
shuffle | seq | Random order |
mirror | seq | Palindrome |
take | seq n | First n elements |
drop | seq n | Remove first n elements |
slice | seq start end | Sub-range (start inclusive, end exclusive) |
every | seq n | Every nth element |
filter | seq | Remove rests |
range | start end [step] | Integer range |
ramp | start end count | Linear interpolation |
choose | arg ... | Pick one argument at random |
rand | count [min max] | Random values (default 0-127) |
prob | seq percent | Probabilistic gate (0-100) |
drunk | steps max start [min max] | Random walk |
quantize | seq scale | Snap to nearest scale degree |
arp | seq dir len | Arpeggiate (0=up, 1=down, 2=up-down) |
cycle | seq len | Loop pattern to length |
grow | seq | Gradually reveal pattern |
gate | seq n | Keep every nth, rest others |
speed | seq n | Stretch with rests |
mask | source gate | Gate-controlled value selection |
delay | seq n | Prepend n rests |
Two objects coordinate high-level cue launching, so alien patterns can drive composition changes. They store no scene data and don't evaluate patterns — alien generates, Pd routes, these just launch.
[alien_cue 4]
- Registers globally in creation order; its position (1-based) is its cue index
- Creation arg: number of outlets (1-64, default 1)
- When launched, bangs all outlets right-to-left
banglaunches manually,indexposts its registry position
[alien_orchestrate]
- Floats are 1-based cue indices, wrapped over the registered cue count
(with 4 cues:
5→ cue 1,0→ cue 4,-1→ cue 3) - Every number retriggers — use rests to let a cue keep playing
- Rests (
-._) do nothing bangrelaunches the last cue,resetclears itcount/dumppost the registry to the console- Outlet: launched cue index (1-based) — useful for displays
Define cues, each a bundle of pattern messages:
[alien_cue 4]
| | | |
[; kick (euclid 4 16)] [; snare (euclid 2 16 4)] [; bass (seq 0 - 3 -)] [; shader (seq 12)]
[alien_cue 4]
| | | |
[; kick (euclid 7 16)] [; snare (prob (euclid 3 16 4) 70)] [; bass (drunk 16 1 3 0 7)] [; shader (seq 31)]
Then drive the arrangement with an alien pattern — each step is a cue number:
[(seq 1 - - - 2 - - - 1 1 2 -)(
|
[alien]
|
[else/sequencer]
|
[alien_orchestrate]
Cue launches feed named aliens, so pattern changes still batch through the 100ms sync window and switch together.
The theme/ folder contains a dark canvas theme.
Named after the Lisp alien
MIT
