17 KiB
Strudel API Reference
Patterns chain with .. Use $: prefix for multiple simultaneous patterns.
Mini-notation: "a b c" = sequence, "[a b]" = subdivision, "<a b>" = alternate, "a*2" = repeat, "a!2" = replicate, "~" = rest
s(sound:string|Pattern)=sound: Select a sound / sample by name. When using mininotation, you can also optionally supply 'n' and 'ga
ex: s("bd hh")
note():
n(value:number|Pattern): Selects the given index: for samples, it picks the sample by index, with wrap around for scales, it
ex: s("bd sd [~ bd] sd,hh6").n("<0 1>")
sound(): (no docs)
freq():
samples(): Loads a collection of samples to use with s
ex: samples('github:tidalcycles/dirt-samples'); s("[bd ]*2, [ hh]2, ~ s
stack()=polyrhythm=pr: The given items are played at the same time at the same length.
ex: stack("g3", "b3", ["e4", "d4"]).note() // "g3,b3,[e4 d4]".note()
cat(items:any)=slowcat: The given items are concatenated, where each one takes one cycle.
ex: cat("e5", "b4", ["d5", "c5"]).note() // "<e5 b4 [d5 c5]>".note()
seq()=fastcat: Like cat, but the items are crammed into one cycle.
ex: seq("e5", "b4", ["d5", "c5"]).note() // "e5 b4 [d5 c5]".note()
silence(): Does absolutely nothing..
ex: silence // "~"
pure(): A discrete value that repeats once per cycle.
ex: pure('e4') // "e4"
fast(factor:number|Pattern)=density: Speed up a pattern by the given factor. Used by "" in mini notation.
ex: s("bd hh sd hh").fast(2) // s("[bd hh sd hh]2")
slow(factor:number|Pattern)=sparsity: Slow down a pattern over the given number of cycles. Like the "/" operator in mini notatio
ex: s("bd hh sd hh").slow(2) // s("[bd hh sd hh]/2")
speed(speed:number|Pattern): Changes the speed of sample playback, i.e. a cheap way of changing pitch.
ex: s("bd6").speed("1 2 4 1 -2 -4")
cps(): (no docs)
setcps(): (no docs)
bpm(): (no docs)
every(n:number, func:function): An alias for firstOf
ex: note("c3 d3 e3 g3").every(4, x=>x.rev())
sometimes(function:function): Applies the given function with a 50% chance
ex: s("hh8").sometimes(x=>x.speed("0.5"))
often(): Shorthand for .sometimesBy(0.75, fn)
ex: s("hh8").often(x=>x.speed("0.5"))
rarely(): Shorthand for .sometimesBy(0.25, fn)
ex: s("hh8").rarely(x=>x.speed("0.5"))
almostAlways(): Shorthand for .sometimesBy(0.9, fn)
ex: s("hh8").almostAlways(x=>x.speed("0.5"))
almostNever(): Shorthand for .sometimesBy(0.1, fn)
ex: s("hh8").almostNever(x=>x.speed("0.5"))
rev(): Reverse all cycles in a pattern. See also revv for reversing a whole pattern.
ex: note("c d e g").rev()
palindrome(): Applies rev to a pattern every other cycle, so that the pattern alternates between forwards and back
ex: note("c d e g").palindrome()
jux(): The jux function creates strange stereo effects, by applying a function to a pattern, but only in th
ex: s("bd lt [~ ht] mt cp ~ bd hh").jux(rev)
superimpose(): Superimposes the result of the given function(s) on top of the original pattern:
ex: "<0 2 4 6 ~ 4 ~ 2 0!3 !5>8" .superimpose(x=>x.add(2)) .scale('C mino
layer(): Layers the result of the given function(s). Like superimpose, but without the original pattern:
ex: "<0 2 4 6 ~ 4 ~ 2 0!3 bd] sd,hh6").lpf("<4000 2000 1000 500 200 100>")
hpf(frequency:number|Pattern)=hp=hcutoff: Applies the cutoff frequency of the high-pass filter. When using mininotation, you can also optional
ex: s("bd sd [~ bd] sd,hh8").hpf("<4000 2000 1000 500 200 100>")
bpf(frequency:number|Pattern)=bandf=bp: Sets the center frequency of the band-pass filter. When using mininotation, you can also optionally
ex: s("bd sd [~ bd] sd,hh6").bpf("<1000 2000 4000 8000>")
lpq(q:number|Pattern)=resonance: Controls the low-pass q-value.
ex: s("bd sd [~ bd] sd,hh8").lpf(2000).lpq("<0 10 20 30>")
hpq(q:number|Pattern)=hresonance: Controls the high-pass q-value.
ex: s("bd sd [~ bd] sd,hh8").hpf(2000).hpq("<0 10 20 30>")
bpq(q:number|Pattern)=bandq: Sets the band-pass q-factor (resonance).
ex: s("bd sd [~ bd] sd").bpf(500).bpq("<0 1 2 3>")
lpenv(modulation:number|Pattern)=lpe: Sets the lowpass filter envelope modulation depth.
ex: note("c2 e2 f2 g2") .sound('sawtooth') .lpf(300) .lpa(.5) .lpenv("<4 2
hpenv():
room(level:number|Pattern): Sets the level of reverb. When using mininotation, you can also optionally add the 'size' parameter,
ex: s("bd sd [~ bd] sd").room("<0 .2 .4 .6 .8 1>")
roomsize(size:number|Pattern)=rsize=sz: Sets the room size of the reverb, see room. When this property is changed, the reverb will be recacu
ex: s("bd sd [~ bd] sd").room(.8).rsize(1)
delay(level:number|Pattern): Sets the level of the delay signal. When using mininotation, you can also optionally add the 'delayt
ex: s("bd bd").delay("<0 .25 .5 1>")
delaytime(delaytime:number|Pattern)=delayt=dt:
ex: note("d d a# a".fast(2)).s("sawtooth").delay(.8).delaytime(1/2).delays
delayfeedback(feedback:number|Pattern)=delayfb=dfb: Sets the level of the signal that is fed back into the delay. Caution: Values >= 1 will result in
ex: s("bd").delay(.25).delayfeedback("<.25 .5 .75 1>")
reverb(): (no docs)
distort():
shape(distortion:number|Pattern): (Deprecated) Wave shaping distortion. WARNING: can suddenly get unpredictably loud. Please use disto
ex: s("bd sd [~ bd] sd,hh8").shape("<0 .2 .4 .6 .8>")
crush():
coarse():
pan(pan:number|Pattern): Sets position in stereo.
ex: s("[bd hh]2").pan("<.5 1 .5 0>")
orbit(number:number|Pattern)=o: An orbit is a global parameter context for patterns. Patterns with the same orbit will share the sam
ex: stack( s("hh6").delay(.5).delaytime(.25).orbit(1), s("~ sd ~ sd").del
fm(): (no docs)
fmh():
fmi():
vib():
vibmod():
begin(amount:number|Pattern): A pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. 0.25 to cut off the first
ex: samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/dirt-sampl
end(length:number|Pattern): The same as .begin, but cuts off the end off each sample.
ex: s("bd2,oh4").end("<.1 .2 .5 1>").fast(2)
loop(on:number|Pattern): Loops the sample. Note that the tempo of the loop is not synced with the cycle tempo. To change the
ex: s("casio").loop(1)
chop(): Cuts each sample into the given number of parts, allowing you to explore a technique known as 'granu
ex: samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_31650
striate(): Cuts each sample into the given number of parts, triggering progressive portions of each sample at e
ex: s("numbers:0 numbers:1 numbers:2").striate(6).slow(3)
loopAt(): Makes the sample fit the given number of cycles by changing the speed.
ex: samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_31650
fit(): Makes the sample fit its event duration. Good for rhythmical loops like drum breaks. Similar to loop
ex: samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_31650
slice(): Chops samples into the given number of slices, triggering those slices with a given pattern of slice
ex: samples('github:tidalcycles/dirt-samples') s("breaks165").slice(8, "0
bank(bank:string|Pattern): Select the sound bank to use. To be used together with s. The bank name (+ "_") will be pr
ex: s("bd sd [~ bd] sd").bank('RolandTR909') // = s("RolandTR909_bd Roland
clip(factor:number|Pattern)=legato: Multiplies the duration with the given number. Also cuts samples off at the end if they exceed the d
ex: note("c a f e").s("piano").clip("<.5 1 2>")
scale(scale:string): Turns numbers into notes in the scale (zero indexed) or quantizes notes to a scale. When describing
ex: n("0 2 4 6 4 2").scale("C:major")
scaleTranspose(offset:offset)=scaleTrans=strans: Transposes notes inside the scale by the number of steps. Expected to be called on a Pattern which a
ex: "-8 [2,4,6]" .scale('C4 bebop major') .scaleTranspose("<0 -1 -2 -3 -4
mode(modeName:string|Pattern): Remove anchor note from the voicing. Useful for melody harmonization
ex: mode("").chord("C").voicing()
chord(symbols:string|Pattern): The chord to voice
ex: chord("").voicing()
voicing(): Turns chord symbols into voicings. You can use the following control params: chord: Note, followed b
ex: n("0 1 2 3").chord("").voicing()
legato(): (no docs)
sustain():
midi(midiport:string|number, options:object): MIDI output: Opens a MIDI output port.
ex: note("c4").midichan(1).midi('IAC Driver Bus 1')
midin(input:string|number): MIDI input: Opens a MIDI input port to receive MIDI control change messages. The output is a functio
ex: const cc = await midin('IAC Driver Bus 1') note("c a f e").lpf(cc(0).r
midichan(channel:number|Pattern): MIDI channel: Sets the MIDI channel for the event.
ex: note("c4").midichan(1).midi()
ccn(MIDI:number|Pattern): MIDI control number: Sends a MIDI control change message.
ccv(MIDI:number|Pattern): MIDI control value: Sends a MIDI control change message.
control(MIDI:number|Pattern, MIDI:number|Pattern): MIDI control: Sends a MIDI control change message.
midibend(midibend:number|Pattern): MIDI pitch bend: Sends a MIDI pitch bend message.
ex: note("c4").midibend(sine.slow(4).range(-0.4,0.4)).midi()
miditouch(miditouch:number|Pattern): MIDI key after touch: Sends a MIDI key after touch message.
ex: note("c4").miditouch(sine.slow(4).range(0,1)).midi()
scope(config:object, align:boolean, color:string, thickness:number, scale:number, pos:number, trigger:number)=tscope: Renders an oscilloscope for the time domain of the audio signal.
ex: s("sawtooth")._scope()
punchcard(): (no docs)
pianoroll(options:Object, cycles:integer, playhead:number, vertical:boolean, labels:boolean, flipTime:boolean, flipValues:boolean, overscan:number, hideNegative:boolean, smear:boolean, fold:boolean, active:string, inactive:string, background:string, playheadColor:string, fill:boolean, fillActive:boolean, stroke:boolean, strokeActive:boolean, hideInactive:boolean, colorizeInactive:boolean, fontFamily:string, minMidi:integer, maxMidi:integer, autorange:boolean)=punchcard: Visualises a pattern as a scrolling 'pianoroll', displayed in the background of the editor. To show
ex: note("c2 a2 eb2") .euclid(5,8) .s('sawtooth') .lpenv(4).lpf(300) .pian
spectrum(config:object, thickness:integer, speed:integer, min:integer, max:integer): Renders a spectrum analyzer for the incoming audio signal.
ex: n("<0 4 <2 3> 1>3") .off(1/8, add(n(5))) .off(1/5, add(n(7))) .scale(
pitchwheel(hapcircles:number, circle:number, edo:number, root:string, thickness:number, hapRadius:number, mode:string, margin:number): Renders a pitch circle to visualize frequencies within one octave
ex: n("0 .. 12").scale("C:chromatic") .s("sawtooth") .lpf(500) ._pitchwhee
spiral(options:Object, stretch:number, size:number, thickness:number, cap:string, inset:string, playheadColor:string, playheadLength:number, playheadThickness:number, padding:number, steady:number, activeColor:number, inactiveColor:number, colorizeInactive:boolean, fade:boolean, logSpiral:boolean): Displays a spiral visual.
ex: note("c2 a2 eb2") .euclid(5,8) .s('sawtooth') .lpenv(4).lpf(300) ._spi
log(): Writes the content of the current event to the console (visible in the side menu).
ex: s("bd sd").log()
hush(): Silences a pattern.
ex: stack( s("bd").hush(), s("hh3") )
setGain(): (no docs)!5>*8" .layer(x=>x.add("0,2")) .scale('C minor'
add(): Assumes a pattern of numbers. Adds the given number to each item in the pattern.
ex: // Here, the triad 0, 2, 4 is shifted by different amounts n("0 2 4".a
sub(): Like add, but the given numbers are subtracted.
ex: n("0 2 4".sub("<0 1 2 3>")).scale("C4:minor") // See add for more info
mul(): Multiplies each number by the given factor.
ex: "<1 1.5 [1.66, <2 2.33>]>*4".mul(150).freq()
div(): Divides each number by the given factor.
mod(): (no docs)
struct(): Applies the given structure to the pattern:
ex: note("c,eb,g") .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ operator
ex: "bd ~".stack("hh ~".early(.1)).s()
late(cycles:number|Pattern): Nudge a pattern to start later in time. Equivalent of Tidal's ~> operator
ex: "bd ~".stack("hh ~".late(.1)).s()
segment(segments:number)=seg: Samples the pattern at a rate of n events per cycle. Useful for turning a continuous pattern into a
ex: note(saw.range(40,52).segment(24))
range(): Assumes a numerical pattern, containing unipolar values in the range 0 .. 1. Returns a new pattern w
ex: s("[bd sd]2,hh8") .cutoff(sine.range(500,4000))
rangex(): Assumes a numerical pattern, containing unipolar values in the range 0 .. 1 Returns a new pattern wi
ex: s("[bd sd]2,hh8") .cutoff(sine.rangex(500,4000))
iter(): Divides a pattern into a given number of subdivisions, plays the subdivisions in order, but incremen
ex: note("0 1 2 3".scale('A minor')).iter(4)
iterBack()=iterback: Like iter, but plays the subdivisions in reverse order. Known as iter' in tidalcycles
ex: note("0 1 2 3".scale('A minor')).iterBack(4)
when(binary_pat:Pattern, func:function): Applies the given function whenever the given pattern is in a true state.
ex: "c3 eb3 g3".when("<0 1>/2", x=>x.sub("5")).note()
ifTrue(): (no docs)
degradeBy(amount:number): Randomly removes events from the pattern by a given amount. 0 = 0% chance of removal 1 = 100% chance
ex: s("hh8").degradeBy(0.2)
degrade(): Randomly removes 50% of events from the pattern. Shorthand for .degradeBy(0.5)
ex: s("hh8").degrade()
undegradeBy(amount:number): Inverse of degradeBy: Randomly removes events from the pattern by a given amount. 0 = 100% chance of
ex: s("hh8").undegradeBy(0.2)
run(): A discrete pattern of numbers from 0 to n-1
ex: n(run(4)).scale("C4:pentatonic") // n("0 1 2 3").scale("C4:pentatonic"
irand(n:number): A continuous pattern of random integers, between 0 and n-1.
ex: // randomly select scale notes from 0 - 7 (= C to C) n(irand(8)).struc
rand(): A continuous pattern of random numbers, between 0 and 1.
ex: // randomly change the cutoff s("bd4,hh8").cutoff(rand.range(500,800
perlin(): Generates a continuous pattern of perlin noise, in the range 0..1.
ex: // randomly change the cutoff s("bd4,hh8").cutoff(perlin.range(500,8
sine(): A sine signal between 0 and 1.
ex: n(sine.segment(16).range(0,15)) .scale("C:minor")
cosine(): A cosine signal between 0 and 1.
ex: n(stack(sine,cosine).segment(16).range(0,15)) .scale("C:minor")
saw(): A sawtooth signal between 0 and 1.
ex: note("<c3 [eb3,g3] g2 [g3,bb3]>8") .clip(saw.slow(2))
square(): A square signal between 0 and 1.
ex: n(square.segment(4).range(0,7)).scale("C:minor")
tri(): A triangle signal between 0 and 1.
ex: n(tri.segment(8).range(0,7)).scale("C:minor")
gain(amount:number|Pattern): Controls the gain by an exponential amount.
ex: s("hh8").gain(".4!2 1 .4!2 1 .4 1").fast(2)
velocity()=vel: Sets the velocity from 0 to 1. Is multiplied together with gain.
ex: s("hh*8") .gain(".4!2 1 .4!2 1 .4 1") .velocity(".4 1")
attack():
decay():
sustain():
release():
adsr(time:number|Pattern, time:number|Pattern, gain:number|Pattern, time:number|Pattern): ADSR envelope: Combination of Attack, Decay, Sustain, and Release.
ex: note("[c3 bb2 f3 eb3]*2").sound("sawtooth").lpf(600).adsr(".1:.1:.5:.2
lpf(frequency:number|Pattern)=cutoff=ctf: Applies the cutoff frequency of the low-pass filter. When using mininotation, you can also optionall
ex: s("bd sd [") .slow(2)
mask(): Returns silence when mask is 0 or ""
ex: note("c [eb,g] d [eb,g]").mask("<1 [0 1]>")
euclid(pulses:number, steps:number): Changes the structure of the pattern to form an Euclidean rhythm. Euclidean rhythms are rhythms obta
ex: // The Cuban tresillo pattern. note("c3").euclid(3,8)
euclidRot(pulses:number, steps:number, rotation:number): Like euclid, but has an additional parameter for 'rotating' the resulting sequence.
ex: // A Samba rhythm necklace from Brazil note("c3").euclidRot(3,16,14)
chunk()=slowChunk=slowchunk: Divides a pattern into a given number of parts, then cycles through those parts in turn, applying th
ex: "0 1 2 3".chunk(4, x=>x.add(7)) .scale("A:minor").note()
chunkBack()=chunkback: Like chunk, but cycles through the parts in reverse order. Known as chunk' in tidalcycles
ex: "0 1 2 3".chunkBack(4, x=>x.add(7)) .scale("A:minor").note()
ply(): The ply function repeats each event the given number of times.
ex: s("bd ~ sd cp").ply("<1 2 3>")
stut(times:number, feedback:number, time:number): Deprecated. Like echo, but the last 2 parameters are flipped.
ex: s("bd sd").stut(3, .8, 1/6)
echo(times:number, time:number, feedback:number): Superimpose and offset multiple times, gradually decreasing the velocity
ex: s("bd sd").echo(3, 1/6, .8)
off(time:Pattern|number, func:function): Superimposes the function result on top of the original pattern, delayed by the given time.
ex: "c3 eb3 g3".off(1/8, x=>x.add(7)).note()
early(cycles:number|Pattern): Nudge a pattern to start earlier in time. Equivalent of Tidal's <