Files
client/www/js/strudel-api-compact.md
T
2026-04-17 16:52:51 -04:00

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 !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 ~ ") .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 < 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 [ 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)