Document remaining functions

This commit is contained in:
Václav Volhejn 2025-10-12 16:07:11 +02:00
parent d516d765d5
commit c62428ca27
25 changed files with 179 additions and 94 deletions

View file

@ -379,6 +379,7 @@ function s4() {
/** /**
* Overrides the css of highlighted events. Make sure to use single quotes! * Overrides the css of highlighted events. Make sure to use single quotes!
* @name markcss * @name markcss
* @tag visualization
* @example * @example
* note("c a f e") * note("c a f e")
* .markcss('text-decoration:underline') * .markcss('text-decoration:underline')

View file

@ -117,6 +117,7 @@ export const sliderPlugin = ViewPlugin.fromClass(
* Displays a slider widget to allow the user manipulate a value * Displays a slider widget to allow the user manipulate a value
* *
* @name slider * @name slider
* @tags external_io, visualization
* @param {number} value Initial value * @param {number} value Initial value
* @param {number} min Minimum value - optional, defaults to 0 * @param {number} min Minimum value - optional, defaults to 0
* @param {number} max Maximum value - optional, defaults to 1 * @param {number} max Maximum value - optional, defaults to 1

View file

@ -949,6 +949,7 @@ export const { duckattack } = registerControl('duckattack', 'duckatt');
* *
* @name byteBeatExpression * @name byteBeatExpression
* @synonyms bbexpr * @synonyms bbexpr
* @tags effects
* *
* @param {number | Pattern} byteBeatExpression bitwise expression for creating bytebeat * @param {number | Pattern} byteBeatExpression bitwise expression for creating bytebeat
* @example * @example
@ -962,6 +963,7 @@ export const { byteBeatExpression, bbexpr } = registerControl('byteBeatExpressio
* *
* @name byteBeatStartTime * @name byteBeatStartTime
* @synonyms bbst * @synonyms bbst
* @tags effects
* *
* @param {number | Pattern} byteBeatStartTime in samples (t) * @param {number | Pattern} byteBeatStartTime in samples (t)
* @example * @example
@ -1518,7 +1520,7 @@ export const { delayspeed } = registerControl('delayspeed');
* Sets the time of the delay effect. * Sets the time of the delay effect.
* *
* @name delayspeed * @name delayspeed
* @tags effects, foo * @tags effects
* @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @param {number | Pattern} delayspeed controls the pitch of the delay feedback
* @synonyms delayt, dt * @synonyms delayt, dt
* @example * @example
@ -1544,7 +1546,7 @@ export const { delaysync } = registerControl('delaysync');
* Specifies whether delaytime is calculated relative to cps. * Specifies whether delaytime is calculated relative to cps.
* *
* @name lock * @name lock
* @tags effects, foo * @tags effects
* @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle. * @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle.
* @superdirtOnly * @superdirtOnly
* @example * @example
@ -1812,6 +1814,7 @@ export const { octave } = registerControl('octave');
* An `orbit` is a global parameter context for patterns. Patterns with the same orbit will share the same global effects. * An `orbit` is a global parameter context for patterns. Patterns with the same orbit will share the same global effects.
* *
* @name orbit * @name orbit
* @tags effects
* @param {number | Pattern} number * @param {number | Pattern} number
* @example * @example
* stack( * stack(

View file

@ -15,6 +15,7 @@ import Fraction, { gcd } from './fraction.mjs';
* - "-" hold previous value * - "-" hold previous value
* - "." silence * - "." silence
* *
* @tags visualization
* @param {Pattern} pattern the pattern to use * @param {Pattern} pattern the pattern to use
* @param {number} chars max number of characters (approximately) * @param {number} chars max number of characters (approximately)
* @returns string * @returns string

View file

@ -61,6 +61,7 @@ export const bjork = function (ons, steps) {
* *
* @memberof Pattern * @memberof Pattern
* @name euclid * @name euclid
* @tags temporal
* @param {number} pulses the number of onsets/beats * @param {number} pulses the number of onsets/beats
* @param {number} steps the number of steps to fill * @param {number} steps the number of steps to fill
* @returns Pattern * @returns Pattern
@ -73,6 +74,7 @@ export const bjork = function (ons, steps) {
* Like `euclid`, but has an additional parameter for 'rotating' the resulting sequence. * Like `euclid`, but has an additional parameter for 'rotating' the resulting sequence.
* @memberof Pattern * @memberof Pattern
* @name euclidRot * @name euclidRot
* @tags temporal
* @param {number} pulses the number of onsets/beats * @param {number} pulses the number of onsets/beats
* @param {number} steps the number of steps to fill * @param {number} steps the number of steps to fill
* @param {number} rotation offset in steps * @param {number} rotation offset in steps
@ -156,6 +158,7 @@ export const { euclidrot, euclidRot } = register(['euclidrot', 'euclidRot'], fun
* so there will be no gaps. * so there will be no gaps.
* @name euclidLegato * @name euclidLegato
* @memberof Pattern * @memberof Pattern
* @tags temporal
* @param {number} pulses the number of onsets/beats * @param {number} pulses the number of onsets/beats
* @param {number} steps the number of steps to fill * @param {number} steps the number of steps to fill
* @param rotation offset in steps * @param rotation offset in steps
@ -187,6 +190,7 @@ export const euclidLegato = register(['euclidLegato'], function (pulses, steps,
* the resulting sequence * the resulting sequence
* @name euclidLegatoRot * @name euclidLegatoRot
* @memberof Pattern * @memberof Pattern
* @tags temporal
* @param {number} pulses the number of onsets/beats * @param {number} pulses the number of onsets/beats
* @param {number} steps the number of steps to fill * @param {number} steps the number of steps to fill
* @param {number} rotation offset in steps * @param {number} rotation offset in steps
@ -208,6 +212,7 @@ export const euclidLegatoRot = register(['euclidLegatoRot'], function (pulses, s
* @name euclidish * @name euclidish
* @synonyms eish * @synonyms eish
* @memberof Pattern * @memberof Pattern
* @tags temporal
* @param {number} pulses the number of onsets * @param {number} pulses the number of onsets
* @param {number} steps the number of steps to fill * @param {number} steps the number of steps to fill
* @param {number} groove exists between the extremes of 0 (straight euclidian) and 1 (straight pulse) * @param {number} groove exists between the extremes of 0 (straight euclidian) and 1 (straight pulse)

View file

@ -889,7 +889,7 @@ export class Pattern {
/** /**
* Writes the content of the current event to the console (visible in the side menu). * Writes the content of the current event to the console (visible in the side menu).
* @tags visualizers * @tags visualization
* @name log * @name log
* @memberof Pattern * @memberof Pattern
* @example * @example
@ -904,7 +904,7 @@ export class Pattern {
/** /**
* A simplified version of `log` which writes all "values" (various configurable parameters) * A simplified version of `log` which writes all "values" (various configurable parameters)
* within the event to the console (visible in the side menu). * within the event to the console (visible in the side menu).
* @tags visualizers * @tags visualization
* @name logValues * @name logValues
* @memberof Pattern * @memberof Pattern
* @example * @example
@ -938,7 +938,7 @@ export class Pattern {
* source pattern to be looped, and for an (optional) given function to be * source pattern to be looped, and for an (optional) given function to be
* applied. False values result in the corresponding part of the source pattern * applied. False values result in the corresponding part of the source pattern
* to be played unchanged. * to be played unchanged.
* @tags structure * @tags temporal
* @name into * @name into
* @memberof Pattern * @memberof Pattern
* @example * @example
@ -1066,6 +1066,7 @@ function _composeOp(a, b, func) {
* Assumes a pattern of numbers. Adds the given number to each item in the pattern. * Assumes a pattern of numbers. Adds the given number to each item in the pattern.
* @name add * @name add
* @memberof Pattern * @memberof Pattern
* @tags math
* @example * @example
* // Here, the triad 0, 2, 4 is shifted by different amounts * // Here, the triad 0, 2, 4 is shifted by different amounts
* n("0 2 4".add("<0 3 4 0>")).scale("C:major") * n("0 2 4".add("<0 3 4 0>")).scale("C:major")
@ -1076,7 +1077,6 @@ function _composeOp(a, b, func) {
* note("c3 e3 g3".add("<0 5 7 0>")) * note("c3 e3 g3".add("<0 5 7 0>"))
* // Behind the scenes, the notes are converted to midi numbers: * // Behind the scenes, the notes are converted to midi numbers:
* // note("48 52 55".add("<0 5 7 0>")) * // note("48 52 55".add("<0 5 7 0>"))
* @tags math
*/ */
add: [numeralArgs((a, b) => a + b)], // support string concatenation add: [numeralArgs((a, b) => a + b)], // support string concatenation
/** /**
@ -1084,6 +1084,7 @@ function _composeOp(a, b, func) {
* Like add, but the given numbers are subtracted. * Like add, but the given numbers are subtracted.
* @name sub * @name sub
* @memberof Pattern * @memberof Pattern
* @tags math
* @example * @example
* n("0 2 4".sub("<0 1 2 3>")).scale("C4:minor") * n("0 2 4".sub("<0 1 2 3>")).scale("C4:minor")
* // See add for more information. * // See add for more information.
@ -1094,6 +1095,7 @@ function _composeOp(a, b, func) {
* Multiplies each number by the given factor. * Multiplies each number by the given factor.
* @name mul * @name mul
* @memberof Pattern * @memberof Pattern
* @tags math
* @example * @example
* "<1 1.5 [1.66, <2 2.33>]>*4".mul(150).freq() * "<1 1.5 [1.66, <2 2.33>]>*4".mul(150).freq()
*/ */
@ -1103,6 +1105,7 @@ function _composeOp(a, b, func) {
* Divides each number by the given factor. * Divides each number by the given factor.
* @name div * @name div
* @memberof Pattern * @memberof Pattern
* @tags math
*/ */
div: [numeralArgs((a, b) => a / b)], div: [numeralArgs((a, b) => a / b)],
mod: [numeralArgs(_mod)], mod: [numeralArgs(_mod)],
@ -1189,7 +1192,7 @@ function _composeOp(a, b, func) {
/** /**
* Applies the given structure to the pattern: * Applies the given structure to the pattern:
* *
* @tags structure * @tags temporal
* @example * @example
* note("c,eb,g") * note("c,eb,g")
* .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~") * .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~")
@ -1204,7 +1207,7 @@ function _composeOp(a, b, func) {
/** /**
* Returns silence when mask is 0 or "~" * Returns silence when mask is 0 or "~"
* *
* @tags structure * @tags temporal
* @example * @example
* note("c [eb,g] d [eb,g]").mask("<1 [0 1]>") * note("c [eb,g] d [eb,g]").mask("<1 [0 1]>")
*/ */
@ -1217,7 +1220,7 @@ function _composeOp(a, b, func) {
/** /**
* Resets the pattern to the start of the cycle for each onset of the reset pattern. * Resets the pattern to the start of the cycle for each onset of the reset pattern.
* *
* @tags structure * @tags temporal
* @example * @example
* s("[<bd lt> sd]*2, hh*8").reset("<x@3 x(5,8)>") * s("[<bd lt> sd]*2, hh*8").reset("<x@3 x(5,8)>")
*/ */
@ -1231,7 +1234,7 @@ function _composeOp(a, b, func) {
* Restarts the pattern for each onset of the restart pattern. * Restarts the pattern for each onset of the restart pattern.
* While reset will only reset the current cycle, restart will start from cycle 0. * While reset will only reset the current cycle, restart will start from cycle 0.
* *
* @tags structure * @tags temporal
* @example * @example
* s("[<bd lt> sd]*2, hh*8").restart("<x@3 x(5,8)>") * s("[<bd lt> sd]*2, hh*8").restart("<x@3 x(5,8)>")
*/ */
@ -1352,7 +1355,7 @@ export function sequenceP(pats) {
/** /**
* 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.
* *
* @tags structure * @tags temporal
* @return {Pattern} * @return {Pattern}
* @synonyms polyrhythm, pr * @synonyms polyrhythm, pr
* @example * @example
@ -1566,14 +1569,9 @@ export function fastcat(...pats) {
return result; return result;
} }
/** See `fastcat` */
export function sequence(...pats) {
return fastcat(...pats);
}
/** Like **cat**, but the items are crammed into one cycle. /** Like **cat**, but the items are crammed into one cycle.
* @tags combiners * @tags combiners
* @synonyms sequence, fastcat * @synonyms seq, fastcat
* @example * @example
* seq("e5", "b4", ["d5", "c5"]).note() * seq("e5", "b4", ["d5", "c5"]).note()
* // "e5 b4 [d5 c5]".note() * // "e5 b4 [d5 c5]".note()
@ -1584,6 +1582,9 @@ export function sequence(...pats) {
* note("c4(5,8)") * note("c4(5,8)")
* ) * )
*/ */
export function sequence(...pats) {
return fastcat(...pats);
}
export function seq(...pats) { export function seq(...pats) {
return fastcat(...pats); return fastcat(...pats);
@ -1877,7 +1878,7 @@ export const ratio = register('ratio', (pat) =>
// Structural and temporal transformations // Structural and temporal transformations
/** Compress each cycle into the given timespan, leaving a gap /** Compress each cycle into the given timespan, leaving a gap
* @tags structure * @tags temporal
* @example * @example
* cat( * cat(
* s("bd sd").compress(.25,.75), * s("bd sd").compress(.25,.75),
@ -1899,7 +1900,7 @@ export const { compressSpan, compressspan } = register(['compressSpan', 'compres
/** /**
* speeds up a pattern like fast, but rather than it playing multiple times as fast would it instead leaves a gap in the remaining space of the cycle. For example, the following will play the sound pattern "bd sn" only once but compressed into the first half of the cycle, i.e. twice as fast. * speeds up a pattern like fast, but rather than it playing multiple times as fast would it instead leaves a gap in the remaining space of the cycle. For example, the following will play the sound pattern "bd sn" only once but compressed into the first half of the cycle, i.e. twice as fast.
* @tags structure * @tags temporal
* @name fastGap * @name fastGap
* @synonyms fastgap * @synonyms fastgap
* @example * @example
@ -1937,7 +1938,7 @@ export const { fastGap, fastgap } = register(['fastGap', 'fastgap'], function (f
/** /**
* Similar to `compress`, but doesn't leave gaps, and the 'focus' can be bigger than a cycle * Similar to `compress`, but doesn't leave gaps, and the 'focus' can be bigger than a cycle
* @tags structure * @tags temporal
* @example * @example
* s("bd hh sd hh").focus(1/4, 3/4) * s("bd hh sd hh").focus(1/4, 3/4)
*/ */
@ -1955,7 +1956,7 @@ export const { focusSpan, focusspan } = register(['focusSpan', 'focusspan'], fun
}); });
/** The ply function repeats each event the given number of times. /** The ply function repeats each event the given number of times.
* @tags structure * @tags temporal
* @example * @example
* s("bd ~ sd cp").ply("<1 2 3>") * s("bd ~ sd cp").ply("<1 2 3>")
*/ */
@ -1970,7 +1971,7 @@ export const ply = register('ply', function (factor, pat) {
/** /**
* Speed up a pattern by the given factor. Used by "*" in mini notation. * Speed up a pattern by the given factor. Used by "*" in mini notation.
* *
* @tags structure * @tags temporal
* @name fast * @name fast
* @synonyms density * @synonyms density
* @memberof Pattern * @memberof Pattern
@ -1995,7 +1996,7 @@ export const { fast, density } = register(
/** /**
* Both speeds up the pattern (like 'fast') and the sample playback (like 'speed'). * Both speeds up the pattern (like 'fast') and the sample playback (like 'speed').
* @tags structure * @tags temporal
* @example * @example
* s("bd sd:2").hurry("<1 2 4 3>").slow(1.5) * s("bd sd:2").hurry("<1 2 4 3>").slow(1.5)
*/ */
@ -2006,7 +2007,7 @@ export const hurry = register('hurry', function (r, pat) {
/** /**
* Slow down a pattern over the given number of cycles. Like the "/" operator in mini notation. * Slow down a pattern over the given number of cycles. Like the "/" operator in mini notation.
* *
* @tags structure * @tags temporal
* @name slow * @name slow
* @synonyms sparsity * @synonyms sparsity
* @memberof Pattern * @memberof Pattern
@ -2024,7 +2025,7 @@ export const { slow, sparsity } = register(['slow', 'sparsity'], function (facto
/** /**
* Carries out an operation 'inside' a cycle. * Carries out an operation 'inside' a cycle.
* @tags structure * @tags temporal
* @example * @example
* "0 1 2 3 4 3 2 1".inside(4, rev).scale('C major').note() * "0 1 2 3 4 3 2 1".inside(4, rev).scale('C major').note()
* // "0 1 2 3 4 3 2 1".slow(4).rev().fast(4).scale('C major').note() * // "0 1 2 3 4 3 2 1".slow(4).rev().fast(4).scale('C major').note()
@ -2035,7 +2036,7 @@ export const inside = register('inside', function (factor, f, pat) {
/** /**
* Carries out an operation 'outside' a cycle. * Carries out an operation 'outside' a cycle.
* @tags structure * @tags temporal
* @example * @example
* "<[0 1] 2 [3 4] 5>".outside(4, rev).scale('C major').note() * "<[0 1] 2 [3 4] 5>".outside(4, rev).scale('C major').note()
* // "<[0 1] 2 [3 4] 5>".fast(4).rev().slow(4).scale('C major').note() * // "<[0 1] 2 [3 4] 5>".fast(4).rev().slow(4).scale('C major').note()
@ -2046,7 +2047,7 @@ export const outside = register('outside', function (factor, f, pat) {
/** /**
* Applies the given function every n cycles, starting from the last cycle. * Applies the given function every n cycles, starting from the last cycle.
* @tags structure * @tags temporal
* @name lastOf * @name lastOf
* @memberof Pattern * @memberof Pattern
* @param {number} n how many cycles * @param {number} n how many cycles
@ -2063,7 +2064,7 @@ export const lastOf = register('lastOf', function (n, func, pat) {
/** /**
* Applies the given function every n cycles, starting from the first cycle. * Applies the given function every n cycles, starting from the first cycle.
* @tags structure * @tags temporal
* @name firstOf * @name firstOf
* @memberof Pattern * @memberof Pattern
* @param {number} n how many cycles * @param {number} n how many cycles
@ -2075,7 +2076,7 @@ export const lastOf = register('lastOf', function (n, func, pat) {
/** /**
* An alias for `firstOf` * An alias for `firstOf`
* @tags structure * @tags temporal
* @name every * @name every
* @memberof Pattern * @memberof Pattern
* @param {number} n how many cycles * @param {number} n how many cycles
@ -2092,7 +2093,7 @@ export const { firstOf, every } = register(['firstOf', 'every'], function (n, fu
/** /**
* Like layer, but with a single function: * Like layer, but with a single function:
* @tags structure * @tags temporal
* @name apply * @name apply
* @example * @example
* "<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4")).note() * "<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4")).note()
@ -2104,7 +2105,7 @@ export const apply = register('apply', function (func, pat) {
/** /**
* Plays the pattern at the given cycles per minute. * Plays the pattern at the given cycles per minute.
* @tags structure * @tags temporal
* @deprecated * @deprecated
* @example * @example
* s("<bd sd>,hh*2").cpm(90) // = 90 bpm * s("<bd sd>,hh*2").cpm(90) // = 90 bpm
@ -2117,7 +2118,7 @@ export const cpm = register('cpm', function (cpm, pat) {
/** /**
* Nudge a pattern to start earlier in time. Equivalent of Tidal's <~ operator * Nudge a pattern to start earlier in time. Equivalent of Tidal's <~ operator
* *
* @tags structure * @tags temporal
* @name early * @name early
* @memberof Pattern * @memberof Pattern
* @param {number | Pattern} cycles number of cycles to nudge left * @param {number | Pattern} cycles number of cycles to nudge left
@ -2138,7 +2139,7 @@ export const early = register(
/** /**
* Nudge a pattern to start later in time. Equivalent of Tidal's ~> operator * Nudge a pattern to start later in time. Equivalent of Tidal's ~> operator
* *
* @tags structure * @tags temporal
* @name late * @name late
* @memberof Pattern * @memberof Pattern
* @param {number | Pattern} cycles number of cycles to nudge right * @param {number | Pattern} cycles number of cycles to nudge right
@ -2159,7 +2160,7 @@ export const late = register(
/** /**
* Plays a portion of a pattern, specified by the beginning and end of a time span. The new resulting pattern is played over the time period of the original pattern: * Plays a portion of a pattern, specified by the beginning and end of a time span. The new resulting pattern is played over the time period of the original pattern:
* *
* @tags structure * @tags temporal
* @example * @example
* s("bd*2 hh*3 [sd bd]*2 perc").zoom(0.25, 0.75) * s("bd*2 hh*3 [sd bd]*2 perc").zoom(0.25, 0.75)
* // s("hh*3 [sd bd]*2") // equivalent * // s("hh*3 [sd bd]*2") // equivalent
@ -2186,7 +2187,7 @@ export const { zoomArc, zoomarc } = register(['zoomArc', 'zoomarc'], function (a
/** /**
* Splits a pattern into the given number of slices, and plays them according to a pattern of slice numbers. * Splits a pattern into the given number of slices, and plays them according to a pattern of slice numbers.
* Similar to `slice`, but slices up patterns rather than sound samples. * Similar to `slice`, but slices up patterns rather than sound samples.
* @tags structure * @tags temporal
* @param {number} number of slices * @param {number} number of slices
* @param {number} slices to play * @param {number} slices to play
* @example * @example
@ -2214,7 +2215,7 @@ export const bite = register(
/** /**
* Selects the given fraction of the pattern and repeats that part to fill the remainder of the cycle. * Selects the given fraction of the pattern and repeats that part to fill the remainder of the cycle.
* @tags structure * @tags temporal
* @param {number} fraction fraction to select * @param {number} fraction fraction to select
* @example * @example
* s("lt ht mt cp, [hh oh]*2").linger("<1 .5 .25 .125>") * s("lt ht mt cp, [hh oh]*2").linger("<1 .5 .25 .125>")
@ -2235,7 +2236,7 @@ export const linger = register(
/** /**
* Samples the pattern at a rate of n events per cycle. Useful for turning a continuous pattern into a discrete one. * Samples the pattern at a rate of n events per cycle. Useful for turning a continuous pattern into a discrete one.
* @tags structure * @tags temporal
* @name segment * @name segment
* @synonyms seg * @synonyms seg
* @param {number} segments number of segments per cycle * @param {number} segments number of segments per cycle
@ -2248,7 +2249,7 @@ export const { segment, seg } = register(['segment', 'seg'], function (rate, pat
/** /**
* The function `swingBy x n` breaks each cycle into `n` slices, and then delays events in the second half of each slice by the amount `x`, which is relative to the size of the (half) slice. So if `x` is 0 it does nothing, `0.5` delays for half the note duration, and 1 will wrap around to doing nothing again. The end result is a shuffle or swing-like rhythm * The function `swingBy x n` breaks each cycle into `n` slices, and then delays events in the second half of each slice by the amount `x`, which is relative to the size of the (half) slice. So if `x` is 0 it does nothing, `0.5` delays for half the note duration, and 1 will wrap around to doing nothing again. The end result is a shuffle or swing-like rhythm
* @tags structure * @tags temporal
* @param {number} subdivision * @param {number} subdivision
* @param {number} offset * @param {number} offset
* @example * @example
@ -2258,7 +2259,7 @@ export const swingBy = register('swingBy', (swing, n, pat) => pat.inside(n, late
/** /**
* Shorthand for swingBy with 1/3: * Shorthand for swingBy with 1/3:
* @tags structure * @tags temporal
* @param {number} subdivision * @param {number} subdivision
* @example * @example
* s("hh*8").swing(4) * s("hh*8").swing(4)
@ -2268,7 +2269,7 @@ export const swing = register('swing', (n, pat) => pat.swingBy(1 / 3, n));
/** /**
* Swaps 1s and 0s in a binary pattern. * Swaps 1s and 0s in a binary pattern.
* @tags structure * @tags temporal
* @name invert * @name invert
* @synonyms inv * @synonyms inv
* @example * @example
@ -2286,7 +2287,7 @@ export const { invert, inv } = register(
/** /**
* Applies the given function whenever the given pattern is in a true state. * Applies the given function whenever the given pattern is in a true state.
* @tags structure * @tags temporal
* @name when * @name when
* @memberof Pattern * @memberof Pattern
* @param {Pattern} binary_pat * @param {Pattern} binary_pat
@ -2301,7 +2302,7 @@ export const when = register('when', function (on, func, pat) {
/** /**
* Superimposes the function result on top of the original pattern, delayed by the given time. * Superimposes the function result on top of the original pattern, delayed by the given time.
* @tags structure * @tags temporal
* @name off * @name off
* @memberof Pattern * @memberof Pattern
* @param {Pattern | number} time offset time * @param {Pattern | number} time offset time
@ -2318,7 +2319,7 @@ export const off = register('off', function (time_pat, func, pat) {
* Returns a new pattern where every other cycle is played once, twice as * 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 * fast, and offset in time by one quarter of a cycle. Creates a kind of
* breakbeat feel. * breakbeat feel.
* @tags structure * @tags temporal
* @returns Pattern * @returns Pattern
*/ */
export const brak = register('brak', function (pat) { export const brak = register('brak', function (pat) {
@ -2328,7 +2329,7 @@ export const brak = register('brak', function (pat) {
/** /**
* Reverse all haps in a pattern * Reverse all haps in a pattern
* *
* @tags structure * @tags temporal
* @name rev * @name rev
* @memberof Pattern * @memberof Pattern
* @returns Pattern * @returns Pattern
@ -2362,7 +2363,7 @@ export const rev = register(
/** Like press, but allows you to specify the amount by which each /** Like press, but allows you to specify the amount by which each
* event is shifted. pressBy(0.5) is the same as press, while * event is shifted. pressBy(0.5) is the same as press, while
* pressBy(1/3) shifts each event by a third of its timespan. * pressBy(1/3) shifts each event by a third of its timespan.
* @tags structure * @tags temporal
* @example * @example
* stack(s("hh*4"), * stack(s("hh*4"),
* s("bd mt sd ht").pressBy("<0 0.5 0.25>") * s("bd mt sd ht").pressBy("<0 0.5 0.25>")
@ -2374,7 +2375,7 @@ export const pressBy = register('pressBy', function (r, pat) {
/** /**
* Syncopates a rhythm, by shifting each event halfway into its timespan. * Syncopates a rhythm, by shifting each event halfway into its timespan.
* @tags structure * @tags temporal
* @example * @example
* stack(s("hh*4"), * stack(s("hh*4"),
* s("bd mt sd ht").every(4, press) * s("bd mt sd ht").every(4, press)
@ -2386,7 +2387,7 @@ export const press = register('press', function (pat) {
/** /**
* Silences a pattern. * Silences a pattern.
* @tags structure * @tags temporal
* @example * @example
* stack( * stack(
* s("bd").hush(), * s("bd").hush(),
@ -2399,7 +2400,7 @@ Pattern.prototype.hush = function () {
/** /**
* Applies `rev` to a pattern every other cycle, so that the pattern alternates between forwards and backwards. * Applies `rev` to a pattern every other cycle, so that the pattern alternates between forwards and backwards.
* @tags structure * @tags temporal
* @example * @example
* note("c d e g").palindrome() * note("c d e g").palindrome()
*/ */
@ -2414,7 +2415,7 @@ export const palindrome = register(
/** /**
* Jux with adjustable stereo width. 0 = mono, 1 = full stereo. * Jux with adjustable stereo width. 0 = mono, 1 = full stereo.
* @tags structure * @tags temporal
* @name juxBy * @name juxBy
* @synonyms juxby * @synonyms juxby
* @example * @example
@ -2436,7 +2437,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. * The jux function creates strange stereo effects, by applying a function to a pattern, but only in the right-hand channel.
* @tags structure * @tags temporal
* @example * @example
* s("bd lt [~ ht] mt cp ~ bd hh").jux(rev) * s("bd lt [~ ht] mt cp ~ bd hh").jux(rev)
* @example * @example
@ -2450,7 +2451,7 @@ export const jux = register('jux', function (func, pat) {
/** /**
* Superimpose and offset multiple times, applying the given function each time. * Superimpose and offset multiple times, applying the given function each time.
* @tags structure * @tags temporal
* @name echoWith * @name echoWith
* @synonyms echowith, stutWith, stutwith * @synonyms echowith, stutWith, stutwith
* @param {number} times how many times to repeat * @param {number} times how many times to repeat
@ -2470,7 +2471,7 @@ export const { echoWith, echowith, stutWith, stutwith } = register(
/** /**
* Superimpose and offset multiple times, gradually decreasing the velocity * Superimpose and offset multiple times, gradually decreasing the velocity
* @tags structure * @tags temporal
* @name echo * @name echo
* @memberof Pattern * @memberof Pattern
* @returns Pattern * @returns Pattern
@ -2486,7 +2487,7 @@ export const echo = register('echo', function (times, time, feedback, pat) {
/** /**
* Deprecated. Like echo, but the last 2 parameters are flipped. * Deprecated. Like echo, but the last 2 parameters are flipped.
* @tags structure * @tags temporal
* @name stut * @name stut
* @param {number} times how many times to repeat * @param {number} times how many times to repeat
* @param {number} feedback velocity multiplicator for each iteration * @param {number} feedback velocity multiplicator for each iteration
@ -2508,7 +2509,7 @@ export const applyN = register('applyN', function (n, func, p) {
/** /**
* The plyWith function repeats each event the given number of times, applying the given function to each event.\n * The plyWith function repeats each event the given number of times, applying the given function to each event.\n
* @tags structure * @tags temporal
* @name plyWith * @name plyWith
* @synonyms plywith * @synonyms plywith
* @param {number} factor how many times to repeat * @param {number} factor how many times to repeat
@ -2531,7 +2532,7 @@ export const plyWith = register(['plyWith', 'plywith'], function (factor, func,
/** /**
* The plyForEach function repeats each event the given number of times, applying the given function to each event. * The plyForEach function repeats each event the given number of times, applying the given function to each event.
* This version of ply uses the iteration index as an argument to the function, similar to echoWith. * This version of ply uses the iteration index as an argument to the function, similar to echoWith.
* @tags structure * @tags temporal
* @name plyForEach * @name plyForEach
* @synonyms plyforeach * @synonyms plyforeach
* @param {number} factor how many times to repeat * @param {number} factor how many times to repeat
@ -2553,7 +2554,7 @@ export const plyForEach = register(['plyForEach', 'plyforeach'], function (facto
/** /**
* Divides a pattern into a given number of subdivisions, plays the subdivisions in order, but increments the starting subdivision each cycle. The pattern wraps to the first subdivision after the last subdivision is played. * Divides a pattern into a given number of subdivisions, plays the subdivisions in order, but increments the starting subdivision each cycle. The pattern wraps to the first subdivision after the last subdivision is played.
* @tags structure * @tags temporal
* @name iter * @name iter
* @memberof Pattern * @memberof Pattern
* @returns Pattern * @returns Pattern
@ -2581,7 +2582,7 @@ export const iter = register(
/** /**
* Like `iter`, but plays the subdivisions in reverse order. Known as iter' in tidalcycles * Like `iter`, but plays the subdivisions in reverse order. Known as iter' in tidalcycles
* @tags structure * @tags temporal
* @name iterBack * @name iterBack
* @synonyms iterback * @synonyms iterback
* @memberof Pattern * @memberof Pattern
@ -2600,7 +2601,7 @@ export const { iterBack, iterback } = register(
/** /**
* Repeats each cycle the given number of times. * Repeats each cycle the given number of times.
* @tags structure * @tags temporal
* @name repeatCycles * @name repeatCycles
* @memberof Pattern * @memberof Pattern
* @returns Pattern * @returns Pattern
@ -2624,7 +2625,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). * 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 structure * @tags temporal
* @name chunk * @name chunk
* @synonyms slowChunk, slowchunk * @synonyms slowChunk, slowchunk
* @memberof Pattern * @memberof Pattern
@ -2656,7 +2657,7 @@ export const { chunk, slowchunk, slowChunk } = register(
/** /**
* Like `chunk`, but cycles through the parts in reverse order. Known as chunk' in tidalcycles * Like `chunk`, but cycles through the parts in reverse order. Known as chunk' in tidalcycles
* @tags structure * @tags temporal
* @name chunkBack * @name chunkBack
* @synonyms chunkback * @synonyms chunkback
* @memberof Pattern * @memberof Pattern
@ -2677,7 +2678,7 @@ export const { chunkBack, chunkback } = register(
/** /**
* Like `chunk`, but the cycles of the source pattern aren't repeated * Like `chunk`, but the cycles of the source pattern aren't repeated
* for each set of chunks. * for each set of chunks.
* @tags structure * @tags temporal
* @name fastChunk * @name fastChunk
* @synonyms fastchunk * @synonyms fastchunk
* @memberof Pattern * @memberof Pattern
@ -2698,7 +2699,7 @@ export const { fastchunk, fastChunk } = register(
/** /**
* Like `chunk`, but the function is applied to a looped subcycle of the source pattern. * Like `chunk`, but the function is applied to a looped subcycle of the source pattern.
* @tags structure * @tags temporal
* @name chunkInto * @name chunkInto
* @synonyms chunkinto * @synonyms chunkinto
* @memberof Pattern * @memberof Pattern
@ -2712,7 +2713,7 @@ export const { chunkinto, chunkInto } = register(['chunkinto', 'chunkInto'], fun
/** /**
* Like `chunkInto`, but moves backwards through the chunks. * Like `chunkInto`, but moves backwards through the chunks.
* @tags structure * @tags temporal
* @name chunkBackInto * @name chunkBackInto
* @synonyms chunkbackinto * @synonyms chunkbackinto
* @memberof Pattern * @memberof Pattern
@ -2743,7 +2744,7 @@ export const bypass = register(
/** /**
* Loops the pattern inside an `offset` for `cycles`. * Loops the pattern inside an `offset` for `cycles`.
* If you think of the entire span of time in cycles as a ribbon, you can cut a single piece and loop it. * If you think of the entire span of time in cycles as a ribbon, you can cut a single piece and loop it.
* @tags structure * @tags temporal
* @name ribbon * @name ribbon
* @synonyms rib * @synonyms rib
* @param {number} offset start point of loop in cycles * @param {number} offset start point of loop in cycles
@ -2772,7 +2773,7 @@ export const hsl = register('hsl', (h, s, l, pat) => {
/** /**
* Tags each Hap with an identifier. Good for filtering. The function populates Hap.context.tags (Array). * Tags each Hap with an identifier. Good for filtering. The function populates Hap.context.tags (Array).
* @name tag * @name tag
* @tags structure * @tags temporal
* @noAutocomplete * @noAutocomplete
* @param {string} tag anything unique * @param {string} tag anything unique
*/ */
@ -2783,7 +2784,7 @@ Pattern.prototype.tag = function (tag) {
/** /**
* Filters haps using the given function * Filters haps using the given function
* @name filter * @name filter
* @tags structure * @tags temporal
* @param {Function} test function to test Hap * @param {Function} test function to test Hap
* @example * @example
* s("hh!7 oh").filter(hap => hap.value.s==='hh') * s("hh!7 oh").filter(hap => hap.value.s==='hh')
@ -2793,7 +2794,7 @@ export const filter = register('filter', (test, pat) => pat.withHaps((haps) => h
/** /**
* Filters haps by their begin time * Filters haps by their begin time
* @name filterWhen * @name filterWhen
* @tags structure * @tags temporal
* @noAutocomplete * @noAutocomplete
* @param {Function} test function to test Hap.whole.begin * @param {Function} test function to test Hap.whole.begin
*/ */
@ -2802,7 +2803,7 @@ export const filterWhen = register('filterWhen', (test, pat) => pat.filter((h) =
/** /**
* Use within to apply a function to only a part of a pattern. * Use within to apply a function to only a part of a pattern.
* @name within * @name within
* @tags structure * @tags temporal
* @param {number} start start within cycle (0 - 1) * @param {number} start start within cycle (0 - 1)
* @param {number} end end within cycle (0 - 1). Must be > start * @param {number} end end within cycle (0 - 1). Must be > start
* @param {Function} func function to be applied to the sub-pattern * @param {Function} func function to be applied to the sub-pattern
@ -2877,7 +2878,7 @@ export function _match(span, hap_p) {
* *Experimental* * *Experimental*
* *
* Speeds a pattern up or down, to fit to the given number of steps per cycle. * Speeds a pattern up or down, to fit to the given number of steps per cycle.
* @tags structure * @tags temporal
* @example * @example
* sound("bd sd cp").pace(4) * sound("bd sd cp").pace(4)
* // The same as sound("{bd sd cp}%4") or sound("<bd sd cp>*4") * // The same as sound("{bd sd cp}%4") or sound("<bd sd cp>*4")
@ -2919,7 +2920,7 @@ export function _polymeterListSteps(steps, ...args) {
* *Experimental* * *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. * 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 structure * @tags temporal
* @synonyms pm * @synonyms pm
* @example * @example
* // The same as note("{c eb g, c2 g2}%6") * // The same as note("{c eb g, c2 g2}%6")
@ -3037,7 +3038,7 @@ export function stepalt(...groups) {
* *
* Takes the given number of steps from a pattern (dropping the rest). * 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. * A positive number will take steps from the start of a pattern, and a negative number from the end.
* @tags structure * @tags temporal
* @return {Pattern} * @return {Pattern}
* @example * @example
* "bd cp ht mt".take("2").sound() * "bd cp ht mt".take("2").sound()
@ -3082,7 +3083,7 @@ export const take = stepRegister('take', function (i, pat) {
* *
* Drops the given number of steps from a pattern. * 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. * A positive number will drop steps from the start of a pattern, and a negative number from the end.
* @tags structure * @tags temporal
* @return {Pattern} * @return {Pattern}
* @example * @example
* "tha dhi thom nam".drop("1").sound().bank("mridangam") * "tha dhi thom nam".drop("1").sound().bank("mridangam")
@ -3111,7 +3112,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 * `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 * 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"`. * `stepcat("a b".fast(2), "c d")` would be the same as `"[a b] [a b] c d"`.
* @tags structure * @tags temporal
* @example * @example
* stepcat( * stepcat(
* sound("bd bd - cp").extend(2), * sound("bd bd - cp").extend(2),
@ -3126,7 +3127,7 @@ export const extend = stepRegister('extend', function (factor, pat) {
* *Experimental* * *Experimental*
* *
* Expands the step size of the pattern by the given factor. * Expands the step size of the pattern by the given factor.
* @tags structure * @tags temporal
* @example * @example
* sound("tha dhi thom nam").bank("mridangam").expand("3 2 1 1 2 3").pace(8) * sound("tha dhi thom nam").bank("mridangam").expand("3 2 1 1 2 3").pace(8)
*/ */
@ -3138,7 +3139,7 @@ export const expand = stepRegister('expand', function (factor, pat) {
* *Experimental* * *Experimental*
* *
* Contracts the step size of the pattern by the given factor. See also `expand`. * Contracts the step size of the pattern by the given factor. See also `expand`.
* @tags structure * @tags temporal
* @example * @example
* sound("tha dhi thom nam").bank("mridangam").contract("3 2 1 1 2 3").pace(8) * sound("tha dhi thom nam").bank("mridangam").contract("3 2 1 1 2 3").pace(8)
*/ */
@ -3193,7 +3194,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 `:`), * 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. * that number of times.
* A positive number will progressively drop steps from the start of a pattern, and a negative number from the end. * A positive number will progressively drop steps from the start of a pattern, and a negative number from the end.
* @tags structure * @tags temporal
* @return {Pattern} * @return {Pattern}
* @example * @example
* "tha dhi thom nam".shrink("1").sound() * "tha dhi thom nam".shrink("1").sound()
@ -3233,7 +3234,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 `:`), * 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. * that number of times.
* A positive number will progressively grow steps from the start of a pattern, and a negative number from the end. * A positive number will progressively grow steps from the start of a pattern, and a negative number from the end.
* @tags structure * @tags temporal
* @return {Pattern} * @return {Pattern}
* @example * @example
* "tha dhi thom nam".grow("1").sound() * "tha dhi thom nam".grow("1").sound()
@ -3552,7 +3553,9 @@ export const { loopAtCps, loopatcps } = register(['loopAtCps', 'loopatcps'], fun
return _loopAt(factor, pat, cps); return _loopAt(factor, pat, cps);
}); });
/** exposes a custom value at query time. basically allows mutating state without evaluation */ /** exposes a custom value at query time. basically allows mutating state without evaluation
* @tags internals
*/
export const ref = (accessor) => export const ref = (accessor) =>
pure(1) pure(1)
.withValue(() => reify(accessor())) .withValue(() => reify(accessor()))
@ -3589,7 +3592,7 @@ Pattern.prototype.xfade = function (pos, b) {
* creates a structure pattern from divisions of a cycle * creates a structure pattern from divisions of a cycle
* especially useful for creating rhythms * especially useful for creating rhythms
* @name beat * @name beat
* @tags structure * @tags temporal
* @example * @example
* s("bd").beat("0,7,10", 16) * s("bd").beat("0,7,10", 16)
* @example * @example
@ -3666,7 +3669,7 @@ export const _morph = (from, to, by) => {
* sine.slow(8) // slowly morph between the rhythms * sine.slow(8) // slowly morph between the rhythms
* ) * )
* ) * )
* @tags structure * @tags temporal
*/ */
export const morph = (frompat, topat, bypat) => { export const morph = (frompat, topat, bypat) => {
frompat = reify(frompat); frompat = reify(frompat);

View file

@ -28,6 +28,7 @@ const _pick = function (lookup, pat, modulo = true) {
/** * Picks patterns (or plain values) either from a list (by index) or a lookup table (by name). /** * Picks patterns (or plain values) either from a list (by index) or a lookup table (by name).
* Similar to `inhabit`, but maintains the structure of the original patterns. * Similar to `inhabit`, but maintains the structure of the original patterns.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -57,6 +58,7 @@ const __pick = register('pick', function (lookup, pat) {
* it wraps around, rather than sticking at the maximum value. * it wraps around, rather than sticking at the maximum value.
* For example, if you pick the fifth pattern of a list of three, you'll get the * For example, if you pick the fifth pattern of a list of three, you'll get the
* second one. * second one.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -67,6 +69,7 @@ export const pickmod = register('pickmod', function (lookup, pat) {
}); });
/** * pickF lets you use a pattern of numbers to pick which function to apply to another pattern. /** * pickF lets you use a pattern of numbers to pick which function to apply to another pattern.
* @tags combiners, functional
* @param {Pattern} pat * @param {Pattern} pat
* @param {Pattern} lookup a pattern of indices * @param {Pattern} lookup a pattern of indices
* @param {function[]} funcs the array of functions from which to pull * @param {function[]} funcs the array of functions from which to pull
@ -83,6 +86,7 @@ export const pickF = register('pickF', function (lookup, funcs, pat) {
/** * The same as `pickF`, but if you pick a number greater than the size of the functions list, /** * The same as `pickF`, but if you pick a number greater than the size of the functions list,
* it wraps around, rather than sticking at the maximum value. * it wraps around, rather than sticking at the maximum value.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {Pattern} lookup a pattern of indices * @param {Pattern} lookup a pattern of indices
* @param {function[]} funcs the array of functions from which to pull * @param {function[]} funcs the array of functions from which to pull
@ -93,6 +97,7 @@ export const pickmodF = register('pickmodF', function (lookup, funcs, pat) {
}); });
/** * Similar to `pick`, but it applies an outerJoin instead of an innerJoin. /** * Similar to `pick`, but it applies an outerJoin instead of an innerJoin.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -103,6 +108,7 @@ export const pickOut = register('pickOut', function (lookup, pat) {
/** * The same as `pickOut`, but if you pick a number greater than the size of the list, /** * The same as `pickOut`, but if you pick a number greater than the size of the list,
* it wraps around, rather than sticking at the maximum value. * it wraps around, rather than sticking at the maximum value.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -112,6 +118,7 @@ export const pickmodOut = register('pickmodOut', function (lookup, pat) {
}); });
/** * Similar to `pick`, but the choosen pattern is restarted when its index is triggered. /** * Similar to `pick`, but the choosen pattern is restarted when its index is triggered.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -122,6 +129,7 @@ export const pickRestart = register('pickRestart', function (lookup, pat) {
/** * The same as `pickRestart`, but if you pick a number greater than the size of the list, /** * The same as `pickRestart`, but if you pick a number greater than the size of the list,
* it wraps around, rather than sticking at the maximum value. * it wraps around, rather than sticking at the maximum value.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -138,6 +146,7 @@ export const pickmodRestart = register('pickmodRestart', function (lookup, pat)
}); });
/** * Similar to `pick`, but the choosen pattern is reset when its index is triggered. /** * Similar to `pick`, but the choosen pattern is reset when its index is triggered.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -148,6 +157,7 @@ export const pickReset = register('pickReset', function (lookup, pat) {
/** * The same as `pickReset`, but if you pick a number greater than the size of the list, /** * The same as `pickReset`, but if you pick a number greater than the size of the list,
* it wraps around, rather than sticking at the maximum value. * it wraps around, rather than sticking at the maximum value.
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -159,6 +169,7 @@ 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). /** 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. * Similar to `pick`, but cycles are squeezed into the target ('inhabited') pattern.
* @name inhabit * @name inhabit
* @tags combiners
* @synonyms pickSqueeze * @synonyms pickSqueeze
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
@ -180,6 +191,7 @@ export const { inhabit, pickSqueeze } = register(['inhabit', 'pickSqueeze'], fun
* second one. * second one.
* @name inhabitmod * @name inhabitmod
* @synonyms pickmodSqueeze * @synonyms pickmodSqueeze
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}
@ -192,6 +204,7 @@ export const { inhabitmod, pickmodSqueeze } = register(['inhabitmod', 'pickmodSq
/** /**
* Pick from the list of values (or patterns of values) via the index using the given * Pick from the list of values (or patterns of values) via the index using the given
* pattern of integers. The selected pattern will be compressed to fit the duration of the selecting event * pattern of integers. The selected pattern will be compressed to fit the duration of the selecting event
* @tags combiners
* @param {Pattern} pat * @param {Pattern} pat
* @param {*} xs * @param {*} xs
* @returns {Pattern} * @returns {Pattern}

View file

@ -102,6 +102,7 @@ export function repl({
* Changes the global tempo to the given cycles per minute * Changes the global tempo to the given cycles per minute
* *
* @name setcpm * @name setcpm
* @tags temporal
* @alias setCpm * @alias setCpm
* @param {number} cpm cycles per minute * @param {number} cpm cycles per minute
* @example * @example
@ -127,6 +128,8 @@ export function repl({
* $: sound("hh*8") * $: sound("hh*8")
* all(x => x.pianoroll()) * all(x => x.pianoroll())
* ``` * ```
*
* @tags combiners
*/ */
let allTransforms = []; let allTransforms = [];
const all = function (transform) { const all = function (transform) {
@ -134,11 +137,13 @@ export function repl({
return silence; return silence;
}; };
/** Applies a function to each of the running patterns separately. This is intended for future use with upcoming 'stepwise' features. See `all` for a version that applies the function to all the patterns stacked together into a single pattern. /** Applies a function to each of the running patterns separately. This is intended for future use with upcoming 'stepwise' features. See `all` for a version that applies the function to all the patterns stacked together into a single pattern.
*
* ``` * ```
* $: sound("bd - cp sd") * $: sound("bd - cp sd")
* $: sound("hh*8") * $: sound("hh*8")
* each(fast("<2 3>")) * each(fast("<2 3>"))
* ``` * ```
* @tags combiners
*/ */
const each = function (transform) { const each = function (transform) {
eachTransform = transform; eachTransform = transform;

View file

@ -337,6 +337,7 @@ export const scramble = register('scramble', (n, pat) => {
export const rand = signal(timeToRand); export const rand = signal(timeToRand);
/** /**
* A continuous pattern of random numbers, between -1 and 1 * A continuous pattern of random numbers, between -1 and 1
* @tags generators
*/ */
export const rand2 = rand.toBipolar(); export const rand2 = rand.toBipolar();

View file

@ -135,6 +135,8 @@ export async function loadOrc(url) {
* p4 -- MIDI key number (as a real number, not an integer but in [0, 127]. * p4 -- MIDI key number (as a real number, not an integer but in [0, 127].
* p5 -- MIDI velocity (as a real number, not an integer but in [0, 127]. * p5 -- MIDI velocity (as a real number, not an integer but in [0, 127].
* p6 -- Strudel controls, as a string. * p6 -- Strudel controls, as a string.
*
* @tags external_io
*/ */
export const csoundm = register('csoundm', (instrument, pat) => { export const csoundm = register('csoundm', (instrument, pat) => {
let p1 = instrument; let p1 = instrument;

View file

@ -42,6 +42,7 @@ const getValue = (e) => {
* *
* @name pianoroll * @name pianoroll
* @synonyms punchcard * @synonyms punchcard
* @tags visualization
* @param {Object} options Object containing all the optional following parameters as key value pairs: * @param {Object} options Object containing all the optional following parameters as key value pairs:
* @param {integer} cycles number of cycles to be displayed at the same time - defaults to 4 * @param {integer} cycles number of cycles to be displayed at the same time - defaults to 4
* @param {number} playhead location of the active notes on the time axis - 0 to 1, defaults to 0.5 * @param {number} playhead location of the active notes on the time axis - 0 to 1, defaults to 0.5
@ -299,6 +300,7 @@ Pattern.prototype.punchcard = function (options) {
* Supports all the same options as pianoroll. * Supports all the same options as pianoroll.
* *
* @name wordfall * @name wordfall
* @tags visualization
*/ */
Pattern.prototype.wordfall = function (options) { Pattern.prototype.wordfall = function (options) {
return this.punchcard({ vertical: 1, labels: 1, stroke: 0, fillActive: 1, active: 'white', ...options }); return this.punchcard({ vertical: 1, labels: 1, stroke: 0, fillActive: 1, active: 'white', ...options });

View file

@ -116,6 +116,7 @@ export function pitchwheel({
/** /**
* Renders a pitch circle to visualize frequencies within one octave * Renders a pitch circle to visualize frequencies within one octave
* @name pitchwheel * @name pitchwheel
* @tags visualization
* @param {number} hapcircles * @param {number} hapcircles
* @param {number} circle * @param {number} circle
* @param {number} edo * @param {number} edo

View file

@ -129,6 +129,7 @@ function drawSpiral(options) {
* Displays a spiral visual. * Displays a spiral visual.
* *
* @name spiral * @name spiral
* @tags visualization
* @param {Object} options Object containing all the optional following parameters as key value pairs: * @param {Object} options Object containing all the optional following parameters as key value pairs:
* @param {number} stretch controls the rotations per cycle ratio, where 1 = 1 cycle / 360 degrees * @param {number} stretch controls the rotations per cycle ratio, where 1 = 1 cycle / 360 degrees
* @param {number} size the diameter of the spiral * @param {number} size the diameter of the spiral

View file

@ -123,6 +123,7 @@ function githubPath(base, subpath = '') {
/** /**
* configures the default midimap, which is used when no "midimap" port is set * configures the default midimap, which is used when no "midimap" port is set
* @tags external_io
* @example * @example
* defaultmidimap({ lpf: 74 }) * defaultmidimap({ lpf: 74 })
* $: note("c a f e").midi(); * $: note("c a f e").midi();
@ -136,6 +137,7 @@ let loadCache = {};
/** /**
* Adds midimaps to the registry. Inside each midimap, control names (e.g. lpf) are mapped to cc numbers. * Adds midimaps to the registry. Inside each midimap, control names (e.g. lpf) are mapped to cc numbers.
* @tags external_io
* @example * @example
* midimaps({ mymap: { lpf: 74 } }) * midimaps({ mymap: { lpf: 74 } })
* $: note("c a f e") * $: note("c a f e")
@ -278,6 +280,7 @@ function sendNote(note, velocity, duration, device, midichan, timeOffsetString)
/** /**
* MIDI output: Opens a MIDI output port. * MIDI output: Opens a MIDI output port.
* @tags external_io
* @param {string | number} midiport MIDI device name or index defaulting to 0 * @param {string | number} midiport MIDI device name or index defaulting to 0
* @param {object} options Additional MIDI configuration options * @param {object} options Additional MIDI configuration options
* @example * @example
@ -465,6 +468,7 @@ const refs = {};
/** /**
* MIDI input: Opens a MIDI input port to receive MIDI control change messages. * MIDI input: Opens a MIDI input port to receive MIDI control change messages.
* @tags external_io
* @param {string | number} input MIDI device name or index defaulting to 0 * @param {string | number} input MIDI device name or index defaulting to 0
* @returns {Function} * @returns {Function}
* @example * @example

View file

@ -78,6 +78,7 @@ export async function oscTrigger(hap, currentTime, cps = 1, targetTime) {
* For more info, read [MIDI & OSC in the docs](https://strudel.cc/learn/input-output/) * For more info, read [MIDI & OSC in the docs](https://strudel.cc/learn/input-output/)
* *
* @name osc * @name osc
* @tags external_io
* @memberof Pattern * @memberof Pattern
* @returns Pattern * @returns Pattern
*/ */

View file

@ -35,7 +35,9 @@ class OLAProcessor extends AudioWorkletProcessor {
} }
/** Handles dynamic reallocation of input/output channels buffer /** Handles dynamic reallocation of input/output channels buffer
(channel numbers may lety during lifecycle) **/ * (channel numbers may vary during lifecycle)
* @tags internals
**/
reallocateChannelsIfNeeded(inputs, outputs) { reallocateChannelsIfNeeded(inputs, outputs) {
for (let i = 0; i < this.nbInputs; i++) { for (let i = 0; i < this.nbInputs; i++) {
let nbChannels = inputs[i].length; let nbChannels = inputs[i].length;
@ -88,7 +90,10 @@ class OLAProcessor extends AudioWorkletProcessor {
} }
} }
/** Read next web audio block to input buffers **/ /**
* Read next web audio block to input buffers
* @tags internals
**/
readInputs(inputs) { readInputs(inputs) {
// when playback is paused, we may stop receiving new samples // when playback is paused, we may stop receiving new samples
if (inputs[0].length && inputs[0][0].length == 0) { if (inputs[0].length && inputs[0][0].length == 0) {
@ -108,7 +113,9 @@ class OLAProcessor extends AudioWorkletProcessor {
} }
} }
/** Write next web audio block from output buffers **/ /** Write next web audio block from output buffers
* @tags internals
**/
writeOutputs(outputs) { writeOutputs(outputs) {
for (let i = 0; i < this.nbInputs; i++) { for (let i = 0; i < this.nbInputs; i++) {
for (let j = 0; j < this.inputBuffers[i].length; j++) { for (let j = 0; j < this.inputBuffers[i].length; j++) {
@ -118,7 +125,9 @@ class OLAProcessor extends AudioWorkletProcessor {
} }
} }
/** Shift left content of input buffers to receive new web audio block **/ /** Shift left content of input buffers to receive new web audio block
* @tags internals
**/
shiftInputBuffers() { shiftInputBuffers() {
for (let i = 0; i < this.nbInputs; i++) { for (let i = 0; i < this.nbInputs; i++) {
for (let j = 0; j < this.inputBuffers[i].length; j++) { for (let j = 0; j < this.inputBuffers[i].length; j++) {
@ -127,7 +136,9 @@ class OLAProcessor extends AudioWorkletProcessor {
} }
} }
/** Shift left content of output buffers to receive new web audio block **/ /** Shift left content of output buffers to receive new web audio block
* @tags internals
**/
shiftOutputBuffers() { shiftOutputBuffers() {
for (let i = 0; i < this.nbOutputs; i++) { for (let i = 0; i < this.nbOutputs; i++) {
for (let j = 0; j < this.outputBuffers[i].length; j++) { for (let j = 0; j < this.outputBuffers[i].length; j++) {
@ -137,7 +148,9 @@ class OLAProcessor extends AudioWorkletProcessor {
} }
} }
/** Copy contents of input buffers to buffer actually sent to process **/ /** Copy contents of input buffers to buffer actually sent to process
* @tags internals
**/
prepareInputBuffersToSend() { prepareInputBuffersToSend() {
for (let i = 0; i < this.nbInputs; i++) { for (let i = 0; i < this.nbInputs; i++) {
for (let j = 0; j < this.inputBuffers[i].length; j++) { for (let j = 0; j < this.inputBuffers[i].length; j++) {
@ -146,7 +159,9 @@ class OLAProcessor extends AudioWorkletProcessor {
} }
} }
/** Add contents of output buffers just processed to output buffers **/ /** Add contents of output buffers just processed to output buffers
* @tags internals
**/
handleOutputBuffersToRetrieve() { handleOutputBuffersToRetrieve() {
for (let i = 0; i < this.nbOutputs; i++) { for (let i = 0; i < this.nbOutputs; i++) {
for (let j = 0; j < this.outputBuffers[i].length; j++) { for (let j = 0; j < this.outputBuffers[i].length; j++) {

View file

@ -16,6 +16,7 @@ var reverbGen = {};
/** Generates a reverb impulse response. /** Generates a reverb impulse response.
@tags internals
@param {!Object} params TODO: Document the properties. @param {!Object} params TODO: Document the properties.
@param {!function(!AudioBuffer)} callback Function to call when @param {!function(!AudioBuffer)} callback Function to call when
the impulse response has been generated. The impulse response the impulse response has been generated. The impulse response
@ -48,7 +49,7 @@ reverbGen.generateReverb = function (params, callback) {
/** Creates a canvas element showing a graph of the given data. /** Creates a canvas element showing a graph of the given data.
@tags internals
@param {!Float32Array} data An array of numbers, or a Float32Array. @param {!Float32Array} data An array of numbers, or a Float32Array.
@param {number} width Width in pixels of the canvas. @param {number} width Width in pixels of the canvas.
@param {number} height Height in pixels of the canvas. @param {number} height Height in pixels of the canvas.
@ -80,7 +81,7 @@ reverbGen.generateGraph = function (data, width, height, min, max) {
@param {number} lpFreqEndAt @param {number} lpFreqEndAt
@param {!function(!AudioBuffer)} callback May be called @param {!function(!AudioBuffer)} callback May be called
immediately within the current execution context, or later. immediately within the current execution context, or later.
@tags effects @tags internals
*/ */
var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, callback) { var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, callback) {
if (lpFreqStart == 0) { if (lpFreqStart == 0) {

View file

@ -221,6 +221,7 @@ export async function fetchSampleMap(url) {
/** /**
* Loads a collection of samples to use with `s` * Loads a collection of samples to use with `s`
* @tags samples
* @example * @example
* samples('github:tidalcycles/dirt-samples'); * samples('github:tidalcycles/dirt-samples');
* s("[bd ~]*2, [~ hh]*2, ~ sd") * s("[bd ~]*2, [~ hh]*2, ~ sd")

View file

@ -91,6 +91,8 @@ async function aliasBankPath(path) {
* Optionally accepts a single argument string of a path to a JSON file containing bank aliases. * Optionally accepts a single argument string of a path to a JSON file containing bank aliases.
* @param {string} bank - The bank to alias * @param {string} bank - The bank to alias
* @param {string} alias - The alias to use for the bank * @param {string} alias - The alias to use for the bank
*
* @tags samples
*/ */
export async function aliasBank(...args) { export async function aliasBank(...args) {
switch (args.length) { switch (args.length) {
@ -109,6 +111,7 @@ export async function aliasBank(...args) {
/** /**
* Register an alias for a sound. * Register an alias for a sound.
* @tags samples
* @param {string} original - The original sound name * @param {string} original - The original sound name
* @param {string} alias - The alias to use for the sound * @param {string} alias - The alias to use for the sound
*/ */

View file

@ -180,6 +180,7 @@ export function registerWaveTable(key, tables, params) {
* Loads a collection of wavetables to use with `s` * Loads a collection of wavetables to use with `s`
* *
* @name tables * @name tables
* @tags effects
*/ */
export const tables = async (url, frameLen, json, options = {}) => { export const tables = async (url, frameLen, json, options = {}) => {
if (json !== undefined) return _processTables(json, url, frameLen); if (json !== undefined) return _processTables(json, url, frameLen);

View file

@ -635,14 +635,18 @@ class PhaseVocoderProcessor extends OLAProcessor {
this.timeCursor += this.hopSize; this.timeCursor += this.hopSize;
} }
/** Apply Hann window in-place */ /** Apply Hann window in-place
* @tags internals
*/
applyHannWindow(input) { applyHannWindow(input) {
for (var i = 0; i < this.blockSize; i++) { for (var i = 0; i < this.blockSize; i++) {
input[i] = input[i] * this.hannWindow[i] * 1.62; input[i] = input[i] * this.hannWindow[i] * 1.62;
} }
} }
/** Compute squared magnitudes for peak finding **/ /** Compute squared magnitudes for peak finding
* @tags internals
**/
computeMagnitudes() { computeMagnitudes() {
var i = 0, var i = 0,
j = 0; j = 0;
@ -656,7 +660,9 @@ class PhaseVocoderProcessor extends OLAProcessor {
} }
} }
/** Find peaks in spectrum magnitudes **/ /** Find peaks in spectrum magnitudes
* @tags internals
**/
findPeaks() { findPeaks() {
this.nbPeaks = 0; this.nbPeaks = 0;
var i = 2; var i = 2;
@ -680,7 +686,9 @@ class PhaseVocoderProcessor extends OLAProcessor {
} }
} }
/** Shift peaks and regions of influence by pitchFactor into new specturm */ /** Shift peaks and regions of influence by pitchFactor into new specturm
* @tags internals
*/
shiftPeaks(pitchFactor) { shiftPeaks(pitchFactor) {
// zero-fill new spectrum // zero-fill new spectrum
this.freqComplexBufferShifted.fill(0); this.freqComplexBufferShifted.fill(0);
@ -843,7 +851,9 @@ class PulseOscillatorProcessor extends AudioWorkletProcessor {
registerProcessor('pulse-oscillator', PulseOscillatorProcessor); registerProcessor('pulse-oscillator', PulseOscillatorProcessor);
/** BYTE BEATS */ /** BYTE BEATS
* @tags internals
*/
const chyx = { const chyx = {
/*bit*/ bitC: function (x, y, z) { /*bit*/ bitC: function (x, y, z) {
return x & y ? z : 0; return x & y ? z : 0;

View file

@ -92,6 +92,7 @@ function scaleOffset(scale, offset, note) {
* - 5P = perfect fifth * - 5P = perfect fifth
* - 5d = diminished fifth * - 5d = diminished fifth
* *
* @tags music_theory
* @param {string | number} amount Either number of semitones or interval string. * @param {string | number} amount Either number of semitones or interval string.
* @returns Pattern * @returns Pattern
* @memberof Pattern * @memberof Pattern
@ -146,6 +147,7 @@ export const { transpose, trans } = register(['transpose', 'trans'], function tr
* *
* @memberof Pattern * @memberof Pattern
* @name scaleTranspose * @name scaleTranspose
* @tags music_theory
* @param {offset} offset number of steps inside the scale * @param {offset} offset number of steps inside the scale
* @returns Pattern * @returns Pattern
* @synonyms scaleTrans, strans * @synonyms scaleTrans, strans
@ -235,6 +237,7 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) {
* The root note defaults to octave 3, if no octave number is given. * The root note defaults to octave 3, if no octave number is given.
* *
* @name scale * @name scale
* @tags music_theory
* @param {string} scale Name of scale * @param {string} scale Name of scale
* @returns Pattern * @returns Pattern
* @example * @example

View file

@ -90,6 +90,7 @@ export const setVoicingRange = (name, range) => addVoicings(name, voicingRegistr
* Adds a new custom voicing dictionary. * Adds a new custom voicing dictionary.
* *
* @name addVoicings * @name addVoicings
* @tags music_theory
* @memberof Pattern * @memberof Pattern
* @param {string} name identifier for the voicing dictionary * @param {string} name identifier for the voicing dictionary
* @param {Object} dictionary maps chord symbol to possible voicings * @param {Object} dictionary maps chord symbol to possible voicings
@ -133,6 +134,7 @@ const getVoicing = (chord, dictionaryName, lastVoicing) => {
* Uses [chord-voicings package](https://github.com/felixroos/chord-voicings#chord-voicings). * Uses [chord-voicings package](https://github.com/felixroos/chord-voicings#chord-voicings).
* *
* @name voicings * @name voicings
* @tags music_theory
* @memberof Pattern * @memberof Pattern
* @param {string} dictionary which voicing dictionary to use. * @param {string} dictionary which voicing dictionary to use.
* @returns Pattern * @returns Pattern
@ -157,6 +159,7 @@ export const voicings = register('voicings', function (dictionary, pat) {
* Maps the chords of the incoming pattern to root notes in the given octave. * Maps the chords of the incoming pattern to root notes in the given octave.
* *
* @name rootNotes * @name rootNotes
* @tags music_theory
* @memberof Pattern * @memberof Pattern
* @param {octave} octave octave to use * @param {octave} octave octave to use
* @returns Pattern * @returns Pattern
@ -189,6 +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. * If you pass a pattern of strings to voicing, they will be interpreted as chords.
* *
* @name voicing * @name voicing
* @tags music_theory
* @returns Pattern * @returns Pattern
* @example * @example
* n("0 1 2 3").chord("<C Am F G>").voicing() * n("0 1 2 3").chord("<C Am F G>").voicing()

View file

@ -98,6 +98,7 @@ function clearScreen(smear = 0, smearRGB = `0,0,0`, ctx = getDrawContext()) {
/** /**
* Renders an oscilloscope for the frequency domain of the audio signal. * Renders an oscilloscope for the frequency domain of the audio signal.
* @name fscope * @name fscope
* @tags visualization
* @param {string} color line color as hex or color name. defaults to white. * @param {string} color line color as hex or color name. defaults to white.
* @param {number} scale scales the y-axis. Defaults to 0.25 * @param {number} scale scales the y-axis. Defaults to 0.25
* @param {number} pos y-position relative to screen height. 0 = top, 1 = bottom of screen * @param {number} pos y-position relative to screen height. 0 = top, 1 = bottom of screen
@ -122,6 +123,7 @@ Pattern.prototype.fscope = function (config = {}) {
* Renders an oscilloscope for the time domain of the audio signal. * Renders an oscilloscope for the time domain of the audio signal.
* @name scope * @name scope
* @synonyms tscope * @synonyms tscope
* @tags visualization
* @param {object} config optional config with options: * @param {object} config optional config with options:
* @param {boolean} align if 1, the scope will be aligned to the first zero crossing. defaults to 1 * @param {boolean} align if 1, the scope will be aligned to the first zero crossing. defaults to 1
* @param {string} color line color as hex or color name. defaults to white. * @param {string} color line color as hex or color name. defaults to white.

View file

@ -5,6 +5,7 @@ import { analysers, getAnalyzerData } from 'superdough';
/** /**
* Renders a spectrum analyzer for the incoming audio signal. * Renders a spectrum analyzer for the incoming audio signal.
* @name spectrum * @name spectrum
* @tags visualization
* @param {object} config optional config with options: * @param {object} config optional config with options:
* @param {integer} thickness line thickness in px (default 3) * @param {integer} thickness line thickness in px (default 3)
* @param {integer} speed scroll speed (default 1) * @param {integer} speed scroll speed (default 1)