random(...) — A Roll of the Dice as a Signal

random() picks a number when it fires and publishes it, so any bindable parameter can be driven by chance:

random(uid:dice, min:1, max:8, int:1, trig:"adc.onset>0.5")
image(path:plates, index: follow(dice.norm))

An attack on the microphone deals a new plate from the folder.

Why it is not called rand(). rand(min, max) already exists as a value function inside patterns and value lists — values:Pseq(1, rand(0.5, 2), inf) — and is used in real scores. A cue of the same name would claim the word everywhere it appears and break them. rand() stays the inline function; random() is the standalone object.


Syntax

random()
random(uid:NAME)
random(uid:NAME, min:1, max:8)
random(uid:NAME, min:1, max:8, int:1)
random(uid:NAME, min:1, max:8, int:1, trig:"adc.onset>0.5")

Parameters

param default description
uid random The name the roll publishes under.
min 0 Low end of the range.
max 1 High end. Writing them the wrong way round is read the way you meant it.
int off int:1 rolls whole numbers only — folder indices, MIDI notes, bar numbers.
trig playhead What makes it roll. Any trigger mode, a uid, or a signal threshold.

Outlets

channel description
value The roll, in the min–max range you asked for
norm The same roll as 0–1

Bind norm unless you have a reason not to. Most inlets expect 0–1 and supply their own output range — image(index:) spans the whole folder that way — so follow(dice.norm) needs no numbers. Use value when the raw number is what the target wants:

image(path:plates, index: follow(dice.norm))       spans the folder
synth(freq: map(dice.value, 1, 8, 200, 900))     eight pitches

int:1 rolls evenly: every whole number in the range is equally likely, endpoints included. (Rounding a scaled float would make the first and last half as likely as the rest — in a folder, the kind of thing that gets written off as bad luck rather than noticed as a bug.)


trig: on a signal threshold

Any cue can be fired by a signal crossing a value, not just this one:

nav(scroll@B,        trig:"adc.amp>0.8")
audio(src:hit.wav,   trig:"adc.onset>0.5")
random(uid:d, max:8, trig:"fader1.t>=0.9")

This is different from if:, which gates a cue that something else is already firing. A threshold trig: makes the signal the cause.

It fires on the rising edge. Conditions are checked on every publish, and audio publishes about sixty times a second, so a cue that fired whenever the condition merely held would fire sixty times through one clap. It fires as the condition becomes true and re-arms when the value falls back. A score loaded while the condition already holds stays quiet rather than firing everything at once.

Add once:1 to fire only the first time, ever.

The quotes are required — the lexer does not read > or < inside an unquoted parameter value, so trig:adc.onset>0.5 fails to parse. Same rule as if:.

A threshold trigger is drawn in the connections view as a cord from the source's channel to the cue it fires.


Examples

Deal a picture on every attack

random(uid:dice, min:1, max:8, int:1, trig:"adc.onset>0.5")
image(path:plates, index: follow(dice.norm))

A random pitch when the room gets loud

random(uid:note, min:48, max:72, int:1, trig:"adc.amp>0.6")
synth(uid:s1, freq: follow(note.norm, 130, 520), dur:1)

One roll, several things

random(uid:r, trig:"adc.onset>0.5")
scale(uid:box,  sx: follow(r.norm, 0.5, 2))
color(uid:box2, dur: follow(r.norm, 0.2, 3))

A source with an outlet composes — the same roll drives everything bound to it.

Roll on the playhead instead

random(uid:d, min:1, max:6, int:1)

With no trig:, it rolls once when the playhead reaches it.


Demo

See demo-generative — an animation used as a clock, random() on a threshold, probability gating with if:, and patterns. Everything in it is built from parts that already exist; the last section is an honest account of where it stops.

http://localhost:8001/?project=demo-generative


See Also

Tip: use ← → or ↑ ↓ to navigate the docs