mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-13 14:48:36 +00:00
commit
c1a27aa6e4
@ -513,11 +513,14 @@ export class Pattern {
|
||||
}
|
||||
|
||||
/**
|
||||
* Assumes a numerical pattern, containing unipolar values in the range 0 ..
|
||||
* 1. Returns a new pattern with values scaled to the given min/max range.
|
||||
* @param {Number} min
|
||||
* @param {Number} max
|
||||
* Assumes a numerical pattern, containing unipolar values in the range 0 .. 1.
|
||||
* Returns a new pattern with values scaled to the given min/max range.
|
||||
* Most useful in combination with continuous patterns.
|
||||
* @name range
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* s("bd sd,hh*4").cutoff(sine.range(500,2000).slow(4)).out()
|
||||
*/
|
||||
range(min, max) {
|
||||
return this.mul(max - min).add(min);
|
||||
@ -683,6 +686,16 @@ export class Pattern {
|
||||
return func(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Layers the result of the given function(s). Like {@link superimpose}, but without the original pattern:
|
||||
* @name layer
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "<0 2 4 6 ~ 4 ~ 2 0!3 ~!5>*4"
|
||||
* .layer(x=>x.add("0,2"))
|
||||
* .scale('C minor').note().out()
|
||||
*/
|
||||
layer(...funcs) {
|
||||
return stack(...funcs.map((func) => func(this)));
|
||||
}
|
||||
@ -734,14 +747,14 @@ export class Pattern {
|
||||
}
|
||||
|
||||
/**
|
||||
* Speed up a pattern by the given factor.
|
||||
* Speed up a pattern by the given factor. Used by "*" in mini notation.
|
||||
*
|
||||
* @name fast
|
||||
* @memberof Pattern
|
||||
* @param {number | Pattern} factor speed up factor
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* seq(e5, b4, d5, c5).fast(2)
|
||||
* s("<bd sd> hh").fast(2).out() // s("[<bd sd> hh]*2").out()
|
||||
*/
|
||||
_fast(factor) {
|
||||
const fastQuery = this.withQueryTime((t) => t.mul(factor));
|
||||
@ -749,14 +762,14 @@ export class Pattern {
|
||||
}
|
||||
|
||||
/**
|
||||
* Slow down a pattern over the given number of cycles.
|
||||
* Slow down a pattern over the given number of cycles. Like the "/" operator in mini notation.
|
||||
*
|
||||
* @name slow
|
||||
* @memberof Pattern
|
||||
* @param {number | Pattern} factor slow down factor
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* seq(e5, b4, d5, c5).slow(2)
|
||||
* s("<bd sd> hh").slow(2).out() // s("[<bd sd> hh]/2").out()
|
||||
*/
|
||||
_slow(factor) {
|
||||
return this._fast(Fraction(1).div(factor));
|
||||
@ -795,14 +808,32 @@ export class Pattern {
|
||||
return this._fast(cpm / 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nudge a pattern to start earlier in time. Equivalent of Tidal's <~ operator
|
||||
*
|
||||
* @name early
|
||||
* @memberof Pattern
|
||||
* @param {number | Pattern} cycles number of cycles to nudge left
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "bd ~".stack("hh ~".early(.1)).s().out()
|
||||
*/
|
||||
_early(offset) {
|
||||
// Equivalent of Tidal's <~ operator
|
||||
offset = Fraction(offset);
|
||||
return this.withQueryTime((t) => t.add(offset)).withHapTime((t) => t.sub(offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Nudge a pattern to start later in time. Equivalent of Tidal's ~> operator
|
||||
*
|
||||
* @name late
|
||||
* @memberof Pattern
|
||||
* @param {number | Pattern} cycles number of cycles to nudge right
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "bd ~".stack("hh ~".late(.1)).s().out()
|
||||
*/
|
||||
_late(offset) {
|
||||
// Equivalent of Tidal's ~> operator
|
||||
offset = Fraction(offset);
|
||||
return this._early(Fraction(0).sub(offset));
|
||||
}
|
||||
@ -829,6 +860,17 @@ export class Pattern {
|
||||
return this._zoom(0, t)._slow(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given structure to the pattern:
|
||||
*
|
||||
* @name struct
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3,eb3,g3"
|
||||
* .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~")
|
||||
* .slow(4).note().out()
|
||||
*/
|
||||
// struct(...binary_pats) {
|
||||
// // Re structure the pattern according to a binary pattern (false values are dropped)
|
||||
// const binary_pat = sequence(binary_pats);
|
||||
@ -876,6 +918,16 @@ export class Pattern {
|
||||
return this.invert();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function whenever the given pattern is in a true state.
|
||||
* @name when
|
||||
* @memberof Pattern
|
||||
* @param {Pattern} binary_pat
|
||||
* @param {function} func
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3 eb3 g3".when("<0 1>/2", x=>x.sub(5))
|
||||
*/
|
||||
when(binary_pat, func) {
|
||||
//binary_pat = sequence(binary_pat)
|
||||
const true_pat = binary_pat._filterValues(id);
|
||||
@ -885,10 +937,47 @@ export class Pattern {
|
||||
return stack(with_pat, without_pat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Superimposes the function result on top of the original pattern, delayed by the given time.
|
||||
* @name off
|
||||
* @memberof Pattern
|
||||
* @param {Pattern | number} time offset time
|
||||
* @param {function} func function to apply
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3 eb3 g3".off(1/8, x=>x.add(7))
|
||||
*/
|
||||
off(time_pat, func) {
|
||||
return stack(this, func(this.late(time_pat)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function every n cycles.
|
||||
* @name every
|
||||
* @memberof Pattern
|
||||
* @param {number} n how many cycles
|
||||
* @param {function} func function to apply
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* note("c3 d3 e3 g3").every(4, x=>x.rev()).out()
|
||||
*/
|
||||
every(n, func) {
|
||||
const pat = this;
|
||||
const pats = Array(n - 1).fill(pat);
|
||||
// pats.unshift(func(pat));
|
||||
pats.push(func(pat));
|
||||
return slowcatPrime(...pats);
|
||||
}
|
||||
/**
|
||||
* Applies the given function every n cycles, starting from the first cycle.
|
||||
* @name every
|
||||
* @memberof Pattern
|
||||
* @param {number} n how many cycles
|
||||
* @param {function} func function to apply
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* note("c3 d3 e3 g3").every(4, x=>x.rev()).out()
|
||||
*/
|
||||
every(n, func) {
|
||||
const pat = this;
|
||||
const pats = Array(n - 1).fill(pat);
|
||||
@ -896,6 +985,23 @@ export class Pattern {
|
||||
return slowcatPrime(...pats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function every n cycles, starting from the last cycle.
|
||||
* @name each
|
||||
* @memberof Pattern
|
||||
* @param {number} n how many cycles
|
||||
* @param {function} func function to apply
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* note("c3 d3 e3 g3").every(4, x=>x.rev()).out()
|
||||
*/
|
||||
each(n, func) {
|
||||
const pat = this;
|
||||
const pats = Array(n - 1).fill(pat);
|
||||
pats.push(func(pat));
|
||||
return slowcatPrime(...pats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new pattern where every other cycle is played once, twice as
|
||||
* fast, and offset in time by one quarter of a cycle. Creates a kind of
|
||||
@ -906,6 +1012,15 @@ export class Pattern {
|
||||
return this.when(slowcat(false, true), (x) => fastcat(x, silence)._late(0.25));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse all haps in a pattern
|
||||
*
|
||||
* @name rev
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3 d3 e3 g3".rev()
|
||||
*/
|
||||
rev() {
|
||||
const pat = this;
|
||||
const query = function (state) {
|
||||
@ -948,6 +1063,15 @@ export class Pattern {
|
||||
return this.juxBy(1, func);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stacks the given pattern(s) to the current pattern.
|
||||
* @name stack
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* s("hh*2").stack(
|
||||
* n("c2(3,8)")
|
||||
* ).out()
|
||||
*/
|
||||
stack(...pats) {
|
||||
return stack(this, ...pats);
|
||||
}
|
||||
@ -956,11 +1080,28 @@ export class Pattern {
|
||||
return sequence(this, ...pats);
|
||||
}
|
||||
|
||||
// shorthand for sequence
|
||||
/**
|
||||
* Appends the given pattern(s) to the current pattern. Synonyms: .sequence .fastcat
|
||||
* @name seq
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* s("hh*2").seq(
|
||||
* n("c2(3,8)")
|
||||
* ).out()
|
||||
*/
|
||||
seq(...pats) {
|
||||
return sequence(this, ...pats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given pattern(s) to the next cycle. Synonym: .slowcat
|
||||
* @name cat
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* s("hh*2").cat(
|
||||
* n("c2(3,8)")
|
||||
* ).out()
|
||||
*/
|
||||
cat(...pats) {
|
||||
return cat(this, ...pats);
|
||||
}
|
||||
@ -973,6 +1114,16 @@ export class Pattern {
|
||||
return slowcat(this, ...pats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Superimposes the result of the given function(s) on top of the original pattern:
|
||||
* @name superimpose
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "<0 2 4 6 ~ 4 ~ 2 0!3 ~!5>*4"
|
||||
* .superimpose(x=>x.add(2))
|
||||
* .scale('C minor').note().out()
|
||||
*/
|
||||
superimpose(...funcs) {
|
||||
return this.stack(...funcs.map((func) => func(this)));
|
||||
}
|
||||
@ -1184,6 +1335,11 @@ Pattern.prototype.patternified = [
|
||||
'slow',
|
||||
'velocity',
|
||||
];
|
||||
|
||||
// aliases
|
||||
export const polyrhythm = stack;
|
||||
export const pr = stack;
|
||||
|
||||
// methods that create patterns, which are added to patternified Pattern methods
|
||||
Pattern.prototype.factories = {
|
||||
pure,
|
||||
@ -1206,12 +1362,11 @@ Pattern.prototype.factories = {
|
||||
// Nothing
|
||||
export const silence = new Pattern((_) => []);
|
||||
|
||||
/** A discrete value that repeats once per cycle:
|
||||
/** A discrete value that repeats once per cycle.
|
||||
*
|
||||
* @param {any} value - The value to repeat
|
||||
* @returns {Pattern}
|
||||
* @example
|
||||
* pure('e4')
|
||||
* pure('e4') // "e4"
|
||||
*/
|
||||
export function pure(value) {
|
||||
function query(state) {
|
||||
@ -1241,12 +1396,11 @@ export function reify(thing) {
|
||||
return pure(thing);
|
||||
}
|
||||
|
||||
/** The given items are played at the same time at the same length:
|
||||
/** The given items are played at the same time at the same length.
|
||||
*
|
||||
* @param {...any} items - The items to stack
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* stack(g3, b3, [e4, d4])
|
||||
* stack(g3, b3, [e4, d4]) // "g3,b3,[e4,d4]"
|
||||
*/
|
||||
export function stack(...pats) {
|
||||
// Array test here is to avoid infinite recursions..
|
||||
@ -1259,7 +1413,6 @@ export function stack(...pats) {
|
||||
*
|
||||
* synonyms: {@link cat}
|
||||
*
|
||||
* @param {...any} items - The items to concatenate
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* slowcat(e5, b4, [d5, c5])
|
||||
@ -1315,16 +1468,22 @@ export function fastcat(...pats) {
|
||||
return slowcat(...pats)._fast(pats.length);
|
||||
}
|
||||
|
||||
/** See {@link slowcat} */
|
||||
/** The given items are con**cat**enated, where each one takes one cycle. Synonym: slowcat
|
||||
*
|
||||
* @param {...any} items - The items to concatenate
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* cat(e5, b4, [d5, c5]) // "<e5 b4 [d5 c5]>"
|
||||
*
|
||||
*/
|
||||
export function cat(...pats) {
|
||||
return slowcat(...pats);
|
||||
}
|
||||
|
||||
/** Like {@link fastcat}, but where each step has a temporal weight:
|
||||
* @param {...Array} items - The items to concatenate
|
||||
/** Like {@link seq}, but each step has a length, relative to the whole.
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* timeCat([3,e3],[1, g3])
|
||||
* timeCat([3,e3],[1, g3]) // "e3@3 g3"
|
||||
*/
|
||||
export function timeCat(...timepats) {
|
||||
const total = timepats.map((a) => a[0]).reduce((a, b) => a.add(b), Fraction(0));
|
||||
@ -1343,7 +1502,11 @@ export function sequence(...pats) {
|
||||
return fastcat(...pats);
|
||||
}
|
||||
|
||||
/** See {@link fastcat} */
|
||||
/** Like **cat**, but the items are crammed into one cycle. Synonyms: fastcat, sequence
|
||||
* @example
|
||||
* seq(e5, b4, [d5, c5]) // "e5 b4 [d5 c5]"
|
||||
*
|
||||
*/
|
||||
export function seq(...pats) {
|
||||
return fastcat(...pats);
|
||||
}
|
||||
@ -1392,20 +1555,6 @@ export function pm(...args) {
|
||||
polymeter(...args);
|
||||
}
|
||||
|
||||
export function polyrhythm(...xs) {
|
||||
const seqs = xs.map((a) => sequence(a));
|
||||
|
||||
if (seqs.length == 0) {
|
||||
return silence;
|
||||
}
|
||||
return stack(...seqs);
|
||||
}
|
||||
|
||||
// alias
|
||||
export function pr(args) {
|
||||
polyrhythm(args);
|
||||
}
|
||||
|
||||
export const add = curry((a, pat) => pat.add(a));
|
||||
export const chop = curry((a, pat) => pat.chop(a));
|
||||
export const chunk = curry((a, pat) => pat.chunk(a));
|
||||
|
||||
@ -74,7 +74,7 @@ export const square2 = square._toBipolar();
|
||||
*
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* triangle.segment(2).range(0,7).scale('C minor')
|
||||
* tri.segment(8).range(0,7).scale('C minor')
|
||||
*
|
||||
*/
|
||||
export const tri = fastcat(isaw, saw);
|
||||
@ -111,7 +111,17 @@ const timeToRandsPrime = (seed, n) => {
|
||||
const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
|
||||
|
||||
/**
|
||||
* A continuous pattern of random numbers, between 0 and 1
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A continuous pattern of random numbers, between 0 and 1.
|
||||
*
|
||||
* @name rand
|
||||
* @example
|
||||
* // randomly change the cutoff
|
||||
* s("bd sd,hh*4").cutoff(rand.range(500,2000)).out()
|
||||
*
|
||||
*/
|
||||
export const rand = signal(timeToRand);
|
||||
/**
|
||||
@ -124,6 +134,17 @@ export const brandBy = (pPat) => reify(pPat).fmap(_brandBy).innerJoin();
|
||||
export const brand = _brandBy(0.5);
|
||||
|
||||
export const _irand = (i) => rand.fmap((x) => Math.trunc(x * i));
|
||||
|
||||
/**
|
||||
* A continuous pattern of random integers, between 0 and n-1.
|
||||
*
|
||||
* @name irand
|
||||
* @param {number} n max value (exclusive)
|
||||
* @example
|
||||
* // randomly select scale notes from 0 - 7 (= C to C)
|
||||
* irand(8).struct("x(3,8)").scale('C minor').note().out()
|
||||
*
|
||||
*/
|
||||
export const irand = (ipat) => reify(ipat).fmap(_irand).innerJoin();
|
||||
|
||||
export const __chooseWith = (pat, xs) => {
|
||||
@ -225,6 +246,15 @@ export const perlinWith = (pat) => {
|
||||
return pat.sub(pata).fmap(interp).appBoth(pata.fmap(timeToRand)).appBoth(patb.fmap(timeToRand));
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a continuous pattern of [perlin noise](https://en.wikipedia.org/wiki/Perlin_noise), in the range 0..1.
|
||||
*
|
||||
* @name perlin
|
||||
* @example
|
||||
* // randomly change the cutoff
|
||||
* s("bd sd,hh*4").cutoff(perlin.range(500,2000)).out()
|
||||
*
|
||||
*/
|
||||
export const perlin = perlinWith(time);
|
||||
|
||||
Pattern.prototype._degradeByWith = function (withPat, x) {
|
||||
|
||||
@ -413,65 +413,21 @@ The above is the same as:
|
||||
|
||||
Using strings, you can also use "#".
|
||||
|
||||
## Functions that create Patterns
|
||||
## Pattern Factories
|
||||
|
||||
The following functions will return a pattern. We will see later what that means.
|
||||
The following functions will return a pattern.
|
||||
|
||||
## pure(value)
|
||||
|
||||
To create a pattern from a value, you can wrap the value in pure:
|
||||
|
||||
<MiniRepl tune={`pure('e4')`} />
|
||||
{{ 'pure' | jsdoc }}
|
||||
|
||||
Most of the time, you won't need that function as input values of pattern creating functions are purified by default.
|
||||
|
||||
### cat(...values)
|
||||
{{ 'cat' | jsdoc }}
|
||||
|
||||
The given items are con**cat**enated, where each one takes one cycle:
|
||||
{{ 'seq' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`cat(e5, b4, [d5, c5])`} />
|
||||
{{ 'stack' | jsdoc }}
|
||||
|
||||
- Square brackets will create a subsequence
|
||||
- The function **slowcat** does the same as **cat**.
|
||||
|
||||
### seq(...values)
|
||||
|
||||
Like **cat**, but the items are crammed into one cycle:
|
||||
|
||||
<MiniRepl tune={`seq(e5, b4, [d5, c5])`} />
|
||||
|
||||
- Synonyms: **fastcat**, **sequence**
|
||||
|
||||
### stack(...values)
|
||||
|
||||
The given items are played at the same time at the same length:
|
||||
|
||||
<MiniRepl tune={`stack(g3, b3, [e4, d4])`} />
|
||||
|
||||
- Square Brackets will create a subsequence
|
||||
|
||||
### Nesting functions
|
||||
|
||||
You can nest functions inside one another:
|
||||
|
||||
<MiniRepl
|
||||
tune={`cat(
|
||||
stack(g3,b3,e4),
|
||||
stack(a3,c3,e4),
|
||||
stack(b3,d3,fs4),
|
||||
stack(b3,e4,g4)
|
||||
)`}
|
||||
/>
|
||||
|
||||
The above is equivalent to
|
||||
|
||||
<MiniRepl tune={`"<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>"`} />
|
||||
|
||||
### timeCat(...[weight,value])
|
||||
|
||||
Like with "@" in mini notation, we can specify weights to the items in a sequence:
|
||||
|
||||
<MiniRepl tune={`timeCat([3,e3],[1, g3])`} />
|
||||
{{ 'timeCat' | jsdoc }}
|
||||
|
||||
<!-- ## polymeter
|
||||
|
||||
@ -479,6 +435,10 @@ how to use?
|
||||
|
||||
<MiniRepl tune={`polymeter(3, e3, g3, b3)`} /> -->
|
||||
|
||||
<!--
|
||||
|
||||
see https://github.com/tidalcycles/strudel/discussions/211
|
||||
|
||||
### polyrhythm(...[...values])
|
||||
|
||||
Plays the given items at the same time, within the same length:
|
||||
@ -491,59 +451,82 @@ We can write the same with **stack** and **cat**:
|
||||
|
||||
You can also use the shorthand **pr** instead of **polyrhythm**.
|
||||
|
||||
## Pattern modifier functions
|
||||
-->
|
||||
|
||||
The following functions modify a pattern.
|
||||
## Combining Patterns
|
||||
|
||||
### slow(factor)
|
||||
You can freely mix JS patterns, mini patterns and values! For example, this pattern:
|
||||
|
||||
Like "/" in mini notation, **slow** will slow down a pattern over the given number of cycles:
|
||||
<MiniRepl
|
||||
tune={`cat(
|
||||
stack(g3,b3,e4),
|
||||
stack(a3,c3,e4),
|
||||
stack(b3,d3,fs4),
|
||||
stack(b3,e4,g4)
|
||||
)`}
|
||||
/>
|
||||
|
||||
<MiniRepl tune={`seq(e5, b4, d5, c5).slow(2)`} />
|
||||
...is equivalent to:
|
||||
|
||||
The same in mini notation:
|
||||
<MiniRepl
|
||||
tune={`cat(
|
||||
"g3,b3,e4",
|
||||
"a3,c3,e4",
|
||||
"b3,d3,f#4",
|
||||
"b3,e4,g4"
|
||||
)`}
|
||||
/>
|
||||
|
||||
<MiniRepl tune={`"[e5 b4 d5 c5]/2"`} />
|
||||
... as well as:
|
||||
|
||||
### fast(factor)
|
||||
<MiniRepl tune={`"<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>"`} />
|
||||
|
||||
Like "\*" in mini notation, **fast** will play a pattern times the given number in one cycle:
|
||||
While mini notation is almost always shorter, it only has a handful of modifiers: \* / ! @.
|
||||
When using JS patterns, there is a lot more you can do.
|
||||
|
||||
<MiniRepl tune={`seq(e5, b4, d5, c5).fast(2)`} />
|
||||
## Time Modifiers
|
||||
|
||||
### early(cycles)
|
||||
The following functions modify a pattern temporal structure in some way.
|
||||
|
||||
With early, you can nudge a pattern to start earlier in time:
|
||||
{{ 'Pattern.slow' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`seq(e5, b4.early(0.5))`} />
|
||||
{{ 'Pattern.fast' | jsdoc }}
|
||||
|
||||
### late(cycles)
|
||||
{{ 'Pattern.early' | jsdoc }}
|
||||
|
||||
Like early, but in the other direction:
|
||||
{{ 'Pattern.late' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`seq(e5, b4.late(0.5))`} />
|
||||
{{ 'Pattern.rev' | jsdoc }}
|
||||
|
||||
<!-- TODO: shouldn't it sound different? -->
|
||||
{{ 'Pattern.struct' | jsdoc }}
|
||||
|
||||
### rev()
|
||||
{{ 'Pattern.legato' | jsdoc }}
|
||||
|
||||
Will reverse the pattern:
|
||||
## Conditional Modifiers
|
||||
|
||||
<MiniRepl tune={`seq(c3,d3,e3,f3).rev()`} />
|
||||
{{ 'Pattern.every' | jsdoc }}
|
||||
|
||||
### every(n, func)
|
||||
{{ 'Pattern.each' | jsdoc }}
|
||||
|
||||
Will apply the given function every n cycles:
|
||||
{{ 'Pattern.when' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`seq(e5, "b4".every(4, late(0.5)))`} />
|
||||
## Accumulation Modifiers
|
||||
|
||||
<!-- TODO: should be able to do b4.every => like already possible with fast slow etc.. -->
|
||||
{{ 'Pattern.stack' | jsdoc }}
|
||||
|
||||
Note that late is called directly. This is a shortcut for:
|
||||
{{ 'Pattern.superimpose' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`seq(e5, "b4".every(4, x => x.late(0.5)))`} />
|
||||
{{ 'Pattern.layer' | jsdoc }}
|
||||
|
||||
<!-- TODO: should the function really run the first cycle? -->
|
||||
{{ 'Pattern.off' | jsdoc }}
|
||||
|
||||
## Concat Modifiers
|
||||
|
||||
{{ 'Pattern.seq' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.cat' | jsdoc }}
|
||||
|
||||
## Value Modifiers
|
||||
|
||||
### add(n)
|
||||
|
||||
@ -597,56 +580,42 @@ Rounds all values to the nearest integer:
|
||||
|
||||
<MiniRepl tune={`"0.5 1.5 2.5".round().scale('C major')`} />
|
||||
|
||||
### struct(binary_pat)
|
||||
|
||||
Applies the given structure to the pattern:
|
||||
|
||||
<MiniRepl tune={`"c3,eb3,g3".struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~").slow(4)`} />
|
||||
|
||||
This is also useful to sample signals:
|
||||
|
||||
<MiniRepl
|
||||
tune={`sine.struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~").mul(7).round()
|
||||
.scale('C minor').slow(4)`}
|
||||
/>
|
||||
|
||||
### when(binary_pat, func)
|
||||
|
||||
Applies the given function whenever the given pattern is in a true state.
|
||||
|
||||
<MiniRepl tune={`"c3 eb3 g3".when("<0 1>/2", sub(5))`} />
|
||||
|
||||
### superimpose(...func)
|
||||
|
||||
Superimposes the result of the given function(s) on top of the original pattern:
|
||||
|
||||
<MiniRepl tune={`"<c3 eb3 g3>".scale('C minor').superimpose(scaleTranspose("2,4"))`} />
|
||||
|
||||
### layer(...func)
|
||||
|
||||
Layers the result of the given function(s) on top of each other. Like superimpose, but the original pattern is not part of the result.
|
||||
|
||||
<MiniRepl tune={`"<c3 eb3 g3>".scale('C minor').layer(scaleTranspose("0,2,4"))`} />
|
||||
|
||||
### apply(func)
|
||||
|
||||
Like layer, but with a single function:
|
||||
|
||||
<MiniRepl tune={`"<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4"))`} />
|
||||
|
||||
### off(time, func)
|
||||
{{ 'Pattern.range' | jsdoc }}
|
||||
|
||||
Applies the given function by the given time offset:
|
||||
## Continuous Signals
|
||||
|
||||
<MiniRepl tune={`"c3 eb3 g3".off(1/8, add(7))`} />
|
||||
Signals are patterns with continuous values, meaning they have theoretically infinite steps.
|
||||
They can provide streams of numbers that can be sampled at discrete points in time.
|
||||
|
||||
### stack(pat)
|
||||
##
|
||||
|
||||
Stacks the given pattern to the current pattern:
|
||||
{{ 'saw' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`"c4,eb4,g4".stack("bb4,d5")`} />
|
||||
{{ 'sine' | jsdoc }}
|
||||
|
||||
## Randomness
|
||||
{{ 'cosine' | jsdoc }}
|
||||
|
||||
{{ 'tri' | jsdoc }}
|
||||
|
||||
{{ 'square' | jsdoc }}
|
||||
|
||||
### Ranges from -1 to 1
|
||||
|
||||
There is also `saw2`, `sine2`, `cosine2`, `tri2` and `square2` which have a range from -1 to 1!
|
||||
|
||||
{{ 'rand' | jsdoc }}
|
||||
|
||||
{{ 'perlin' | jsdoc }}
|
||||
|
||||
{{ 'irand' | jsdoc }}
|
||||
|
||||
## Random Modifiers
|
||||
|
||||
These methods add random behavior to your Patterns.
|
||||
|
||||
@ -678,11 +647,186 @@ These methods add random behavior to your Patterns.
|
||||
|
||||
{{ 'Pattern.always' | jsdoc }}
|
||||
|
||||
## Tone API
|
||||
# Tonal API
|
||||
|
||||
To make the sounds more interesting, we can use Tone.js instruments ands effects.
|
||||
The Tonal API, uses [tonaljs](https://github.com/tonaljs/tonal) to provide helpers for musical operations.
|
||||
|
||||
[Show Source on Github](https://github.com/tidalcycles/strudel/blob/main/repl/src/tone.ts)
|
||||
### transpose(semitones)
|
||||
|
||||
Transposes all notes to the given number of semitones:
|
||||
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).transpose(0)`} />
|
||||
|
||||
This method gets really exciting when we use it with a pattern as above.
|
||||
|
||||
Instead of numbers, scientific interval notation can be used as well:
|
||||
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).transpose(1)`} />
|
||||
|
||||
### scale(name)
|
||||
|
||||
Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like scaleTranpose.
|
||||
|
||||
<MiniRepl
|
||||
tune={`"0 2 4 6 4 2"
|
||||
.scale(seq('C2 major', 'C2 minor').slow(2))`}
|
||||
/>
|
||||
|
||||
Note that the scale root is octaved here. You can also omit the octave, then index zero will default to octave 3.
|
||||
|
||||
All the available scale names can be found [here](https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts).
|
||||
|
||||
### scaleTranspose(steps)
|
||||
|
||||
Transposes notes inside the scale by the number of steps:
|
||||
|
||||
<MiniRepl
|
||||
tune={`"-8 [2,4,6]"
|
||||
.scale('C4 bebop major')
|
||||
.scaleTranspose("<0 -1 -2 -3 -4 -5 -6 -4>")`}
|
||||
/>
|
||||
|
||||
### voicings(range?)
|
||||
|
||||
Turns chord symbols into voicings, using the smoothest voice leading possible:
|
||||
|
||||
<MiniRepl tune={`stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")`} />
|
||||
|
||||
<!-- TODO: use voicing collection as first param + patternify. -->
|
||||
|
||||
### rootNotes(octave = 2)
|
||||
|
||||
Turns chord symbols into root notes of chords in given octave.
|
||||
|
||||
<MiniRepl tune={`"<C^7 A7b13 Dm7 G7>".rootNotes(3)`} />
|
||||
|
||||
Together with layer, struct and voicings, this can be used to create a basic backing track:
|
||||
|
||||
<MiniRepl
|
||||
tune={`"<C^7 A7b13 Dm7 G7>".layer(
|
||||
x => x.voicings(['d3','g4']).struct("~ x"),
|
||||
x => x.rootNotes(2).tone(synth(osc('sawtooth4')).chain(out()))
|
||||
)`}
|
||||
/>
|
||||
|
||||
<!-- TODO: use range instead of octave. -->
|
||||
<!-- TODO: find out why composition does not work -->
|
||||
|
||||
## Microtonal API
|
||||
|
||||
TODO
|
||||
|
||||
## MIDI API
|
||||
|
||||
Strudel also supports midi via [webmidi](https://npmjs.com/package/webmidi).
|
||||
|
||||
### midi(outputName?)
|
||||
|
||||
Make sure to have a midi device connected or to use an IAC Driver.
|
||||
If no outputName is given, it uses the first midi output it finds.
|
||||
|
||||
Midi is currently not supported by the mini repl used here, but you can [open the midi example in the repl](https://strudel.tidalcycles.org/#c3RhY2soIjxDXjcgQTcgRG03IEc3PiIubS52b2ljaW5ncygpLCAnPEMzIEEyIEQzIEcyPicubSkKICAubWlkaSgp).
|
||||
|
||||
In the REPL, you will se a log of the available MIDI devices.
|
||||
|
||||
<!--<MiniRepl
|
||||
tune={`stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")
|
||||
.midi()`}
|
||||
/>-->
|
||||
|
||||
# Superdirt API
|
||||
|
||||
In mainline tidal, the actual sound is generated via Superdirt, which runs inside Supercollider.
|
||||
Strudel also supports using Superdirt as a backend, although it requires some developer tooling to run.
|
||||
|
||||
## Prequisites
|
||||
|
||||
Getting Superdirt to work with Strudel, you need to
|
||||
|
||||
1. install SuperCollider + sc3 plugins, see [Tidal Docs](https://tidalcycles.org/docs/) (Install Tidal) for more info.
|
||||
2. install [node.js](https://nodejs.org/en/)
|
||||
3. download [Strudel Repo](https://github.com/tidalcycles/strudel/) (or git clone, if you have git installed)
|
||||
4. run `npm i` in the strudel directory
|
||||
5. run `npm run osc` to start the osc server, which forwards OSC messages from Strudel REPL to SuperCollider
|
||||
|
||||
Now you're all set!
|
||||
|
||||
## Usage
|
||||
|
||||
1. Start SuperCollider, either using SuperCollider IDE or by running `sclang` in a terminal
|
||||
2. Open the [Strudel REPL](https://strudel.tidalcycles.org/#cygiYmQgc2QiKS5vc2MoKQ%3D%3D)
|
||||
|
||||
...or test it here:
|
||||
|
||||
<MiniRepl tune={`s("bd sd").osc()`} />
|
||||
|
||||
If you now hear sound, congratulations! If not, you can get help on the [#strudel channel in the TidalCycles discord](https://discord.com/invite/HGEdXmRkzT).
|
||||
|
||||
{{ 'Pattern.osc' | jsdoc }}
|
||||
|
||||
## Superdirt Params
|
||||
|
||||
The following functions can be used with superdirt:
|
||||
|
||||
- s
|
||||
- n
|
||||
- freq
|
||||
- channel
|
||||
- orbit
|
||||
- cutoff
|
||||
- resonance
|
||||
- hcutoff
|
||||
- hresonance
|
||||
- bandf
|
||||
- bandq
|
||||
- djf
|
||||
- vowelSa
|
||||
- cut
|
||||
- begin
|
||||
- end
|
||||
- loop
|
||||
- fadeTime
|
||||
- speed
|
||||
- unitA
|
||||
- gain
|
||||
- amp
|
||||
- accelerate
|
||||
- crush
|
||||
- coarse
|
||||
- delay
|
||||
- lock
|
||||
- leslie
|
||||
- lrate
|
||||
- lsize
|
||||
- pan
|
||||
- panspan
|
||||
- pansplay
|
||||
- room
|
||||
- size
|
||||
- dry
|
||||
- shape
|
||||
- squiz
|
||||
- waveloss
|
||||
- attack
|
||||
- decayS
|
||||
- octave
|
||||
- detune
|
||||
- tremolodepth
|
||||
|
||||
Please refer to [Tidal Docs](https://tidalcycles.org/) for more info.
|
||||
|
||||
# Webdirt API (deprecated)
|
||||
|
||||
You can use the powerful sampling engine [Webdirt](https://github.com/dktr0/WebDirt) with Strudel.
|
||||
|
||||
{{ 'Pattern.webdirt' | jsdoc }}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
# Tone API (deprecated)
|
||||
|
||||
The Tone API uses Tone.js instruments ands effects to create sounds.
|
||||
|
||||
<MiniRepl
|
||||
tune={`stack(
|
||||
@ -819,309 +963,3 @@ Helper to set the envelope of a Tone.js instrument. Intended to be used with Ton
|
||||
tune={`"[c4 c4 bb3 c4] [~ g3 ~ g3] [c4 f4 e4 c4] ~".slow(4)
|
||||
.tone(synth(adsr(0,.1,0,0)).chain(out()))`}
|
||||
/>
|
||||
|
||||
## Tonal API
|
||||
|
||||
The Tonal API, uses [tonaljs](https://github.com/tonaljs/tonal) to provide helpers for musical operations.
|
||||
|
||||
### transpose(semitones)
|
||||
|
||||
Transposes all notes to the given number of semitones:
|
||||
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).transpose(0)`} />
|
||||
|
||||
This method gets really exciting when we use it with a pattern as above.
|
||||
|
||||
Instead of numbers, scientific interval notation can be used as well:
|
||||
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).transpose(1)`} />
|
||||
|
||||
### scale(name)
|
||||
|
||||
Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like scaleTranpose.
|
||||
|
||||
<MiniRepl
|
||||
tune={`"0 2 4 6 4 2"
|
||||
.scale(seq('C2 major', 'C2 minor').slow(2))`}
|
||||
/>
|
||||
|
||||
Note that the scale root is octaved here. You can also omit the octave, then index zero will default to octave 3.
|
||||
|
||||
All the available scale names can be found [here](https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts).
|
||||
|
||||
### scaleTranspose(steps)
|
||||
|
||||
Transposes notes inside the scale by the number of steps:
|
||||
|
||||
<MiniRepl
|
||||
tune={`"-8 [2,4,6]"
|
||||
.scale('C4 bebop major')
|
||||
.scaleTranspose("<0 -1 -2 -3 -4 -5 -6 -4>")`}
|
||||
/>
|
||||
|
||||
### voicings(range?)
|
||||
|
||||
Turns chord symbols into voicings, using the smoothest voice leading possible:
|
||||
|
||||
<MiniRepl tune={`stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")`} />
|
||||
|
||||
<!-- TODO: use voicing collection as first param + patternify. -->
|
||||
|
||||
### rootNotes(octave = 2)
|
||||
|
||||
Turns chord symbols into root notes of chords in given octave.
|
||||
|
||||
<MiniRepl tune={`"<C^7 A7b13 Dm7 G7>".rootNotes(3)`} />
|
||||
|
||||
Together with layer, struct and voicings, this can be used to create a basic backing track:
|
||||
|
||||
<MiniRepl
|
||||
tune={`"<C^7 A7b13 Dm7 G7>".layer(
|
||||
x => x.voicings(['d3','g4']).struct("~ x"),
|
||||
x => x.rootNotes(2).tone(synth(osc('sawtooth4')).chain(out()))
|
||||
)`}
|
||||
/>
|
||||
|
||||
<!-- TODO: use range instead of octave. -->
|
||||
<!-- TODO: find out why composition does not work -->
|
||||
|
||||
## Microtonal API
|
||||
|
||||
TODO
|
||||
|
||||
## MIDI API
|
||||
|
||||
Strudel also supports midi via [webmidi](https://npmjs.com/package/webmidi).
|
||||
|
||||
### midi(outputName?)
|
||||
|
||||
Make sure to have a midi device connected or to use an IAC Driver.
|
||||
If no outputName is given, it uses the first midi output it finds.
|
||||
|
||||
Midi is currently not supported by the mini repl used here, but you can [open the midi example in the repl](https://strudel.tidalcycles.org/#c3RhY2soIjxDXjcgQTcgRG03IEc3PiIubS52b2ljaW5ncygpLCAnPEMzIEEyIEQzIEcyPicubSkKICAubWlkaSgp).
|
||||
|
||||
In the REPL, you will se a log of the available MIDI devices.
|
||||
|
||||
<!--<MiniRepl
|
||||
tune={`stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")
|
||||
.midi()`}
|
||||
/>-->
|
||||
|
||||
# Contributing
|
||||
|
||||
Contributions of any sort are very welcome! You can contribute by editing [this file](https://github.com/tidalcycles/strudel/blob/main/repl/src/tutorial/tutorial.mdx).
|
||||
All you need is a github account.
|
||||
|
||||
If you want to run the tutorial locally, you can clone the and run:
|
||||
|
||||
```sh
|
||||
cd repl && npm i && npm run tutorial
|
||||
```
|
||||
|
||||
If you want to contribute in another way, either
|
||||
|
||||
- [fork strudel repo on GitHub](https://github.com/tidalcycles/strudel)
|
||||
- [Join the Discord Channel](https://discord.gg/remJ6gQA)
|
||||
- [play with the Strudel REPL](https://strudel.tidalcycles.org/)
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
# API Docs
|
||||
|
||||
The following is generated from the source documentation.
|
||||
|
||||
## Pattern Factories
|
||||
|
||||
The following functions will return a pattern. We will see later what that means.
|
||||
|
||||
{{ 'pure' | jsdoc }}
|
||||
|
||||
{{ 'slowcat' | jsdoc }}
|
||||
|
||||
{{ 'fastcat' | jsdoc }}
|
||||
|
||||
{{ 'stack' | jsdoc }}
|
||||
|
||||
{{ 'timeCat' | jsdoc }}
|
||||
|
||||
{{ 'polyrhythm' | jsdoc }}
|
||||
|
||||
## Pattern Modifiers
|
||||
|
||||
{{ 'Pattern.slow' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.fast' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.early' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.late' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.rev' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.legato' | jsdoc }}
|
||||
|
||||
## Continuous Signals
|
||||
|
||||
Signals are patterns with continuous values, meaning they have theoretically infinite steps.
|
||||
They can provide streams of numbers that can be sampled at discrete points in time.
|
||||
|
||||
{{ 'Pattern.range' | jsdoc }}
|
||||
|
||||
{{ 'saw' | jsdoc }}
|
||||
|
||||
{{ 'saw2' | jsdoc }}
|
||||
|
||||
{{ 'sine' | jsdoc }}
|
||||
|
||||
{{ 'sine2' | jsdoc }}
|
||||
|
||||
{{ 'cosine' | jsdoc }}
|
||||
|
||||
{{ 'cosine2' | jsdoc }}
|
||||
|
||||
{{ 'tri' | jsdoc }}
|
||||
|
||||
{{ 'tri2' | jsdoc }}
|
||||
|
||||
{{ 'square' | jsdoc }}
|
||||
|
||||
{{ 'square2' | jsdoc }}
|
||||
|
||||
## Using Samples with Webdirt
|
||||
|
||||
You can use the powerful sampling engine [Webdirt](https://github.com/dktr0/WebDirt) with Strudel.
|
||||
|
||||
{{ 'Pattern.webdirt' | jsdoc }}
|
||||
|
||||
## Using Superdirt via OSC
|
||||
|
||||
In mainline tidal, the actual sound is generated via Superdirt, which runs inside Supercollider.
|
||||
Strudel also supports using Superdirt as a backend, although it requires some developer tooling to run.
|
||||
|
||||
### Getting Started
|
||||
|
||||
Getting Superdirt to work with Strudel, you need to
|
||||
|
||||
1. install SuperCollider + sc3 plugins, see [Tidal Docs](https://tidalcycles.org/docs/) (Install Tidal) for more info.
|
||||
2. install [node.js](https://nodejs.org/en/)
|
||||
3. download [Strudel Repo](https://github.com/tidalcycles/strudel/) (or git clone, if you have git installed)
|
||||
4. run `npm i` in the strudel directory
|
||||
5. run `npm run osc` to start the osc server, which forwards OSC messages from Strudel REPL to SuperCollider
|
||||
|
||||
Now you're all set!
|
||||
|
||||
### Usage
|
||||
|
||||
1. Start SuperCollider, either using SuperCollider IDE or by running `sclang` in a terminal
|
||||
2. Open the [Strudel REPL](https://strudel.tidalcycles.org/#cygiYmQgc2QiKS5vc2MoKQ%3D%3D)
|
||||
|
||||
...or test it here:
|
||||
|
||||
<MiniRepl tune={`s("bd sd").osc()`} />
|
||||
|
||||
If you now hear sound, congratulations! If not, you can get help on the [#strudel channel in the TidalCycles discord](https://discord.com/invite/HGEdXmRkzT).
|
||||
|
||||
{{ 'Pattern.osc' | jsdoc }}
|
||||
|
||||
# Superdirt Params
|
||||
|
||||
The following functions are specific to SuperDirt and won't work with other Strudel outputs.
|
||||
|
||||
## Basic Types
|
||||
|
||||
{{ 's' | jsdoc }}
|
||||
|
||||
{{ 'n' | jsdoc }}
|
||||
|
||||
{{ 'freq' | jsdoc }}
|
||||
|
||||
{{ 'channel' | jsdoc }}
|
||||
|
||||
{{ 'orbit' | jsdoc }}
|
||||
|
||||
## Filters
|
||||
|
||||
{{ 'cutoff' | jsdoc }}
|
||||
|
||||
{{ 'resonance' | jsdoc }}
|
||||
|
||||
{{ 'hcutoff' | jsdoc }}
|
||||
|
||||
{{ 'hresonance' | jsdoc }}
|
||||
|
||||
{{ 'bandf' | jsdoc }}
|
||||
|
||||
{{ 'bandq' | jsdoc }}
|
||||
|
||||
{{ 'djf' | jsdoc }}
|
||||
|
||||
{{ 'vowel' | jsdoc }}
|
||||
|
||||
## Sample Editing
|
||||
|
||||
{{ 'cut' | jsdoc }}
|
||||
|
||||
{{ 'begin' | jsdoc }}
|
||||
|
||||
{{ 'end' | jsdoc }}
|
||||
|
||||
{{ 'loop' | jsdoc }}
|
||||
|
||||
{{ 'fadeTime' | jsdoc }}
|
||||
|
||||
{{ 'speed' | jsdoc }}
|
||||
|
||||
{{ 'unit' | jsdoc }}
|
||||
|
||||
## Audio Effects
|
||||
|
||||
{{ 'gain' | jsdoc }}
|
||||
|
||||
{{ 'amp' | jsdoc }}
|
||||
|
||||
{{ 'accelerate' | jsdoc }}
|
||||
|
||||
{{ 'crush' | jsdoc }}
|
||||
|
||||
{{ 'coarse' | jsdoc }}
|
||||
|
||||
{{ 'delay' | jsdoc }}
|
||||
|
||||
{{ 'lock' | jsdoc }}
|
||||
|
||||
{{ 'leslie' | jsdoc }}
|
||||
|
||||
{{ 'lrate' | jsdoc }}
|
||||
|
||||
{{ 'lsize' | jsdoc }}
|
||||
|
||||
{{ 'pan' | jsdoc }}
|
||||
|
||||
{{ 'panspan' | jsdoc }}
|
||||
|
||||
{{ 'pansplay' | jsdoc }}
|
||||
|
||||
{{ 'room' | jsdoc }}
|
||||
|
||||
{{ 'size' | jsdoc }}
|
||||
|
||||
{{ 'dry' | jsdoc }}
|
||||
|
||||
{{ 'shape' | jsdoc }}
|
||||
|
||||
{{ 'squiz' | jsdoc }}
|
||||
|
||||
{{ 'waveloss' | jsdoc }}
|
||||
|
||||
{{ 'attack' | jsdoc }}
|
||||
|
||||
{{ 'decay' | jsdoc }}
|
||||
|
||||
## Synth Effects
|
||||
|
||||
{{ 'octave' | jsdoc }}
|
||||
|
||||
{{ 'detune' | jsdoc }}
|
||||
|
||||
{{ 'tremolodepth' | jsdoc }}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user