mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-13 06:19:33 -04:00
tagging a lot of superdough functions
This commit is contained in:
+219
-217
File diff suppressed because it is too large
Load Diff
+55
-59
@@ -818,7 +818,6 @@ export class Pattern {
|
||||
* @name layer
|
||||
* @tags combiners
|
||||
* @memberof Pattern
|
||||
* @synonyms apply
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "<0 2 4 6 ~ 4 ~ 2 0!3 ~!5>*8"
|
||||
@@ -1265,6 +1264,7 @@ const ALIGNMENT_KEYS = ALIGNMENTS.map((how) => how.toLowerCase());
|
||||
* 'add.mix', 'set.squeeze', etc.
|
||||
*
|
||||
* @param {string} method Default join method to use. Options: 'in', 'out', 'mix', 'squeeze', 'squeezeout', 'reset', 'restart', 'poly'
|
||||
* @tags combiners
|
||||
* @example
|
||||
* setDefaultJoin('mix') // also try 'in', 'out', 'squeeze', etc.
|
||||
* s("saw").vel("1 0.5").note("F A C E").delay("0 0.2 0.3")
|
||||
@@ -1564,10 +1564,10 @@ export function arrange(...sections) {
|
||||
* @tags combiners
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
seqPLoop([0, 2, "bd(3,8)"],
|
||||
[1, 3, "cp(3,8)"]
|
||||
)
|
||||
.sound()
|
||||
seqPLoop(
|
||||
[0, 2, "bd(3,8)"],
|
||||
[1, 3, "cp(3,8)"]
|
||||
).sound()
|
||||
*/
|
||||
export function seqPLoop(...parts) {
|
||||
let total = Fraction(0);
|
||||
@@ -1610,7 +1610,7 @@ export function sequence(...pats) {
|
||||
|
||||
/** Like **cat**, but the items are crammed into one cycle.
|
||||
* @tags combiners
|
||||
* @synonyms seq, fastcat
|
||||
* @synonyms fastcat
|
||||
* @example
|
||||
* seq("e5", "b4", ["d5", "c5"]).note()
|
||||
* // "e5 b4 [d5 c5]".note()
|
||||
@@ -2137,13 +2137,12 @@ export const { firstOf, every } = register(['firstOf', 'every'], function (n, fu
|
||||
});
|
||||
|
||||
/**
|
||||
* Like layer, but with a single function:
|
||||
* @tags temporal
|
||||
* Applies the given function to the pattern. Like layer, but with a single function:
|
||||
* @tags combiners
|
||||
* @name apply
|
||||
* @example
|
||||
* "<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4")).note()
|
||||
*/
|
||||
// TODO: remove or dedupe with layer?
|
||||
export const apply = register('apply', function (func, pat) {
|
||||
return func(pat);
|
||||
});
|
||||
@@ -2500,7 +2499,7 @@ export const { juxBy, juxby } = register(['juxBy', 'juxby'], function (by, func,
|
||||
|
||||
/**
|
||||
* The jux function creates strange stereo effects, by applying a function to a pattern, but only in the right-hand channel.
|
||||
* @tags temporal
|
||||
* @tags temporal, superdough
|
||||
* @example
|
||||
* s("bd lt [~ ht] mt cp ~ bd hh").jux(rev)
|
||||
* @example
|
||||
@@ -2514,7 +2513,7 @@ export const jux = register('jux', function (func, pat) {
|
||||
|
||||
/**
|
||||
* Superimpose and offset multiple times, applying the given function each time.
|
||||
* @tags temporal
|
||||
* @tags temporal, functional
|
||||
* @name echoWith
|
||||
* @synonyms echowith, stutWith, stutwith
|
||||
* @param {number} times how many times to repeat
|
||||
@@ -2688,7 +2687,7 @@ export const { repeatCycles } = register(
|
||||
|
||||
/**
|
||||
* Divides a pattern into a given number of parts, then cycles through those parts in turn, applying the given function to each part in turn (one part per cycle).
|
||||
* @tags temporal
|
||||
* @tags temporal, functional
|
||||
* @name chunk
|
||||
* @synonyms slowChunk, slowchunk
|
||||
* @memberof Pattern
|
||||
@@ -2852,7 +2851,7 @@ Pattern.prototype.tag = function (tag) {
|
||||
/**
|
||||
* Filters haps using the given function
|
||||
* @name filter
|
||||
* @tags temporal
|
||||
* @tags temporal, functional
|
||||
* @param {Function} test function to test Hap
|
||||
* @example
|
||||
* s("hh!7 oh").filter(hap => hap.value.s === 'hh')
|
||||
@@ -2862,7 +2861,7 @@ export const filter = register('filter', (test, pat) => pat.withHaps((haps) => h
|
||||
/**
|
||||
* Filters haps by their begin time
|
||||
* @name filterWhen
|
||||
* @tags temporal
|
||||
* @tags temporal, functional
|
||||
* @param {Function} test function to test Hap.whole.begin
|
||||
* @example
|
||||
* oneCycle: s("bd*4").filterWhen((t) => t < 1)
|
||||
@@ -2872,7 +2871,7 @@ export const filterWhen = register('filterWhen', (test, pat) => pat.filter((h) =
|
||||
/**
|
||||
* Use within to apply a function to only a part of a pattern.
|
||||
* @name within
|
||||
* @tags temporal
|
||||
* @tags temporal, functional
|
||||
* @param {number} start start within cycle (0 - 1)
|
||||
* @param {number} end end within cycle (0 - 1). Must be > start
|
||||
* @param {Function} func function to be applied to the sub-pattern
|
||||
@@ -2947,7 +2946,7 @@ export function _match(span, hap_p) {
|
||||
* *Experimental*
|
||||
*
|
||||
* Speeds a pattern up or down, to fit to the given number of steps per cycle.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @example
|
||||
* sound("bd sd cp").pace(4)
|
||||
* // The same as sound("{bd sd cp}%4") or sound("<bd sd cp>*4")
|
||||
@@ -2989,7 +2988,7 @@ export function _polymeterListSteps(steps, ...args) {
|
||||
* *Experimental*
|
||||
*
|
||||
* Aligns the steps of the patterns, creating polymeters. The patterns are repeated until they all fit the cycle. For example, in the below the first pattern is repeated twice, and the second is repeated three times, to fit the lowest common multiple of six steps.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @synonyms pm
|
||||
* @example
|
||||
* // The same as note("{c eb g, c2 g2}%6")
|
||||
@@ -3022,7 +3021,7 @@ export function polymeter(...args) {
|
||||
* The steps can either be inferred from the pattern, or provided as a [length, pattern] pair.
|
||||
* Has the alias `timecat`.
|
||||
* @name stepcat
|
||||
* @tags combiners
|
||||
* @tags stepwise
|
||||
* @synonyms timeCat, timecat
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
@@ -3080,7 +3079,7 @@ export function stepcat(...timepats) {
|
||||
* Concatenates patterns stepwise, according to an inferred 'steps per cycle'.
|
||||
* Similar to `stepcat`, but if an argument is a list, the whole pattern will alternate between the elements in the list.
|
||||
*
|
||||
* @tags combiners
|
||||
* @tags stepwise
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* stepalt(["bd cp", "mt"], "bd").sound()
|
||||
@@ -3107,7 +3106,7 @@ export function stepalt(...groups) {
|
||||
*
|
||||
* Takes the given number of steps from a pattern (dropping the rest).
|
||||
* A positive number will take steps from the start of a pattern, and a negative number from the end.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* "bd cp ht mt".take("2").sound()
|
||||
@@ -3152,7 +3151,7 @@ export const take = stepRegister('take', function (i, pat) {
|
||||
*
|
||||
* Drops the given number of steps from a pattern.
|
||||
* A positive number will drop steps from the start of a pattern, and a negative number from the end.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* "tha dhi thom nam".drop("1").sound().bank("mridangam")
|
||||
@@ -3181,7 +3180,7 @@ export const drop = stepRegister('drop', function (i, pat) {
|
||||
* `extend` is similar to `fast` in that it increases its density, but it also increases the step count
|
||||
* accordingly. So `stepcat("a b".extend(2), "c d")` would be the same as `"a b a b c d"`, whereas
|
||||
* `stepcat("a b".fast(2), "c d")` would be the same as `"[a b] [a b] c d"`.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @example
|
||||
* stepcat(
|
||||
* sound("bd bd - cp").extend(2),
|
||||
@@ -3200,7 +3199,7 @@ export const extend = stepRegister('extend', function (factor, pat) {
|
||||
* `stepcat("a b".fast(2), "c d")` would be the same as `"[a b] [a b] c d"`.
|
||||
*
|
||||
* TODO: find out how this function differs from extend
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @example
|
||||
* stepcat(
|
||||
* sound("bd bd - cp").replicate(2),
|
||||
@@ -3215,7 +3214,7 @@ export const replicate = stepRegister('replicate', function (factor, pat) {
|
||||
* *Experimental*
|
||||
*
|
||||
* Expands the step size of the pattern by the given factor.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @example
|
||||
* sound("tha dhi thom nam").bank("mridangam").expand("3 2 1 1 2 3").pace(8)
|
||||
*/
|
||||
@@ -3227,7 +3226,7 @@ export const expand = stepRegister('expand', function (factor, pat) {
|
||||
* *Experimental*
|
||||
*
|
||||
* Contracts the step size of the pattern by the given factor. See also `expand`.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @example
|
||||
* sound("tha dhi thom nam").bank("mridangam").contract("3 2 1 1 2 3").pace(8)
|
||||
*/
|
||||
@@ -3282,7 +3281,7 @@ export const shrinklist = (amount, pat) => pat.shrinklist(amount);
|
||||
* Progressively shrinks the pattern by 'n' steps until there's nothing left, or if a second value is given (using mininotation list syntax with `:`),
|
||||
* that number of times.
|
||||
* A positive number will progressively drop steps from the start of a pattern, and a negative number from the end.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* "tha dhi thom nam".shrink("1").sound()
|
||||
@@ -3322,7 +3321,7 @@ export const shrink = register(
|
||||
* Progressively grows the pattern by 'n' steps until the full pattern is played, or if a second value is given (using mininotation list syntax with `:`),
|
||||
* that number of times.
|
||||
* A positive number will progressively grow steps from the start of a pattern, and a negative number from the end.
|
||||
* @tags temporal
|
||||
* @tags stepwise
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* "tha dhi thom nam".grow("1").sound()
|
||||
@@ -3363,7 +3362,7 @@ export const grow = register(
|
||||
* on successive repetitions. The patterns are added together stepwise, with all repetitions taking place over a single cycle. Using `pace` to set the
|
||||
* number of steps per cycle is therefore usually recommended.
|
||||
*
|
||||
* @tags combiners
|
||||
* @tags stepwise
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* "[c g]".tour("e f", "e f g", "g f e c").note()
|
||||
@@ -3390,7 +3389,7 @@ Pattern.prototype.tour = function (...many) {
|
||||
* 'zips' together the steps of the provided patterns. This can create a long repetition, taking place over a single, dense cycle.
|
||||
* Using `pace` to set the number of steps per cycle is therefore usually recommended.
|
||||
*
|
||||
* @tags combiners
|
||||
* @tags stepwise
|
||||
* @returns {Pattern}
|
||||
* @example
|
||||
* zip("e f", "e f g", "g [f e] a f4 c").note()
|
||||
@@ -3442,7 +3441,7 @@ Pattern.prototype.steps = Pattern.prototype.pace;
|
||||
* Cuts each sample into the given number of parts, allowing you to explore a technique known as 'granular synthesis'.
|
||||
* It turns a pattern of samples into a pattern of parts of samples.
|
||||
* @name chop
|
||||
* @tags temporal
|
||||
* @tags samples
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
@@ -3473,7 +3472,7 @@ export const chop = register('chop', function (n, pat) {
|
||||
/**
|
||||
* Cuts each sample into the given number of parts, triggering progressive portions of each sample at each loop.
|
||||
* @name striate
|
||||
* @tags temporal
|
||||
* @tags samples
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
@@ -3492,14 +3491,13 @@ export const striate = register('striate', function (n, pat) {
|
||||
/**
|
||||
* Makes the sample fit the given number of cycles by changing the speed.
|
||||
* @name loopAt
|
||||
* @tags temporal
|
||||
* @tags samples, pitch
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' })
|
||||
* s("rhodes").loopAt(2)
|
||||
*/
|
||||
// TODO - global cps clock
|
||||
const _loopAt = function (factor, pat, cps = 0.5) {
|
||||
return pat
|
||||
.speed((1 / factor) * cps)
|
||||
@@ -3507,11 +3505,16 @@ const _loopAt = function (factor, pat, cps = 0.5) {
|
||||
.slow(factor);
|
||||
};
|
||||
|
||||
export const { loopAt, loopat } = register(['loopAt', 'loopat'], function (factor, pat) {
|
||||
const steps = pat._steps ? pat._steps.div(factor) : undefined;
|
||||
return new Pattern((state) => _loopAt(factor, pat, state.controls._cps).query(state), steps);
|
||||
});
|
||||
|
||||
/**
|
||||
* Chops samples into the given number of slices, triggering those slices with a given pattern of slice numbers.
|
||||
* Instead of a number, it also accepts a list of numbers from 0 to 1 to slice at specific points.
|
||||
* @name slice
|
||||
* @tags temporal
|
||||
* @tags samples
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
@@ -3565,7 +3568,7 @@ Pattern.prototype.onTriggerTime = function (func) {
|
||||
/**
|
||||
* Works the same as slice, but changes the playback speed of each slice to match the duration of its step.
|
||||
* @name splice
|
||||
* @tags temporal
|
||||
* @tags samples, pitch
|
||||
* @example
|
||||
* samples('github:tidalcycles/dirt-samples')
|
||||
* s("breaks165")
|
||||
@@ -3594,16 +3597,11 @@ export const splice = register(
|
||||
false, // turns off auto-patternification
|
||||
);
|
||||
|
||||
export const { loopAt, loopat } = register(['loopAt', 'loopat'], function (factor, pat) {
|
||||
const steps = pat._steps ? pat._steps.div(factor) : undefined;
|
||||
return new Pattern((state) => _loopAt(factor, pat, state.controls._cps).query(state), steps);
|
||||
});
|
||||
|
||||
/**
|
||||
* Makes the sample fit its event duration. Good for rhythmical loops like drum breaks.
|
||||
* Similar to `loopAt`.
|
||||
* @name fit
|
||||
* @tags temporal
|
||||
* @tags samples, pitch
|
||||
* @example
|
||||
* samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' })
|
||||
* s("rhodes/2").fit()
|
||||
@@ -3625,18 +3623,16 @@ export const fit = register('fit', (pat) =>
|
||||
|
||||
/**
|
||||
* Makes the sample fit the given number of cycles and cps value, by
|
||||
* changing the speed. Please note that at some point cps will be
|
||||
* given by a global clock and this function will be
|
||||
* deprecated/removed.
|
||||
* changing the speed. deprecated: use loopAt or fit instead, together with setCps / setCpm.
|
||||
* @name loopAtCps
|
||||
* @tags temporal
|
||||
* @tags samples, pitch
|
||||
* @memberof Pattern
|
||||
* @deprecated
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' })
|
||||
* s("rhodes").loopAtCps(4,1.5).cps(1.5)
|
||||
*/
|
||||
// TODO - global cps clock
|
||||
export const { loopAtCps, loopatcps } = register(['loopAtCps', 'loopatcps'], function (factor, cps, pat) {
|
||||
return _loopAt(factor, pat, cps);
|
||||
});
|
||||
@@ -3658,7 +3654,7 @@ let fadeGain = (p) => (p < 0.5 ? 1 : 1 - (p - 0.5) / 0.5);
|
||||
* - 1 = (no left, full right)
|
||||
*
|
||||
* @name xfade
|
||||
* @tags combiners
|
||||
* @tags amplitude
|
||||
* @example
|
||||
* xfade(s("bd*2"), "<0 .25 .5 .75 1>", s("hh*8"))
|
||||
*/
|
||||
@@ -3784,7 +3780,7 @@ const _distortWithAlg = function (name) {
|
||||
* Soft-clipping distortion
|
||||
*
|
||||
* @name soft
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3795,7 +3791,7 @@ export const soft = _distortWithAlg('soft');
|
||||
* Hard-clipping distortion
|
||||
*
|
||||
* @name hard
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3806,7 +3802,7 @@ export const hard = _distortWithAlg('hard');
|
||||
* Cubic polynomial distortion
|
||||
*
|
||||
* @name cubic
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3817,7 +3813,7 @@ export const cubic = _distortWithAlg('cubic');
|
||||
* Diode-emulating distortion
|
||||
*
|
||||
* @name diode
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3828,7 +3824,7 @@ export const diode = _distortWithAlg('diode');
|
||||
* Asymmetrical diode distortion
|
||||
*
|
||||
* @name asym
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3839,7 +3835,7 @@ export const asym = _distortWithAlg('asym');
|
||||
* Wavefolding distortion
|
||||
*
|
||||
* @name fold
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3850,7 +3846,7 @@ export const fold = _distortWithAlg('fold');
|
||||
* Wavefolding distortion composed with sinusoid
|
||||
*
|
||||
* @name sinefold
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3861,7 +3857,7 @@ export const sinefold = _distortWithAlg('sinefold');
|
||||
* Distortion via Chebyshev polynomials
|
||||
*
|
||||
* @name chebyshev
|
||||
* @tags fx
|
||||
* @tags distortion, superdough
|
||||
* @param {number | Pattern} distortion amount of distortion to apply
|
||||
* @param {number | Pattern} volume linear postgain of the distortion
|
||||
*
|
||||
@@ -3895,7 +3891,7 @@ const _ensureListPattern = (list) => {
|
||||
* Can also be used to create a new synth via `s('user').partials(...)`
|
||||
*
|
||||
* @name partials
|
||||
* @tags fx, superdough
|
||||
* @tags superdough
|
||||
* @param {number[] | Pattern} magnitudes List of [0, 1] magnitudes for partials. 0th entry is the fundamental harmonic (i.e. DC offset is skipped)
|
||||
* @example
|
||||
* s("user").seg(16).n(irand(8)).scale("A:major")
|
||||
@@ -3917,7 +3913,7 @@ export const partials = (list) => {
|
||||
* Rotates the harmonics of one of the core synths ('sine', 'tri', 'saw', 'user', ..) by a list of phases
|
||||
*
|
||||
* @name phases
|
||||
* @tags fx, superdough
|
||||
* @tags superdough
|
||||
* @param {number[] | Pattern} phases List of [0, 1) phases for partials. 0th entry is the fundamental phase (i.e. DC offset is skipped)
|
||||
* @example
|
||||
* // Phase cancellation
|
||||
@@ -3939,7 +3935,7 @@ export const phases = (list) => {
|
||||
* calls and/or in a single .FX(fx1, fx2, ..) call. The fx1, .. are _patterns_ which
|
||||
* establish the controls of the given effect. See examples.
|
||||
* @name FX
|
||||
* @tags fx, superdough
|
||||
* @tags superdough
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
@@ -3990,7 +3986,7 @@ const _asArrayPattern = (pats) => {
|
||||
* by wrapping them inside a function in K (see example).
|
||||
*
|
||||
* @name K
|
||||
* @tags generators, fx, superdough
|
||||
* @tags generators, superdough
|
||||
* @param {KabelsalatExpression | Function} expr Kabelsalat graph definition
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
|
||||
+17
-15
@@ -78,7 +78,7 @@ export const pickmod = register('pickmod', function (lookup, pat) {
|
||||
* s("bd [rim hh]").pickF("<0 1 2>", [rev,jux(rev),fast(2)])
|
||||
* @example
|
||||
* note("<c2 d2>(3,8)").s("square")
|
||||
* .pickF("<0 2> 1", [jux(rev),fast(2),x=>x.lpf(800)])
|
||||
* .pickF("<0 2> 1", [jux(rev), fast(2), x=>x.lpf(800)])
|
||||
*/
|
||||
export const pickF = register('pickF', function (lookup, funcs, pat) {
|
||||
return pat.apply(pick(lookup, funcs));
|
||||
@@ -167,20 +167,22 @@ export const pickmodReset = register('pickmodReset', function (lookup, pat) {
|
||||
});
|
||||
|
||||
/** Picks patterns (or plain values) either from a list (by index) or a lookup table (by name).
|
||||
* Similar to `pick`, but cycles are squeezed into the target ('inhabited') pattern.
|
||||
* @name inhabit
|
||||
* @tags combiners
|
||||
* @synonyms pickSqueeze
|
||||
* @param {Pattern} pat
|
||||
* @param {*} xs
|
||||
* @returns {Pattern}
|
||||
* @example
|
||||
* "<a b [a,b]>".inhabit({a: s("bd(3,8)"),
|
||||
b: s("cp sd")
|
||||
})
|
||||
* @example
|
||||
* s("a@2 [a b] a".inhabit({a: "bd(3,8)", b: "sd sd"})).slow(4)
|
||||
*/
|
||||
* Similar to `pick`, but cycles are squeezed into the target ('inhabited') pattern.
|
||||
* @name inhabit
|
||||
* @tags combiners
|
||||
* @synonyms pickSqueeze
|
||||
* @param {Pattern} pat
|
||||
* @param {*} xs
|
||||
* @returns {Pattern}
|
||||
* @example
|
||||
* let a = s("bd(3,8)")
|
||||
* let b = s("cp sd")
|
||||
* "<a b [a,b]>".inhabit({ a, b })
|
||||
* @example
|
||||
* s("a@2 [a b] a"
|
||||
* .inhabit({a: "bd(3,8)", b: "sd sd"}))
|
||||
* .slow(4)
|
||||
*/
|
||||
export const { inhabit, pickSqueeze } = register(['inhabit', 'pickSqueeze'], function (lookup, pat) {
|
||||
return _pick(lookup, pat, false).squeezeJoin();
|
||||
});
|
||||
|
||||
@@ -138,7 +138,7 @@ function githubPath(base, subpath = '') {
|
||||
|
||||
/**
|
||||
* configures the default midimap, which is used when no "midimap" port is set
|
||||
* @tags external_io
|
||||
* @tags external_io, midi
|
||||
* @example
|
||||
* defaultmidimap({ lpf: 74 })
|
||||
* $: note("c a f e").midi();
|
||||
@@ -152,7 +152,7 @@ let loadCache = {};
|
||||
|
||||
/**
|
||||
* Adds midimaps to the registry. Inside each midimap, control names (e.g. lpf) are mapped to cc numbers.
|
||||
* @tags external_io
|
||||
* @tags external_io, midi
|
||||
* @example
|
||||
* midimaps({ mymap: { lpf: 74 } })
|
||||
* $: note("c a f e")
|
||||
@@ -529,7 +529,7 @@ async function _initialize(input) {
|
||||
* The output is a function that accepts a midi cc value to query as well as (optionally) a midi channel
|
||||
*
|
||||
* @name midin
|
||||
* @tags external_io
|
||||
* @tags external_io, midi
|
||||
* @param {string | number} input MIDI device name or index defaulting to 0
|
||||
* @returns {function(number, number=): Pattern} A function from (cc, channel?) to a pattern.
|
||||
* When queried, the pattern will produces the most recently received midi value (normalized to 0 to 1)
|
||||
@@ -577,7 +577,7 @@ export async function midin(input) {
|
||||
* note durations
|
||||
*
|
||||
* @name midikeys
|
||||
* @tags external_io
|
||||
* @tags external_io, midi
|
||||
* @param {string | number} input MIDI device name or index defaulting to 0
|
||||
* @returns {function((number | Pattern)=): Pattern} A function that produces a pattern.
|
||||
* When queried, the pattern will produces the most recently played midi notes and velocities,
|
||||
|
||||
@@ -40,7 +40,7 @@ export let maxPolyphony = DEFAULT_MAX_POLYPHONY;
|
||||
* start to die out in first-in-first-out order once the max polyphony has been hit
|
||||
*
|
||||
* @name setMaxPolyphony
|
||||
* @tags fx, superdough
|
||||
* @tags superdough
|
||||
* @param {number} Max polyphony. Defaults to 128
|
||||
* @example
|
||||
* setMaxPolyphony(4)
|
||||
@@ -74,7 +74,7 @@ export function applyGainCurve(val) {
|
||||
* quadratic, exponential, etc. rather than linear
|
||||
*
|
||||
* @name setGainCurve
|
||||
* @tags fx, superdough
|
||||
* @tags amplitude, superdough
|
||||
* @param {Function} function to apply to all gain values
|
||||
* @example
|
||||
* setGainCurve((x) => x * x) // quadratic gain
|
||||
|
||||
@@ -186,7 +186,7 @@ export function registerWaveTable(key, tables, params) {
|
||||
* Loads a collection of wavetables to use with `s`
|
||||
*
|
||||
* @name tables
|
||||
* @tags fx
|
||||
* @tags wavetable
|
||||
*/
|
||||
export const tables = async (url, frameLen, json, options = {}) => {
|
||||
if (json !== undefined) return _processTables(json, url, frameLen);
|
||||
|
||||
@@ -100,7 +100,7 @@ function scaleOffset(scale, offset, note) {
|
||||
* - 5P = perfect fifth
|
||||
* - 5d = diminished fifth
|
||||
*
|
||||
* @tags music_theory
|
||||
* @tags tonal
|
||||
* @param {string | number} amount Either number of semitones or interval string.
|
||||
* @returns Pattern
|
||||
* @memberof Pattern
|
||||
@@ -155,7 +155,7 @@ export const { transpose, trans } = register(['transpose', 'trans'], function tr
|
||||
*
|
||||
* @memberof Pattern
|
||||
* @name scaleTranspose
|
||||
* @tags music_theory
|
||||
* @tags tonal
|
||||
* @param {offset} offset number of steps inside the scale
|
||||
* @returns Pattern
|
||||
* @synonyms scaleTrans, strans
|
||||
@@ -246,7 +246,7 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) {
|
||||
* The root note defaults to octave 3, if no octave number is given.
|
||||
*
|
||||
* @name scale
|
||||
* @tags music_theory
|
||||
* @tags tonal
|
||||
* @param {string} scale Name of scale
|
||||
* @returns Pattern
|
||||
* @example
|
||||
|
||||
@@ -90,7 +90,7 @@ export const setVoicingRange = (name, range) => addVoicings(name, voicingRegistr
|
||||
* Adds a new custom voicing dictionary.
|
||||
*
|
||||
* @name addVoicings
|
||||
* @tags music_theory
|
||||
* @tags tonal
|
||||
* @memberof Pattern
|
||||
* @param {string} name identifier for the voicing dictionary
|
||||
* @param {Object} dictionary maps chord symbol to possible voicings
|
||||
@@ -134,7 +134,7 @@ const getVoicing = (chord, dictionaryName, lastVoicing) => {
|
||||
* Uses [chord-voicings package](https://github.com/felixroos/chord-voicings#chord-voicings).
|
||||
*
|
||||
* @name voicings
|
||||
* @tags music_theory
|
||||
* @tags tonal
|
||||
* @memberof Pattern
|
||||
* @param {string} dictionary which voicing dictionary to use.
|
||||
* @returns Pattern
|
||||
@@ -159,7 +159,7 @@ export const voicings = register('voicings', function (dictionary, pat) {
|
||||
* Maps the chords of the incoming pattern to root notes in the given octave.
|
||||
*
|
||||
* @name rootNotes
|
||||
* @tags music_theory
|
||||
* @tags tonal
|
||||
* @memberof Pattern
|
||||
* @param {octave} octave octave to use
|
||||
* @returns Pattern
|
||||
@@ -192,7 +192,7 @@ export const rootNotes = register('rootNotes', function (octave, pat) {
|
||||
* If you pass a pattern of strings to voicing, they will be interpreted as chords.
|
||||
*
|
||||
* @name voicing
|
||||
* @tags music_theory
|
||||
* @tags tonal
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* n("0 1 2 3").chord("<C Am F G>").voicing()
|
||||
|
||||
@@ -4,7 +4,11 @@ import jsdocJson from '../../../../../doc.json';
|
||||
import { Textbox } from '@src/repl/components/panel/SettingsTab';
|
||||
import { settingsMap, useSettings } from '@src/settings.mjs';
|
||||
|
||||
const isValid = ({ name, description }) => name && !name.startsWith('_') && !!description;
|
||||
const isValid = ({ name, description, tags = [] }) => {
|
||||
const isSupradoughOnly = tags.includes('supradough') && !tags.includes('superdough');
|
||||
const isSuperdirtOnly = tags.includes('superdirt') && !tags.includes('superdough');
|
||||
return name && !name.startsWith('_') && !!description && !isSupradoughOnly && !isSuperdirtOnly;
|
||||
};
|
||||
|
||||
const availableFunctions = (() => {
|
||||
const seen = new Set(); // avoid repetition
|
||||
@@ -14,7 +18,7 @@ const availableFunctions = (() => {
|
||||
if (seen.has(doc.name)) continue;
|
||||
|
||||
// jsdoc also uses "tags" for when you use @something in the comments and it doesn't know what
|
||||
// @something is. We only want data from comments like `@tags fx, superdough` here.
|
||||
// @something is. We only want data from comments like `@tags superdough` here.
|
||||
// If nothing is specified, we default to "untagged" for debugging
|
||||
doc.tags = doc.tags?.filter((t) => t && typeof t === 'string') || ['untagged'];
|
||||
functions.push(doc);
|
||||
@@ -39,11 +43,12 @@ const availableFunctions = (() => {
|
||||
})();
|
||||
|
||||
const tagCounts = {};
|
||||
const ignoredTags = ['supradough', 'superdirt'];
|
||||
// const tagOptions = { all: `all (${availableFunctions.length})` };
|
||||
const tagOptions = { all: `all` };
|
||||
for (const doc of availableFunctions) {
|
||||
(doc.tags || ['untagged']).forEach((t) => {
|
||||
if (typeof t === 'string' && t) {
|
||||
if (typeof t === 'string' && t && !ignoredTags.includes(t)) {
|
||||
tagCounts[t] = (tagCounts[t] || 0) + 1;
|
||||
//tagOptions[t] = `${t} (${tagCounts[t]})`;
|
||||
tagOptions[t] = t;
|
||||
@@ -204,7 +209,7 @@ export const Reference = memo(function Reference() {
|
||||
</h3>
|
||||
{entry.tags && (
|
||||
<span className="ml-2 text-xs text-foreground border border-muted px-1 py-0.5">
|
||||
{entry.tags.join(', ')}
|
||||
{entry.tags.filter((t) => !ignoredTags.includes(t)).join(', ')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user