Skip to content

Latest commit

History

64 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

alien

alien

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

Installation

Via Pd's package manager (recommended — no compiler needed)

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).

From source

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/externals

To load-test a build, open pkg-tester.pd and check the Pd console for creation errors — every object should appear with a solid border.

Usage

Generator Mode

[alien]

Send a pattern, get a list:

(seq 1 2 3) → 1 2 3

Sequencer Mode

[alien kick snare hihat]
  • One outlet per voice, plus loop bang
  • Send patterns via [; kick (euclid 4 16)]
  • Bang to advance step

Pattern Language Reference

All operators use prefix notation: (operator arg1 arg2 ...). Patterns nest freely — any argument can be another expression. The - character represents a rest (silence).


Basics

SyntaxDescription
60A number (e.g. MIDI note)
-A rest (silence)
6060--

seq — Sequence

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 flatten

rep — Repeat

Repeat a value or sequence n times.

(rep value count)
(rep 14) → 1111
(rep (seq 12) 3) → 121212
(rep -4) → ----
(rep (seq 606467) 2) → 606467606467

Arithmetic

All arithmetic preserves rests — rests pass through unchanged.

add — Add

(add sequence n)
(add (seq 606264) 12) → 727476; transpose up octave
(add (seq 1-3) 10) → 11-13; rests preserved

sub — Subtract

(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 — Multiply

(mul sequence n)
(mul (seq 123) 2) → 246
(mul (seq 123) 0) → 000
(mul (seq 1-3) 5) → 5-15

mod — Modulo

(modsequence n)
(mod (seq 8910) 7) → 123
(mod (seq 101112) 12) → 10110
(mod (seq 1-5) 3) → 1-2

scale — Map Range

Linearly 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 preserved

clamp — Clamp Range

Constrain values to a min/max range.

(clamp sequenceminmax)
(clamp (seq 1510) 38) → 358
(clamp (seq 050127) 20100) → 2050100
(clamp (seq 1-10) 38) → 3-8

wrap — Modular Wrap

Values 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-5

fold — Fold / Reflect

Values 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-8

Rhythm

euclid — Euclidean Rhythm

Distribute 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-42

subdiv — Subdivide

Repeat 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

List Manipulation

reverse

(reversesequence)
(reverse (seq 123)) → 321
(reverse (seq 1-3)) → 3-1

rotate

Rotate 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; identity

interleave

Weave 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)) → 11022030

shuffle

Randomly reorder a sequence. Non-deterministic — different result each time.

(shuffle sequence)
(shuffle (seq 1234)) → (random order)

mirror

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

Selection / Filtering

take — First N

(take sequence n)
(take (seq 12345) 3) → 123
(take (seq 123) 5) → 123; clamps to length
(take (seq 123) 0) → (empty)

drop — Remove First N

(drop sequence n)
(drop (seq 12345) 2) → 345
(drop (seq 123) 10) → (empty)
(drop (seq 123) 0) → 123; identity

slice — Sub-range

Extract 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) → 4050

every — Every Nth

Take every nth element, starting from the first.

(everysequence n)
(every (seq 123456) 2) → 135
(every (seq 123456) 3) → 14
(every (seq 1234) 1) → 1234; identity

filter — Remove Rests

Strip all rests from a sequence, keeping only values.

(filter sequence)
(filter (seq 1-2-3)) → 123
(filter (seq ---)) → (empty)
(filter (euclid 38)) → 111

Pattern Generation

range

Generate 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) → 0

ramp

Interpolate 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) → 024681012

Randomness

All random operators are non-deterministic — they produce different results on each evaluation.

choose — Pick One

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)

rand — Random Values

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)

prob — Probabilistic Gate

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) → ----; never

drunk — Random Walk

Generate 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)

Musical

quantize — Snap to Scale

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; Cmaj7

arp — Arpeggiate

Generate 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 note

Time / Structure

cycle — Loop to Length

Repeat 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-64

grow — Gradual Reveal

Progressively 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-60646772

gate — Rhythmic Gate

Keep 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; identity

speed — Stretch

Insert 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--

mask — Pattern Gating

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-38

delay — Prepend Rests

Add n rests before the sequence.

(delay sequence n)
(delay (seq 123) 2) → --123
(delay (seq 60) 4) → ----60
(delay (seq 123) 0) → 123; identity

Composition

Patterns 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))

CLI Tool

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)

Examples

Four-on-the-floor

[; kick (euclid 4 16 0 36)]
[; snare (euclid 2 16 4 38)]
[; hihat (rep 42 16)]

Generative melody

[; lead (quantize (drunk 16 3 60 48 72) (seq 0 2 4 5 7 9 11))]

Polyrhythm

[; a (euclid 3 8)]
[; b (euclid 5 8)]
[; c (euclid 7 8)]

Build-up

[; perc (grow (seq 36 38 42 46))]

Operator Quick Reference

OperatorArgsDescription
seqval ...Sequence of values
repval nRepeat n times
addseq nAdd n to each value
subseq nSubtract n from each value
mulseq nMultiply each value by n
modseq nModulo each value by n
scaleseq fmin fmax tmin tmaxMap from one range to another
clampseq min maxConstrain to range
wrapseq min maxModular wrap to range
foldseq min maxReflect/fold at range boundaries
euclidhits steps [rot [val]]Euclidean rhythm
subdivseq nSubdivide each element n times
reverseseqReverse order
rotateseq nRotate right by n
interleavea bAlternate elements from two sequences
shuffleseqRandom order
mirrorseqPalindrome
takeseq nFirst n elements
dropseq nRemove first n elements
sliceseq start endSub-range (start inclusive, end exclusive)
everyseq nEvery nth element
filterseqRemove rests
rangestart end [step]Integer range
rampstart end countLinear interpolation
choosearg ...Pick one argument at random
randcount [min max]Random values (default 0-127)
probseq percentProbabilistic gate (0-100)
drunksteps max start [min max]Random walk
quantizeseq scaleSnap to nearest scale degree
arpseq dir lenArpeggiate (0=up, 1=down, 2=up-down)
cycleseq lenLoop pattern to length
growseqGradually reveal pattern
gateseq nKeep every nth, rest others
speedseq nStretch with rests
masksource gateGate-controlled value selection
delayseq nPrepend n rests

Orchestration

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 — Cue Bundle

[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
  • bang launches manually, index posts its registry position

alien_orchestrate — Cue Launcher

[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
  • bang relaunches the last cue, reset clears it
  • count / dump post the registry to the console
  • Outlet: launched cue index (1-based) — useful for displays

Example

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.

Theme

The theme/ folder contains a dark canvas theme.

Credits

Named after the Lisp alien

License

MIT

About

Pure data externals for algorithmic composition

Topics

Resources

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages