From df544047332a9ea5f71e744b12b33bbbb393721b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Wed, 1 Oct 2025 22:21:03 +0200 Subject: [PATCH 01/26] Group by category --- jsdoc/jsdoc-synonyms.js | 8 +++ packages/motion/motion.mjs | 15 +++++ .../src/repl/components/panel/Reference.jsx | 60 ++++++++++++------- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/jsdoc/jsdoc-synonyms.js b/jsdoc/jsdoc-synonyms.js index d59c8dac4..aed0dcc06 100644 --- a/jsdoc/jsdoc-synonyms.js +++ b/jsdoc/jsdoc-synonyms.js @@ -12,6 +12,14 @@ function defineTags(dictionary) { doclet.synonyms = doclet.synonyms_text.split(/[ ,]+/); }, }); + + dictionary.defineTag('group', { + mustHaveValue: true, + onTagged: function (doclet, tag) { + doclet.group = tag.value; + console.log('TAGGED GROUP:', doclet.group); + }, + }); } module.exports = { defineTags: defineTags }; diff --git a/packages/motion/motion.mjs b/packages/motion/motion.mjs index 875704eae..cba814a84 100644 --- a/packages/motion/motion.mjs +++ b/packages/motion/motion.mjs @@ -7,6 +7,7 @@ import { signal } from '../core/signal.mjs'; * @name accelerationX * @return {Pattern} * @synonyms accX + * @group external_io * @example * n(accelerationX.segment(4).range(0,7)).scale("C:minor") * @@ -17,6 +18,7 @@ import { signal } from '../core/signal.mjs'; * @name accelerationY * @return {Pattern} * @synonyms accY + * @group external_io * @example * n(accelerationY.segment(4).range(0,7)).scale("C:minor") * @@ -27,6 +29,7 @@ import { signal } from '../core/signal.mjs'; * @name accelerationZ * @return {Pattern} * @synonyms accZ + * @group external_io * @example * n(accelerationZ.segment(4).range(0,7)).scale("C:minor") * @@ -37,6 +40,7 @@ import { signal } from '../core/signal.mjs'; * @name gravityX * @return {Pattern} * @synonyms gravX + * @group external_io * @example * n(gravityX.segment(4).range(0,7)).scale("C:minor") * @@ -47,6 +51,7 @@ import { signal } from '../core/signal.mjs'; * @name gravityY * @return {Pattern} * @synonyms gravY + * @group external_io * @example * n(gravityY.segment(4).range(0,7)).scale("C:minor") * @@ -57,6 +62,7 @@ import { signal } from '../core/signal.mjs'; * @name gravityZ * @return {Pattern} * @synonyms gravZ + * @group external_io * @example * n(gravityZ.segment(4).range(0,7)).scale("C:minor") * @@ -67,6 +73,7 @@ import { signal } from '../core/signal.mjs'; * @name rotationAlpha * @return {Pattern} * @synonyms rotA, rotZ, rotationZ + * @group external_io * @example * n(rotationAlpha.segment(4).range(0,7)).scale("C:minor") * @@ -77,6 +84,7 @@ import { signal } from '../core/signal.mjs'; * @name rotationBeta * @return {Pattern} * @synonyms rotB, rotX, rotationX + * @group external_io * @example * n(rotationBeta.segment(4).range(0,7)).scale("C:minor") * @@ -87,6 +95,7 @@ import { signal } from '../core/signal.mjs'; * @name rotationGamma * @return {Pattern} * @synonyms rotG, rotY, rotationY + * @group external_io * @example * n(rotationGamma.segment(4).range(0,7)).scale("C:minor") * @@ -97,6 +106,7 @@ import { signal } from '../core/signal.mjs'; * @name orientationAlpha * @return {Pattern} * @synonyms oriA, oriZ, orientationZ + * @group external_io * @example * n(orientationAlpha.segment(4).range(0,7)).scale("C:minor") * @@ -107,6 +117,7 @@ import { signal } from '../core/signal.mjs'; * @name orientationBeta * @return {Pattern} * @synonyms oriB, oriX, orientationX + * @group external_io * @example * n(orientationBeta.segment(4).range(0,7)).scale("C:minor") * @@ -117,6 +128,7 @@ import { signal } from '../core/signal.mjs'; * @name orientationGamma * @return {Pattern} * @synonyms oriG, oriY, orientationY + * @group external_io * @example * n(orientationGamma.segment(4).range(0,7)).scale("C:minor") * @@ -127,6 +139,7 @@ import { signal } from '../core/signal.mjs'; * @name absoluteOrientationAlpha * @return {Pattern} * @synonyms absOriA, absOriZ, absoluteOrientationZ + * @group external_io * @example * n(absoluteOrientationAlpha.segment(4).range(0,7)).scale("C:minor") * @@ -137,6 +150,7 @@ import { signal } from '../core/signal.mjs'; * @name absoluteOrientationBeta * @return {Pattern} * @synonyms absOriB, absOriX, absoluteOrientationX + * @group external_io * @example * n(absoluteOrientationBeta.segment(4).range(0,7)).scale("C:minor") * @@ -147,6 +161,7 @@ import { signal } from '../core/signal.mjs'; * @name absoluteOrientationGamma * @return {Pattern} * @synonyms absOriG, absOriY, absoluteOrientationY + * @group external_io * @example * n(absoluteOrientationGamma.segment(4).range(0,7)).scale("C:minor") * diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 6007667fa..a7b4702c4 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -17,13 +17,13 @@ const availableFunctions = (() => { seen.add(s); // Swap `doc.name` in for `s` in the list of synonyms const synonymsWithDoc = [doc.name, ...synonyms].filter((x) => x && x !== s); - functions.push({ - ...doc, - name: s, // update names for the synonym - longname: s, - synonyms: synonymsWithDoc, - synonyms_text: synonymsWithDoc.join(', '), - }); + // functions.push({ + // ...doc, + // name: s, // update names for the synonym + // longname: s, + // synonyms: synonymsWithDoc, + // synonyms_text: synonymsWithDoc.join(', '), + // }); } } return functions.sort((a, b) => /* a.meta.filename.localeCompare(b.meta.filename) + */ a.name.localeCompare(b.name)); @@ -52,6 +52,19 @@ export function Reference() { }); }, [search]); + const visibleFunctionsByGroup = (() => { + const groups = {}; + for (const doc of visibleFunctions) { + const group = doc.group || 'Ungrouped'; + if (!groups[group]) { + groups[group] = []; + } + groups[group].push(doc); + } + return groups; + })(); + console.log(visibleFunctionsByGroup); + return (
@@ -59,18 +72,25 @@ export function Reference() {
- {visibleFunctions.map((entry, i) => ( - { - const el = document.getElementById(`doc-${i}`); - const container = document.getElementById('reference-container'); - container.scrollTo(0, el.offsetTop); - }} - > - {entry.name} {/* {entry.meta.filename} */} - + {Object.entries(visibleFunctionsByGroup).map(([groupName, groupEntries]) => ( + <> +

+ {groupName} +

+ {groupEntries.map((entry, i) => ( + { + const el = document.getElementById(`doc-${entry.name}`); + const container = document.getElementById('reference-container'); + container.scrollTo(0, el.offsetTop); + }} + > + {entry.name} {/* {entry.meta.filename} */} + + ))} + ))}
@@ -86,7 +106,7 @@ export function Reference() {

{visibleFunctions.map((entry, i) => (
-

{entry.name}

+

{entry.name}

{!!entry.synonyms_text && (

Synonyms: {entry.synonyms_text} From c754dab1ef257b8873c59380eb9e5e4b5e7b5d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Wed, 1 Oct 2025 22:31:03 +0200 Subject: [PATCH 02/26] Order groups --- packages/supradough/dough.mjs | 1 + .../src/repl/components/panel/Reference.jsx | 30 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 1cb9241ad..7eeb7a507 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -18,6 +18,7 @@ function applyGainCurve(val) { * @param {number} a - Signal A (can be a single value or an array value in buffer processing). * @param {number} b - Signal B (can be a single value or an array value in buffer processing). * @param {number} m - Crossfade parameter (0.0 = all A, 1.0 = all B, 0.5 = equal mix). + * @group effects * @returns {number} Crossfaded output value. */ function crossfade(a, b, m) { diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index a7b4702c4..aa0453c3a 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -35,6 +35,14 @@ const getInnerText = (html) => { return div.textContent || div.innerText || ''; }; +const GROUP_DISPLAY_NAMES = { + external_io: 'External I/O', + effects: 'Effects', + ungrouped: 'Ungrouped', +}; + +const GROUP_ORDER = ['effects', 'external_io', 'ungrouped']; + export function Reference() { const [search, setSearch] = useState(''); @@ -55,7 +63,7 @@ export function Reference() { const visibleFunctionsByGroup = (() => { const groups = {}; for (const doc of visibleFunctions) { - const group = doc.group || 'Ungrouped'; + const group = doc.group || 'ungrouped'; if (!groups[group]) { groups[group] = []; } @@ -63,7 +71,17 @@ export function Reference() { } return groups; })(); - console.log(visibleFunctionsByGroup); + // console.log(visibleFunctionsByGroup); + + // Sort and map group entries + const sortedGroups = Object.entries(visibleFunctionsByGroup).sort(([a], [b]) => { + const ai = GROUP_ORDER.indexOf(a); + const bi = GROUP_ORDER.indexOf(b); + if (ai === -1 && bi === -1) return a.localeCompare(b); + if (ai === -1) return 1; + if (bi === -1) return -1; + return ai - bi; + }); return (

@@ -72,14 +90,14 @@ export function Reference() {
- {Object.entries(visibleFunctionsByGroup).map(([groupName, groupEntries]) => ( + {sortedGroups.map(([groupId, groupEntries]) => ( <> -

- {groupName} +

+ {GROUP_DISPLAY_NAMES[groupId] || groupId}

{groupEntries.map((entry, i) => ( { const el = document.getElementById(`doc-${entry.name}`); From 4a395f372dc60d77ae77d63b1608f0c63157f5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Wed, 1 Oct 2025 23:45:48 +0200 Subject: [PATCH 03/26] Annote pattern.mjs and signal.mjs --- jsdoc/jsdoc-synonyms.js | 1 - packages/core/pattern.mjs | 146 +++++++++++++++++- packages/core/signal.mjs | 52 +++++++ .../src/repl/components/panel/Reference.jsx | 6 +- 4 files changed, 198 insertions(+), 7 deletions(-) diff --git a/jsdoc/jsdoc-synonyms.js b/jsdoc/jsdoc-synonyms.js index aed0dcc06..423c7ad6e 100644 --- a/jsdoc/jsdoc-synonyms.js +++ b/jsdoc/jsdoc-synonyms.js @@ -17,7 +17,6 @@ function defineTags(dictionary) { mustHaveValue: true, onTagged: function (doclet, tag) { doclet.group = tag.value; - console.log('TAGGED GROUP:', doclet.group); }, }); } diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index d0be3f599..e3d4f5f9c 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -84,6 +84,7 @@ export class Pattern { /** * Returns a new pattern, with the function applied to the value of * each hap. It has the alias `fmap`. + * @group functional * @synonyms fmap * @param {Function} func to to apply to the value * @returns Pattern @@ -116,6 +117,7 @@ export class Pattern { * Assumes 'this' is a pattern of functions, and given a function to * resolve wholes, applies a given pattern of values to that * pattern of functions. + * @group functional * @param {Function} whole_func * @param {Function} func * @noAutocomplete @@ -153,6 +155,7 @@ export class Pattern { * In this `_appBoth` variant, where timespans of the function and value haps * are not the same but do intersect, the resulting hap has a timespan of the * intersection. This applies to both the part and the whole timespan. + * @group functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -180,6 +183,7 @@ export class Pattern { * on. In practice, this means that the pattern structure, including onsets, * are preserved from the pattern of functions (often referred to as the left * hand or inner pattern). + * @group functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -213,6 +217,7 @@ export class Pattern { * As with `appLeft`, but `whole` timespans are instead taken from the * pattern of values, i.e. structure is preserved from the right hand/outer * pattern. + * @group functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -403,6 +408,7 @@ export class Pattern { /** * Query haps inside the given time span. * + * @group internals * @param {Fraction | number} begin from time * @param {Fraction | number} end to time * @returns Hap[] @@ -426,6 +432,7 @@ export class Pattern { * Returns a new pattern, with queries split at cycle boundaries. This makes * some calculations easier to express, as all haps are then constrained to * happen within a cycle. + * @group internals * @returns Pattern * @noAutocomplete */ @@ -440,6 +447,7 @@ export class Pattern { /** * Returns a new pattern, where the given function is applied to the query * timespan before passing it to the original pattern. + * @group internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -462,6 +470,7 @@ export class Pattern { /** * As with `withQuerySpan`, but the function is applied to both the * begin and end time of the query timespan. + * @group internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -474,6 +483,7 @@ export class Pattern { * Similar to `withQuerySpan`, but the function is applied to the timespans * of all haps returned by pattern queries (both `part` timespans, and where * present, `whole` timespans). + * @group internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -485,6 +495,7 @@ export class Pattern { /** * As with `withHapSpan`, but the function is applied to both the * begin and end time of the hap timespans. + * @group internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -495,6 +506,7 @@ export class Pattern { /** * Returns a new pattern with the given function applied to the list of haps returned by every query. + * @group internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -507,6 +519,7 @@ export class Pattern { /** * As with `withHaps`, but applies the function to every hap, rather than every list of haps. + * @group internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -517,6 +530,7 @@ export class Pattern { /** * Returns a new pattern with the context field set to every hap set to the given value. + * @group internals * @param {*} context * @returns Pattern * @noAutocomplete @@ -527,6 +541,7 @@ export class Pattern { /** * Returns a new pattern with the given function applied to the context field of every hap. + * @group internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -542,6 +557,7 @@ export class Pattern { /** * Returns a new pattern with the context field of every hap set to an empty object. + * @group internals * @returns Pattern * @noAutocomplete */ @@ -552,6 +568,7 @@ export class Pattern { /** * Returns a new pattern with the given location information added to the * context of every hap. + * @group internals * @param {Number} start start offset * @param {Number} end end offset * @returns Pattern @@ -575,6 +592,7 @@ export class Pattern { /** * Returns a new Pattern, which only returns haps that meet the given test. + * @group internals * @param {Function} hap_test - a function which returns false for haps to be removed from the pattern * @returns Pattern * @noAutocomplete @@ -586,6 +604,7 @@ export class Pattern { /** * As with `filterHaps`, but the function is applied to values * inside haps. + * @group internals * @param {Function} value_test * @returns Pattern * @noAutocomplete @@ -597,6 +616,7 @@ export class Pattern { /** * Returns a new pattern, with haps containing undefined values removed from * query results. + * @group internals * @returns Pattern * @noAutocomplete */ @@ -608,6 +628,7 @@ export class Pattern { * Returns a new pattern, with all haps without onsets filtered out. A hap * with an onset is one with a `whole` timespan that begins at the same time * as its `part` timespan. + * @group internals * @returns Pattern * @noAutocomplete */ @@ -621,6 +642,7 @@ export class Pattern { /** * Returns a new pattern, with 'continuous' haps (those without 'whole' * timespans) removed from query results. + * @group internals * @returns Pattern * @noAutocomplete */ @@ -632,6 +654,7 @@ export class Pattern { /** * Combines adjacent haps with the same value and whole. Only * intended for use in tests. + * @group internals * @noAutocomplete */ defragmentHaps() { @@ -684,6 +707,7 @@ export class Pattern { /** * Queries the pattern for the first cycle, returning Haps. Mainly of use when * debugging a pattern. + * @group internals * @param {Boolean} with_context - set to true, otherwise the context field * will be stripped from the resulting haps. * @returns [Hap] @@ -699,6 +723,7 @@ export class Pattern { /** * Accessor for a list of values returned by querying the first cycle. + * @group internals * @noAutocomplete */ get firstCycleValues() { @@ -707,6 +732,7 @@ export class Pattern { /** * More human-readable version of the `firstCycleValues` accessor. + * @group internals * @noAutocomplete */ get showFirstCycle() { @@ -718,6 +744,7 @@ export class Pattern { /** * Returns a new pattern, which returns haps sorted in temporal order. Mainly * of use when comparing two patterns for equality, in tests. + * @group internals * @returns Pattern * @noAutocomplete */ @@ -732,6 +759,10 @@ export class Pattern { ); } + /** + * Returns a new pattern with all values parsed as numerals. + * @group internals + */ asNumber() { return this.fmap(parseNumeral); } @@ -782,6 +813,7 @@ export class Pattern { /** * Layers the result of the given function(s). Like `superimpose`, but without the original pattern: * @name layer + * @group combiners * @memberof Pattern * @synonyms apply * @returns Pattern @@ -797,6 +829,7 @@ export class Pattern { /** * Superimposes the result of the given function(s) on top of the original pattern: * @name superimpose + * @group combiners * @memberof Pattern * @returns Pattern * @example @@ -856,6 +889,7 @@ export class Pattern { /** * Writes the content of the current event to the console (visible in the side menu). + * @group visualizers * @name log * @memberof Pattern * @example @@ -870,6 +904,7 @@ export class Pattern { /** * A simplified version of `log` which writes all "values" (various configurable parameters) * within the event to the console (visible in the side menu). + * @group visualizers * @name logValues * @memberof Pattern * @example @@ -903,6 +938,7 @@ export class Pattern { * 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 * to be played unchanged. + * @group structure * @name into * @memberof Pattern * @example @@ -942,6 +978,7 @@ Pattern.prototype.collect = function () { /** * Selects indices in in stacked notes. + * @group transforms * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arpWith(haps => haps[2]) @@ -956,6 +993,7 @@ export const arpWith = register('arpWith', (func, pat) => { /** * Selects indices in in stacked notes. + * @group transforms * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arp("0 [0,2] 1 [0,2]") @@ -1038,6 +1076,7 @@ function _composeOp(a, b, func) { * note("c3 e3 g3".add("<0 5 7 0>")) * // Behind the scenes, the notes are converted to midi numbers: * // note("48 52 55".add("<0 5 7 0>")) + * @group transforms */ add: [numeralArgs((a, b) => a + b)], // support string concatenation /** @@ -1150,6 +1189,7 @@ function _composeOp(a, b, func) { /** * Applies the given structure to the pattern: * + * @group structure * @example * note("c,eb,g") * .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~") @@ -1164,6 +1204,7 @@ function _composeOp(a, b, func) { /** * Returns silence when mask is 0 or "~" * + * @group structure * @example * note("c [eb,g] d [eb,g]").mask("<1 [0 1]>") */ @@ -1176,6 +1217,7 @@ function _composeOp(a, b, func) { /** * Resets the pattern to the start of the cycle for each onset of the reset pattern. * + * @group structure * @example * s("[ sd]*2, hh*8").reset("") */ @@ -1189,6 +1231,7 @@ function _composeOp(a, b, func) { * Restarts the pattern for each onset of the restart pattern. * While reset will only reset the current cycle, restart will start from cycle 0. * + * @group structure * @example * s("[ sd]*2, hh*8").restart("") */ @@ -1229,6 +1272,7 @@ export const pm = polymeter; /** * Does absolutely nothing, but with a given metrical 'steps' * @name gap + * @group generators * @param {number} steps * @example * gap(3) // "~@3" @@ -1238,6 +1282,7 @@ export const gap = (steps) => new Pattern(() => [], steps); /** * Does absolutely nothing.. * @name silence + * @group generators * @example * silence // "~" */ @@ -1249,6 +1294,7 @@ export const nothing = gap(0); /** * A discrete value that repeats once per cycle. * + * @group generators * @returns {Pattern} * @example * pure('e4') // "e4" @@ -1290,7 +1336,10 @@ export function reify(thing) { return pure(thing); } -/** Takes a list of patterns, and returns a pattern of lists. +/** + * Takes a list of patterns, and returns a pattern of lists. + * + * @group transforms */ export function sequenceP(pats) { let result = pure([]); @@ -1303,6 +1352,7 @@ export function sequenceP(pats) { /** * The given items are played at the same time at the same length. * + * @group structure * @return {Pattern} * @synonyms polyrhythm, pr * @example @@ -1387,6 +1437,7 @@ export function stackBy(by, ...pats) { /** * Concatenation: combines a list of patterns, switching between them successively, one per cycle. * + * @group combiners * @return {Pattern} * @synonyms cat * @example @@ -1420,6 +1471,7 @@ export function slowcat(...pats) { } /** Concatenation: combines a list of patterns, switching between them successively, one per cycle. Unlike slowcat, this version will skip cycles. + * @group combiners * @param {...any} items - The items to concatenate * @return {Pattern} */ @@ -1435,6 +1487,7 @@ export function slowcatPrime(...pats) { /** The given items are con**cat**enated, where each one takes one cycle. * + * @group combiners * @param {...any} items - The items to concatenate * @synonyms slowcat * @return {Pattern} @@ -1456,6 +1509,7 @@ export function cat(...pats) { * Allows to arrange multiple patterns together over multiple cycles. * Takes a variable number of arrays with two elements specifying the number of cycles and the pattern to use. * + * @group combiners * @return {Pattern} * @example * arrange( @@ -1473,6 +1527,7 @@ export function arrange(...sections) { * Similarly to `arrange`, allows you to arrange multiple patterns together over multiple cycles. * Unlike `arrange`, you specify a start and stop time for each pattern rather than duration, which * means that patterns can overlap. + * @group combiners * @return {Pattern} * @example seqPLoop([0, 2, "bd(3,8)"], @@ -1517,6 +1572,7 @@ export function sequence(...pats) { } /** Like **cat**, but the items are crammed into one cycle. + * @group combiners * @synonyms sequence, fastcat * @example * seq("e5", "b4", ["d5", "c5"]).note() @@ -1690,6 +1746,7 @@ function stepRegister(name, func, patternify = true, preserveSteps = false, join * Assumes a numerical pattern. Returns a new pattern with all values rounded * to the nearest integer. * @name round + * @group math * @memberof Pattern * @returns Pattern * @example @@ -1698,13 +1755,13 @@ function stepRegister(name, func, patternify = true, preserveSteps = false, join export const round = register('round', function (pat) { return pat.asNumber().fmap((v) => Math.round(v)); }); - /** * Assumes a numerical pattern. Returns a new pattern with all values set to * their mathematical floor. E.g. `3.7` replaced with to `3`, and `-4.2` * replaced with `-5`. * @name floor * @memberof Pattern + * @group math * @returns Pattern * @example * note("42 42.1 42.5 43".floor()) @@ -1719,6 +1776,7 @@ export const floor = register('floor', function (pat) { * replaced with `-4`. * @name ceil * @memberof Pattern + * @group math * @returns Pattern * @example * note("42 42.1 42.5 43".ceil()) @@ -1729,6 +1787,7 @@ export const ceil = register('ceil', function (pat) { /** * Assumes a numerical pattern, containing unipolar values in the range 0 .. * 1. Returns a new pattern with values scaled to the bipolar range -1 .. 1 + * @group math * @returns Pattern * @noAutocomplete */ @@ -1739,6 +1798,7 @@ export const toBipolar = register('toBipolar', function (pat) { /** * Assumes a numerical pattern, containing bipolar values in the range -1 .. 1 * Returns a new pattern with values scaled to the unipolar range 0 .. 1 + * @group math * @returns Pattern * @noAutocomplete */ @@ -1752,6 +1812,7 @@ export const fromBipolar = register('fromBipolar', function (pat) { * Most useful in combination with continuous patterns. * @name range * @memberof Pattern + * @group math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1767,6 +1828,7 @@ export const range = register('range', function (min, max, pat) { * following an exponential curve. * @name rangex * @memberof Pattern + * @group math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1781,6 +1843,7 @@ export const rangex = register('rangex', function (min, max, pat) { * Returns a new pattern with values scaled to the given min/max range. * @name range2 * @memberof Pattern + * @group math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1795,6 +1858,7 @@ export const range2 = register('range2', function (min, max, pat) { * Returns a new pattern with just numbers. * @name ratio * @memberof Pattern + * @group math * @returns Pattern * @example * ratio("1, 5:4, 3:2").mul(110) @@ -1813,6 +1877,7 @@ export const ratio = register('ratio', (pat) => // Structural and temporal transformations /** Compress each cycle into the given timespan, leaving a gap + * @group structure * @example * cat( * s("bd sd").compress(.25,.75), @@ -1834,6 +1899,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. + * @group structure * @name fastGap * @synonyms fastgap * @example @@ -1871,6 +1937,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 + * @group structure * @example * s("bd hh sd hh").focus(1/4, 3/4) */ @@ -1888,6 +1955,7 @@ export const { focusSpan, focusspan } = register(['focusSpan', 'focusspan'], fun }); /** The ply function repeats each event the given number of times. + * @group structure * @example * s("bd ~ sd cp").ply("<1 2 3>") */ @@ -1902,6 +1970,7 @@ export const ply = register('ply', function (factor, pat) { /** * Speed up a pattern by the given factor. Used by "*" in mini notation. * + * @group structure * @name fast * @synonyms density * @memberof Pattern @@ -1926,6 +1995,7 @@ export const { fast, density } = register( /** * Both speeds up the pattern (like 'fast') and the sample playback (like 'speed'). + * @group structure * @example * s("bd sd:2").hurry("<1 2 4 3>").slow(1.5) */ @@ -1936,6 +2006,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. * + * @group structure * @name slow * @synonyms sparsity * @memberof Pattern @@ -1953,6 +2024,7 @@ export const { slow, sparsity } = register(['slow', 'sparsity'], function (facto /** * Carries out an operation 'inside' a cycle. + * @group structure * @example * "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() @@ -1963,6 +2035,7 @@ export const inside = register('inside', function (factor, f, pat) { /** * Carries out an operation 'outside' a cycle. + * @group structure * @example * "<[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() @@ -1973,6 +2046,7 @@ export const outside = register('outside', function (factor, f, pat) { /** * Applies the given function every n cycles, starting from the last cycle. + * @group structure * @name lastOf * @memberof Pattern * @param {number} n how many cycles @@ -1989,6 +2063,7 @@ export const lastOf = register('lastOf', function (n, func, pat) { /** * Applies the given function every n cycles, starting from the first cycle. + * @group structure * @name firstOf * @memberof Pattern * @param {number} n how many cycles @@ -2000,6 +2075,7 @@ export const lastOf = register('lastOf', function (n, func, pat) { /** * An alias for `firstOf` + * @group structure * @name every * @memberof Pattern * @param {number} n how many cycles @@ -2016,8 +2092,8 @@ export const { firstOf, every } = register(['firstOf', 'every'], function (n, fu /** * Like layer, but with a single function: + * @group structure * @name apply - * @memberof Pattern * @example * "".scale('C minor').apply(scaleTranspose("0,2,4")).note() */ @@ -2028,6 +2104,7 @@ export const apply = register('apply', function (func, pat) { /** * Plays the pattern at the given cycles per minute. + * @group structure * @deprecated * @example * s(",hh*2").cpm(90) // = 90 bpm @@ -2040,6 +2117,7 @@ export const cpm = register('cpm', function (cpm, pat) { /** * Nudge a pattern to start earlier in time. Equivalent of Tidal's <~ operator * + * @group structure * @name early * @memberof Pattern * @param {number | Pattern} cycles number of cycles to nudge left @@ -2060,6 +2138,7 @@ export const early = register( /** * Nudge a pattern to start later in time. Equivalent of Tidal's ~> operator * + * @group structure * @name late * @memberof Pattern * @param {number | Pattern} cycles number of cycles to nudge right @@ -2080,6 +2159,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: * + * @group structure * @example * s("bd*2 hh*3 [sd bd]*2 perc").zoom(0.25, 0.75) * // s("hh*3 [sd bd]*2") // equivalent @@ -2106,6 +2186,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. * Similar to `slice`, but slices up patterns rather than sound samples. + * @group structure * @param {number} number of slices * @param {number} slices to play * @example @@ -2133,6 +2214,7 @@ export const bite = register( /** * Selects the given fraction of the pattern and repeats that part to fill the remainder of the cycle. + * @group structure * @param {number} fraction fraction to select * @example * s("lt ht mt cp, [hh oh]*2").linger("<1 .5 .25 .125>") @@ -2153,6 +2235,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. + * @group structure * @name segment * @synonyms seg * @param {number} segments number of segments per cycle @@ -2165,6 +2248,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 + * @group structure * @param {number} subdivision * @param {number} offset * @example @@ -2174,6 +2258,7 @@ export const swingBy = register('swingBy', (swing, n, pat) => pat.inside(n, late /** * Shorthand for swingBy with 1/3: + * @group structure * @param {number} subdivision * @example * s("hh*8").swing(4) @@ -2183,6 +2268,7 @@ export const swing = register('swing', (n, pat) => pat.swingBy(1 / 3, n)); /** * Swaps 1s and 0s in a binary pattern. + * @group structure * @name invert * @synonyms inv * @example @@ -2200,6 +2286,7 @@ export const { invert, inv } = register( /** * Applies the given function whenever the given pattern is in a true state. + * @group structure * @name when * @memberof Pattern * @param {Pattern} binary_pat @@ -2214,6 +2301,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. + * @group structure * @name off * @memberof Pattern * @param {Pattern | number} time offset time @@ -2230,6 +2318,7 @@ export const off = register('off', function (time_pat, func, pat) { * 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 * breakbeat feel. + * @group structure * @returns Pattern */ export const brak = register('brak', function (pat) { @@ -2239,6 +2328,7 @@ export const brak = register('brak', function (pat) { /** * Reverse all haps in a pattern * + * @group structure * @name rev * @memberof Pattern * @returns Pattern @@ -2272,6 +2362,7 @@ export const rev = register( /** Like press, but allows you to specify the amount by which each * event is shifted. pressBy(0.5) is the same as press, while * pressBy(1/3) shifts each event by a third of its timespan. + * @group structure * @example * stack(s("hh*4"), * s("bd mt sd ht").pressBy("<0 0.5 0.25>") @@ -2283,6 +2374,7 @@ export const pressBy = register('pressBy', function (r, pat) { /** * Syncopates a rhythm, by shifting each event halfway into its timespan. + * @group structure * @example * stack(s("hh*4"), * s("bd mt sd ht").every(4, press) @@ -2294,6 +2386,7 @@ export const press = register('press', function (pat) { /** * Silences a pattern. + * @group structure * @example * stack( * s("bd").hush(), @@ -2306,6 +2399,7 @@ Pattern.prototype.hush = function () { /** * Applies `rev` to a pattern every other cycle, so that the pattern alternates between forwards and backwards. + * @group structure * @example * note("c d e g").palindrome() */ @@ -2320,6 +2414,7 @@ export const palindrome = register( /** * Jux with adjustable stereo width. 0 = mono, 1 = full stereo. + * @group structure * @name juxBy * @synonyms juxby * @example @@ -2341,6 +2436,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. + * @group structure * @example * s("bd lt [~ ht] mt cp ~ bd hh").jux(rev) * @example @@ -2354,6 +2450,7 @@ export const jux = register('jux', function (func, pat) { /** * Superimpose and offset multiple times, applying the given function each time. + * @group structure * @name echoWith * @synonyms echowith, stutWith, stutwith * @param {number} times how many times to repeat @@ -2373,6 +2470,7 @@ export const { echoWith, echowith, stutWith, stutwith } = register( /** * Superimpose and offset multiple times, gradually decreasing the velocity + * @group structure * @name echo * @memberof Pattern * @returns Pattern @@ -2388,6 +2486,7 @@ export const echo = register('echo', function (times, time, feedback, pat) { /** * Deprecated. Like echo, but the last 2 parameters are flipped. + * @group structure * @name stut * @param {number} times how many times to repeat * @param {number} feedback velocity multiplicator for each iteration @@ -2409,6 +2508,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 + * @group structure * @name plyWith * @synonyms plywith * @param {number} factor how many times to repeat @@ -2431,6 +2531,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. * This version of ply uses the iteration index as an argument to the function, similar to echoWith. + * @group structure * @name plyForEach * @synonyms plyforeach * @param {number} factor how many times to repeat @@ -2452,6 +2553,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. + * @group structure * @name iter * @memberof Pattern * @returns Pattern @@ -2479,6 +2581,7 @@ export const iter = register( /** * Like `iter`, but plays the subdivisions in reverse order. Known as iter' in tidalcycles + * @group structure * @name iterBack * @synonyms iterback * @memberof Pattern @@ -2497,6 +2600,7 @@ export const { iterBack, iterback } = register( /** * Repeats each cycle the given number of times. + * @group structure * @name repeatCycles * @memberof Pattern * @returns Pattern @@ -2520,6 +2624,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). + * @group structure * @name chunk * @synonyms slowChunk, slowchunk * @memberof Pattern @@ -2551,6 +2656,7 @@ export const { chunk, slowchunk, slowChunk } = register( /** * Like `chunk`, but cycles through the parts in reverse order. Known as chunk' in tidalcycles + * @group structure * @name chunkBack * @synonyms chunkback * @memberof Pattern @@ -2571,6 +2677,7 @@ export const { chunkBack, chunkback } = register( /** * Like `chunk`, but the cycles of the source pattern aren't repeated * for each set of chunks. + * @group structure * @name fastChunk * @synonyms fastchunk * @memberof Pattern @@ -2591,6 +2698,7 @@ export const { fastchunk, fastChunk } = register( /** * Like `chunk`, but the function is applied to a looped subcycle of the source pattern. + * @group structure * @name chunkInto * @synonyms chunkinto * @memberof Pattern @@ -2604,6 +2712,7 @@ export const { chunkinto, chunkInto } = register(['chunkinto', 'chunkInto'], fun /** * Like `chunkInto`, but moves backwards through the chunks. + * @group structure * @name chunkBackInto * @synonyms chunkbackinto * @memberof Pattern @@ -2634,6 +2743,7 @@ export const bypass = register( /** * 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. + * @group structure * @name ribbon * @synonyms rib * @param {number} offset start point of loop in cycles @@ -2662,6 +2772,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). * @name tag + * @group structure * @noAutocomplete * @param {string} tag anything unique */ @@ -2672,6 +2783,7 @@ Pattern.prototype.tag = function (tag) { /** * Filters haps using the given function * @name filter + * @group structure * @param {Function} test function to test Hap * @example * s("hh!7 oh").filter(hap => hap.value.s==='hh') @@ -2681,6 +2793,7 @@ export const filter = register('filter', (test, pat) => pat.withHaps((haps) => h /** * Filters haps by their begin time * @name filterWhen + * @group structure * @noAutocomplete * @param {Function} test function to test Hap.whole.begin */ @@ -2689,6 +2802,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 + * @group structure * @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 @@ -2763,6 +2877,7 @@ export function _match(span, hap_p) { * *Experimental* * * Speeds a pattern up or down, to fit to the given number of steps per cycle. + * @group structure * @example * sound("bd sd cp").pace(4) * // The same as sound("{bd sd cp}%4") or sound("*4") @@ -2804,6 +2919,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. + * @group structure * @synonyms pm * @example * // The same as note("{c eb g, c2 g2}%6") @@ -2836,6 +2952,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 + * @group combiners * @synonyms timeCat, timecat * @return {Pattern} * @example @@ -2893,6 +3010,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. * + * @group combiners * @return {Pattern} * @example * stepalt(["bd cp", "mt"], "bd").sound() @@ -2919,6 +3037,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. + * @group structure * @return {Pattern} * @example * "bd cp ht mt".take("2").sound() @@ -2963,6 +3082,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. + * @group structure * @return {Pattern} * @example * "tha dhi thom nam".drop("1").sound().bank("mridangam") @@ -2991,6 +3111,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"`. + * @group structure * @example * stepcat( * sound("bd bd - cp").extend(2), @@ -3005,6 +3126,7 @@ export const extend = stepRegister('extend', function (factor, pat) { * *Experimental* * * Expands the step size of the pattern by the given factor. + * @group structure * @example * sound("tha dhi thom nam").bank("mridangam").expand("3 2 1 1 2 3").pace(8) */ @@ -3016,6 +3138,7 @@ export const expand = stepRegister('expand', function (factor, pat) { * *Experimental* * * Contracts the step size of the pattern by the given factor. See also `expand`. + * @group structure * @example * sound("tha dhi thom nam").bank("mridangam").contract("3 2 1 1 2 3").pace(8) */ @@ -3070,6 +3193,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. + * @group structure * @return {Pattern} * @example * "tha dhi thom nam".shrink("1").sound() @@ -3109,6 +3233,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. + * @group structure * @return {Pattern} * @example * "tha dhi thom nam".grow("1").sound() @@ -3148,7 +3273,8 @@ export const grow = register( * Inserts a pattern into a list of patterns. On the first repetition it will be inserted at the end of the list, then moved backwards through the list * 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. - * + * + * @group combiners * @return {Pattern} * @example * "[c g]".tour("e f", "e f g", "g f e c").note() @@ -3175,6 +3301,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. * + * @group combiners * @returns {Pattern} * @example * zip("e f", "e f g", "g [f e] a f4 c").note() @@ -3226,6 +3353,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 + * @group transforms * @memberof Pattern * @returns Pattern * @example @@ -3256,6 +3384,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 + * @group transforms * @memberof Pattern * @returns Pattern * @example @@ -3274,6 +3403,7 @@ export const striate = register('striate', function (n, pat) { /** * Makes the sample fit the given number of cycles by changing the speed. * @name loopAt + * @group transforms * @memberof Pattern * @returns Pattern * @example @@ -3292,6 +3422,7 @@ const _loopAt = function (factor, pat, cps = 0.5) { * 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 + * @group transforms * @memberof Pattern * @returns Pattern * @example @@ -3327,6 +3458,7 @@ export const slice = register( * make something happen on event time * uses browser timeout which is innacurate for audio tasks * @name onTriggerTime + * @group external_io * @memberof Pattern * @returns Pattern * @example @@ -3344,6 +3476,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 + * @group transforms * @example * samples('github:tidalcycles/dirt-samples') * s("breaks165") @@ -3381,6 +3514,7 @@ export const { loopAt, loopat } = register(['loopAt', 'loopat'], function (facto * Makes the sample fit its event duration. Good for rhythmical loops like drum breaks. * Similar to `loopAt`. * @name fit + * @group transforms * @example * samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' }) * s("rhodes/2").fit() @@ -3406,6 +3540,7 @@ export const fit = register('fit', (pat) => * given by a global clock and this function will be * deprecated/removed. * @name loopAtCps + * @group transforms * @memberof Pattern * @returns Pattern * @example @@ -3432,6 +3567,7 @@ let fadeGain = (p) => (p < 0.5 ? 1 : 1 - (p - 0.5) / 0.5); * - 1 = (no left, full right) * * @name xfade + * @group combiners * @example * xfade(s("bd*2"), "<0 .25 .5 .75 1>", s("hh*8")) */ @@ -3453,6 +3589,7 @@ Pattern.prototype.xfade = function (pos, b) { * creates a structure pattern from divisions of a cycle * especially useful for creating rhythms * @name beat + * @group structure * @example * s("bd").beat("0,7,10", 16) * @example @@ -3529,6 +3666,7 @@ export const _morph = (from, to, by) => { * sine.slow(8) // slowly morph between the rhythms * ) * ) + * @group structure */ export const morph = (frompat, topat, bypat) => { frompat = reify(frompat); diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 6bd6fde67..9f6636c84 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -24,6 +24,7 @@ export const signal = (func) => { * A sawtooth signal between 0 and 1. * * @return {Pattern} + * @group generators * @example * note("*8") * .clip(saw.slow(2)) @@ -38,6 +39,7 @@ export const saw = signal((t) => t % 1); * A sawtooth signal between -1 and 1 (like `saw`, but bipolar). * * @return {Pattern} + * @group generators */ export const saw2 = saw.toBipolar(); @@ -45,6 +47,7 @@ export const saw2 = saw.toBipolar(); * A sawtooth signal between 1 and 0 (like `saw`, but flipped). * * @return {Pattern} + * @group generators * @example * note("*8") * .clip(isaw.slow(2)) @@ -59,6 +62,7 @@ export const isaw = signal((t) => 1 - (t % 1)); * A sawtooth signal between 1 and -1 (like `saw2`, but flipped). * * @return {Pattern} + * @group generators */ export const isaw2 = isaw.toBipolar(); @@ -66,12 +70,14 @@ export const isaw2 = isaw.toBipolar(); * A sine signal between -1 and 1 (like `sine`, but bipolar). * * @return {Pattern} + * @group generators */ export const sine2 = signal((t) => Math.sin(Math.PI * 2 * t)); /** * A sine signal between 0 and 1. * @return {Pattern} + * @group generators * @example * n(sine.segment(16).range(0,15)) * .scale("C:minor") @@ -83,6 +89,7 @@ export const sine = sine2.fromBipolar(); * A cosine signal between 0 and 1. * * @return {Pattern} + * @group generators * @example * n(stack(sine,cosine).segment(16).range(0,15)) * .scale("C:minor") @@ -94,12 +101,14 @@ export const cosine = sine._early(Fraction(1).div(4)); * A cosine signal between -1 and 1 (like `cosine`, but bipolar). * * @return {Pattern} + * @group generators */ export const cosine2 = sine2._early(Fraction(1).div(4)); /** * A square signal between 0 and 1. * @return {Pattern} + * @group generators * @example * n(square.segment(4).range(0,7)).scale("C:minor") * @@ -110,6 +119,7 @@ export const square = signal((t) => Math.floor((t * 2) % 2)); * A square signal between -1 and 1 (like `square`, but bipolar). * * @return {Pattern} + * @group generators */ export const square2 = square.toBipolar(); @@ -117,6 +127,7 @@ export const square2 = square.toBipolar(); * A triangle signal between 0 and 1. * * @return {Pattern} + * @group generators * @example * n(tri.segment(8).range(0,7)).scale("C:minor") * @@ -127,6 +138,7 @@ export const tri = fastcat(saw, isaw); * A triangle signal between -1 and 1 (like `tri`, but bipolar). * * @return {Pattern} + * @group generators */ export const tri2 = fastcat(saw2, isaw2); @@ -134,6 +146,7 @@ export const tri2 = fastcat(saw2, isaw2); * An inverted triangle signal between 1 and 0 (like `tri`, but flipped). * * @return {Pattern} + * @group generators * @example * n(itri.segment(8).range(0,7)).scale("C:minor") * @@ -144,6 +157,7 @@ export const itri = fastcat(isaw, saw); * An inverted triangle signal between -1 and 1 (like `itri`, but bipolar). * * @return {Pattern} + * @group generators */ export const itri2 = fastcat(isaw2, saw2); @@ -151,6 +165,7 @@ export const itri2 = fastcat(isaw2, saw2); * A signal representing the cycle time. * * @return {Pattern} + * @group generators */ export const time = signal(id); @@ -158,6 +173,7 @@ export const time = signal(id); * The mouse's x position value ranges from 0 to 1. * @name mousex * @return {Pattern} + * @group external_io * @example * n(mousex.segment(4).range(0,7)).scale("C:minor") * @@ -167,6 +183,7 @@ export const time = signal(id); * The mouse's y position value ranges from 0 to 1. * @name mousey * @return {Pattern} + * @group external_io * @example * n(mousey.segment(4).range(0,7)).scale("C:minor") * @@ -221,6 +238,7 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n); /** * A discrete pattern of numbers from 0 to n-1 + * @group generators * @example * n(run(4)).scale("C4:pentatonic") * // n("0 1 2 3").scale("C4:pentatonic") @@ -231,6 +249,7 @@ export const run = (n) => saw.range(0, n).round().segment(n); * Creates a pattern from a binary number. * * @name binary + * @group generators * @param {number} n - input number to convert to binary * @example * "hh".s().struct(binary(5)) @@ -245,6 +264,7 @@ export const binary = (n) => { * Creates a pattern from a binary number, padded to n bits long. * * @name binaryN + * @group generators * @param {number} n - input number to convert to binary * @param {number} nBits - pattern length, defaults to 16 * @example @@ -280,6 +300,7 @@ const _rearrangeWith = (ipat, n, pat) => { * Slices a pattern into the given number of parts, then plays those parts in random order. * Each part will be played exactly once per cycle. * @name shuffle + * @group transforms * @example * note("c d e f").sound("piano").shuffle(4) * @example @@ -293,6 +314,7 @@ export const shuffle = register('shuffle', (n, pat) => { * Slices a pattern into the given number of parts, then plays those parts at random. Similar to `shuffle`, * but parts might be played more than once, or not at all, per cycle. * @name scramble + * @group transforms * @example * note("c d e f").sound("piano").scramble(4) * @example @@ -306,6 +328,7 @@ export const scramble = register('scramble', (n, pat) => { * A continuous pattern of random numbers, between 0 and 1. * * @name rand + * @group generators * @example * // randomly change the cutoff * s("bd*4,hh*8").cutoff(rand.range(500,8000)) @@ -323,6 +346,7 @@ export const _brandBy = (p) => rand.fmap((x) => x < p); * A continuous pattern of 0 or 1 (binary random), with a probability for the value being 1 * * @name brandBy + * @group generators * @param {number} probability - a number between 0 and 1 * @example * s("hh*10").pan(brandBy(0.2)) @@ -333,6 +357,7 @@ export const brandBy = (pPat) => reify(pPat).fmap(_brandBy).innerJoin(); * A continuous pattern of 0 or 1 (binary random) * * @name brand + * @group generators * @example * s("hh*10").pan(brand) */ @@ -344,6 +369,7 @@ export const _irand = (i) => rand.fmap((x) => Math.trunc(x * i)); * A continuous pattern of random integers, between 0 and n-1. * * @name irand + * @group generators * @param {number} n max value (exclusive) * @example * // randomly select scale notes from 0 - 7 (= C to C) @@ -366,6 +392,7 @@ export const __chooseWith = (pat, xs) => { /** * Choose from the list of values (or patterns of values) using the given * pattern of numbers, which should be in the range of 0..1 + * @group transforms * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -379,6 +406,7 @@ export const chooseWith = (pat, xs) => { /** * As with {chooseWith}, but the structure comes from the chosen values, rather * than the pattern you're using to choose with. + * @group transforms * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -389,6 +417,7 @@ export const chooseInWith = (pat, xs) => { /** * Chooses randomly from the given list of elements. + * @group transforms * @param {...any} xs values / patterns to choose from. * @returns {Pattern} - a continuous pattern. * @example @@ -404,6 +433,7 @@ export const chooseOut = choose; * Chooses from the given list of values (or patterns of values), according * to the pattern that the method is called on. The pattern should be in * the range 0 .. 1. + * @group transforms * @param {...any} xs * @returns {Pattern} */ @@ -414,6 +444,7 @@ Pattern.prototype.choose = function (...xs) { /** * As with choose, but the pattern that this method is called on should be * in the range -1 .. 1 + * @group transforms * @param {...any} xs * @returns {Pattern} */ @@ -423,6 +454,7 @@ Pattern.prototype.choose2 = function (...xs) { /** * Picks one of the elements at random each cycle. + * @group transforms * @synonyms randcat * @returns {Pattern} * @example @@ -465,6 +497,7 @@ const wchooseWith = (...args) => _wchooseWith(...args).outerJoin(); /** * Chooses randomly from the given list of elements by giving a probability to each element + * @group transforms * @param {...any} pairs arrays of value and weight * @returns {Pattern} - a continuous pattern. * @example @@ -474,6 +507,7 @@ export const wchoose = (...pairs) => wchooseWith(rand, ...pairs); /** * Picks one of the elements at random each cycle by giving a probability to each element + * @group transforms * @synonyms wrandcat * @returns {Pattern} * @example @@ -521,6 +555,7 @@ export const berlinWith = (tpat) => { /** * Generates a continuous pattern of [perlin noise](https://en.wikipedia.org/wiki/Perlin_noise), in the range 0..1. * + * @group generators * @name perlin * @example * // randomly change the cutoff @@ -533,6 +568,7 @@ export const perlin = perlinWith(time.fmap((v) => Number(v))); * Generates a continuous pattern of [berlin noise](conceived by Jame Coyne and Jade Rowland as a joke but turned out to be surprisingly cool and useful, * like perlin noise but with sawtooth waves), in the range 0..1. * + * @group generators * @name berlin * @example * // ascending arpeggios @@ -553,6 +589,7 @@ export const degradeByWith = register( * 0 = 0% chance of removal * 1 = 100% chance of removal * + * @group transforms * @name degradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -578,6 +615,7 @@ export const degradeBy = register( * * Randomly removes 50% of events from the pattern. Shorthand for `.degradeBy(0.5)` * + * @group transforms * @name degrade * @memberof Pattern * @returns Pattern @@ -594,6 +632,7 @@ export const degrade = register('degrade', (pat) => pat._degradeBy(0.5), true, t * 1 = 0% chance of removal * Events that would be removed by degradeBy are let through by undegradeBy and vice versa (see second example). * + * @group transforms * @name undegradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -622,6 +661,7 @@ export const undegradeBy = register( * Inverse of `degrade`: Randomly removes 50% of events from the pattern. Shorthand for `.undegradeBy(0.5)` * Events that would be removed by degrade are let through by undegrade and vice versa (see second example). * + * @group transforms * @name undegrade * @memberof Pattern * @returns Pattern @@ -640,6 +680,7 @@ export const undegrade = register('undegrade', (pat) => pat._undegradeBy(0.5), t * Randomly applies the given function by the given probability. * Similar to `someCyclesBy` * + * @group transforms * @name sometimesBy * @memberof Pattern * @param {number | Pattern} probability - a number between 0 and 1 @@ -659,6 +700,7 @@ export const sometimesBy = register('sometimesBy', function (patx, func, pat) { * * Applies the given function with a 50% chance * + * @group transforms * @name sometimes * @memberof Pattern * @param {function} function - the transformation to apply @@ -680,6 +722,7 @@ export const sometimes = register('sometimes', function (func, pat) { * @param {number | Pattern} probability - a number between 0 and 1 * @param {function} function - the transformation to apply * @returns Pattern + * @group transforms * @example * s("bd,hh*8").someCyclesBy(.3, x=>x.speed("0.5")) */ @@ -702,6 +745,7 @@ export const someCyclesBy = register('someCyclesBy', function (patx, func, pat) * @name someCycles * @memberof Pattern * @returns Pattern + * @group transforms * @example * s("bd,hh*8").someCycles(x=>x.speed("0.5")) */ @@ -716,6 +760,7 @@ export const someCycles = register('someCycles', function (func, pat) { * @name often * @memberof Pattern * @returns Pattern + * @group transforms * @example * s("hh*8").often(x=>x.speed("0.5")) */ @@ -730,6 +775,7 @@ export const often = register('often', function (func, pat) { * @name rarely * @memberof Pattern * @returns Pattern + * @group transforms * @example * s("hh*8").rarely(x=>x.speed("0.5")) */ @@ -741,6 +787,7 @@ export const rarely = register('rarely', function (func, pat) { * * Shorthand for `.sometimesBy(0.1, fn)` * + * @group transforms * @name almostNever * @memberof Pattern * @returns Pattern @@ -755,6 +802,7 @@ export const almostNever = register('almostNever', function (func, pat) { * * Shorthand for `.sometimesBy(0.9, fn)` * + * @group transforms * @name almostAlways * @memberof Pattern * @returns Pattern @@ -769,6 +817,7 @@ export const almostAlways = register('almostAlways', function (func, pat) { * * Shorthand for `.sometimesBy(0, fn)` (never calls fn) * + * @group transforms * @name never * @memberof Pattern * @returns Pattern @@ -783,6 +832,7 @@ export const never = register('never', function (_, pat) { * * Shorthand for `.sometimesBy(1, fn)` (always calls fn) * + * @group transforms * @name always * @memberof Pattern * @returns Pattern @@ -811,6 +861,7 @@ export function _keyDown(keyname) { * Do something on a keypress, or array of keypresses * [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) * + * @group external_io * @name whenKey * @memberof Pattern * @returns Pattern @@ -827,6 +878,7 @@ export const whenKey = register('whenKey', function (input, func, pat) { * returns true when a key or array of keys is held * [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) * + * @group external_io * @name keyDown * @memberof Pattern * @returns Pattern diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index aa0453c3a..552551b5c 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -39,9 +39,11 @@ const GROUP_DISPLAY_NAMES = { external_io: 'External I/O', effects: 'Effects', ungrouped: 'Ungrouped', + structure: 'Structure', + transforms: 'Transforms', }; -const GROUP_ORDER = ['effects', 'external_io', 'ungrouped']; +const GROUP_ORDER = ['effects', 'transforms', 'structure', 'ungrouped', 'external_io']; export function Reference() { const [search, setSearch] = useState(''); @@ -93,7 +95,7 @@ export function Reference() { {sortedGroups.map(([groupId, groupEntries]) => ( <>

- {GROUP_DISPLAY_NAMES[groupId] || groupId} + {GROUP_DISPLAY_NAMES[groupId] || groupId} ({groupEntries.length})

{groupEntries.map((entry, i) => (
Date: Thu, 2 Oct 2025 21:59:45 +0200 Subject: [PATCH 04/26] Annotate controls.mjs --- packages/core/controls.mjs | 162 ++++++++++++++++++++++++++++++ packages/superdough/reverbGen.mjs | 4 +- 2 files changed, 165 insertions(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 7e3c2a8e2..e43af8967 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -77,6 +77,7 @@ export function registerControl(names, ...aliases) { * separated by ':'. * * @name s + * @group samples * @param {string | Pattern} sound The sound / pattern of sounds to pick * @synonyms sound * @example @@ -91,6 +92,7 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); * Position in the wavetable of the wavetable oscillator * * @name wt + * @group effects * @param {number | Pattern} position Position in the wavetable from 0 to 1 * @synonyms wavetablePosition * @example @@ -102,6 +104,7 @@ export const { wt, wavetablePosition } = registerControl('wt', 'wavetablePositio * Amount of envelope applied wavetable oscillator's position envelope * * @name wtenv + * @group effects * @param {number | Pattern} amount between 0 and 1 */ export const { wtenv } = registerControl('wtenv'); @@ -109,6 +112,7 @@ export const { wtenv } = registerControl('wtenv'); * Attack time of the wavetable oscillator's position envelope * * @name wtattack + * @group effects * @synonyms wtatt * @param {number | Pattern} time attack time in seconds */ @@ -118,6 +122,7 @@ export const { wtattack, wtatt } = registerControl('wtattack', 'wtatt'); * Decay time of the wavetable oscillator's position envelope * * @name wtdecay + * @group effects * @synonyms wtdec * @param {number | Pattern} time decay time in seconds */ @@ -127,6 +132,7 @@ export const { wtdecay, wtdec } = registerControl('wtdecay', 'wtdec'); * Sustain time of the wavetable oscillator's position envelope * * @name wtsustain + * @group effects * @synonyms wtsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -136,6 +142,7 @@ export const { wtsustain, wtsus } = registerControl('wtsustain', 'wtsus'); * Release time of the wavetable oscillator's position envelope * * @name wtrelease + * @group effects * @synonyms wtrel * @param {number | Pattern} time release time in seconds */ @@ -145,6 +152,7 @@ export const { wtrelease, wtrel } = registerControl('wtrelease', 'wtrel'); * Rate of the LFO for the wavetable oscillator's position * * @name wtrate + * @group effects * @param {number | Pattern} rate rate in hertz */ export const { wtrate } = registerControl('wtrate'); @@ -152,6 +160,7 @@ export const { wtrate } = registerControl('wtrate'); * cycle synced rate of the LFO for the wavetable oscillator's position * * @name wtsync + * @group effects * @param {number | Pattern} rate rate in cycles */ export const { wtsync } = registerControl('wtsync'); @@ -160,6 +169,7 @@ export const { wtsync } = registerControl('wtsync'); * Depth of the LFO for the wavetable oscillator's position * * @name wtdepth + * @group effects * @param {number | Pattern} depth depth of modulation */ export const { wtdepth } = registerControl('wtdepth'); @@ -168,6 +178,7 @@ export const { wtdepth } = registerControl('wtdepth'); * Shape of the LFO for the wavetable oscillator's position * * @name wtshape + * @group effects * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { wtshape } = registerControl('wtshape'); @@ -176,6 +187,7 @@ export const { wtshape } = registerControl('wtshape'); * DC offset of the LFO for the wavetable oscillator's position * * @name wtdc + * @group effects * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { wtdc } = registerControl('wtdc'); @@ -184,6 +196,7 @@ export const { wtdc } = registerControl('wtdc'); * Skew of the LFO for the wavetable oscillator's position * * @name wtskew + * @group effects * @param {number | Pattern} skew How much to bend the LFO shape */ export const { wtskew } = registerControl('wtskew'); @@ -192,6 +205,7 @@ export const { wtskew } = registerControl('wtskew'); * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator * * @name warp + * @group effects * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 * @synonyms wavetableWarp * @example @@ -204,6 +218,7 @@ export const { warp, wavetableWarp } = registerControl('warp', 'wavetableWarp'); * Attack time of the wavetable oscillator's warp envelope * * @name warpattack + * @group effects * @synonyms warpatt * @param {number | Pattern} time attack time in seconds */ @@ -213,6 +228,7 @@ export const { warpattack, warpatt } = registerControl('warpattack', 'warpatt'); * Decay time of the wavetable oscillator's warp envelope * * @name warpdecay + * @group effects * @synonyms warpdec * @param {number | Pattern} time decay time in seconds */ @@ -222,6 +238,7 @@ export const { warpdecay, warpdec } = registerControl('warpdecay', 'warpdec'); * Sustain time of the wavetable oscillator's warp envelope * * @name warpsustain + * @group effects * @synonyms warpsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -231,6 +248,7 @@ export const { warpsustain, warpsus } = registerControl('warpsustain', 'warpsus' * Release time of the wavetable oscillator's warp envelope * * @name warprelease + * @group effects * @synonyms warprel * @param {number | Pattern} time release time in seconds */ @@ -240,6 +258,7 @@ export const { warprelease, warprel } = registerControl('warprelease', 'warprel' * Rate of the LFO for the wavetable oscillator's warp * * @name warprate + * @group effects * @param {number | Pattern} rate rate in hertz */ export const { warprate } = registerControl('warprate'); @@ -248,6 +267,7 @@ export const { warprate } = registerControl('warprate'); * Depth of the LFO for the wavetable oscillator's warp * * @name warpdepth + * @group effects * @param {number | Pattern} depth depth of modulation */ export const { warpdepth } = registerControl('warpdepth'); @@ -256,6 +276,7 @@ export const { warpdepth } = registerControl('warpdepth'); * Shape of the LFO for the wavetable oscillator's warp * * @name warpshape + * @group effects * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { warpshape } = registerControl('warpshape'); @@ -264,6 +285,7 @@ export const { warpshape } = registerControl('warpshape'); * DC offset of the LFO for the wavetable oscillator's warp * * @name warpdc + * @group effects * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { warpdc } = registerControl('warpdc'); @@ -272,6 +294,7 @@ export const { warpdc } = registerControl('warpdc'); * Skew of the LFO for the wavetable oscillator's warp * * @name warpskew + * @group effects * @param {number | Pattern} skew How much to bend the LFO shape */ export const { warpskew } = registerControl('warpskew'); @@ -283,6 +306,7 @@ export const { warpskew } = registerControl('warpskew'); * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * * @name warpmode + * @group effects * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode * @example @@ -296,6 +320,7 @@ export const { warpmode, wavetableWarpMode } = registerControl('warpmode', 'wave * Amount of randomness of the initial phase of the wavetable oscillator. * * @name wtphaserand + * @group effects * @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random) * @synonyms wavetablePhaseRand * @example @@ -308,6 +333,7 @@ export const { wtphaserand, wavetablePhaseRand } = registerControl('wtphaserand' * Amount of envelope applied wavetable oscillator's position envelope * * @name warpenv + * @group effects * @param {number | Pattern} amount between 0 and 1 */ export const { warpenv } = registerControl('warpenv'); @@ -316,6 +342,7 @@ export const { warpenv } = registerControl('warpenv'); * cycle synced rate of the LFO for the wavetable warp position * * @name warpsync + * @group effects * @param {number | Pattern} rate rate in cycles */ export const { warpsync } = registerControl('warpsync'); @@ -324,6 +351,7 @@ export const { warpsync } = registerControl('warpsync'); * Define a custom webaudio node to use as a sound source. * * @name source + * @group external_io * @synonyms src * @param {function} getSource * @synonyms src @@ -336,6 +364,7 @@ export const { source, src } = registerControl('source', 'src'); * `n` can also be used to play midi numbers, but it is recommended to use `note` instead. * * @name n + * @group samples * @param {number | Pattern} value sample index starting from 0 * @example * s("bd sd [~ bd] sd,hh*6").n("<0 1>") @@ -354,6 +383,7 @@ export const { n } = registerControl('n'); * You can also use midi numbers instead of note names, where 69 is mapped to A4 440Hz in 12EDO. * * @name note + * @group music_theory * @example * note("c a f e") * @example @@ -369,6 +399,7 @@ export const { note } = registerControl(['note', 'n']); * A pattern of numbers that speed up (or slow down) samples while they play. Currently only supported by osc / superdirt. * * @name accelerate + * @group samples * @param {number | Pattern} amount acceleration. * @superdirtOnly * @example @@ -380,6 +411,7 @@ export const { accelerate } = registerControl('accelerate'); * Sets the velocity from 0 to 1. Is multiplied together with gain. * * @name velocity + * @group effects * @example * s("hh*8") * .gain(".4!2 1 .4!2 1 .4 1") @@ -390,6 +422,7 @@ export const { velocity } = registerControl('velocity'); * Controls the gain by an exponential amount. * * @name gain + * @group effects * @param {number | Pattern} amount gain. * @example * s("hh*8").gain(".4!2 1 .4!2 1 .4 1").fast(2) @@ -400,6 +433,7 @@ export const { gain } = registerControl('gain'); * Gain applied after all effects have been processed. * * @name postgain + * @group effects * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02").postgain(1.5) @@ -410,6 +444,7 @@ export const { postgain } = registerControl('postgain'); * Like `gain`, but linear. * * @name amp + * @group effects * @param {number | Pattern} amount gain. * @superdirtOnly * @example @@ -421,6 +456,7 @@ export const { amp } = registerControl('amp'); * Amplitude envelope attack time: Specifies how long it takes for the sound to reach its peak value, relative to the onset. * * @name attack + * @group effects * @param {number | Pattern} attack time in seconds. * @synonyms att * @example @@ -436,6 +472,7 @@ export const { attack, att } = registerControl('attack', 'att'); * while decimal numbers and complex ratios sound metallic. * * @name fmh + * @group effects * @param {number | Pattern} harmonicity * @example * note("c e g b g e") @@ -450,6 +487,7 @@ export const { fmh } = registerControl(['fmh', 'fmi'], 'fmh'); * Controls the modulation index, which defines the brightness of the sound. * * @name fm + * @group effects * @param {number | Pattern} brightness modulation index * @synonyms fmi * @example @@ -464,6 +502,7 @@ export const { fmi, fm } = registerControl(['fmi', 'fmh'], 'fm'); * Ramp type of fm envelope. Exp might be a bit broken.. * * @name fmenv + * @group effects * @param {number | Pattern} type lin | exp * @example * note("c e g b g e") @@ -479,6 +518,7 @@ export const { fmenv } = registerControl('fmenv'); * Attack time for the FM envelope: time it takes to reach maximum modulation * * @name fmattack + * @group effects * @param {number | Pattern} time attack time * @example * note("c e g b g e") @@ -493,6 +533,7 @@ export const { fmattack } = registerControl('fmattack'); * Waveform of the fm modulator * * @name fmwave + * @group effects * @param {number | Pattern} wave waveform * @example * n("0 1 2 3".fast(4)).scale("d:minor").s("sine").fmwave("").fm(4).fmh(2.01) @@ -506,6 +547,7 @@ export const { fmwave } = registerControl('fmwave'); * Decay time for the FM envelope: seconds until the sustain level is reached after the attack phase. * * @name fmdecay + * @group effects * @param {number | Pattern} time decay time * @example * note("c e g b g e") @@ -520,6 +562,7 @@ export const { fmdecay } = registerControl('fmdecay'); * Sustain level for the FM envelope: how much modulation is applied after the decay phase * * @name fmsustain + * @group effects * @param {number | Pattern} level sustain level * @example * note("c e g b g e") @@ -538,6 +581,7 @@ export const { fmvelocity } = registerControl('fmvelocity'); * Select the sound bank to use. To be used together with `s`. The bank name (+ "_") will be prepended to the value of `s`. * * @name bank + * @group samples * @param {string | Pattern} bank the name of the bank * @example * s("bd sd [~ bd] sd").bank('RolandTR909') // = s("RolandTR909_bd RolandTR909_sd") @@ -549,6 +593,7 @@ export const { bank } = registerControl('bank'); * mix control for the chorus effect * * @name chorus + * @group effects * @param {string | Pattern} chorus mix amount between 0 and 1 * @example * note("d d a# a").s("sawtooth").chorus(.5) @@ -566,6 +611,7 @@ export const { fft } = registerControl('fft'); * Note that the decay is only audible if the sustain value is lower than 1. * * @name decay + * @group effects * @param {number | Pattern} time decay time in seconds * @synonyms dec * @example @@ -577,6 +623,7 @@ export const { decay, dec } = registerControl('decay', 'dec'); * Amplitude envelope sustain level: The level which is reached after attack / decay, being sustained until the offset. * * @name sustain + * @group effects * @param {number | Pattern} gain sustain level between 0 and 1 * @synonyms sus * @example @@ -588,6 +635,7 @@ export const { sustain, sus } = registerControl('sustain', 'sus'); * Amplitude envelope release time: The time it takes after the offset to go from sustain level to zero. * * @name release + * @group effects * @param {number | Pattern} time release time in seconds * @synonyms rel * @example @@ -602,6 +650,7 @@ export const { hold } = registerControl('hold'); * can also optionally supply the 'bpq' parameter separated by ':'. * * @name bpf + * @group effects * @param {number | Pattern} frequency center frequency * @synonyms bandf, bp * @example @@ -614,6 +663,7 @@ export const { bandf, bpf, bp } = registerControl(['bandf', 'bandq', 'bpenv'], ' * Sets the **b**and-**p**ass **q**-factor (resonance). * * @name bpq + * @group effects * @param {number | Pattern} q q factor * @synonyms bandq * @example @@ -628,6 +678,7 @@ export const { bandq, bpq } = registerControl('bandq', 'bpq'); * * @memberof Pattern * @name begin + * @group samples * @param {number | Pattern} amount between 0 and 1, where 1 is the length of the sample * @example * samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/dirt-samples') @@ -640,6 +691,7 @@ export const { begin } = registerControl('begin'); * * @memberof Pattern * @name end + * @group samples * @param {number | Pattern} length 1 = whole sample, .5 = half sample, .25 = quarter sample etc.. * @example * s("bd*2,oh*4").end("<.1 .2 .5 1>").fast(2) @@ -652,6 +704,7 @@ export const { end } = registerControl('end'); * To change the loop region, use loopBegin / loopEnd. * * @name loop + * @group samples * @param {number | Pattern} on If 1, the sample is looped * @example * s("casio").loop(1) @@ -664,6 +717,7 @@ export const { loop } = registerControl('loop'); * Note: Samples starting with wt_ will automatically loop! (wt = wavetable) * * @name loopBegin + * @group samples * @param {number | Pattern} time between 0 and 1, where 1 is the length of the sample * @synonyms loopb * @example @@ -677,6 +731,7 @@ export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb'); * Note that the loop point must be inbetween `begin` and `end`, and after `loopBegin`! * * @name loopEnd + * @group samples * @param {number | Pattern} time between 0 and 1, where 1 is the length of the sample * @synonyms loope * @example @@ -688,6 +743,7 @@ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); * Bit crusher effect. * * @name crush + * @group effects * @param {number | Pattern} depth between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction). * @example * s(",hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>") @@ -699,6 +755,7 @@ export const { crush } = registerControl('crush'); * Fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers * * @name coarse + * @group effects * @param {number | Pattern} factor 1 for original 2 for half, 3 for a third and so on. * @example * s("bd sd [~ bd] sd,hh*8").coarse("<1 4 8 16 32>") @@ -710,6 +767,7 @@ export const { coarse } = registerControl('coarse'); * Modulate the amplitude of a sound with a continuous waveform * * @name tremolo + * @group effects * @synonyms trem * @param {number | Pattern} speed modulation speed in HZ * @example @@ -722,6 +780,7 @@ export const { tremolo } = registerControl(['tremolo', 'tremolodepth', 'tremolos * Modulate the amplitude of a sound with a continuous waveform * * @name tremolosync + * @group effects * @synonyms tremsync * @param {number | Pattern} cycles modulation speed in cycles * @example @@ -737,6 +796,7 @@ export const { tremolosync } = registerControl( * Depth of amplitude modulation * * @name tremolodepth + * @group effects * @synonyms tremdepth * @param {number | Pattern} depth * @example @@ -748,6 +808,7 @@ export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth'); * Alter the shape of the modulation waveform * * @name tremoloskew + * @group effects * @synonyms tremskew * @param {number | Pattern} amount between 0 & 1, the shape of the waveform * @example @@ -760,6 +821,7 @@ export const { tremoloskew } = registerControl('tremoloskew', 'tremskew'); * Alter the phase of the modulation waveform * * @name tremolophase + * @group effects * @synonyms tremphase * @param {number | Pattern} offset the offset in cycles of the modulation * @example @@ -772,6 +834,7 @@ export const { tremolophase } = registerControl('tremolophase', 'tremphase'); * Shape of amplitude modulation * * @name tremoloshape + * @group effects * @synonyms tremshape * @param {number | Pattern} shape tri | square | sine | saw | ramp * @example @@ -783,6 +846,7 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); * Filter overdrive for supported filter types * * @name drive + * @group effects * @param {number | Pattern} amount * @example * note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>") @@ -796,6 +860,7 @@ export const { drive } = registerControl('drive'); * Can be applied to multiple orbits with the ':' mininotation, e.g. `duckorbit("2:3")` * * @name duckorbit + * @group effects * @synonyms duck * @param {number | Pattern} orbit target orbit * @example @@ -816,6 +881,7 @@ export const { duck } = registerControl('duckorbit', 'duck'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckdepth + * @group effects * @param {number | Pattern} depth depth of modulation from 0 to 1 * @example * stack( n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2), s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack(0.2).duckdepth("<1 .9 .6 0>")) @@ -835,6 +901,7 @@ export const { duckdepth } = registerControl('duckdepth'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckonset + * @group effects * @synonyms duckons * * @param {number | Pattern} time The onset time in seconds @@ -862,6 +929,7 @@ export const { duckonset } = registerControl('duckonset', 'duckons'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckattack + * @group effects * @synonyms duckatt * * @param {number | Pattern} time The attack time in seconds @@ -906,6 +974,7 @@ export const { byteBeatStartTime, bbst } = registerControl('byteBeatStartTime', * Allows you to set the output channels on the interface * * @name channels + * @group external_io * @synonyms ch * * @param {number | Pattern} channels pattern the output channels @@ -919,6 +988,7 @@ export const { channels, ch } = registerControl('channels', 'ch'); * Controls the pulsewidth of the pulse oscillator * * @name pw + * @group effects * @param {number | Pattern} pulsewidth * @example * note("{f a c e}%16").s("pulse").pw(".8:1:.2") @@ -931,6 +1001,7 @@ export const { pw } = registerControl(['pw', 'pwrate', 'pwsweep']); * Controls the lfo rate for the pulsewidth of the pulse oscillator * * @name pwrate + * @group effects * @param {number | Pattern} rate * @example * n(run(8)).scale("D:pentatonic").s("pulse").pw("0.5").pwrate("<5 .1 25>").pwsweep("<0.3 .8>") @@ -943,6 +1014,7 @@ export const { pwrate } = registerControl('pwrate'); * Controls the lfo sweep for the pulsewidth of the pulse oscillator * * @name pwsweep + * @group effects * @param {number | Pattern} sweep * @example * n(run(8)).scale("D:pentatonic").s("pulse").pw("0.5").pwrate("<5 .1 25>").pwsweep("<0.3 .8>") @@ -954,6 +1026,7 @@ export const { pwsweep } = registerControl('pwsweep'); * Phaser audio effect that approximates popular guitar pedals. * * @name phaser + * @group effects * @synonyms ph * @param {number | Pattern} speed speed of modulation * @example @@ -971,6 +1044,7 @@ export const { phaserrate, ph, phaser } = registerControl( * The frequency sweep range of the lfo for the phaser effect. Defaults to 2000 * * @name phasersweep + * @group effects * @synonyms phs * @param {number | Pattern} phasersweep most useful values are between 0 and 4000 * @example @@ -984,6 +1058,7 @@ export const { phasersweep, phs } = registerControl('phasersweep', 'phs'); * The center frequency of the phaser in HZ. Defaults to 1000 * * @name phasercenter + * @group effects * @synonyms phc * @param {number | Pattern} centerfrequency in HZ * @example @@ -998,6 +1073,7 @@ export const { phasercenter, phc } = registerControl('phasercenter', 'phc'); * The amount the signal is affected by the phaser effect. Defaults to 0.75 * * @name phaserdepth + * @group effects * @synonyms phd, phasdp * @param {number | Pattern} depth number between 0 and 1 * @example @@ -1012,6 +1088,7 @@ export const { phaserdepth, phd, phasdp } = registerControl('phaserdepth', 'phd' * Choose the channel the pattern is sent to in superdirt * * @name channel + * @group effects * @param {number | Pattern} channel channel number * */ @@ -1020,6 +1097,7 @@ export const { channel } = registerControl('channel'); * In the style of classic drum-machines, `cut` will stop a playing sample as soon as another samples with in same cutgroup is to be played. An example would be an open hi-hat followed by a closed one, essentially muting the open. * * @name cut + * @group effects * @param {number | Pattern} group cut group number * @example * s("[oh hh]*4").cut(1) @@ -1032,6 +1110,7 @@ export const { cut } = registerControl('cut'); * When using mininotation, you can also optionally add the 'lpq' parameter, separated by ':'. * * @name lpf + * @group effects * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms cutoff, ctf, lp * @example @@ -1045,6 +1124,7 @@ export const { cutoff, ctf, lpf, lp } = registerControl(['cutoff', 'resonance', /** * Sets the lowpass filter envelope modulation depth. * @name lpenv + * @group effects * @param {number | Pattern} modulation depth of the lowpass filter envelope between 0 and _n_ * @synonyms lpe * @example @@ -1058,6 +1138,7 @@ export const { lpenv, lpe } = registerControl('lpenv', 'lpe'); /** * Sets the highpass filter envelope modulation depth. * @name hpenv + * @group effects * @param {number | Pattern} modulation depth of the highpass filter envelope between 0 and _n_ * @synonyms hpe * @example @@ -1071,6 +1152,7 @@ export const { hpenv, hpe } = registerControl('hpenv', 'hpe'); /** * Sets the bandpass filter envelope modulation depth. * @name bpenv + * @group effects * @param {number | Pattern} modulation depth of the bandpass filter envelope between 0 and _n_ * @synonyms bpe * @example @@ -1084,6 +1166,7 @@ export const { bpenv, bpe } = registerControl('bpenv', 'bpe'); /** * Sets the attack duration for the lowpass filter envelope. * @name lpattack + * @group effects * @param {number | Pattern} attack time of the filter envelope * @synonyms lpa * @example @@ -1097,6 +1180,7 @@ export const { lpattack, lpa } = registerControl('lpattack', 'lpa'); /** * Sets the attack duration for the highpass filter envelope. * @name hpattack + * @group effects * @param {number | Pattern} attack time of the highpass filter envelope * @synonyms hpa * @example @@ -1110,6 +1194,7 @@ export const { hpattack, hpa } = registerControl('hpattack', 'hpa'); /** * Sets the attack duration for the bandpass filter envelope. * @name bpattack + * @group effects * @param {number | Pattern} attack time of the bandpass filter envelope * @synonyms bpa * @example @@ -1123,6 +1208,7 @@ export const { bpattack, bpa } = registerControl('bpattack', 'bpa'); /** * Sets the decay duration for the lowpass filter envelope. * @name lpdecay + * @group effects * @param {number | Pattern} decay time of the filter envelope * @synonyms lpd * @example @@ -1136,6 +1222,7 @@ export const { lpdecay, lpd } = registerControl('lpdecay', 'lpd'); /** * Sets the decay duration for the highpass filter envelope. * @name hpdecay + * @group effects * @param {number | Pattern} decay time of the highpass filter envelope * @synonyms hpd * @example @@ -1150,6 +1237,7 @@ export const { hpdecay, hpd } = registerControl('hpdecay', 'hpd'); /** * Sets the decay duration for the bandpass filter envelope. * @name bpdecay + * @group effects * @param {number | Pattern} decay time of the bandpass filter envelope * @synonyms bpd * @example @@ -1164,6 +1252,7 @@ export const { bpdecay, bpd } = registerControl('bpdecay', 'bpd'); /** * Sets the sustain amplitude for the lowpass filter envelope. * @name lpsustain + * @group effects * @param {number | Pattern} sustain amplitude of the lowpass filter envelope * @synonyms lps * @example @@ -1178,6 +1267,7 @@ export const { lpsustain, lps } = registerControl('lpsustain', 'lps'); /** * Sets the sustain amplitude for the highpass filter envelope. * @name hpsustain + * @group effects * @param {number | Pattern} sustain amplitude of the highpass filter envelope * @synonyms hps * @example @@ -1192,6 +1282,7 @@ export const { hpsustain, hps } = registerControl('hpsustain', 'hps'); /** * Sets the sustain amplitude for the bandpass filter envelope. * @name bpsustain + * @group effects * @param {number | Pattern} sustain amplitude of the bandpass filter envelope * @synonyms bps * @example @@ -1206,6 +1297,7 @@ export const { bpsustain, bps } = registerControl('bpsustain', 'bps'); /** * Sets the release time for the lowpass filter envelope. * @name lprelease + * @group effects * @param {number | Pattern} release time of the filter envelope * @synonyms lpr * @example @@ -1221,6 +1313,7 @@ export const { lprelease, lpr } = registerControl('lprelease', 'lpr'); /** * Sets the release time for the highpass filter envelope. * @name hprelease + * @group effects * @param {number | Pattern} release time of the highpass filter envelope * @synonyms hpr * @example @@ -1236,6 +1329,7 @@ export const { hprelease, hpr } = registerControl('hprelease', 'hpr'); /** * Sets the release time for the bandpass filter envelope. * @name bprelease + * @group effects * @param {number | Pattern} release time of the bandpass filter envelope * @synonyms bpr * @example @@ -1251,6 +1345,7 @@ export const { bprelease, bpr } = registerControl('bprelease', 'bpr'); /** * Sets the filter type. The ladder filter is more aggressive. More types might be added in the future. * @name ftype + * @group effects * @param {number | Pattern} type 12db (0), ladder (1), or 24db (2) * @example * note("{f g g c d a a#}%8").s("sawtooth").lpenv(4).lpf(500).ftype("<0 1 2>").lpq(1) @@ -1266,6 +1361,7 @@ export const { ftype } = registerControl('ftype'); /** * controls the center of the filter envelope. 0 is unipolar positive, .5 is bipolar, 1 is unipolar negative * @name fanchor + * @group effects * @param {number | Pattern} center 0 to 1 * @example * note("{f g g c d a a#}%8").s("sawtooth").lpf("{1000}%2") @@ -1278,6 +1374,7 @@ export const { fanchor } = registerControl('fanchor'); * When using mininotation, you can also optionally add the 'hpq' parameter, separated by ':'. * * @name hpf + * @group effects * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms hp, hcutoff * @example @@ -1292,6 +1389,7 @@ export const { fanchor } = registerControl('fanchor'); * Applies a vibrato to the frequency of the oscillator. * * @name vib + * @group effects * @synonyms vibrato, v * @param {number | Pattern} frequency of the vibrato in hertz * @example @@ -1309,6 +1407,7 @@ export const { vib, vibrato, v } = registerControl(['vib', 'vibmod'], 'vibrato', * Adds pink noise to the mix * * @name noise + * @group generators * @param {number | Pattern} wet wet amount * @example * sound("/2") @@ -1318,6 +1417,7 @@ export const { noise } = registerControl('noise'); * Sets the vibrato depth in semitones. Only has an effect if `vibrato` | `vib` | `v` is is also set * * @name vibmod + * @group effects * @synonyms vmod * @param {number | Pattern} depth of vibrato (in semitones) * @example @@ -1336,6 +1436,7 @@ export const { hcutoff, hpf, hp } = registerControl(['hcutoff', 'hresonance', 'h * Controls the **h**igh-**p**ass **q**-value. * * @name hpq + * @group effects * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms hresonance * @example @@ -1347,6 +1448,7 @@ export const { hresonance, hpq } = registerControl('hresonance', 'hpq'); * Controls the **l**ow-**p**ass **q**-value. * * @name lpq + * @group effects * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms resonance * @example @@ -1359,6 +1461,7 @@ export const { resonance, lpq } = registerControl('resonance', 'lpq'); * DJ filter, below 0.5 is low pass filter, above is high pass filter. * * @name djf + * @group effects * @param {number | Pattern} cutoff below 0.5 is low pass filter, above is high pass filter * @example * n(irand(16).seg(8)).scale("d:phrygian").s("supersaw").djf("<.5 .3 .2 .75>") @@ -1375,6 +1478,7 @@ export const { djf } = registerControl('djf'); * * * @name delay + * @group effects * @param {number | Pattern} level between 0 and 1 * @example * s("bd bd").delay("<0 .25 .5 1>") @@ -1388,6 +1492,7 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback + * @group effects * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1401,6 +1506,7 @@ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback + * @group effects * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1412,6 +1518,7 @@ export const { delayspeed } = registerControl('delayspeed'); * Sets the time of the delay effect. * * @name delayspeed + * @group effects * @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @synonyms delayt, dt * @example @@ -1424,6 +1531,7 @@ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', * Sets the time of the delay effect in cycles. * * @name delaysync + * @group effects * @param {number | Pattern} cycles delay length in cycles * @synonyms delayt, dt * @example @@ -1436,6 +1544,7 @@ export const { delaysync } = registerControl('delaysync'); * Specifies whether delaytime is calculated relative to cps. * * @name lock + * @group effects * @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle. * @superdirtOnly * @example @@ -1449,6 +1558,7 @@ export const { lock } = registerControl('lock'); * Set detune for stacked voices of supported oscillators * * @name detune + * @group effects * @param {number | Pattern} amount * @synonyms det * @example @@ -1460,6 +1570,7 @@ export const { detune, det } = registerControl('detune', 'det'); * Set number of stacked voices for supported oscillators * * @name unison + * @group effects * @param {number | Pattern} numvoices * @example * note("d f a a# a d3").fast(2).s("supersaw").unison("<1 2 7>") @@ -1471,6 +1582,7 @@ export const { unison } = registerControl('unison'); * Set the stereo pan spread for supported oscillators * * @name spread + * @group effects * @param {number | Pattern} spread between 0 and 1 * @example * note("d f a a# a d3").fast(2).s("supersaw").spread("<0 .3 1>") @@ -1481,6 +1593,7 @@ export const { spread } = registerControl('spread'); * Set dryness of reverb. See `room` and `size` for more information about reverb. * * @name dry + * @group effects * @param {number | Pattern} dry 0 = wet, 1 = dry * @example * n("[0,3,7](3,8)").s("superpiano").room(.7).dry("<0 .5 .75 1>").osc() @@ -1506,6 +1619,7 @@ export const { fadeInTime } = registerControl('fadeInTime'); * Set frequency of sound. * * @name freq + * @group transforms * @param {number | Pattern} frequency in Hz. the audible range is between 20 and 20000 Hz * @example * freq("220 110 440 110").s("superzow").osc() @@ -1519,6 +1633,7 @@ export const { freq } = registerControl('freq'); * Attack time of pitch envelope. * * @name pattack + * @group effects * @synonyms patt * @param {number | Pattern} time time in seconds * @example @@ -1530,6 +1645,7 @@ export const { pattack, patt } = registerControl('pattack', 'patt'); * Decay time of pitch envelope. * * @name pdecay + * @group effects * @synonyms pdec * @param {number | Pattern} time time in seconds * @example @@ -1543,6 +1659,7 @@ export const { psustain, psus } = registerControl('psustain', 'psus'); * Release time of pitch envelope * * @name prelease + * @group effects * @synonyms prel * @param {number | Pattern} time time in seconds * @example @@ -1557,6 +1674,7 @@ export const { prelease, prel } = registerControl('prelease', 'prel'); * If you don't set other pitch envelope controls, `pattack:.2` will be the default. * * @name penv + * @group effects * @param {number | Pattern} semitones change in semitones * @example * note("c") @@ -1568,6 +1686,7 @@ export const { penv } = registerControl('penv'); * Curve of envelope. Defaults to linear. exponential is good for kicks * * @name pcurve + * @group effects * @param {number | Pattern} type 0 = linear, 1 = exponential * @example * note("g1*4") @@ -1584,6 +1703,7 @@ export const { pcurve } = registerControl('pcurve'); * If you don't set an anchor, the value will default to the psustain value. * * @name panchor + * @group effects * @param {number | Pattern} anchor anchor offset * @example * note("c c4").penv(12).panchor("<0 .5 1 .5>") @@ -1605,6 +1725,7 @@ export const { gate, gat } = registerControl('gate', 'gat'); * Emulation of a Leslie speaker: speakers rotating in a wooden amplified cabinet. * * @name leslie + * @group effects * @param {number | Pattern} wet between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie("<0 .4 .6 1>").osc() @@ -1616,6 +1737,7 @@ export const { leslie } = registerControl('leslie'); * Rate of modulation / rotation for leslie effect * * @name lrate + * @group effects * @param {number | Pattern} rate 6.7 for fast, 0.7 for slow * @example * n("0,4,7").s("supersquare").leslie(1).lrate("<1 2 4 8>").osc() @@ -1628,6 +1750,7 @@ export const { lrate } = registerControl('lrate'); * Physical size of the cabinet in meters. Be careful, it might be slightly larger than your computer. Affects the Doppler amount (pitch warble) * * @name lsize + * @group effects * @param {number | Pattern} meters somewhere between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie(1).lrate(2).lsize("<.1 .5 1>").osc() @@ -1639,6 +1762,7 @@ export const { lsize } = registerControl('lsize'); * Sets the displayed text for an event on the pianoroll * * @name label + * @group visualization * @param {string} label text to display */ export const { activeLabel } = registerControl('activeLabel'); @@ -1704,6 +1828,7 @@ export const { overshape } = registerControl('overshape'); * Sets position in stereo. * * @name pan + * @group effects * @param {number | Pattern} pan between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel) * @example * s("[bd hh]*2").pan("<.5 1 .5 0>") @@ -1769,6 +1894,7 @@ export const { mode } = registerControl(['mode', 'anchor']); * When using mininotation, you can also optionally add the 'size' parameter, separated by ':'. * * @name room + * @group effects * @param {number | Pattern} level between 0 and 1 * @example * s("bd sd [~ bd] sd").room("<0 .2 .4 .6 .8 1>") @@ -1782,6 +1908,7 @@ export const { room } = registerControl(['room', 'size']); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomlp + * @group effects * @synonyms rlp * @param {number} frequency between 0 and 20000hz * @example @@ -1795,6 +1922,7 @@ export const { roomlp, rlp } = registerControl('roomlp', 'rlp'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomdim + * @group effects * @synonyms rdim * @param {number} frequency between 0 and 20000hz * @example @@ -1809,6 +1937,7 @@ export const { roomdim, rdim } = registerControl('roomdim', 'rdim'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomfade + * @group effects * @synonyms rfade * @param {number} seconds for the reverb to fade * @example @@ -1821,6 +1950,7 @@ export const { roomfade, rfade } = registerControl('roomfade', 'rfade'); /** * Sets the sample to use as an impulse response for the reverb. * @name iresponse + * @group effects * @param {string | Pattern} sample to use as an impulse response * @synonyms ir * @example @@ -1832,6 +1962,7 @@ export const { ir, iresponse } = registerControl(['ir', 'i'], 'iresponse'); /** * Sets speed of the sample for the impulse response. * @name irspeed + * @group effects * @param {string | Pattern} speed * @example * samples('github:switchangel/pad') @@ -1843,6 +1974,7 @@ export const { irspeed } = registerControl('irspeed'); /** * Sets the beginning of the IR response sample * @name irbegin + * @group effects * @param {string | Pattern} begin between 0 and 1 * @synonyms ir * @example @@ -1856,6 +1988,7 @@ export const { irbegin } = registerControl('irbegin'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomsize + * @group effects * @param {number | Pattern} size between 0 and 10 * @synonyms rsize, sz, size * @example @@ -1879,6 +2012,7 @@ export const { roomsize, size, sz, rsize } = registerControl('roomsize', 'size', * * * @name shape + * @group effects * @param {number | Pattern} distortion between 0 and 1 * @example * s("bd sd [~ bd] sd,hh*8").shape("<0 .2 .4 .6 .8>") @@ -1891,6 +2025,7 @@ export const { shape } = registerControl(['shape', 'shapevol']); * Most useful values are usually between 0 and 10 (depending on source gain). If you are feeling adventurous, you can turn it up to 11 and beyond ;) * * @name distort + * @group effects * @synonyms dist * @param {number | Pattern} distortion * @example @@ -1905,6 +2040,7 @@ export const { distort, dist } = registerControl(['distort', 'distortvol'], 'dis * More info [here](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) * * @name compressor + * @group effects * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02") @@ -1925,6 +2061,7 @@ export const { compressorRelease } = registerControl('compressorRelease'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name speed + * @group effects * @param {number | Pattern} speed -inf to inf, negative numbers play the sample backwards. * @example * s("bd*6").speed("1 2 4 1 -2 -4") @@ -1938,6 +2075,7 @@ export const { speed } = registerControl('speed'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name stretch + * @group effects * @param {number | Pattern} factor -inf to inf, negative numbers play the sample backwards. * @example * s("gm_flute").stretch("1 2 .5") @@ -1948,6 +2086,7 @@ export const { stretch } = registerControl('stretch'); * Used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`. * * @name unit + * @group effects * @param {number | string | Pattern} unit see description above * @example * speed("1 2 .5 3").s("bd").unit("c").osc() @@ -1962,6 +2101,7 @@ export const { unit } = registerControl('unit'); * "A simplistic pitch-raising algorithm. It's not meant to sound natural; its sound is reminiscent of some weird mixture of filter, ring-modulator and pitch-shifter, depending on the input. The algorithm works by cutting the signal into fragments (delimited by upwards-going zero-crossings) and squeezing those fragments in the time domain (i.e. simply playing them back faster than they came in), leaving silences inbetween. All the parameters apart from memlen can be modulated." * * @name squiz + * @group effects * @param {number | Pattern} squiz Try passing multiples of 2 to it - 2, 4, 8 etc. * @example * squiz("2 4/2 6 [8 16]").s("bd").osc() @@ -1986,6 +2126,7 @@ export const { squiz } = registerControl('squiz'); * Formant filter to make things sound like vowels. * * @name vowel + * @group effects * @param {string | Pattern} vowel You can use a e i o u ae aa oe ue y uh un en an on, corresponding to [a] [e] [i] [o] [u] [æ] [ɑ] [ø] [y] [ɯ] [ʌ] [œ̃] [ɛ̃] [ɑ̃] [ɔ̃]. Aliases: aa = å = ɑ, oe = ø = ö, y = ı, ae = æ. * @example * note("[c2 >]*2").s('sawtooth') @@ -2010,6 +2151,7 @@ export const { waveloss } = registerControl('waveloss'); * Noise crackle density * * @name density + * @group effects * @param {number | Pattern} density between 0 and x * @example * s("crackle*4").density("<0.01 0.04 0.2 0.5>".slow(4)) @@ -2060,6 +2202,7 @@ export const { cps } = registerControl('cps'); * Multiplies the duration with the given number. Also cuts samples off at the end if they exceed the duration. * * @name clip + * @group transforms * @synonyms legato * @param {number | Pattern} factor >= 0 * @example @@ -2072,6 +2215,7 @@ export const { clip, legato } = registerControl('clip', 'legato'); * Sets the duration of the event in cycles. Similar to clip / legato, it also cuts samples off at the end if they exceed the duration. * * @name duration + * @group transforms * @synonyms dur * @param {number | Pattern} seconds >= 0 * @example @@ -2100,6 +2244,7 @@ export const { zzfx } = registerControl('zzfx'); /** * Sets the color of the hap in visualizations like pianoroll or highlighting. * @name color + * @group visualization * @synonyms colour * @param {string} color Hexadecimal or CSS color name */ @@ -2114,6 +2259,7 @@ export let createParams = (...names) => * ADSR envelope: Combination of Attack, Decay, Sustain, and Release. * * @name adsr + * @group effects * @param {number | Pattern} time attack time in seconds * @param {number | Pattern} time decay time in seconds * @param {number | Pattern} gain sustain level (0 to 1) @@ -2148,6 +2294,7 @@ export const ar = register('ar', (t, pat) => { * MIDI channel: Sets the MIDI channel for the event. * * @name midichan + * @group examples * @param {number | Pattern} channel MIDI channel number (0-15) * @example * note("c4").midichan(1).midi() @@ -2160,6 +2307,7 @@ export const { midimap } = registerControl('midimap'); * MIDI port: Sets the MIDI port for the event. * * @name midiport + * @group examples * @param {number | Pattern} port MIDI port * @example * note("c a f e").midiport("<0 1 2 3>").midi() @@ -2170,6 +2318,7 @@ export const { midiport } = registerControl('midiport'); * MIDI command: Sends a MIDI command message. * * @name midicmd + * @group examples * @param {number | Pattern} command MIDI command * @example * midicmd("clock*48,/2").midi() @@ -2180,6 +2329,7 @@ export const { midicmd } = registerControl('midicmd'); * MIDI control: Sends a MIDI control change message. * * @name control + * @group examples * @param {number | Pattern} MIDI control number (0-127) * @param {number | Pattern} MIDI controller value (0-127) */ @@ -2195,6 +2345,7 @@ export const control = register('control', (args, pat) => { * MIDI control number: Sends a MIDI control change message. * * @name ccn + * @group examples * @param {number | Pattern} MIDI control number (0-127) */ export const { ccn } = registerControl('ccn'); @@ -2202,6 +2353,7 @@ export const { ccn } = registerControl('ccn'); * MIDI control value: Sends a MIDI control change message. * * @name ccv + * @group examples * @param {number | Pattern} MIDI control value (0-127) */ export const { ccv } = registerControl('ccv'); @@ -2211,6 +2363,7 @@ export const { ctlNum } = registerControl('ctlNum'); /** * MIDI NRPN non-registered parameter number: Sends a MIDI NRPN non-registered parameter number message. * @name nrpnn + * @group examples * @param {number | Pattern} nrpnn MIDI NRPN non-registered parameter number (0-127) * @example * note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi() @@ -2219,6 +2372,7 @@ export const { nrpnn } = registerControl('nrpnn'); /** * MIDI NRPN non-registered parameter value: Sends a MIDI NRPN non-registered parameter value message. * @name nrpv + * @group examples * @param {number | Pattern} nrpv MIDI NRPN non-registered parameter value (0-127) * @example * note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi() @@ -2229,6 +2383,7 @@ export const { nrpv } = registerControl('nrpv'); * MIDI program number: Sends a MIDI program change message. * * @name progNum + * @group examples * @param {number | Pattern} program MIDI program number (0-127) * @example * note("c4").progNum(10).midichan(1).midi() @@ -2238,6 +2393,7 @@ export const { progNum } = registerControl('progNum'); /** * MIDI sysex: Sends a MIDI sysex message. * @name sysex + * @group examples * @param {number | Pattern} id Sysex ID * @param {number | Pattern} data Sysex data * @example @@ -2253,6 +2409,7 @@ export const sysex = register('sysex', (args, pat) => { /** * MIDI sysex ID: Sends a MIDI sysex identifier message. * @name sysexid + * @group examples * @param {number | Pattern} id Sysex ID * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2261,6 +2418,7 @@ export const { sysexid } = registerControl('sysexid'); /** * MIDI sysex data: Sends a MIDI sysex message. * @name sysexdata + * @group examples * @param {number | Pattern} data Sysex data * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2270,6 +2428,7 @@ export const { sysexdata } = registerControl('sysexdata'); /** * MIDI pitch bend: Sends a MIDI pitch bend message. * @name midibend + * @group examples * @param {number | Pattern} midibend MIDI pitch bend (-1 - 1) * @example * note("c4").midibend(sine.slow(4).range(-0.4,0.4)).midi() @@ -2278,6 +2437,7 @@ export const { midibend } = registerControl('midibend'); /** * MIDI key after touch: Sends a MIDI key after touch message. * @name miditouch + * @group examples * @param {number | Pattern} miditouch MIDI key after touch (0-1) * @example * note("c4").miditouch(sine.slow(4).range(0,1)).midi() @@ -2298,6 +2458,7 @@ export const getControlName = (alias) => { * Sets properties in a batch. * * @name as + * @group transforms * @param {String | Array} mapping the control names that are set * @example * "c:.5 a:1 f:.25 e:.8".as("note:clip") @@ -2317,6 +2478,7 @@ export const as = register('as', (mapping, pat) => { * Allows you to scrub an audio file like a tape loop by passing values that represents the position in the audio file * in the optional array syntax ex: "0.5:2", the second value controls the speed of playback * @name scrub + * @group samples * @memberof Pattern * @returns Pattern * @example diff --git a/packages/superdough/reverbGen.mjs b/packages/superdough/reverbGen.mjs index d2533cae4..0d5fee264 100644 --- a/packages/superdough/reverbGen.mjs +++ b/packages/superdough/reverbGen.mjs @@ -79,7 +79,9 @@ reverbGen.generateGraph = function (data, width, height, min, max) { @param {number} lpFreqEnd @param {number} lpFreqEndAt @param {!function(!AudioBuffer)} callback May be called - immediately within the current execution context, or later.*/ + immediately within the current execution context, or later. + @group effects + */ var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, callback) { if (lpFreqStart == 0) { callback(input); From 5032b4e966ecd3c92c47497457a5bf0576d85a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 11 Oct 2025 14:11:50 +0200 Subject: [PATCH 05/26] Rename group -> tags --- jsdoc/jsdoc-synonyms.js | 4 +- packages/core/controls.mjs | 324 +++++++++++++++--------------- packages/core/pattern.mjs | 270 ++++++++++++------------- packages/core/signal.mjs | 104 +++++----- packages/motion/motion.mjs | 30 +-- packages/superdough/reverbGen.mjs | 2 +- packages/supradough/dough.mjs | 2 +- 7 files changed, 368 insertions(+), 368 deletions(-) diff --git a/jsdoc/jsdoc-synonyms.js b/jsdoc/jsdoc-synonyms.js index 423c7ad6e..c5860626a 100644 --- a/jsdoc/jsdoc-synonyms.js +++ b/jsdoc/jsdoc-synonyms.js @@ -13,10 +13,10 @@ function defineTags(dictionary) { }, }); - dictionary.defineTag('group', { + dictionary.defineTag('tags', { mustHaveValue: true, onTagged: function (doclet, tag) { - doclet.group = tag.value; + doclet.tags = tag.value.split(/[ ,]+/); }, }); } diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index e43af8967..44b358e67 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -77,7 +77,7 @@ export function registerControl(names, ...aliases) { * separated by ':'. * * @name s - * @group samples + * @tags samples * @param {string | Pattern} sound The sound / pattern of sounds to pick * @synonyms sound * @example @@ -92,7 +92,7 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); * Position in the wavetable of the wavetable oscillator * * @name wt - * @group effects + * @tags effects * @param {number | Pattern} position Position in the wavetable from 0 to 1 * @synonyms wavetablePosition * @example @@ -104,7 +104,7 @@ export const { wt, wavetablePosition } = registerControl('wt', 'wavetablePositio * Amount of envelope applied wavetable oscillator's position envelope * * @name wtenv - * @group effects + * @tags effects * @param {number | Pattern} amount between 0 and 1 */ export const { wtenv } = registerControl('wtenv'); @@ -112,7 +112,7 @@ export const { wtenv } = registerControl('wtenv'); * Attack time of the wavetable oscillator's position envelope * * @name wtattack - * @group effects + * @tags effects * @synonyms wtatt * @param {number | Pattern} time attack time in seconds */ @@ -122,7 +122,7 @@ export const { wtattack, wtatt } = registerControl('wtattack', 'wtatt'); * Decay time of the wavetable oscillator's position envelope * * @name wtdecay - * @group effects + * @tags effects * @synonyms wtdec * @param {number | Pattern} time decay time in seconds */ @@ -132,7 +132,7 @@ export const { wtdecay, wtdec } = registerControl('wtdecay', 'wtdec'); * Sustain time of the wavetable oscillator's position envelope * * @name wtsustain - * @group effects + * @tags effects * @synonyms wtsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -142,7 +142,7 @@ export const { wtsustain, wtsus } = registerControl('wtsustain', 'wtsus'); * Release time of the wavetable oscillator's position envelope * * @name wtrelease - * @group effects + * @tags effects * @synonyms wtrel * @param {number | Pattern} time release time in seconds */ @@ -152,7 +152,7 @@ export const { wtrelease, wtrel } = registerControl('wtrelease', 'wtrel'); * Rate of the LFO for the wavetable oscillator's position * * @name wtrate - * @group effects + * @tags effects * @param {number | Pattern} rate rate in hertz */ export const { wtrate } = registerControl('wtrate'); @@ -160,7 +160,7 @@ export const { wtrate } = registerControl('wtrate'); * cycle synced rate of the LFO for the wavetable oscillator's position * * @name wtsync - * @group effects + * @tags effects * @param {number | Pattern} rate rate in cycles */ export const { wtsync } = registerControl('wtsync'); @@ -169,7 +169,7 @@ export const { wtsync } = registerControl('wtsync'); * Depth of the LFO for the wavetable oscillator's position * * @name wtdepth - * @group effects + * @tags effects * @param {number | Pattern} depth depth of modulation */ export const { wtdepth } = registerControl('wtdepth'); @@ -178,7 +178,7 @@ export const { wtdepth } = registerControl('wtdepth'); * Shape of the LFO for the wavetable oscillator's position * * @name wtshape - * @group effects + * @tags effects * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { wtshape } = registerControl('wtshape'); @@ -187,7 +187,7 @@ export const { wtshape } = registerControl('wtshape'); * DC offset of the LFO for the wavetable oscillator's position * * @name wtdc - * @group effects + * @tags effects * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { wtdc } = registerControl('wtdc'); @@ -196,7 +196,7 @@ export const { wtdc } = registerControl('wtdc'); * Skew of the LFO for the wavetable oscillator's position * * @name wtskew - * @group effects + * @tags effects * @param {number | Pattern} skew How much to bend the LFO shape */ export const { wtskew } = registerControl('wtskew'); @@ -205,7 +205,7 @@ export const { wtskew } = registerControl('wtskew'); * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator * * @name warp - * @group effects + * @tags effects * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 * @synonyms wavetableWarp * @example @@ -218,7 +218,7 @@ export const { warp, wavetableWarp } = registerControl('warp', 'wavetableWarp'); * Attack time of the wavetable oscillator's warp envelope * * @name warpattack - * @group effects + * @tags effects * @synonyms warpatt * @param {number | Pattern} time attack time in seconds */ @@ -228,7 +228,7 @@ export const { warpattack, warpatt } = registerControl('warpattack', 'warpatt'); * Decay time of the wavetable oscillator's warp envelope * * @name warpdecay - * @group effects + * @tags effects * @synonyms warpdec * @param {number | Pattern} time decay time in seconds */ @@ -238,7 +238,7 @@ export const { warpdecay, warpdec } = registerControl('warpdecay', 'warpdec'); * Sustain time of the wavetable oscillator's warp envelope * * @name warpsustain - * @group effects + * @tags effects * @synonyms warpsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -248,7 +248,7 @@ export const { warpsustain, warpsus } = registerControl('warpsustain', 'warpsus' * Release time of the wavetable oscillator's warp envelope * * @name warprelease - * @group effects + * @tags effects * @synonyms warprel * @param {number | Pattern} time release time in seconds */ @@ -258,7 +258,7 @@ export const { warprelease, warprel } = registerControl('warprelease', 'warprel' * Rate of the LFO for the wavetable oscillator's warp * * @name warprate - * @group effects + * @tags effects * @param {number | Pattern} rate rate in hertz */ export const { warprate } = registerControl('warprate'); @@ -267,7 +267,7 @@ export const { warprate } = registerControl('warprate'); * Depth of the LFO for the wavetable oscillator's warp * * @name warpdepth - * @group effects + * @tags effects * @param {number | Pattern} depth depth of modulation */ export const { warpdepth } = registerControl('warpdepth'); @@ -276,7 +276,7 @@ export const { warpdepth } = registerControl('warpdepth'); * Shape of the LFO for the wavetable oscillator's warp * * @name warpshape - * @group effects + * @tags effects * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { warpshape } = registerControl('warpshape'); @@ -285,7 +285,7 @@ export const { warpshape } = registerControl('warpshape'); * DC offset of the LFO for the wavetable oscillator's warp * * @name warpdc - * @group effects + * @tags effects * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { warpdc } = registerControl('warpdc'); @@ -294,7 +294,7 @@ export const { warpdc } = registerControl('warpdc'); * Skew of the LFO for the wavetable oscillator's warp * * @name warpskew - * @group effects + * @tags effects * @param {number | Pattern} skew How much to bend the LFO shape */ export const { warpskew } = registerControl('warpskew'); @@ -306,7 +306,7 @@ export const { warpskew } = registerControl('warpskew'); * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * * @name warpmode - * @group effects + * @tags effects * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode * @example @@ -320,7 +320,7 @@ export const { warpmode, wavetableWarpMode } = registerControl('warpmode', 'wave * Amount of randomness of the initial phase of the wavetable oscillator. * * @name wtphaserand - * @group effects + * @tags effects * @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random) * @synonyms wavetablePhaseRand * @example @@ -333,7 +333,7 @@ export const { wtphaserand, wavetablePhaseRand } = registerControl('wtphaserand' * Amount of envelope applied wavetable oscillator's position envelope * * @name warpenv - * @group effects + * @tags effects * @param {number | Pattern} amount between 0 and 1 */ export const { warpenv } = registerControl('warpenv'); @@ -342,7 +342,7 @@ export const { warpenv } = registerControl('warpenv'); * cycle synced rate of the LFO for the wavetable warp position * * @name warpsync - * @group effects + * @tags effects * @param {number | Pattern} rate rate in cycles */ export const { warpsync } = registerControl('warpsync'); @@ -351,7 +351,7 @@ export const { warpsync } = registerControl('warpsync'); * Define a custom webaudio node to use as a sound source. * * @name source - * @group external_io + * @tags external_io * @synonyms src * @param {function} getSource * @synonyms src @@ -364,7 +364,7 @@ export const { source, src } = registerControl('source', 'src'); * `n` can also be used to play midi numbers, but it is recommended to use `note` instead. * * @name n - * @group samples + * @tags samples * @param {number | Pattern} value sample index starting from 0 * @example * s("bd sd [~ bd] sd,hh*6").n("<0 1>") @@ -383,7 +383,7 @@ export const { n } = registerControl('n'); * You can also use midi numbers instead of note names, where 69 is mapped to A4 440Hz in 12EDO. * * @name note - * @group music_theory + * @tags music_theory * @example * note("c a f e") * @example @@ -399,7 +399,7 @@ export const { note } = registerControl(['note', 'n']); * A pattern of numbers that speed up (or slow down) samples while they play. Currently only supported by osc / superdirt. * * @name accelerate - * @group samples + * @tags samples * @param {number | Pattern} amount acceleration. * @superdirtOnly * @example @@ -411,7 +411,7 @@ export const { accelerate } = registerControl('accelerate'); * Sets the velocity from 0 to 1. Is multiplied together with gain. * * @name velocity - * @group effects + * @tags effects * @example * s("hh*8") * .gain(".4!2 1 .4!2 1 .4 1") @@ -422,7 +422,7 @@ export const { velocity } = registerControl('velocity'); * Controls the gain by an exponential amount. * * @name gain - * @group effects + * @tags effects * @param {number | Pattern} amount gain. * @example * s("hh*8").gain(".4!2 1 .4!2 1 .4 1").fast(2) @@ -433,7 +433,7 @@ export const { gain } = registerControl('gain'); * Gain applied after all effects have been processed. * * @name postgain - * @group effects + * @tags effects * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02").postgain(1.5) @@ -444,7 +444,7 @@ export const { postgain } = registerControl('postgain'); * Like `gain`, but linear. * * @name amp - * @group effects + * @tags effects * @param {number | Pattern} amount gain. * @superdirtOnly * @example @@ -456,7 +456,7 @@ export const { amp } = registerControl('amp'); * Amplitude envelope attack time: Specifies how long it takes for the sound to reach its peak value, relative to the onset. * * @name attack - * @group effects + * @tags effects * @param {number | Pattern} attack time in seconds. * @synonyms att * @example @@ -472,7 +472,7 @@ export const { attack, att } = registerControl('attack', 'att'); * while decimal numbers and complex ratios sound metallic. * * @name fmh - * @group effects + * @tags effects * @param {number | Pattern} harmonicity * @example * note("c e g b g e") @@ -487,7 +487,7 @@ export const { fmh } = registerControl(['fmh', 'fmi'], 'fmh'); * Controls the modulation index, which defines the brightness of the sound. * * @name fm - * @group effects + * @tags effects * @param {number | Pattern} brightness modulation index * @synonyms fmi * @example @@ -502,7 +502,7 @@ export const { fmi, fm } = registerControl(['fmi', 'fmh'], 'fm'); * Ramp type of fm envelope. Exp might be a bit broken.. * * @name fmenv - * @group effects + * @tags effects * @param {number | Pattern} type lin | exp * @example * note("c e g b g e") @@ -518,7 +518,7 @@ export const { fmenv } = registerControl('fmenv'); * Attack time for the FM envelope: time it takes to reach maximum modulation * * @name fmattack - * @group effects + * @tags effects * @param {number | Pattern} time attack time * @example * note("c e g b g e") @@ -533,7 +533,7 @@ export const { fmattack } = registerControl('fmattack'); * Waveform of the fm modulator * * @name fmwave - * @group effects + * @tags effects * @param {number | Pattern} wave waveform * @example * n("0 1 2 3".fast(4)).scale("d:minor").s("sine").fmwave("").fm(4).fmh(2.01) @@ -547,7 +547,7 @@ export const { fmwave } = registerControl('fmwave'); * Decay time for the FM envelope: seconds until the sustain level is reached after the attack phase. * * @name fmdecay - * @group effects + * @tags effects * @param {number | Pattern} time decay time * @example * note("c e g b g e") @@ -562,7 +562,7 @@ export const { fmdecay } = registerControl('fmdecay'); * Sustain level for the FM envelope: how much modulation is applied after the decay phase * * @name fmsustain - * @group effects + * @tags effects * @param {number | Pattern} level sustain level * @example * note("c e g b g e") @@ -581,7 +581,7 @@ export const { fmvelocity } = registerControl('fmvelocity'); * Select the sound bank to use. To be used together with `s`. The bank name (+ "_") will be prepended to the value of `s`. * * @name bank - * @group samples + * @tags samples * @param {string | Pattern} bank the name of the bank * @example * s("bd sd [~ bd] sd").bank('RolandTR909') // = s("RolandTR909_bd RolandTR909_sd") @@ -593,7 +593,7 @@ export const { bank } = registerControl('bank'); * mix control for the chorus effect * * @name chorus - * @group effects + * @tags effects * @param {string | Pattern} chorus mix amount between 0 and 1 * @example * note("d d a# a").s("sawtooth").chorus(.5) @@ -611,7 +611,7 @@ export const { fft } = registerControl('fft'); * Note that the decay is only audible if the sustain value is lower than 1. * * @name decay - * @group effects + * @tags effects * @param {number | Pattern} time decay time in seconds * @synonyms dec * @example @@ -623,7 +623,7 @@ export const { decay, dec } = registerControl('decay', 'dec'); * Amplitude envelope sustain level: The level which is reached after attack / decay, being sustained until the offset. * * @name sustain - * @group effects + * @tags effects * @param {number | Pattern} gain sustain level between 0 and 1 * @synonyms sus * @example @@ -635,7 +635,7 @@ export const { sustain, sus } = registerControl('sustain', 'sus'); * Amplitude envelope release time: The time it takes after the offset to go from sustain level to zero. * * @name release - * @group effects + * @tags effects * @param {number | Pattern} time release time in seconds * @synonyms rel * @example @@ -650,7 +650,7 @@ export const { hold } = registerControl('hold'); * can also optionally supply the 'bpq' parameter separated by ':'. * * @name bpf - * @group effects + * @tags effects * @param {number | Pattern} frequency center frequency * @synonyms bandf, bp * @example @@ -663,7 +663,7 @@ export const { bandf, bpf, bp } = registerControl(['bandf', 'bandq', 'bpenv'], ' * Sets the **b**and-**p**ass **q**-factor (resonance). * * @name bpq - * @group effects + * @tags effects * @param {number | Pattern} q q factor * @synonyms bandq * @example @@ -678,7 +678,7 @@ export const { bandq, bpq } = registerControl('bandq', 'bpq'); * * @memberof Pattern * @name begin - * @group samples + * @tags samples * @param {number | Pattern} amount between 0 and 1, where 1 is the length of the sample * @example * samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/dirt-samples') @@ -691,7 +691,7 @@ export const { begin } = registerControl('begin'); * * @memberof Pattern * @name end - * @group samples + * @tags samples * @param {number | Pattern} length 1 = whole sample, .5 = half sample, .25 = quarter sample etc.. * @example * s("bd*2,oh*4").end("<.1 .2 .5 1>").fast(2) @@ -704,7 +704,7 @@ export const { end } = registerControl('end'); * To change the loop region, use loopBegin / loopEnd. * * @name loop - * @group samples + * @tags samples * @param {number | Pattern} on If 1, the sample is looped * @example * s("casio").loop(1) @@ -717,7 +717,7 @@ export const { loop } = registerControl('loop'); * Note: Samples starting with wt_ will automatically loop! (wt = wavetable) * * @name loopBegin - * @group samples + * @tags samples * @param {number | Pattern} time between 0 and 1, where 1 is the length of the sample * @synonyms loopb * @example @@ -731,7 +731,7 @@ export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb'); * Note that the loop point must be inbetween `begin` and `end`, and after `loopBegin`! * * @name loopEnd - * @group samples + * @tags samples * @param {number | Pattern} time between 0 and 1, where 1 is the length of the sample * @synonyms loope * @example @@ -743,7 +743,7 @@ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); * Bit crusher effect. * * @name crush - * @group effects + * @tags effects * @param {number | Pattern} depth between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction). * @example * s(",hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>") @@ -755,7 +755,7 @@ export const { crush } = registerControl('crush'); * Fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers * * @name coarse - * @group effects + * @tags effects * @param {number | Pattern} factor 1 for original 2 for half, 3 for a third and so on. * @example * s("bd sd [~ bd] sd,hh*8").coarse("<1 4 8 16 32>") @@ -767,7 +767,7 @@ export const { coarse } = registerControl('coarse'); * Modulate the amplitude of a sound with a continuous waveform * * @name tremolo - * @group effects + * @tags effects * @synonyms trem * @param {number | Pattern} speed modulation speed in HZ * @example @@ -780,7 +780,7 @@ export const { tremolo } = registerControl(['tremolo', 'tremolodepth', 'tremolos * Modulate the amplitude of a sound with a continuous waveform * * @name tremolosync - * @group effects + * @tags effects * @synonyms tremsync * @param {number | Pattern} cycles modulation speed in cycles * @example @@ -796,7 +796,7 @@ export const { tremolosync } = registerControl( * Depth of amplitude modulation * * @name tremolodepth - * @group effects + * @tags effects * @synonyms tremdepth * @param {number | Pattern} depth * @example @@ -808,7 +808,7 @@ export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth'); * Alter the shape of the modulation waveform * * @name tremoloskew - * @group effects + * @tags effects * @synonyms tremskew * @param {number | Pattern} amount between 0 & 1, the shape of the waveform * @example @@ -821,7 +821,7 @@ export const { tremoloskew } = registerControl('tremoloskew', 'tremskew'); * Alter the phase of the modulation waveform * * @name tremolophase - * @group effects + * @tags effects * @synonyms tremphase * @param {number | Pattern} offset the offset in cycles of the modulation * @example @@ -834,7 +834,7 @@ export const { tremolophase } = registerControl('tremolophase', 'tremphase'); * Shape of amplitude modulation * * @name tremoloshape - * @group effects + * @tags effects * @synonyms tremshape * @param {number | Pattern} shape tri | square | sine | saw | ramp * @example @@ -846,7 +846,7 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); * Filter overdrive for supported filter types * * @name drive - * @group effects + * @tags effects * @param {number | Pattern} amount * @example * note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>") @@ -860,7 +860,7 @@ export const { drive } = registerControl('drive'); * Can be applied to multiple orbits with the ':' mininotation, e.g. `duckorbit("2:3")` * * @name duckorbit - * @group effects + * @tags effects * @synonyms duck * @param {number | Pattern} orbit target orbit * @example @@ -881,7 +881,7 @@ export const { duck } = registerControl('duckorbit', 'duck'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckdepth - * @group effects + * @tags effects * @param {number | Pattern} depth depth of modulation from 0 to 1 * @example * stack( n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2), s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack(0.2).duckdepth("<1 .9 .6 0>")) @@ -901,7 +901,7 @@ export const { duckdepth } = registerControl('duckdepth'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckonset - * @group effects + * @tags effects * @synonyms duckons * * @param {number | Pattern} time The onset time in seconds @@ -929,7 +929,7 @@ export const { duckonset } = registerControl('duckonset', 'duckons'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckattack - * @group effects + * @tags effects * @synonyms duckatt * * @param {number | Pattern} time The attack time in seconds @@ -974,7 +974,7 @@ export const { byteBeatStartTime, bbst } = registerControl('byteBeatStartTime', * Allows you to set the output channels on the interface * * @name channels - * @group external_io + * @tags external_io * @synonyms ch * * @param {number | Pattern} channels pattern the output channels @@ -988,7 +988,7 @@ export const { channels, ch } = registerControl('channels', 'ch'); * Controls the pulsewidth of the pulse oscillator * * @name pw - * @group effects + * @tags effects * @param {number | Pattern} pulsewidth * @example * note("{f a c e}%16").s("pulse").pw(".8:1:.2") @@ -1001,7 +1001,7 @@ export const { pw } = registerControl(['pw', 'pwrate', 'pwsweep']); * Controls the lfo rate for the pulsewidth of the pulse oscillator * * @name pwrate - * @group effects + * @tags effects * @param {number | Pattern} rate * @example * n(run(8)).scale("D:pentatonic").s("pulse").pw("0.5").pwrate("<5 .1 25>").pwsweep("<0.3 .8>") @@ -1014,7 +1014,7 @@ export const { pwrate } = registerControl('pwrate'); * Controls the lfo sweep for the pulsewidth of the pulse oscillator * * @name pwsweep - * @group effects + * @tags effects * @param {number | Pattern} sweep * @example * n(run(8)).scale("D:pentatonic").s("pulse").pw("0.5").pwrate("<5 .1 25>").pwsweep("<0.3 .8>") @@ -1026,7 +1026,7 @@ export const { pwsweep } = registerControl('pwsweep'); * Phaser audio effect that approximates popular guitar pedals. * * @name phaser - * @group effects + * @tags effects * @synonyms ph * @param {number | Pattern} speed speed of modulation * @example @@ -1044,7 +1044,7 @@ export const { phaserrate, ph, phaser } = registerControl( * The frequency sweep range of the lfo for the phaser effect. Defaults to 2000 * * @name phasersweep - * @group effects + * @tags effects * @synonyms phs * @param {number | Pattern} phasersweep most useful values are between 0 and 4000 * @example @@ -1058,7 +1058,7 @@ export const { phasersweep, phs } = registerControl('phasersweep', 'phs'); * The center frequency of the phaser in HZ. Defaults to 1000 * * @name phasercenter - * @group effects + * @tags effects * @synonyms phc * @param {number | Pattern} centerfrequency in HZ * @example @@ -1073,7 +1073,7 @@ export const { phasercenter, phc } = registerControl('phasercenter', 'phc'); * The amount the signal is affected by the phaser effect. Defaults to 0.75 * * @name phaserdepth - * @group effects + * @tags effects * @synonyms phd, phasdp * @param {number | Pattern} depth number between 0 and 1 * @example @@ -1088,7 +1088,7 @@ export const { phaserdepth, phd, phasdp } = registerControl('phaserdepth', 'phd' * Choose the channel the pattern is sent to in superdirt * * @name channel - * @group effects + * @tags effects * @param {number | Pattern} channel channel number * */ @@ -1097,7 +1097,7 @@ export const { channel } = registerControl('channel'); * In the style of classic drum-machines, `cut` will stop a playing sample as soon as another samples with in same cutgroup is to be played. An example would be an open hi-hat followed by a closed one, essentially muting the open. * * @name cut - * @group effects + * @tags effects * @param {number | Pattern} group cut group number * @example * s("[oh hh]*4").cut(1) @@ -1110,7 +1110,7 @@ export const { cut } = registerControl('cut'); * When using mininotation, you can also optionally add the 'lpq' parameter, separated by ':'. * * @name lpf - * @group effects + * @tags effects * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms cutoff, ctf, lp * @example @@ -1124,7 +1124,7 @@ export const { cutoff, ctf, lpf, lp } = registerControl(['cutoff', 'resonance', /** * Sets the lowpass filter envelope modulation depth. * @name lpenv - * @group effects + * @tags effects * @param {number | Pattern} modulation depth of the lowpass filter envelope between 0 and _n_ * @synonyms lpe * @example @@ -1138,7 +1138,7 @@ export const { lpenv, lpe } = registerControl('lpenv', 'lpe'); /** * Sets the highpass filter envelope modulation depth. * @name hpenv - * @group effects + * @tags effects * @param {number | Pattern} modulation depth of the highpass filter envelope between 0 and _n_ * @synonyms hpe * @example @@ -1152,7 +1152,7 @@ export const { hpenv, hpe } = registerControl('hpenv', 'hpe'); /** * Sets the bandpass filter envelope modulation depth. * @name bpenv - * @group effects + * @tags effects * @param {number | Pattern} modulation depth of the bandpass filter envelope between 0 and _n_ * @synonyms bpe * @example @@ -1166,7 +1166,7 @@ export const { bpenv, bpe } = registerControl('bpenv', 'bpe'); /** * Sets the attack duration for the lowpass filter envelope. * @name lpattack - * @group effects + * @tags effects * @param {number | Pattern} attack time of the filter envelope * @synonyms lpa * @example @@ -1180,7 +1180,7 @@ export const { lpattack, lpa } = registerControl('lpattack', 'lpa'); /** * Sets the attack duration for the highpass filter envelope. * @name hpattack - * @group effects + * @tags effects * @param {number | Pattern} attack time of the highpass filter envelope * @synonyms hpa * @example @@ -1194,7 +1194,7 @@ export const { hpattack, hpa } = registerControl('hpattack', 'hpa'); /** * Sets the attack duration for the bandpass filter envelope. * @name bpattack - * @group effects + * @tags effects * @param {number | Pattern} attack time of the bandpass filter envelope * @synonyms bpa * @example @@ -1208,7 +1208,7 @@ export const { bpattack, bpa } = registerControl('bpattack', 'bpa'); /** * Sets the decay duration for the lowpass filter envelope. * @name lpdecay - * @group effects + * @tags effects * @param {number | Pattern} decay time of the filter envelope * @synonyms lpd * @example @@ -1222,7 +1222,7 @@ export const { lpdecay, lpd } = registerControl('lpdecay', 'lpd'); /** * Sets the decay duration for the highpass filter envelope. * @name hpdecay - * @group effects + * @tags effects * @param {number | Pattern} decay time of the highpass filter envelope * @synonyms hpd * @example @@ -1237,7 +1237,7 @@ export const { hpdecay, hpd } = registerControl('hpdecay', 'hpd'); /** * Sets the decay duration for the bandpass filter envelope. * @name bpdecay - * @group effects + * @tags effects * @param {number | Pattern} decay time of the bandpass filter envelope * @synonyms bpd * @example @@ -1252,7 +1252,7 @@ export const { bpdecay, bpd } = registerControl('bpdecay', 'bpd'); /** * Sets the sustain amplitude for the lowpass filter envelope. * @name lpsustain - * @group effects + * @tags effects * @param {number | Pattern} sustain amplitude of the lowpass filter envelope * @synonyms lps * @example @@ -1267,7 +1267,7 @@ export const { lpsustain, lps } = registerControl('lpsustain', 'lps'); /** * Sets the sustain amplitude for the highpass filter envelope. * @name hpsustain - * @group effects + * @tags effects * @param {number | Pattern} sustain amplitude of the highpass filter envelope * @synonyms hps * @example @@ -1282,7 +1282,7 @@ export const { hpsustain, hps } = registerControl('hpsustain', 'hps'); /** * Sets the sustain amplitude for the bandpass filter envelope. * @name bpsustain - * @group effects + * @tags effects * @param {number | Pattern} sustain amplitude of the bandpass filter envelope * @synonyms bps * @example @@ -1297,7 +1297,7 @@ export const { bpsustain, bps } = registerControl('bpsustain', 'bps'); /** * Sets the release time for the lowpass filter envelope. * @name lprelease - * @group effects + * @tags effects * @param {number | Pattern} release time of the filter envelope * @synonyms lpr * @example @@ -1313,7 +1313,7 @@ export const { lprelease, lpr } = registerControl('lprelease', 'lpr'); /** * Sets the release time for the highpass filter envelope. * @name hprelease - * @group effects + * @tags effects * @param {number | Pattern} release time of the highpass filter envelope * @synonyms hpr * @example @@ -1329,7 +1329,7 @@ export const { hprelease, hpr } = registerControl('hprelease', 'hpr'); /** * Sets the release time for the bandpass filter envelope. * @name bprelease - * @group effects + * @tags effects * @param {number | Pattern} release time of the bandpass filter envelope * @synonyms bpr * @example @@ -1345,7 +1345,7 @@ export const { bprelease, bpr } = registerControl('bprelease', 'bpr'); /** * Sets the filter type. The ladder filter is more aggressive. More types might be added in the future. * @name ftype - * @group effects + * @tags effects * @param {number | Pattern} type 12db (0), ladder (1), or 24db (2) * @example * note("{f g g c d a a#}%8").s("sawtooth").lpenv(4).lpf(500).ftype("<0 1 2>").lpq(1) @@ -1361,7 +1361,7 @@ export const { ftype } = registerControl('ftype'); /** * controls the center of the filter envelope. 0 is unipolar positive, .5 is bipolar, 1 is unipolar negative * @name fanchor - * @group effects + * @tags effects * @param {number | Pattern} center 0 to 1 * @example * note("{f g g c d a a#}%8").s("sawtooth").lpf("{1000}%2") @@ -1374,7 +1374,7 @@ export const { fanchor } = registerControl('fanchor'); * When using mininotation, you can also optionally add the 'hpq' parameter, separated by ':'. * * @name hpf - * @group effects + * @tags effects * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms hp, hcutoff * @example @@ -1389,7 +1389,7 @@ export const { fanchor } = registerControl('fanchor'); * Applies a vibrato to the frequency of the oscillator. * * @name vib - * @group effects + * @tags effects * @synonyms vibrato, v * @param {number | Pattern} frequency of the vibrato in hertz * @example @@ -1407,7 +1407,7 @@ export const { vib, vibrato, v } = registerControl(['vib', 'vibmod'], 'vibrato', * Adds pink noise to the mix * * @name noise - * @group generators + * @tags generators * @param {number | Pattern} wet wet amount * @example * sound("/2") @@ -1417,7 +1417,7 @@ export const { noise } = registerControl('noise'); * Sets the vibrato depth in semitones. Only has an effect if `vibrato` | `vib` | `v` is is also set * * @name vibmod - * @group effects + * @tags effects * @synonyms vmod * @param {number | Pattern} depth of vibrato (in semitones) * @example @@ -1436,7 +1436,7 @@ export const { hcutoff, hpf, hp } = registerControl(['hcutoff', 'hresonance', 'h * Controls the **h**igh-**p**ass **q**-value. * * @name hpq - * @group effects + * @tags effects * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms hresonance * @example @@ -1448,7 +1448,7 @@ export const { hresonance, hpq } = registerControl('hresonance', 'hpq'); * Controls the **l**ow-**p**ass **q**-value. * * @name lpq - * @group effects + * @tags effects * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms resonance * @example @@ -1461,7 +1461,7 @@ export const { resonance, lpq } = registerControl('resonance', 'lpq'); * DJ filter, below 0.5 is low pass filter, above is high pass filter. * * @name djf - * @group effects + * @tags effects * @param {number | Pattern} cutoff below 0.5 is low pass filter, above is high pass filter * @example * n(irand(16).seg(8)).scale("d:phrygian").s("supersaw").djf("<.5 .3 .2 .75>") @@ -1478,7 +1478,7 @@ export const { djf } = registerControl('djf'); * * * @name delay - * @group effects + * @tags effects * @param {number | Pattern} level between 0 and 1 * @example * s("bd bd").delay("<0 .25 .5 1>") @@ -1492,7 +1492,7 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @group effects + * @tags effects * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1506,7 +1506,7 @@ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @group effects + * @tags effects * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1518,7 +1518,7 @@ export const { delayspeed } = registerControl('delayspeed'); * Sets the time of the delay effect. * * @name delayspeed - * @group effects + * @tags effects, foo * @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @synonyms delayt, dt * @example @@ -1531,7 +1531,7 @@ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', * Sets the time of the delay effect in cycles. * * @name delaysync - * @group effects + * @tags effects * @param {number | Pattern} cycles delay length in cycles * @synonyms delayt, dt * @example @@ -1544,7 +1544,7 @@ export const { delaysync } = registerControl('delaysync'); * Specifies whether delaytime is calculated relative to cps. * * @name lock - * @group effects + * @tags effects, foo * @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle. * @superdirtOnly * @example @@ -1558,7 +1558,7 @@ export const { lock } = registerControl('lock'); * Set detune for stacked voices of supported oscillators * * @name detune - * @group effects + * @tags effects * @param {number | Pattern} amount * @synonyms det * @example @@ -1570,7 +1570,7 @@ export const { detune, det } = registerControl('detune', 'det'); * Set number of stacked voices for supported oscillators * * @name unison - * @group effects + * @tags effects * @param {number | Pattern} numvoices * @example * note("d f a a# a d3").fast(2).s("supersaw").unison("<1 2 7>") @@ -1582,7 +1582,7 @@ export const { unison } = registerControl('unison'); * Set the stereo pan spread for supported oscillators * * @name spread - * @group effects + * @tags effects * @param {number | Pattern} spread between 0 and 1 * @example * note("d f a a# a d3").fast(2).s("supersaw").spread("<0 .3 1>") @@ -1593,7 +1593,7 @@ export const { spread } = registerControl('spread'); * Set dryness of reverb. See `room` and `size` for more information about reverb. * * @name dry - * @group effects + * @tags effects * @param {number | Pattern} dry 0 = wet, 1 = dry * @example * n("[0,3,7](3,8)").s("superpiano").room(.7).dry("<0 .5 .75 1>").osc() @@ -1619,7 +1619,7 @@ export const { fadeInTime } = registerControl('fadeInTime'); * Set frequency of sound. * * @name freq - * @group transforms + * @tags transforms * @param {number | Pattern} frequency in Hz. the audible range is between 20 and 20000 Hz * @example * freq("220 110 440 110").s("superzow").osc() @@ -1633,7 +1633,7 @@ export const { freq } = registerControl('freq'); * Attack time of pitch envelope. * * @name pattack - * @group effects + * @tags effects * @synonyms patt * @param {number | Pattern} time time in seconds * @example @@ -1645,7 +1645,7 @@ export const { pattack, patt } = registerControl('pattack', 'patt'); * Decay time of pitch envelope. * * @name pdecay - * @group effects + * @tags effects * @synonyms pdec * @param {number | Pattern} time time in seconds * @example @@ -1659,7 +1659,7 @@ export const { psustain, psus } = registerControl('psustain', 'psus'); * Release time of pitch envelope * * @name prelease - * @group effects + * @tags effects * @synonyms prel * @param {number | Pattern} time time in seconds * @example @@ -1674,7 +1674,7 @@ export const { prelease, prel } = registerControl('prelease', 'prel'); * If you don't set other pitch envelope controls, `pattack:.2` will be the default. * * @name penv - * @group effects + * @tags effects * @param {number | Pattern} semitones change in semitones * @example * note("c") @@ -1686,7 +1686,7 @@ export const { penv } = registerControl('penv'); * Curve of envelope. Defaults to linear. exponential is good for kicks * * @name pcurve - * @group effects + * @tags effects * @param {number | Pattern} type 0 = linear, 1 = exponential * @example * note("g1*4") @@ -1703,7 +1703,7 @@ export const { pcurve } = registerControl('pcurve'); * If you don't set an anchor, the value will default to the psustain value. * * @name panchor - * @group effects + * @tags effects * @param {number | Pattern} anchor anchor offset * @example * note("c c4").penv(12).panchor("<0 .5 1 .5>") @@ -1725,7 +1725,7 @@ export const { gate, gat } = registerControl('gate', 'gat'); * Emulation of a Leslie speaker: speakers rotating in a wooden amplified cabinet. * * @name leslie - * @group effects + * @tags effects * @param {number | Pattern} wet between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie("<0 .4 .6 1>").osc() @@ -1737,7 +1737,7 @@ export const { leslie } = registerControl('leslie'); * Rate of modulation / rotation for leslie effect * * @name lrate - * @group effects + * @tags effects * @param {number | Pattern} rate 6.7 for fast, 0.7 for slow * @example * n("0,4,7").s("supersquare").leslie(1).lrate("<1 2 4 8>").osc() @@ -1750,7 +1750,7 @@ export const { lrate } = registerControl('lrate'); * Physical size of the cabinet in meters. Be careful, it might be slightly larger than your computer. Affects the Doppler amount (pitch warble) * * @name lsize - * @group effects + * @tags effects * @param {number | Pattern} meters somewhere between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie(1).lrate(2).lsize("<.1 .5 1>").osc() @@ -1762,7 +1762,7 @@ export const { lsize } = registerControl('lsize'); * Sets the displayed text for an event on the pianoroll * * @name label - * @group visualization + * @tags visualization * @param {string} label text to display */ export const { activeLabel } = registerControl('activeLabel'); @@ -1828,7 +1828,7 @@ export const { overshape } = registerControl('overshape'); * Sets position in stereo. * * @name pan - * @group effects + * @tags effects * @param {number | Pattern} pan between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel) * @example * s("[bd hh]*2").pan("<.5 1 .5 0>") @@ -1894,7 +1894,7 @@ export const { mode } = registerControl(['mode', 'anchor']); * When using mininotation, you can also optionally add the 'size' parameter, separated by ':'. * * @name room - * @group effects + * @tags effects * @param {number | Pattern} level between 0 and 1 * @example * s("bd sd [~ bd] sd").room("<0 .2 .4 .6 .8 1>") @@ -1908,7 +1908,7 @@ export const { room } = registerControl(['room', 'size']); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomlp - * @group effects + * @tags effects * @synonyms rlp * @param {number} frequency between 0 and 20000hz * @example @@ -1922,7 +1922,7 @@ export const { roomlp, rlp } = registerControl('roomlp', 'rlp'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomdim - * @group effects + * @tags effects * @synonyms rdim * @param {number} frequency between 0 and 20000hz * @example @@ -1937,7 +1937,7 @@ export const { roomdim, rdim } = registerControl('roomdim', 'rdim'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomfade - * @group effects + * @tags effects * @synonyms rfade * @param {number} seconds for the reverb to fade * @example @@ -1950,7 +1950,7 @@ export const { roomfade, rfade } = registerControl('roomfade', 'rfade'); /** * Sets the sample to use as an impulse response for the reverb. * @name iresponse - * @group effects + * @tags effects * @param {string | Pattern} sample to use as an impulse response * @synonyms ir * @example @@ -1962,7 +1962,7 @@ export const { ir, iresponse } = registerControl(['ir', 'i'], 'iresponse'); /** * Sets speed of the sample for the impulse response. * @name irspeed - * @group effects + * @tags effects * @param {string | Pattern} speed * @example * samples('github:switchangel/pad') @@ -1974,7 +1974,7 @@ export const { irspeed } = registerControl('irspeed'); /** * Sets the beginning of the IR response sample * @name irbegin - * @group effects + * @tags effects * @param {string | Pattern} begin between 0 and 1 * @synonyms ir * @example @@ -1988,7 +1988,7 @@ export const { irbegin } = registerControl('irbegin'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomsize - * @group effects + * @tags effects * @param {number | Pattern} size between 0 and 10 * @synonyms rsize, sz, size * @example @@ -2012,7 +2012,7 @@ export const { roomsize, size, sz, rsize } = registerControl('roomsize', 'size', * * * @name shape - * @group effects + * @tags effects * @param {number | Pattern} distortion between 0 and 1 * @example * s("bd sd [~ bd] sd,hh*8").shape("<0 .2 .4 .6 .8>") @@ -2025,7 +2025,7 @@ export const { shape } = registerControl(['shape', 'shapevol']); * Most useful values are usually between 0 and 10 (depending on source gain). If you are feeling adventurous, you can turn it up to 11 and beyond ;) * * @name distort - * @group effects + * @tags effects * @synonyms dist * @param {number | Pattern} distortion * @example @@ -2040,7 +2040,7 @@ export const { distort, dist } = registerControl(['distort', 'distortvol'], 'dis * More info [here](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) * * @name compressor - * @group effects + * @tags effects * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02") @@ -2061,7 +2061,7 @@ export const { compressorRelease } = registerControl('compressorRelease'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name speed - * @group effects + * @tags effects * @param {number | Pattern} speed -inf to inf, negative numbers play the sample backwards. * @example * s("bd*6").speed("1 2 4 1 -2 -4") @@ -2075,7 +2075,7 @@ export const { speed } = registerControl('speed'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name stretch - * @group effects + * @tags effects * @param {number | Pattern} factor -inf to inf, negative numbers play the sample backwards. * @example * s("gm_flute").stretch("1 2 .5") @@ -2086,7 +2086,7 @@ export const { stretch } = registerControl('stretch'); * Used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`. * * @name unit - * @group effects + * @tags effects * @param {number | string | Pattern} unit see description above * @example * speed("1 2 .5 3").s("bd").unit("c").osc() @@ -2101,7 +2101,7 @@ export const { unit } = registerControl('unit'); * "A simplistic pitch-raising algorithm. It's not meant to sound natural; its sound is reminiscent of some weird mixture of filter, ring-modulator and pitch-shifter, depending on the input. The algorithm works by cutting the signal into fragments (delimited by upwards-going zero-crossings) and squeezing those fragments in the time domain (i.e. simply playing them back faster than they came in), leaving silences inbetween. All the parameters apart from memlen can be modulated." * * @name squiz - * @group effects + * @tags effects * @param {number | Pattern} squiz Try passing multiples of 2 to it - 2, 4, 8 etc. * @example * squiz("2 4/2 6 [8 16]").s("bd").osc() @@ -2126,7 +2126,7 @@ export const { squiz } = registerControl('squiz'); * Formant filter to make things sound like vowels. * * @name vowel - * @group effects + * @tags effects * @param {string | Pattern} vowel You can use a e i o u ae aa oe ue y uh un en an on, corresponding to [a] [e] [i] [o] [u] [æ] [ɑ] [ø] [y] [ɯ] [ʌ] [œ̃] [ɛ̃] [ɑ̃] [ɔ̃]. Aliases: aa = å = ɑ, oe = ø = ö, y = ı, ae = æ. * @example * note("[c2 >]*2").s('sawtooth') @@ -2151,7 +2151,7 @@ export const { waveloss } = registerControl('waveloss'); * Noise crackle density * * @name density - * @group effects + * @tags effects * @param {number | Pattern} density between 0 and x * @example * s("crackle*4").density("<0.01 0.04 0.2 0.5>".slow(4)) @@ -2202,7 +2202,7 @@ export const { cps } = registerControl('cps'); * Multiplies the duration with the given number. Also cuts samples off at the end if they exceed the duration. * * @name clip - * @group transforms + * @tags transforms * @synonyms legato * @param {number | Pattern} factor >= 0 * @example @@ -2215,7 +2215,7 @@ export const { clip, legato } = registerControl('clip', 'legato'); * Sets the duration of the event in cycles. Similar to clip / legato, it also cuts samples off at the end if they exceed the duration. * * @name duration - * @group transforms + * @tags transforms * @synonyms dur * @param {number | Pattern} seconds >= 0 * @example @@ -2244,7 +2244,7 @@ export const { zzfx } = registerControl('zzfx'); /** * Sets the color of the hap in visualizations like pianoroll or highlighting. * @name color - * @group visualization + * @tags visualization * @synonyms colour * @param {string} color Hexadecimal or CSS color name */ @@ -2259,7 +2259,7 @@ export let createParams = (...names) => * ADSR envelope: Combination of Attack, Decay, Sustain, and Release. * * @name adsr - * @group effects + * @tags effects * @param {number | Pattern} time attack time in seconds * @param {number | Pattern} time decay time in seconds * @param {number | Pattern} gain sustain level (0 to 1) @@ -2294,7 +2294,7 @@ export const ar = register('ar', (t, pat) => { * MIDI channel: Sets the MIDI channel for the event. * * @name midichan - * @group examples + * @tags examples * @param {number | Pattern} channel MIDI channel number (0-15) * @example * note("c4").midichan(1).midi() @@ -2307,7 +2307,7 @@ export const { midimap } = registerControl('midimap'); * MIDI port: Sets the MIDI port for the event. * * @name midiport - * @group examples + * @tags examples * @param {number | Pattern} port MIDI port * @example * note("c a f e").midiport("<0 1 2 3>").midi() @@ -2318,7 +2318,7 @@ export const { midiport } = registerControl('midiport'); * MIDI command: Sends a MIDI command message. * * @name midicmd - * @group examples + * @tags examples * @param {number | Pattern} command MIDI command * @example * midicmd("clock*48,/2").midi() @@ -2329,7 +2329,7 @@ export const { midicmd } = registerControl('midicmd'); * MIDI control: Sends a MIDI control change message. * * @name control - * @group examples + * @tags examples * @param {number | Pattern} MIDI control number (0-127) * @param {number | Pattern} MIDI controller value (0-127) */ @@ -2345,7 +2345,7 @@ export const control = register('control', (args, pat) => { * MIDI control number: Sends a MIDI control change message. * * @name ccn - * @group examples + * @tags examples * @param {number | Pattern} MIDI control number (0-127) */ export const { ccn } = registerControl('ccn'); @@ -2353,7 +2353,7 @@ export const { ccn } = registerControl('ccn'); * MIDI control value: Sends a MIDI control change message. * * @name ccv - * @group examples + * @tags examples * @param {number | Pattern} MIDI control value (0-127) */ export const { ccv } = registerControl('ccv'); @@ -2363,7 +2363,7 @@ export const { ctlNum } = registerControl('ctlNum'); /** * MIDI NRPN non-registered parameter number: Sends a MIDI NRPN non-registered parameter number message. * @name nrpnn - * @group examples + * @tags examples * @param {number | Pattern} nrpnn MIDI NRPN non-registered parameter number (0-127) * @example * note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi() @@ -2372,7 +2372,7 @@ export const { nrpnn } = registerControl('nrpnn'); /** * MIDI NRPN non-registered parameter value: Sends a MIDI NRPN non-registered parameter value message. * @name nrpv - * @group examples + * @tags examples * @param {number | Pattern} nrpv MIDI NRPN non-registered parameter value (0-127) * @example * note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi() @@ -2383,7 +2383,7 @@ export const { nrpv } = registerControl('nrpv'); * MIDI program number: Sends a MIDI program change message. * * @name progNum - * @group examples + * @tags examples * @param {number | Pattern} program MIDI program number (0-127) * @example * note("c4").progNum(10).midichan(1).midi() @@ -2393,7 +2393,7 @@ export const { progNum } = registerControl('progNum'); /** * MIDI sysex: Sends a MIDI sysex message. * @name sysex - * @group examples + * @tags examples * @param {number | Pattern} id Sysex ID * @param {number | Pattern} data Sysex data * @example @@ -2409,7 +2409,7 @@ export const sysex = register('sysex', (args, pat) => { /** * MIDI sysex ID: Sends a MIDI sysex identifier message. * @name sysexid - * @group examples + * @tags examples * @param {number | Pattern} id Sysex ID * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2418,7 +2418,7 @@ export const { sysexid } = registerControl('sysexid'); /** * MIDI sysex data: Sends a MIDI sysex message. * @name sysexdata - * @group examples + * @tags examples * @param {number | Pattern} data Sysex data * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2428,7 +2428,7 @@ export const { sysexdata } = registerControl('sysexdata'); /** * MIDI pitch bend: Sends a MIDI pitch bend message. * @name midibend - * @group examples + * @tags examples * @param {number | Pattern} midibend MIDI pitch bend (-1 - 1) * @example * note("c4").midibend(sine.slow(4).range(-0.4,0.4)).midi() @@ -2437,7 +2437,7 @@ export const { midibend } = registerControl('midibend'); /** * MIDI key after touch: Sends a MIDI key after touch message. * @name miditouch - * @group examples + * @tags examples * @param {number | Pattern} miditouch MIDI key after touch (0-1) * @example * note("c4").miditouch(sine.slow(4).range(0,1)).midi() @@ -2458,7 +2458,7 @@ export const getControlName = (alias) => { * Sets properties in a batch. * * @name as - * @group transforms + * @tags transforms * @param {String | Array} mapping the control names that are set * @example * "c:.5 a:1 f:.25 e:.8".as("note:clip") @@ -2478,7 +2478,7 @@ export const as = register('as', (mapping, pat) => { * Allows you to scrub an audio file like a tape loop by passing values that represents the position in the audio file * in the optional array syntax ex: "0.5:2", the second value controls the speed of playback * @name scrub - * @group samples + * @tags samples * @memberof Pattern * @returns Pattern * @example diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index e3d4f5f9c..39d6555f5 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -84,7 +84,7 @@ export class Pattern { /** * Returns a new pattern, with the function applied to the value of * each hap. It has the alias `fmap`. - * @group functional + * @tags functional * @synonyms fmap * @param {Function} func to to apply to the value * @returns Pattern @@ -117,7 +117,7 @@ export class Pattern { * Assumes 'this' is a pattern of functions, and given a function to * resolve wholes, applies a given pattern of values to that * pattern of functions. - * @group functional + * @tags functional * @param {Function} whole_func * @param {Function} func * @noAutocomplete @@ -155,7 +155,7 @@ export class Pattern { * In this `_appBoth` variant, where timespans of the function and value haps * are not the same but do intersect, the resulting hap has a timespan of the * intersection. This applies to both the part and the whole timespan. - * @group functional + * @tags functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -183,7 +183,7 @@ export class Pattern { * on. In practice, this means that the pattern structure, including onsets, * are preserved from the pattern of functions (often referred to as the left * hand or inner pattern). - * @group functional + * @tags functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -217,7 +217,7 @@ export class Pattern { * As with `appLeft`, but `whole` timespans are instead taken from the * pattern of values, i.e. structure is preserved from the right hand/outer * pattern. - * @group functional + * @tags functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -408,7 +408,7 @@ export class Pattern { /** * Query haps inside the given time span. * - * @group internals + * @tags internals * @param {Fraction | number} begin from time * @param {Fraction | number} end to time * @returns Hap[] @@ -432,7 +432,7 @@ export class Pattern { * Returns a new pattern, with queries split at cycle boundaries. This makes * some calculations easier to express, as all haps are then constrained to * happen within a cycle. - * @group internals + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -447,7 +447,7 @@ export class Pattern { /** * Returns a new pattern, where the given function is applied to the query * timespan before passing it to the original pattern. - * @group internals + * @tags internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -470,7 +470,7 @@ export class Pattern { /** * As with `withQuerySpan`, but the function is applied to both the * begin and end time of the query timespan. - * @group internals + * @tags internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -483,7 +483,7 @@ export class Pattern { * Similar to `withQuerySpan`, but the function is applied to the timespans * of all haps returned by pattern queries (both `part` timespans, and where * present, `whole` timespans). - * @group internals + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -495,7 +495,7 @@ export class Pattern { /** * As with `withHapSpan`, but the function is applied to both the * begin and end time of the hap timespans. - * @group internals + * @tags internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -506,7 +506,7 @@ export class Pattern { /** * Returns a new pattern with the given function applied to the list of haps returned by every query. - * @group internals + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -519,7 +519,7 @@ export class Pattern { /** * As with `withHaps`, but applies the function to every hap, rather than every list of haps. - * @group internals + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -530,7 +530,7 @@ export class Pattern { /** * Returns a new pattern with the context field set to every hap set to the given value. - * @group internals + * @tags internals * @param {*} context * @returns Pattern * @noAutocomplete @@ -541,7 +541,7 @@ export class Pattern { /** * Returns a new pattern with the given function applied to the context field of every hap. - * @group internals + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -557,7 +557,7 @@ export class Pattern { /** * Returns a new pattern with the context field of every hap set to an empty object. - * @group internals + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -568,7 +568,7 @@ export class Pattern { /** * Returns a new pattern with the given location information added to the * context of every hap. - * @group internals + * @tags internals * @param {Number} start start offset * @param {Number} end end offset * @returns Pattern @@ -592,7 +592,7 @@ export class Pattern { /** * Returns a new Pattern, which only returns haps that meet the given test. - * @group internals + * @tags internals * @param {Function} hap_test - a function which returns false for haps to be removed from the pattern * @returns Pattern * @noAutocomplete @@ -604,7 +604,7 @@ export class Pattern { /** * As with `filterHaps`, but the function is applied to values * inside haps. - * @group internals + * @tags internals * @param {Function} value_test * @returns Pattern * @noAutocomplete @@ -616,7 +616,7 @@ export class Pattern { /** * Returns a new pattern, with haps containing undefined values removed from * query results. - * @group internals + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -628,7 +628,7 @@ export class Pattern { * Returns a new pattern, with all haps without onsets filtered out. A hap * with an onset is one with a `whole` timespan that begins at the same time * as its `part` timespan. - * @group internals + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -642,7 +642,7 @@ export class Pattern { /** * Returns a new pattern, with 'continuous' haps (those without 'whole' * timespans) removed from query results. - * @group internals + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -654,7 +654,7 @@ export class Pattern { /** * Combines adjacent haps with the same value and whole. Only * intended for use in tests. - * @group internals + * @tags internals * @noAutocomplete */ defragmentHaps() { @@ -707,7 +707,7 @@ export class Pattern { /** * Queries the pattern for the first cycle, returning Haps. Mainly of use when * debugging a pattern. - * @group internals + * @tags internals * @param {Boolean} with_context - set to true, otherwise the context field * will be stripped from the resulting haps. * @returns [Hap] @@ -723,7 +723,7 @@ export class Pattern { /** * Accessor for a list of values returned by querying the first cycle. - * @group internals + * @tags internals * @noAutocomplete */ get firstCycleValues() { @@ -732,7 +732,7 @@ export class Pattern { /** * More human-readable version of the `firstCycleValues` accessor. - * @group internals + * @tags internals * @noAutocomplete */ get showFirstCycle() { @@ -744,7 +744,7 @@ export class Pattern { /** * Returns a new pattern, which returns haps sorted in temporal order. Mainly * of use when comparing two patterns for equality, in tests. - * @group internals + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -761,7 +761,7 @@ export class Pattern { /** * Returns a new pattern with all values parsed as numerals. - * @group internals + * @tags internals */ asNumber() { return this.fmap(parseNumeral); @@ -813,7 +813,7 @@ export class Pattern { /** * Layers the result of the given function(s). Like `superimpose`, but without the original pattern: * @name layer - * @group combiners + * @tags combiners * @memberof Pattern * @synonyms apply * @returns Pattern @@ -829,7 +829,7 @@ export class Pattern { /** * Superimposes the result of the given function(s) on top of the original pattern: * @name superimpose - * @group combiners + * @tags combiners * @memberof Pattern * @returns Pattern * @example @@ -889,7 +889,7 @@ export class Pattern { /** * Writes the content of the current event to the console (visible in the side menu). - * @group visualizers + * @tags visualizers * @name log * @memberof Pattern * @example @@ -904,7 +904,7 @@ export class Pattern { /** * A simplified version of `log` which writes all "values" (various configurable parameters) * within the event to the console (visible in the side menu). - * @group visualizers + * @tags visualizers * @name logValues * @memberof Pattern * @example @@ -938,7 +938,7 @@ export class Pattern { * 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 * to be played unchanged. - * @group structure + * @tags structure * @name into * @memberof Pattern * @example @@ -978,7 +978,7 @@ Pattern.prototype.collect = function () { /** * Selects indices in in stacked notes. - * @group transforms + * @tags transforms * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arpWith(haps => haps[2]) @@ -993,7 +993,7 @@ export const arpWith = register('arpWith', (func, pat) => { /** * Selects indices in in stacked notes. - * @group transforms + * @tags transforms * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arp("0 [0,2] 1 [0,2]") @@ -1076,7 +1076,7 @@ function _composeOp(a, b, func) { * note("c3 e3 g3".add("<0 5 7 0>")) * // Behind the scenes, the notes are converted to midi numbers: * // note("48 52 55".add("<0 5 7 0>")) - * @group transforms + * @tags math */ add: [numeralArgs((a, b) => a + b)], // support string concatenation /** @@ -1189,7 +1189,7 @@ function _composeOp(a, b, func) { /** * Applies the given structure to the pattern: * - * @group structure + * @tags structure * @example * note("c,eb,g") * .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~") @@ -1204,7 +1204,7 @@ function _composeOp(a, b, func) { /** * Returns silence when mask is 0 or "~" * - * @group structure + * @tags structure * @example * note("c [eb,g] d [eb,g]").mask("<1 [0 1]>") */ @@ -1217,7 +1217,7 @@ function _composeOp(a, b, func) { /** * Resets the pattern to the start of the cycle for each onset of the reset pattern. * - * @group structure + * @tags structure * @example * s("[ sd]*2, hh*8").reset("") */ @@ -1231,7 +1231,7 @@ function _composeOp(a, b, func) { * Restarts the pattern for each onset of the restart pattern. * While reset will only reset the current cycle, restart will start from cycle 0. * - * @group structure + * @tags structure * @example * s("[ sd]*2, hh*8").restart("") */ @@ -1272,7 +1272,7 @@ export const pm = polymeter; /** * Does absolutely nothing, but with a given metrical 'steps' * @name gap - * @group generators + * @tags generators * @param {number} steps * @example * gap(3) // "~@3" @@ -1282,7 +1282,7 @@ export const gap = (steps) => new Pattern(() => [], steps); /** * Does absolutely nothing.. * @name silence - * @group generators + * @tags generators * @example * silence // "~" */ @@ -1294,7 +1294,7 @@ export const nothing = gap(0); /** * A discrete value that repeats once per cycle. * - * @group generators + * @tags generators * @returns {Pattern} * @example * pure('e4') // "e4" @@ -1339,7 +1339,7 @@ export function reify(thing) { /** * Takes a list of patterns, and returns a pattern of lists. * - * @group transforms + * @tags transforms */ export function sequenceP(pats) { let result = pure([]); @@ -1352,7 +1352,7 @@ export function sequenceP(pats) { /** * The given items are played at the same time at the same length. * - * @group structure + * @tags structure * @return {Pattern} * @synonyms polyrhythm, pr * @example @@ -1437,7 +1437,7 @@ export function stackBy(by, ...pats) { /** * Concatenation: combines a list of patterns, switching between them successively, one per cycle. * - * @group combiners + * @tags combiners * @return {Pattern} * @synonyms cat * @example @@ -1471,7 +1471,7 @@ export function slowcat(...pats) { } /** Concatenation: combines a list of patterns, switching between them successively, one per cycle. Unlike slowcat, this version will skip cycles. - * @group combiners + * @tags combiners * @param {...any} items - The items to concatenate * @return {Pattern} */ @@ -1487,7 +1487,7 @@ export function slowcatPrime(...pats) { /** The given items are con**cat**enated, where each one takes one cycle. * - * @group combiners + * @tags combiners * @param {...any} items - The items to concatenate * @synonyms slowcat * @return {Pattern} @@ -1509,7 +1509,7 @@ export function cat(...pats) { * Allows to arrange multiple patterns together over multiple cycles. * Takes a variable number of arrays with two elements specifying the number of cycles and the pattern to use. * - * @group combiners + * @tags combiners * @return {Pattern} * @example * arrange( @@ -1527,7 +1527,7 @@ export function arrange(...sections) { * Similarly to `arrange`, allows you to arrange multiple patterns together over multiple cycles. * Unlike `arrange`, you specify a start and stop time for each pattern rather than duration, which * means that patterns can overlap. - * @group combiners + * @tags combiners * @return {Pattern} * @example seqPLoop([0, 2, "bd(3,8)"], @@ -1572,7 +1572,7 @@ export function sequence(...pats) { } /** Like **cat**, but the items are crammed into one cycle. - * @group combiners + * @tags combiners * @synonyms sequence, fastcat * @example * seq("e5", "b4", ["d5", "c5"]).note() @@ -1746,7 +1746,7 @@ function stepRegister(name, func, patternify = true, preserveSteps = false, join * Assumes a numerical pattern. Returns a new pattern with all values rounded * to the nearest integer. * @name round - * @group math + * @tags math * @memberof Pattern * @returns Pattern * @example @@ -1761,7 +1761,7 @@ export const round = register('round', function (pat) { * replaced with `-5`. * @name floor * @memberof Pattern - * @group math + * @tags math * @returns Pattern * @example * note("42 42.1 42.5 43".floor()) @@ -1776,7 +1776,7 @@ export const floor = register('floor', function (pat) { * replaced with `-4`. * @name ceil * @memberof Pattern - * @group math + * @tags math * @returns Pattern * @example * note("42 42.1 42.5 43".ceil()) @@ -1787,7 +1787,7 @@ export const ceil = register('ceil', function (pat) { /** * Assumes a numerical pattern, containing unipolar values in the range 0 .. * 1. Returns a new pattern with values scaled to the bipolar range -1 .. 1 - * @group math + * @tags math * @returns Pattern * @noAutocomplete */ @@ -1798,7 +1798,7 @@ export const toBipolar = register('toBipolar', function (pat) { /** * Assumes a numerical pattern, containing bipolar values in the range -1 .. 1 * Returns a new pattern with values scaled to the unipolar range 0 .. 1 - * @group math + * @tags math * @returns Pattern * @noAutocomplete */ @@ -1812,7 +1812,7 @@ export const fromBipolar = register('fromBipolar', function (pat) { * Most useful in combination with continuous patterns. * @name range * @memberof Pattern - * @group math + * @tags math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1828,7 +1828,7 @@ export const range = register('range', function (min, max, pat) { * following an exponential curve. * @name rangex * @memberof Pattern - * @group math + * @tags math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1843,7 +1843,7 @@ export const rangex = register('rangex', function (min, max, pat) { * Returns a new pattern with values scaled to the given min/max range. * @name range2 * @memberof Pattern - * @group math + * @tags math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1858,7 +1858,7 @@ export const range2 = register('range2', function (min, max, pat) { * Returns a new pattern with just numbers. * @name ratio * @memberof Pattern - * @group math + * @tags math * @returns Pattern * @example * ratio("1, 5:4, 3:2").mul(110) @@ -1877,7 +1877,7 @@ export const ratio = register('ratio', (pat) => // Structural and temporal transformations /** Compress each cycle into the given timespan, leaving a gap - * @group structure + * @tags structure * @example * cat( * s("bd sd").compress(.25,.75), @@ -1899,7 +1899,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. - * @group structure + * @tags structure * @name fastGap * @synonyms fastgap * @example @@ -1937,7 +1937,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 - * @group structure + * @tags structure * @example * s("bd hh sd hh").focus(1/4, 3/4) */ @@ -1955,7 +1955,7 @@ export const { focusSpan, focusspan } = register(['focusSpan', 'focusspan'], fun }); /** The ply function repeats each event the given number of times. - * @group structure + * @tags structure * @example * s("bd ~ sd cp").ply("<1 2 3>") */ @@ -1970,7 +1970,7 @@ export const ply = register('ply', function (factor, pat) { /** * Speed up a pattern by the given factor. Used by "*" in mini notation. * - * @group structure + * @tags structure * @name fast * @synonyms density * @memberof Pattern @@ -1995,7 +1995,7 @@ export const { fast, density } = register( /** * Both speeds up the pattern (like 'fast') and the sample playback (like 'speed'). - * @group structure + * @tags structure * @example * s("bd sd:2").hurry("<1 2 4 3>").slow(1.5) */ @@ -2006,7 +2006,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. * - * @group structure + * @tags structure * @name slow * @synonyms sparsity * @memberof Pattern @@ -2024,7 +2024,7 @@ export const { slow, sparsity } = register(['slow', 'sparsity'], function (facto /** * Carries out an operation 'inside' a cycle. - * @group structure + * @tags structure * @example * "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() @@ -2035,7 +2035,7 @@ export const inside = register('inside', function (factor, f, pat) { /** * Carries out an operation 'outside' a cycle. - * @group structure + * @tags structure * @example * "<[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() @@ -2046,7 +2046,7 @@ export const outside = register('outside', function (factor, f, pat) { /** * Applies the given function every n cycles, starting from the last cycle. - * @group structure + * @tags structure * @name lastOf * @memberof Pattern * @param {number} n how many cycles @@ -2063,7 +2063,7 @@ export const lastOf = register('lastOf', function (n, func, pat) { /** * Applies the given function every n cycles, starting from the first cycle. - * @group structure + * @tags structure * @name firstOf * @memberof Pattern * @param {number} n how many cycles @@ -2075,7 +2075,7 @@ export const lastOf = register('lastOf', function (n, func, pat) { /** * An alias for `firstOf` - * @group structure + * @tags structure * @name every * @memberof Pattern * @param {number} n how many cycles @@ -2092,7 +2092,7 @@ export const { firstOf, every } = register(['firstOf', 'every'], function (n, fu /** * Like layer, but with a single function: - * @group structure + * @tags structure * @name apply * @example * "".scale('C minor').apply(scaleTranspose("0,2,4")).note() @@ -2104,7 +2104,7 @@ export const apply = register('apply', function (func, pat) { /** * Plays the pattern at the given cycles per minute. - * @group structure + * @tags structure * @deprecated * @example * s(",hh*2").cpm(90) // = 90 bpm @@ -2117,7 +2117,7 @@ export const cpm = register('cpm', function (cpm, pat) { /** * Nudge a pattern to start earlier in time. Equivalent of Tidal's <~ operator * - * @group structure + * @tags structure * @name early * @memberof Pattern * @param {number | Pattern} cycles number of cycles to nudge left @@ -2138,7 +2138,7 @@ export const early = register( /** * Nudge a pattern to start later in time. Equivalent of Tidal's ~> operator * - * @group structure + * @tags structure * @name late * @memberof Pattern * @param {number | Pattern} cycles number of cycles to nudge right @@ -2159,7 +2159,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: * - * @group structure + * @tags structure * @example * s("bd*2 hh*3 [sd bd]*2 perc").zoom(0.25, 0.75) * // s("hh*3 [sd bd]*2") // equivalent @@ -2186,7 +2186,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. * Similar to `slice`, but slices up patterns rather than sound samples. - * @group structure + * @tags structure * @param {number} number of slices * @param {number} slices to play * @example @@ -2214,7 +2214,7 @@ export const bite = register( /** * Selects the given fraction of the pattern and repeats that part to fill the remainder of the cycle. - * @group structure + * @tags structure * @param {number} fraction fraction to select * @example * s("lt ht mt cp, [hh oh]*2").linger("<1 .5 .25 .125>") @@ -2235,7 +2235,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. - * @group structure + * @tags structure * @name segment * @synonyms seg * @param {number} segments number of segments per cycle @@ -2248,7 +2248,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 - * @group structure + * @tags structure * @param {number} subdivision * @param {number} offset * @example @@ -2258,7 +2258,7 @@ export const swingBy = register('swingBy', (swing, n, pat) => pat.inside(n, late /** * Shorthand for swingBy with 1/3: - * @group structure + * @tags structure * @param {number} subdivision * @example * s("hh*8").swing(4) @@ -2268,7 +2268,7 @@ export const swing = register('swing', (n, pat) => pat.swingBy(1 / 3, n)); /** * Swaps 1s and 0s in a binary pattern. - * @group structure + * @tags structure * @name invert * @synonyms inv * @example @@ -2286,7 +2286,7 @@ export const { invert, inv } = register( /** * Applies the given function whenever the given pattern is in a true state. - * @group structure + * @tags structure * @name when * @memberof Pattern * @param {Pattern} binary_pat @@ -2301,7 +2301,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. - * @group structure + * @tags structure * @name off * @memberof Pattern * @param {Pattern | number} time offset time @@ -2318,7 +2318,7 @@ export const off = register('off', function (time_pat, func, pat) { * 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 * breakbeat feel. - * @group structure + * @tags structure * @returns Pattern */ export const brak = register('brak', function (pat) { @@ -2328,7 +2328,7 @@ export const brak = register('brak', function (pat) { /** * Reverse all haps in a pattern * - * @group structure + * @tags structure * @name rev * @memberof Pattern * @returns Pattern @@ -2362,7 +2362,7 @@ export const rev = register( /** Like press, but allows you to specify the amount by which each * event is shifted. pressBy(0.5) is the same as press, while * pressBy(1/3) shifts each event by a third of its timespan. - * @group structure + * @tags structure * @example * stack(s("hh*4"), * s("bd mt sd ht").pressBy("<0 0.5 0.25>") @@ -2374,7 +2374,7 @@ export const pressBy = register('pressBy', function (r, pat) { /** * Syncopates a rhythm, by shifting each event halfway into its timespan. - * @group structure + * @tags structure * @example * stack(s("hh*4"), * s("bd mt sd ht").every(4, press) @@ -2386,7 +2386,7 @@ export const press = register('press', function (pat) { /** * Silences a pattern. - * @group structure + * @tags structure * @example * stack( * s("bd").hush(), @@ -2399,7 +2399,7 @@ Pattern.prototype.hush = function () { /** * Applies `rev` to a pattern every other cycle, so that the pattern alternates between forwards and backwards. - * @group structure + * @tags structure * @example * note("c d e g").palindrome() */ @@ -2414,7 +2414,7 @@ export const palindrome = register( /** * Jux with adjustable stereo width. 0 = mono, 1 = full stereo. - * @group structure + * @tags structure * @name juxBy * @synonyms juxby * @example @@ -2436,7 +2436,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. - * @group structure + * @tags structure * @example * s("bd lt [~ ht] mt cp ~ bd hh").jux(rev) * @example @@ -2450,7 +2450,7 @@ export const jux = register('jux', function (func, pat) { /** * Superimpose and offset multiple times, applying the given function each time. - * @group structure + * @tags structure * @name echoWith * @synonyms echowith, stutWith, stutwith * @param {number} times how many times to repeat @@ -2470,7 +2470,7 @@ export const { echoWith, echowith, stutWith, stutwith } = register( /** * Superimpose and offset multiple times, gradually decreasing the velocity - * @group structure + * @tags structure * @name echo * @memberof Pattern * @returns Pattern @@ -2486,7 +2486,7 @@ export const echo = register('echo', function (times, time, feedback, pat) { /** * Deprecated. Like echo, but the last 2 parameters are flipped. - * @group structure + * @tags structure * @name stut * @param {number} times how many times to repeat * @param {number} feedback velocity multiplicator for each iteration @@ -2508,7 +2508,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 - * @group structure + * @tags structure * @name plyWith * @synonyms plywith * @param {number} factor how many times to repeat @@ -2531,7 +2531,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. * This version of ply uses the iteration index as an argument to the function, similar to echoWith. - * @group structure + * @tags structure * @name plyForEach * @synonyms plyforeach * @param {number} factor how many times to repeat @@ -2553,7 +2553,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. - * @group structure + * @tags structure * @name iter * @memberof Pattern * @returns Pattern @@ -2581,7 +2581,7 @@ export const iter = register( /** * Like `iter`, but plays the subdivisions in reverse order. Known as iter' in tidalcycles - * @group structure + * @tags structure * @name iterBack * @synonyms iterback * @memberof Pattern @@ -2600,7 +2600,7 @@ export const { iterBack, iterback } = register( /** * Repeats each cycle the given number of times. - * @group structure + * @tags structure * @name repeatCycles * @memberof Pattern * @returns Pattern @@ -2624,7 +2624,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). - * @group structure + * @tags structure * @name chunk * @synonyms slowChunk, slowchunk * @memberof Pattern @@ -2656,7 +2656,7 @@ export const { chunk, slowchunk, slowChunk } = register( /** * Like `chunk`, but cycles through the parts in reverse order. Known as chunk' in tidalcycles - * @group structure + * @tags structure * @name chunkBack * @synonyms chunkback * @memberof Pattern @@ -2677,7 +2677,7 @@ export const { chunkBack, chunkback } = register( /** * Like `chunk`, but the cycles of the source pattern aren't repeated * for each set of chunks. - * @group structure + * @tags structure * @name fastChunk * @synonyms fastchunk * @memberof Pattern @@ -2698,7 +2698,7 @@ export const { fastchunk, fastChunk } = register( /** * Like `chunk`, but the function is applied to a looped subcycle of the source pattern. - * @group structure + * @tags structure * @name chunkInto * @synonyms chunkinto * @memberof Pattern @@ -2712,7 +2712,7 @@ export const { chunkinto, chunkInto } = register(['chunkinto', 'chunkInto'], fun /** * Like `chunkInto`, but moves backwards through the chunks. - * @group structure + * @tags structure * @name chunkBackInto * @synonyms chunkbackinto * @memberof Pattern @@ -2743,7 +2743,7 @@ export const bypass = register( /** * 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. - * @group structure + * @tags structure * @name ribbon * @synonyms rib * @param {number} offset start point of loop in cycles @@ -2772,7 +2772,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). * @name tag - * @group structure + * @tags structure * @noAutocomplete * @param {string} tag anything unique */ @@ -2783,7 +2783,7 @@ Pattern.prototype.tag = function (tag) { /** * Filters haps using the given function * @name filter - * @group structure + * @tags structure * @param {Function} test function to test Hap * @example * s("hh!7 oh").filter(hap => hap.value.s==='hh') @@ -2793,7 +2793,7 @@ export const filter = register('filter', (test, pat) => pat.withHaps((haps) => h /** * Filters haps by their begin time * @name filterWhen - * @group structure + * @tags structure * @noAutocomplete * @param {Function} test function to test Hap.whole.begin */ @@ -2802,7 +2802,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 - * @group structure + * @tags structure * @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 @@ -2877,7 +2877,7 @@ export function _match(span, hap_p) { * *Experimental* * * Speeds a pattern up or down, to fit to the given number of steps per cycle. - * @group structure + * @tags structure * @example * sound("bd sd cp").pace(4) * // The same as sound("{bd sd cp}%4") or sound("*4") @@ -2919,7 +2919,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. - * @group structure + * @tags structure * @synonyms pm * @example * // The same as note("{c eb g, c2 g2}%6") @@ -2952,7 +2952,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 - * @group combiners + * @tags combiners * @synonyms timeCat, timecat * @return {Pattern} * @example @@ -3010,7 +3010,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. * - * @group combiners + * @tags combiners * @return {Pattern} * @example * stepalt(["bd cp", "mt"], "bd").sound() @@ -3037,7 +3037,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. - * @group structure + * @tags structure * @return {Pattern} * @example * "bd cp ht mt".take("2").sound() @@ -3082,7 +3082,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. - * @group structure + * @tags structure * @return {Pattern} * @example * "tha dhi thom nam".drop("1").sound().bank("mridangam") @@ -3111,7 +3111,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"`. - * @group structure + * @tags structure * @example * stepcat( * sound("bd bd - cp").extend(2), @@ -3126,7 +3126,7 @@ export const extend = stepRegister('extend', function (factor, pat) { * *Experimental* * * Expands the step size of the pattern by the given factor. - * @group structure + * @tags structure * @example * sound("tha dhi thom nam").bank("mridangam").expand("3 2 1 1 2 3").pace(8) */ @@ -3138,7 +3138,7 @@ export const expand = stepRegister('expand', function (factor, pat) { * *Experimental* * * Contracts the step size of the pattern by the given factor. See also `expand`. - * @group structure + * @tags structure * @example * sound("tha dhi thom nam").bank("mridangam").contract("3 2 1 1 2 3").pace(8) */ @@ -3193,7 +3193,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. - * @group structure + * @tags structure * @return {Pattern} * @example * "tha dhi thom nam".shrink("1").sound() @@ -3233,7 +3233,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. - * @group structure + * @tags structure * @return {Pattern} * @example * "tha dhi thom nam".grow("1").sound() @@ -3274,7 +3274,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. * - * @group combiners + * @tags combiners * @return {Pattern} * @example * "[c g]".tour("e f", "e f g", "g f e c").note() @@ -3301,7 +3301,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. * - * @group combiners + * @tags combiners * @returns {Pattern} * @example * zip("e f", "e f g", "g [f e] a f4 c").note() @@ -3353,7 +3353,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 - * @group transforms + * @tags transforms * @memberof Pattern * @returns Pattern * @example @@ -3384,7 +3384,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 - * @group transforms + * @tags transforms * @memberof Pattern * @returns Pattern * @example @@ -3403,7 +3403,7 @@ export const striate = register('striate', function (n, pat) { /** * Makes the sample fit the given number of cycles by changing the speed. * @name loopAt - * @group transforms + * @tags transforms * @memberof Pattern * @returns Pattern * @example @@ -3422,7 +3422,7 @@ const _loopAt = function (factor, pat, cps = 0.5) { * 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 - * @group transforms + * @tags transforms * @memberof Pattern * @returns Pattern * @example @@ -3458,7 +3458,7 @@ export const slice = register( * make something happen on event time * uses browser timeout which is innacurate for audio tasks * @name onTriggerTime - * @group external_io + * @tags external_io * @memberof Pattern * @returns Pattern * @example @@ -3476,7 +3476,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 - * @group transforms + * @tags transforms * @example * samples('github:tidalcycles/dirt-samples') * s("breaks165") @@ -3514,7 +3514,7 @@ export const { loopAt, loopat } = register(['loopAt', 'loopat'], function (facto * Makes the sample fit its event duration. Good for rhythmical loops like drum breaks. * Similar to `loopAt`. * @name fit - * @group transforms + * @tags transforms * @example * samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' }) * s("rhodes/2").fit() @@ -3540,7 +3540,7 @@ export const fit = register('fit', (pat) => * given by a global clock and this function will be * deprecated/removed. * @name loopAtCps - * @group transforms + * @tags transforms * @memberof Pattern * @returns Pattern * @example @@ -3567,7 +3567,7 @@ let fadeGain = (p) => (p < 0.5 ? 1 : 1 - (p - 0.5) / 0.5); * - 1 = (no left, full right) * * @name xfade - * @group combiners + * @tags combiners * @example * xfade(s("bd*2"), "<0 .25 .5 .75 1>", s("hh*8")) */ @@ -3589,7 +3589,7 @@ Pattern.prototype.xfade = function (pos, b) { * creates a structure pattern from divisions of a cycle * especially useful for creating rhythms * @name beat - * @group structure + * @tags structure * @example * s("bd").beat("0,7,10", 16) * @example @@ -3666,7 +3666,7 @@ export const _morph = (from, to, by) => { * sine.slow(8) // slowly morph between the rhythms * ) * ) - * @group structure + * @tags structure */ export const morph = (frompat, topat, bypat) => { frompat = reify(frompat); diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 9f6636c84..03dd641a5 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -24,7 +24,7 @@ export const signal = (func) => { * A sawtooth signal between 0 and 1. * * @return {Pattern} - * @group generators + * @tags generators * @example * note("*8") * .clip(saw.slow(2)) @@ -39,7 +39,7 @@ export const saw = signal((t) => t % 1); * A sawtooth signal between -1 and 1 (like `saw`, but bipolar). * * @return {Pattern} - * @group generators + * @tags generators */ export const saw2 = saw.toBipolar(); @@ -47,7 +47,7 @@ export const saw2 = saw.toBipolar(); * A sawtooth signal between 1 and 0 (like `saw`, but flipped). * * @return {Pattern} - * @group generators + * @tags generators * @example * note("*8") * .clip(isaw.slow(2)) @@ -62,7 +62,7 @@ export const isaw = signal((t) => 1 - (t % 1)); * A sawtooth signal between 1 and -1 (like `saw2`, but flipped). * * @return {Pattern} - * @group generators + * @tags generators */ export const isaw2 = isaw.toBipolar(); @@ -70,14 +70,14 @@ export const isaw2 = isaw.toBipolar(); * A sine signal between -1 and 1 (like `sine`, but bipolar). * * @return {Pattern} - * @group generators + * @tags generators */ export const sine2 = signal((t) => Math.sin(Math.PI * 2 * t)); /** * A sine signal between 0 and 1. * @return {Pattern} - * @group generators + * @tags generators * @example * n(sine.segment(16).range(0,15)) * .scale("C:minor") @@ -89,7 +89,7 @@ export const sine = sine2.fromBipolar(); * A cosine signal between 0 and 1. * * @return {Pattern} - * @group generators + * @tags generators * @example * n(stack(sine,cosine).segment(16).range(0,15)) * .scale("C:minor") @@ -101,14 +101,14 @@ export const cosine = sine._early(Fraction(1).div(4)); * A cosine signal between -1 and 1 (like `cosine`, but bipolar). * * @return {Pattern} - * @group generators + * @tags generators */ export const cosine2 = sine2._early(Fraction(1).div(4)); /** * A square signal between 0 and 1. * @return {Pattern} - * @group generators + * @tags generators * @example * n(square.segment(4).range(0,7)).scale("C:minor") * @@ -119,7 +119,7 @@ export const square = signal((t) => Math.floor((t * 2) % 2)); * A square signal between -1 and 1 (like `square`, but bipolar). * * @return {Pattern} - * @group generators + * @tags generators */ export const square2 = square.toBipolar(); @@ -127,7 +127,7 @@ export const square2 = square.toBipolar(); * A triangle signal between 0 and 1. * * @return {Pattern} - * @group generators + * @tags generators * @example * n(tri.segment(8).range(0,7)).scale("C:minor") * @@ -138,7 +138,7 @@ export const tri = fastcat(saw, isaw); * A triangle signal between -1 and 1 (like `tri`, but bipolar). * * @return {Pattern} - * @group generators + * @tags generators */ export const tri2 = fastcat(saw2, isaw2); @@ -146,7 +146,7 @@ export const tri2 = fastcat(saw2, isaw2); * An inverted triangle signal between 1 and 0 (like `tri`, but flipped). * * @return {Pattern} - * @group generators + * @tags generators * @example * n(itri.segment(8).range(0,7)).scale("C:minor") * @@ -157,7 +157,7 @@ export const itri = fastcat(isaw, saw); * An inverted triangle signal between -1 and 1 (like `itri`, but bipolar). * * @return {Pattern} - * @group generators + * @tags generators */ export const itri2 = fastcat(isaw2, saw2); @@ -165,7 +165,7 @@ export const itri2 = fastcat(isaw2, saw2); * A signal representing the cycle time. * * @return {Pattern} - * @group generators + * @tags generators */ export const time = signal(id); @@ -173,7 +173,7 @@ export const time = signal(id); * The mouse's x position value ranges from 0 to 1. * @name mousex * @return {Pattern} - * @group external_io + * @tags external_io * @example * n(mousex.segment(4).range(0,7)).scale("C:minor") * @@ -183,7 +183,7 @@ export const time = signal(id); * The mouse's y position value ranges from 0 to 1. * @name mousey * @return {Pattern} - * @group external_io + * @tags external_io * @example * n(mousey.segment(4).range(0,7)).scale("C:minor") * @@ -238,7 +238,7 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n); /** * A discrete pattern of numbers from 0 to n-1 - * @group generators + * @tags generators * @example * n(run(4)).scale("C4:pentatonic") * // n("0 1 2 3").scale("C4:pentatonic") @@ -249,7 +249,7 @@ export const run = (n) => saw.range(0, n).round().segment(n); * Creates a pattern from a binary number. * * @name binary - * @group generators + * @tags generators * @param {number} n - input number to convert to binary * @example * "hh".s().struct(binary(5)) @@ -264,7 +264,7 @@ export const binary = (n) => { * Creates a pattern from a binary number, padded to n bits long. * * @name binaryN - * @group generators + * @tags generators * @param {number} n - input number to convert to binary * @param {number} nBits - pattern length, defaults to 16 * @example @@ -300,7 +300,7 @@ const _rearrangeWith = (ipat, n, pat) => { * Slices a pattern into the given number of parts, then plays those parts in random order. * Each part will be played exactly once per cycle. * @name shuffle - * @group transforms + * @tags transforms * @example * note("c d e f").sound("piano").shuffle(4) * @example @@ -314,7 +314,7 @@ export const shuffle = register('shuffle', (n, pat) => { * Slices a pattern into the given number of parts, then plays those parts at random. Similar to `shuffle`, * but parts might be played more than once, or not at all, per cycle. * @name scramble - * @group transforms + * @tags transforms * @example * note("c d e f").sound("piano").scramble(4) * @example @@ -328,7 +328,7 @@ export const scramble = register('scramble', (n, pat) => { * A continuous pattern of random numbers, between 0 and 1. * * @name rand - * @group generators + * @tags generators * @example * // randomly change the cutoff * s("bd*4,hh*8").cutoff(rand.range(500,8000)) @@ -346,7 +346,7 @@ export const _brandBy = (p) => rand.fmap((x) => x < p); * A continuous pattern of 0 or 1 (binary random), with a probability for the value being 1 * * @name brandBy - * @group generators + * @tags generators * @param {number} probability - a number between 0 and 1 * @example * s("hh*10").pan(brandBy(0.2)) @@ -357,7 +357,7 @@ export const brandBy = (pPat) => reify(pPat).fmap(_brandBy).innerJoin(); * A continuous pattern of 0 or 1 (binary random) * * @name brand - * @group generators + * @tags generators * @example * s("hh*10").pan(brand) */ @@ -369,7 +369,7 @@ export const _irand = (i) => rand.fmap((x) => Math.trunc(x * i)); * A continuous pattern of random integers, between 0 and n-1. * * @name irand - * @group generators + * @tags generators * @param {number} n max value (exclusive) * @example * // randomly select scale notes from 0 - 7 (= C to C) @@ -392,7 +392,7 @@ export const __chooseWith = (pat, xs) => { /** * Choose from the list of values (or patterns of values) using the given * pattern of numbers, which should be in the range of 0..1 - * @group transforms + * @tags transforms * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -406,7 +406,7 @@ export const chooseWith = (pat, xs) => { /** * As with {chooseWith}, but the structure comes from the chosen values, rather * than the pattern you're using to choose with. - * @group transforms + * @tags transforms * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -417,7 +417,7 @@ export const chooseInWith = (pat, xs) => { /** * Chooses randomly from the given list of elements. - * @group transforms + * @tags transforms * @param {...any} xs values / patterns to choose from. * @returns {Pattern} - a continuous pattern. * @example @@ -433,7 +433,7 @@ export const chooseOut = choose; * Chooses from the given list of values (or patterns of values), according * to the pattern that the method is called on. The pattern should be in * the range 0 .. 1. - * @group transforms + * @tags transforms * @param {...any} xs * @returns {Pattern} */ @@ -444,7 +444,7 @@ Pattern.prototype.choose = function (...xs) { /** * As with choose, but the pattern that this method is called on should be * in the range -1 .. 1 - * @group transforms + * @tags transforms * @param {...any} xs * @returns {Pattern} */ @@ -454,7 +454,7 @@ Pattern.prototype.choose2 = function (...xs) { /** * Picks one of the elements at random each cycle. - * @group transforms + * @tags transforms * @synonyms randcat * @returns {Pattern} * @example @@ -497,7 +497,7 @@ const wchooseWith = (...args) => _wchooseWith(...args).outerJoin(); /** * Chooses randomly from the given list of elements by giving a probability to each element - * @group transforms + * @tags transforms * @param {...any} pairs arrays of value and weight * @returns {Pattern} - a continuous pattern. * @example @@ -507,7 +507,7 @@ export const wchoose = (...pairs) => wchooseWith(rand, ...pairs); /** * Picks one of the elements at random each cycle by giving a probability to each element - * @group transforms + * @tags transforms * @synonyms wrandcat * @returns {Pattern} * @example @@ -555,7 +555,7 @@ export const berlinWith = (tpat) => { /** * Generates a continuous pattern of [perlin noise](https://en.wikipedia.org/wiki/Perlin_noise), in the range 0..1. * - * @group generators + * @tags generators * @name perlin * @example * // randomly change the cutoff @@ -568,7 +568,7 @@ export const perlin = perlinWith(time.fmap((v) => Number(v))); * Generates a continuous pattern of [berlin noise](conceived by Jame Coyne and Jade Rowland as a joke but turned out to be surprisingly cool and useful, * like perlin noise but with sawtooth waves), in the range 0..1. * - * @group generators + * @tags generators * @name berlin * @example * // ascending arpeggios @@ -589,7 +589,7 @@ export const degradeByWith = register( * 0 = 0% chance of removal * 1 = 100% chance of removal * - * @group transforms + * @tags transforms * @name degradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -615,7 +615,7 @@ export const degradeBy = register( * * Randomly removes 50% of events from the pattern. Shorthand for `.degradeBy(0.5)` * - * @group transforms + * @tags transforms * @name degrade * @memberof Pattern * @returns Pattern @@ -632,7 +632,7 @@ export const degrade = register('degrade', (pat) => pat._degradeBy(0.5), true, t * 1 = 0% chance of removal * Events that would be removed by degradeBy are let through by undegradeBy and vice versa (see second example). * - * @group transforms + * @tags transforms * @name undegradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -661,7 +661,7 @@ export const undegradeBy = register( * Inverse of `degrade`: Randomly removes 50% of events from the pattern. Shorthand for `.undegradeBy(0.5)` * Events that would be removed by degrade are let through by undegrade and vice versa (see second example). * - * @group transforms + * @tags transforms * @name undegrade * @memberof Pattern * @returns Pattern @@ -680,7 +680,7 @@ export const undegrade = register('undegrade', (pat) => pat._undegradeBy(0.5), t * Randomly applies the given function by the given probability. * Similar to `someCyclesBy` * - * @group transforms + * @tags transforms * @name sometimesBy * @memberof Pattern * @param {number | Pattern} probability - a number between 0 and 1 @@ -700,7 +700,7 @@ export const sometimesBy = register('sometimesBy', function (patx, func, pat) { * * Applies the given function with a 50% chance * - * @group transforms + * @tags transforms * @name sometimes * @memberof Pattern * @param {function} function - the transformation to apply @@ -722,7 +722,7 @@ export const sometimes = register('sometimes', function (func, pat) { * @param {number | Pattern} probability - a number between 0 and 1 * @param {function} function - the transformation to apply * @returns Pattern - * @group transforms + * @tags transforms * @example * s("bd,hh*8").someCyclesBy(.3, x=>x.speed("0.5")) */ @@ -745,7 +745,7 @@ export const someCyclesBy = register('someCyclesBy', function (patx, func, pat) * @name someCycles * @memberof Pattern * @returns Pattern - * @group transforms + * @tags transforms * @example * s("bd,hh*8").someCycles(x=>x.speed("0.5")) */ @@ -760,7 +760,7 @@ export const someCycles = register('someCycles', function (func, pat) { * @name often * @memberof Pattern * @returns Pattern - * @group transforms + * @tags transforms * @example * s("hh*8").often(x=>x.speed("0.5")) */ @@ -775,7 +775,7 @@ export const often = register('often', function (func, pat) { * @name rarely * @memberof Pattern * @returns Pattern - * @group transforms + * @tags transforms * @example * s("hh*8").rarely(x=>x.speed("0.5")) */ @@ -787,7 +787,7 @@ export const rarely = register('rarely', function (func, pat) { * * Shorthand for `.sometimesBy(0.1, fn)` * - * @group transforms + * @tags transforms * @name almostNever * @memberof Pattern * @returns Pattern @@ -802,7 +802,7 @@ export const almostNever = register('almostNever', function (func, pat) { * * Shorthand for `.sometimesBy(0.9, fn)` * - * @group transforms + * @tags transforms * @name almostAlways * @memberof Pattern * @returns Pattern @@ -817,7 +817,7 @@ export const almostAlways = register('almostAlways', function (func, pat) { * * Shorthand for `.sometimesBy(0, fn)` (never calls fn) * - * @group transforms + * @tags transforms * @name never * @memberof Pattern * @returns Pattern @@ -832,7 +832,7 @@ export const never = register('never', function (_, pat) { * * Shorthand for `.sometimesBy(1, fn)` (always calls fn) * - * @group transforms + * @tags transforms * @name always * @memberof Pattern * @returns Pattern @@ -861,7 +861,7 @@ export function _keyDown(keyname) { * Do something on a keypress, or array of keypresses * [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) * - * @group external_io + * @tags external_io * @name whenKey * @memberof Pattern * @returns Pattern @@ -878,7 +878,7 @@ export const whenKey = register('whenKey', function (input, func, pat) { * returns true when a key or array of keys is held * [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) * - * @group external_io + * @tags external_io * @name keyDown * @memberof Pattern * @returns Pattern diff --git a/packages/motion/motion.mjs b/packages/motion/motion.mjs index cba814a84..fed0fbe0c 100644 --- a/packages/motion/motion.mjs +++ b/packages/motion/motion.mjs @@ -7,7 +7,7 @@ import { signal } from '../core/signal.mjs'; * @name accelerationX * @return {Pattern} * @synonyms accX - * @group external_io + * @tags external_io * @example * n(accelerationX.segment(4).range(0,7)).scale("C:minor") * @@ -18,7 +18,7 @@ import { signal } from '../core/signal.mjs'; * @name accelerationY * @return {Pattern} * @synonyms accY - * @group external_io + * @tags external_io * @example * n(accelerationY.segment(4).range(0,7)).scale("C:minor") * @@ -29,7 +29,7 @@ import { signal } from '../core/signal.mjs'; * @name accelerationZ * @return {Pattern} * @synonyms accZ - * @group external_io + * @tags external_io * @example * n(accelerationZ.segment(4).range(0,7)).scale("C:minor") * @@ -40,7 +40,7 @@ import { signal } from '../core/signal.mjs'; * @name gravityX * @return {Pattern} * @synonyms gravX - * @group external_io + * @tags external_io * @example * n(gravityX.segment(4).range(0,7)).scale("C:minor") * @@ -51,7 +51,7 @@ import { signal } from '../core/signal.mjs'; * @name gravityY * @return {Pattern} * @synonyms gravY - * @group external_io + * @tags external_io * @example * n(gravityY.segment(4).range(0,7)).scale("C:minor") * @@ -62,7 +62,7 @@ import { signal } from '../core/signal.mjs'; * @name gravityZ * @return {Pattern} * @synonyms gravZ - * @group external_io + * @tags external_io * @example * n(gravityZ.segment(4).range(0,7)).scale("C:minor") * @@ -73,7 +73,7 @@ import { signal } from '../core/signal.mjs'; * @name rotationAlpha * @return {Pattern} * @synonyms rotA, rotZ, rotationZ - * @group external_io + * @tags external_io * @example * n(rotationAlpha.segment(4).range(0,7)).scale("C:minor") * @@ -84,7 +84,7 @@ import { signal } from '../core/signal.mjs'; * @name rotationBeta * @return {Pattern} * @synonyms rotB, rotX, rotationX - * @group external_io + * @tags external_io * @example * n(rotationBeta.segment(4).range(0,7)).scale("C:minor") * @@ -95,7 +95,7 @@ import { signal } from '../core/signal.mjs'; * @name rotationGamma * @return {Pattern} * @synonyms rotG, rotY, rotationY - * @group external_io + * @tags external_io * @example * n(rotationGamma.segment(4).range(0,7)).scale("C:minor") * @@ -106,7 +106,7 @@ import { signal } from '../core/signal.mjs'; * @name orientationAlpha * @return {Pattern} * @synonyms oriA, oriZ, orientationZ - * @group external_io + * @tags external_io * @example * n(orientationAlpha.segment(4).range(0,7)).scale("C:minor") * @@ -117,7 +117,7 @@ import { signal } from '../core/signal.mjs'; * @name orientationBeta * @return {Pattern} * @synonyms oriB, oriX, orientationX - * @group external_io + * @tags external_io * @example * n(orientationBeta.segment(4).range(0,7)).scale("C:minor") * @@ -128,7 +128,7 @@ import { signal } from '../core/signal.mjs'; * @name orientationGamma * @return {Pattern} * @synonyms oriG, oriY, orientationY - * @group external_io + * @tags external_io * @example * n(orientationGamma.segment(4).range(0,7)).scale("C:minor") * @@ -139,7 +139,7 @@ import { signal } from '../core/signal.mjs'; * @name absoluteOrientationAlpha * @return {Pattern} * @synonyms absOriA, absOriZ, absoluteOrientationZ - * @group external_io + * @tags external_io * @example * n(absoluteOrientationAlpha.segment(4).range(0,7)).scale("C:minor") * @@ -150,7 +150,7 @@ import { signal } from '../core/signal.mjs'; * @name absoluteOrientationBeta * @return {Pattern} * @synonyms absOriB, absOriX, absoluteOrientationX - * @group external_io + * @tags external_io * @example * n(absoluteOrientationBeta.segment(4).range(0,7)).scale("C:minor") * @@ -161,7 +161,7 @@ import { signal } from '../core/signal.mjs'; * @name absoluteOrientationGamma * @return {Pattern} * @synonyms absOriG, absOriY, absoluteOrientationY - * @group external_io + * @tags external_io * @example * n(absoluteOrientationGamma.segment(4).range(0,7)).scale("C:minor") * diff --git a/packages/superdough/reverbGen.mjs b/packages/superdough/reverbGen.mjs index 0d5fee264..42da7c6d5 100644 --- a/packages/superdough/reverbGen.mjs +++ b/packages/superdough/reverbGen.mjs @@ -80,7 +80,7 @@ reverbGen.generateGraph = function (data, width, height, min, max) { @param {number} lpFreqEndAt @param {!function(!AudioBuffer)} callback May be called immediately within the current execution context, or later. - @group effects + @tags effects */ var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, callback) { if (lpFreqStart == 0) { diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 7eeb7a507..23dfbee09 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -18,7 +18,7 @@ function applyGainCurve(val) { * @param {number} a - Signal A (can be a single value or an array value in buffer processing). * @param {number} b - Signal B (can be a single value or an array value in buffer processing). * @param {number} m - Crossfade parameter (0.0 = all A, 1.0 = all B, 0.5 = equal mix). - * @group effects + * @tags effects * @returns {number} Crossfaded output value. */ function crossfade(a, b, m) { From d516d765d5556617adb1a5cfe8b672c35a09effa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 11 Oct 2025 14:12:45 +0200 Subject: [PATCH 06/26] Redo frontend for tags --- .../src/repl/components/panel/Reference.jsx | 92 +++++++++++++------ 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 552551b5c..3faa5c6f1 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -10,8 +10,10 @@ const availableFunctions = (() => { const functions = []; for (const doc of jsdocJson.docs) { if (!isValid(doc)) continue; + if (seen.has(doc.name)) continue; functions.push(doc); const synonyms = doc.synonyms || []; + seen.add(doc.name); for (const s of synonyms) { if (!s || seen.has(s)) continue; seen.add(s); @@ -38,18 +40,33 @@ const getInnerText = (html) => { const GROUP_DISPLAY_NAMES = { external_io: 'External I/O', effects: 'Effects', - ungrouped: 'Ungrouped', + untagged: 'Untagged', structure: 'Structure', transforms: 'Transforms', }; -const GROUP_ORDER = ['effects', 'transforms', 'structure', 'ungrouped', 'external_io']; +const GROUP_ORDER = ['effects', 'transforms', 'structure', 'untagged', 'external_io']; export function Reference() { const [search, setSearch] = useState(''); + const [selectedTag, setSelectedTag] = useState(null); + + const toggleTag = (tag) => { + if (selectedTag === tag) { + setSelectedTag(null); + } else { + setSelectedTag(tag); + } + }; const visibleFunctions = useMemo(() => { return availableFunctions.filter((entry) => { + if (selectedTag) { + if (!(entry.tags || ['untagged']).includes(selectedTag)) { + return false; + } + } + if (!search) { return true; } @@ -60,12 +77,12 @@ export function Reference() { (entry.synonyms?.some((s) => s.includes(lowCaseSearch)) ?? false) ); }); - }, [search]); + }, [search, selectedTag]); const visibleFunctionsByGroup = (() => { const groups = {}; for (const doc of visibleFunctions) { - const group = doc.group || 'ungrouped'; + const group = (doc.tags || ['untagged'])[0]; if (!groups[group]) { groups[group] = []; } @@ -85,37 +102,56 @@ export function Reference() { return ai - bi; }); + const tagCounts = {}; + for (const doc of availableFunctions) { + (doc.tags || ['untagged']).forEach((t) => { + if (typeof t === 'string' && t) { + tagCounts[t] = (tagCounts[t] || 0) + 1; + } + }); + } + return ( -
-
-
+
+
From c62428ca27b34f62598db1506dd42af36f23f80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 12 Oct 2025 16:07:11 +0200 Subject: [PATCH 07/26] Document remaining functions --- packages/codemirror/codemirror.mjs | 1 + packages/codemirror/slider.mjs | 1 + packages/core/controls.mjs | 7 +- packages/core/drawLine.mjs | 1 + packages/core/euclid.mjs | 5 + packages/core/pattern.mjs | 159 ++++++++++++++------------- packages/core/pick.mjs | 13 +++ packages/core/repl.mjs | 5 + packages/core/signal.mjs | 1 + packages/csound/index.mjs | 2 + packages/draw/pianoroll.mjs | 2 + packages/draw/pitchwheel.mjs | 1 + packages/draw/spiral.mjs | 1 + packages/midi/midi.mjs | 4 + packages/osc/osc.mjs | 1 + packages/superdough/ola-processor.js | 29 +++-- packages/superdough/reverbGen.mjs | 5 +- packages/superdough/sampler.mjs | 1 + packages/superdough/superdough.mjs | 3 + packages/superdough/wavetable.mjs | 1 + packages/superdough/worklets.mjs | 20 +++- packages/tonal/tonal.mjs | 3 + packages/tonal/voicings.mjs | 4 + packages/webaudio/scope.mjs | 2 + packages/webaudio/spectrum.mjs | 1 + 25 files changed, 179 insertions(+), 94 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 4dc23996f..193b93e3e 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -379,6 +379,7 @@ function s4() { /** * Overrides the css of highlighted events. Make sure to use single quotes! * @name markcss + * @tag visualization * @example * note("c a f e") * .markcss('text-decoration:underline') diff --git a/packages/codemirror/slider.mjs b/packages/codemirror/slider.mjs index 72f951254..cc224a6cc 100644 --- a/packages/codemirror/slider.mjs +++ b/packages/codemirror/slider.mjs @@ -117,6 +117,7 @@ export const sliderPlugin = ViewPlugin.fromClass( * Displays a slider widget to allow the user manipulate a value * * @name slider + * @tags external_io, visualization * @param {number} value Initial value * @param {number} min Minimum value - optional, defaults to 0 * @param {number} max Maximum value - optional, defaults to 1 diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 44b358e67..4e60fc487 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -949,6 +949,7 @@ export const { duckattack } = registerControl('duckattack', 'duckatt'); * * @name byteBeatExpression * @synonyms bbexpr + * @tags effects * * @param {number | Pattern} byteBeatExpression bitwise expression for creating bytebeat * @example @@ -962,6 +963,7 @@ export const { byteBeatExpression, bbexpr } = registerControl('byteBeatExpressio * * @name byteBeatStartTime * @synonyms bbst + * @tags effects * * @param {number | Pattern} byteBeatStartTime in samples (t) * @example @@ -1518,7 +1520,7 @@ export const { delayspeed } = registerControl('delayspeed'); * Sets the time of the delay effect. * * @name delayspeed - * @tags effects, foo + * @tags effects * @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @synonyms delayt, dt * @example @@ -1544,7 +1546,7 @@ export const { delaysync } = registerControl('delaysync'); * Specifies whether delaytime is calculated relative to cps. * * @name lock - * @tags effects, foo + * @tags effects * @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle. * @superdirtOnly * @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. * * @name orbit + * @tags effects * @param {number | Pattern} number * @example * stack( diff --git a/packages/core/drawLine.mjs b/packages/core/drawLine.mjs index 7509c0f6f..212d06279 100644 --- a/packages/core/drawLine.mjs +++ b/packages/core/drawLine.mjs @@ -15,6 +15,7 @@ import Fraction, { gcd } from './fraction.mjs'; * - "-" hold previous value * - "." silence * + * @tags visualization * @param {Pattern} pattern the pattern to use * @param {number} chars max number of characters (approximately) * @returns string diff --git a/packages/core/euclid.mjs b/packages/core/euclid.mjs index 44ab07f11..e8252a984 100644 --- a/packages/core/euclid.mjs +++ b/packages/core/euclid.mjs @@ -61,6 +61,7 @@ export const bjork = function (ons, steps) { * * @memberof Pattern * @name euclid + * @tags temporal * @param {number} pulses the number of onsets/beats * @param {number} steps the number of steps to fill * @returns Pattern @@ -73,6 +74,7 @@ export const bjork = function (ons, steps) { * Like `euclid`, but has an additional parameter for 'rotating' the resulting sequence. * @memberof Pattern * @name euclidRot + * @tags temporal * @param {number} pulses the number of onsets/beats * @param {number} steps the number of steps to fill * @param {number} rotation offset in steps @@ -156,6 +158,7 @@ export const { euclidrot, euclidRot } = register(['euclidrot', 'euclidRot'], fun * so there will be no gaps. * @name euclidLegato * @memberof Pattern + * @tags temporal * @param {number} pulses the number of onsets/beats * @param {number} steps the number of steps to fill * @param rotation offset in steps @@ -187,6 +190,7 @@ export const euclidLegato = register(['euclidLegato'], function (pulses, steps, * the resulting sequence * @name euclidLegatoRot * @memberof Pattern + * @tags temporal * @param {number} pulses the number of onsets/beats * @param {number} steps the number of steps to fill * @param {number} rotation offset in steps @@ -208,6 +212,7 @@ export const euclidLegatoRot = register(['euclidLegatoRot'], function (pulses, s * @name euclidish * @synonyms eish * @memberof Pattern + * @tags temporal * @param {number} pulses the number of onsets * @param {number} steps the number of steps to fill * @param {number} groove exists between the extremes of 0 (straight euclidian) and 1 (straight pulse) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 39d6555f5..2d6459a89 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -889,7 +889,7 @@ export class Pattern { /** * Writes the content of the current event to the console (visible in the side menu). - * @tags visualizers + * @tags visualization * @name log * @memberof Pattern * @example @@ -904,7 +904,7 @@ export class Pattern { /** * A simplified version of `log` which writes all "values" (various configurable parameters) * within the event to the console (visible in the side menu). - * @tags visualizers + * @tags visualization * @name logValues * @memberof Pattern * @example @@ -938,7 +938,7 @@ export class Pattern { * 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 * to be played unchanged. - * @tags structure + * @tags temporal * @name into * @memberof Pattern * @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. * @name add * @memberof Pattern + * @tags math * @example * // Here, the triad 0, 2, 4 is shifted by different amounts * 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>")) * // Behind the scenes, the notes are converted to midi numbers: * // note("48 52 55".add("<0 5 7 0>")) - * @tags math */ 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. * @name sub * @memberof Pattern + * @tags math * @example * n("0 2 4".sub("<0 1 2 3>")).scale("C4:minor") * // See add for more information. @@ -1094,6 +1095,7 @@ function _composeOp(a, b, func) { * Multiplies each number by the given factor. * @name mul * @memberof Pattern + * @tags math * @example * "<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. * @name div * @memberof Pattern + * @tags math */ div: [numeralArgs((a, b) => a / b)], mod: [numeralArgs(_mod)], @@ -1189,7 +1192,7 @@ function _composeOp(a, b, func) { /** * Applies the given structure to the pattern: * - * @tags structure + * @tags temporal * @example * note("c,eb,g") * .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~") @@ -1204,7 +1207,7 @@ function _composeOp(a, b, func) { /** * Returns silence when mask is 0 or "~" * - * @tags structure + * @tags temporal * @example * 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. * - * @tags structure + * @tags temporal * @example * s("[ sd]*2, hh*8").reset("") */ @@ -1231,7 +1234,7 @@ function _composeOp(a, b, func) { * Restarts the pattern for each onset of the restart pattern. * While reset will only reset the current cycle, restart will start from cycle 0. * - * @tags structure + * @tags temporal * @example * s("[ sd]*2, hh*8").restart("") */ @@ -1352,7 +1355,7 @@ export function sequenceP(pats) { /** * The given items are played at the same time at the same length. * - * @tags structure + * @tags temporal * @return {Pattern} * @synonyms polyrhythm, pr * @example @@ -1566,14 +1569,9 @@ export function fastcat(...pats) { return result; } -/** See `fastcat` */ -export function sequence(...pats) { - return fastcat(...pats); -} - /** Like **cat**, but the items are crammed into one cycle. * @tags combiners - * @synonyms sequence, fastcat + * @synonyms seq, fastcat * @example * seq("e5", "b4", ["d5", "c5"]).note() * // "e5 b4 [d5 c5]".note() @@ -1584,6 +1582,9 @@ export function sequence(...pats) { * note("c4(5,8)") * ) */ +export function sequence(...pats) { + return fastcat(...pats); +} export function seq(...pats) { return fastcat(...pats); @@ -1877,7 +1878,7 @@ export const ratio = register('ratio', (pat) => // Structural and temporal transformations /** Compress each cycle into the given timespan, leaving a gap - * @tags structure + * @tags temporal * @example * cat( * 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. - * @tags structure + * @tags temporal * @name fastGap * @synonyms fastgap * @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 - * @tags structure + * @tags temporal * @example * 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. - * @tags structure + * @tags temporal * @example * 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. * - * @tags structure + * @tags temporal * @name fast * @synonyms density * @memberof Pattern @@ -1995,7 +1996,7 @@ export const { fast, density } = register( /** * Both speeds up the pattern (like 'fast') and the sample playback (like 'speed'). - * @tags structure + * @tags temporal * @example * 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. * - * @tags structure + * @tags temporal * @name slow * @synonyms sparsity * @memberof Pattern @@ -2024,7 +2025,7 @@ export const { slow, sparsity } = register(['slow', 'sparsity'], function (facto /** * Carries out an operation 'inside' a cycle. - * @tags structure + * @tags temporal * @example * "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() @@ -2035,7 +2036,7 @@ export const inside = register('inside', function (factor, f, pat) { /** * Carries out an operation 'outside' a cycle. - * @tags structure + * @tags temporal * @example * "<[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() @@ -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. - * @tags structure + * @tags temporal * @name lastOf * @memberof Pattern * @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. - * @tags structure + * @tags temporal * @name firstOf * @memberof Pattern * @param {number} n how many cycles @@ -2075,7 +2076,7 @@ export const lastOf = register('lastOf', function (n, func, pat) { /** * An alias for `firstOf` - * @tags structure + * @tags temporal * @name every * @memberof Pattern * @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: - * @tags structure + * @tags temporal * @name apply * @example * "".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. - * @tags structure + * @tags temporal * @deprecated * @example * s(",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 * - * @tags structure + * @tags temporal * @name early * @memberof Pattern * @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 * - * @tags structure + * @tags temporal * @name late * @memberof Pattern * @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: * - * @tags structure + * @tags temporal * @example * s("bd*2 hh*3 [sd bd]*2 perc").zoom(0.25, 0.75) * // 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. * Similar to `slice`, but slices up patterns rather than sound samples. - * @tags structure + * @tags temporal * @param {number} number of slices * @param {number} slices to play * @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. - * @tags structure + * @tags temporal * @param {number} fraction fraction to select * @example * 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. - * @tags structure + * @tags temporal * @name segment * @synonyms seg * @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 - * @tags structure + * @tags temporal * @param {number} subdivision * @param {number} offset * @example @@ -2258,7 +2259,7 @@ export const swingBy = register('swingBy', (swing, n, pat) => pat.inside(n, late /** * Shorthand for swingBy with 1/3: - * @tags structure + * @tags temporal * @param {number} subdivision * @example * 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. - * @tags structure + * @tags temporal * @name invert * @synonyms inv * @example @@ -2286,7 +2287,7 @@ export const { invert, inv } = register( /** * Applies the given function whenever the given pattern is in a true state. - * @tags structure + * @tags temporal * @name when * @memberof Pattern * @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. - * @tags structure + * @tags temporal * @name off * @memberof Pattern * @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 * fast, and offset in time by one quarter of a cycle. Creates a kind of * breakbeat feel. - * @tags structure + * @tags temporal * @returns Pattern */ export const brak = register('brak', function (pat) { @@ -2328,7 +2329,7 @@ export const brak = register('brak', function (pat) { /** * Reverse all haps in a pattern * - * @tags structure + * @tags temporal * @name rev * @memberof Pattern * @returns Pattern @@ -2362,7 +2363,7 @@ export const rev = register( /** Like press, but allows you to specify the amount by which each * event is shifted. pressBy(0.5) is the same as press, while * pressBy(1/3) shifts each event by a third of its timespan. - * @tags structure + * @tags temporal * @example * stack(s("hh*4"), * 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. - * @tags structure + * @tags temporal * @example * stack(s("hh*4"), * s("bd mt sd ht").every(4, press) @@ -2386,7 +2387,7 @@ export const press = register('press', function (pat) { /** * Silences a pattern. - * @tags structure + * @tags temporal * @example * stack( * 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. - * @tags structure + * @tags temporal * @example * note("c d e g").palindrome() */ @@ -2414,7 +2415,7 @@ export const palindrome = register( /** * Jux with adjustable stereo width. 0 = mono, 1 = full stereo. - * @tags structure + * @tags temporal * @name juxBy * @synonyms juxby * @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. - * @tags structure + * @tags temporal * @example * s("bd lt [~ ht] mt cp ~ bd hh").jux(rev) * @example @@ -2450,7 +2451,7 @@ export const jux = register('jux', function (func, pat) { /** * Superimpose and offset multiple times, applying the given function each time. - * @tags structure + * @tags temporal * @name echoWith * @synonyms echowith, stutWith, stutwith * @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 - * @tags structure + * @tags temporal * @name echo * @memberof 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. - * @tags structure + * @tags temporal * @name stut * @param {number} times how many times to repeat * @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 - * @tags structure + * @tags temporal * @name plyWith * @synonyms plywith * @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. * This version of ply uses the iteration index as an argument to the function, similar to echoWith. - * @tags structure + * @tags temporal * @name plyForEach * @synonyms plyforeach * @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. - * @tags structure + * @tags temporal * @name iter * @memberof 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 - * @tags structure + * @tags temporal * @name iterBack * @synonyms iterback * @memberof Pattern @@ -2600,7 +2601,7 @@ export const { iterBack, iterback } = register( /** * Repeats each cycle the given number of times. - * @tags structure + * @tags temporal * @name repeatCycles * @memberof 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). - * @tags structure + * @tags temporal * @name chunk * @synonyms slowChunk, slowchunk * @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 - * @tags structure + * @tags temporal * @name chunkBack * @synonyms chunkback * @memberof Pattern @@ -2677,7 +2678,7 @@ export const { chunkBack, chunkback } = register( /** * Like `chunk`, but the cycles of the source pattern aren't repeated * for each set of chunks. - * @tags structure + * @tags temporal * @name fastChunk * @synonyms fastchunk * @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. - * @tags structure + * @tags temporal * @name chunkInto * @synonyms chunkinto * @memberof Pattern @@ -2712,7 +2713,7 @@ export const { chunkinto, chunkInto } = register(['chunkinto', 'chunkInto'], fun /** * Like `chunkInto`, but moves backwards through the chunks. - * @tags structure + * @tags temporal * @name chunkBackInto * @synonyms chunkbackinto * @memberof Pattern @@ -2743,7 +2744,7 @@ export const bypass = register( /** * 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. - * @tags structure + * @tags temporal * @name ribbon * @synonyms rib * @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). * @name tag - * @tags structure + * @tags temporal * @noAutocomplete * @param {string} tag anything unique */ @@ -2783,7 +2784,7 @@ Pattern.prototype.tag = function (tag) { /** * Filters haps using the given function * @name filter - * @tags structure + * @tags temporal * @param {Function} test function to test Hap * @example * 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 * @name filterWhen - * @tags structure + * @tags temporal * @noAutocomplete * @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. * @name within - * @tags structure + * @tags temporal * @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 @@ -2877,7 +2878,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 structure + * @tags temporal * @example * sound("bd sd cp").pace(4) * // The same as sound("{bd sd cp}%4") or sound("*4") @@ -2919,7 +2920,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 structure + * @tags temporal * @synonyms pm * @example * // 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). * 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} * @example * "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. * 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} * @example * "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 * 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 structure + * @tags temporal * @example * stepcat( * sound("bd bd - cp").extend(2), @@ -3126,7 +3127,7 @@ export const extend = stepRegister('extend', function (factor, pat) { * *Experimental* * * Expands the step size of the pattern by the given factor. - * @tags structure + * @tags temporal * @example * 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* * * Contracts the step size of the pattern by the given factor. See also `expand`. - * @tags structure + * @tags temporal * @example * 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 `:`), * 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 structure + * @tags temporal * @return {Pattern} * @example * "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 `:`), * 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 structure + * @tags temporal * @return {Pattern} * @example * "tha dhi thom nam".grow("1").sound() @@ -3552,7 +3553,9 @@ export const { loopAtCps, loopatcps } = register(['loopAtCps', 'loopatcps'], fun 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) => pure(1) .withValue(() => reify(accessor())) @@ -3589,7 +3592,7 @@ Pattern.prototype.xfade = function (pos, b) { * creates a structure pattern from divisions of a cycle * especially useful for creating rhythms * @name beat - * @tags structure + * @tags temporal * @example * s("bd").beat("0,7,10", 16) * @example @@ -3666,7 +3669,7 @@ export const _morph = (from, to, by) => { * sine.slow(8) // slowly morph between the rhythms * ) * ) - * @tags structure + * @tags temporal */ export const morph = (frompat, topat, bypat) => { frompat = reify(frompat); diff --git a/packages/core/pick.mjs b/packages/core/pick.mjs index 206fa619b..cce691905 100644 --- a/packages/core/pick.mjs +++ b/packages/core/pick.mjs @@ -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). * Similar to `inhabit`, but maintains the structure of the original patterns. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -57,6 +58,7 @@ const __pick = register('pick', function (lookup, pat) { * 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 * second one. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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. + * @tags combiners, functional * @param {Pattern} pat * @param {Pattern} lookup a pattern of indices * @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, * it wraps around, rather than sticking at the maximum value. + * @tags combiners * @param {Pattern} pat * @param {Pattern} lookup a pattern of indices * @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. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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, * it wraps around, rather than sticking at the maximum value. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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, * it wraps around, rather than sticking at the maximum value. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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, * it wraps around, rather than sticking at the maximum value. + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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). * Similar to `pick`, but cycles are squeezed into the target ('inhabited') pattern. * @name inhabit + * @tags combiners * @synonyms pickSqueeze * @param {Pattern} pat * @param {*} xs @@ -180,6 +191,7 @@ export const { inhabit, pickSqueeze } = register(['inhabit', 'pickSqueeze'], fun * second one. * @name inhabitmod * @synonyms pickmodSqueeze + * @tags combiners * @param {Pattern} pat * @param {*} xs * @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 * pattern of integers. The selected pattern will be compressed to fit the duration of the selecting event + * @tags combiners * @param {Pattern} pat * @param {*} xs * @returns {Pattern} diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 53562f216..b8bab3d4b 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -102,6 +102,7 @@ export function repl({ * Changes the global tempo to the given cycles per minute * * @name setcpm + * @tags temporal * @alias setCpm * @param {number} cpm cycles per minute * @example @@ -127,6 +128,8 @@ export function repl({ * $: sound("hh*8") * all(x => x.pianoroll()) * ``` + * + * @tags combiners */ let allTransforms = []; const all = function (transform) { @@ -134,11 +137,13 @@ export function repl({ 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. + * * ``` * $: sound("bd - cp sd") * $: sound("hh*8") * each(fast("<2 3>")) * ``` + * @tags combiners */ const each = function (transform) { eachTransform = transform; diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 03dd641a5..2c3a63324 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -337,6 +337,7 @@ export const scramble = register('scramble', (n, pat) => { export const rand = signal(timeToRand); /** * A continuous pattern of random numbers, between -1 and 1 + * @tags generators */ export const rand2 = rand.toBipolar(); diff --git a/packages/csound/index.mjs b/packages/csound/index.mjs index e44765227..e459f3873 100644 --- a/packages/csound/index.mjs +++ b/packages/csound/index.mjs @@ -135,6 +135,8 @@ export async function loadOrc(url) { * 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]. * p6 -- Strudel controls, as a string. + * + * @tags external_io */ export const csoundm = register('csoundm', (instrument, pat) => { let p1 = instrument; diff --git a/packages/draw/pianoroll.mjs b/packages/draw/pianoroll.mjs index 1cf218fa0..6fb1dfc76 100644 --- a/packages/draw/pianoroll.mjs +++ b/packages/draw/pianoroll.mjs @@ -42,6 +42,7 @@ const getValue = (e) => { * * @name pianoroll * @synonyms punchcard + * @tags visualization * @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 {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. * * @name wordfall + * @tags visualization */ Pattern.prototype.wordfall = function (options) { return this.punchcard({ vertical: 1, labels: 1, stroke: 0, fillActive: 1, active: 'white', ...options }); diff --git a/packages/draw/pitchwheel.mjs b/packages/draw/pitchwheel.mjs index ba76df079..f9dacc53f 100644 --- a/packages/draw/pitchwheel.mjs +++ b/packages/draw/pitchwheel.mjs @@ -116,6 +116,7 @@ export function pitchwheel({ /** * Renders a pitch circle to visualize frequencies within one octave * @name pitchwheel + * @tags visualization * @param {number} hapcircles * @param {number} circle * @param {number} edo diff --git a/packages/draw/spiral.mjs b/packages/draw/spiral.mjs index cebf3d374..c18c66c59 100644 --- a/packages/draw/spiral.mjs +++ b/packages/draw/spiral.mjs @@ -129,6 +129,7 @@ function drawSpiral(options) { * Displays a spiral visual. * * @name spiral + * @tags visualization * @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} size the diameter of the spiral diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index ae983d200..bff36c870 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -123,6 +123,7 @@ function githubPath(base, subpath = '') { /** * configures the default midimap, which is used when no "midimap" port is set + * @tags external_io * @example * defaultmidimap({ lpf: 74 }) * $: 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. + * @tags external_io * @example * midimaps({ mymap: { lpf: 74 } }) * $: note("c a f e") @@ -278,6 +280,7 @@ function sendNote(note, velocity, duration, device, midichan, timeOffsetString) /** * MIDI output: Opens a MIDI output port. + * @tags external_io * @param {string | number} midiport MIDI device name or index defaulting to 0 * @param {object} options Additional MIDI configuration options * @example @@ -465,6 +468,7 @@ const refs = {}; /** * 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 * @returns {Function} * @example diff --git a/packages/osc/osc.mjs b/packages/osc/osc.mjs index fe0691522..1358ad2db 100644 --- a/packages/osc/osc.mjs +++ b/packages/osc/osc.mjs @@ -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/) * * @name osc + * @tags external_io * @memberof Pattern * @returns Pattern */ diff --git a/packages/superdough/ola-processor.js b/packages/superdough/ola-processor.js index 38d45a25d..0000d1bbb 100644 --- a/packages/superdough/ola-processor.js +++ b/packages/superdough/ola-processor.js @@ -35,7 +35,9 @@ class OLAProcessor extends AudioWorkletProcessor { } /** 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) { for (let i = 0; i < this.nbInputs; i++) { 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) { // when playback is paused, we may stop receiving new samples 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) { for (let i = 0; i < this.nbInputs; i++) { 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() { for (let i = 0; i < this.nbInputs; i++) { 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() { for (let i = 0; i < this.nbOutputs; i++) { 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() { for (let i = 0; i < this.nbInputs; i++) { 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() { for (let i = 0; i < this.nbOutputs; i++) { for (let j = 0; j < this.outputBuffers[i].length; j++) { diff --git a/packages/superdough/reverbGen.mjs b/packages/superdough/reverbGen.mjs index 42da7c6d5..c52188b08 100644 --- a/packages/superdough/reverbGen.mjs +++ b/packages/superdough/reverbGen.mjs @@ -16,6 +16,7 @@ var reverbGen = {}; /** Generates a reverb impulse response. + @tags internals @param {!Object} params TODO: Document the properties. @param {!function(!AudioBuffer)} callback Function to call when 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. - + @tags internals @param {!Float32Array} data An array of numbers, or a Float32Array. @param {number} width Width 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 {!function(!AudioBuffer)} callback May be called immediately within the current execution context, or later. - @tags effects + @tags internals */ var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, callback) { if (lpFreqStart == 0) { diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index b195ba79c..69a949ad1 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -221,6 +221,7 @@ export async function fetchSampleMap(url) { /** * Loads a collection of samples to use with `s` + * @tags samples * @example * samples('github:tidalcycles/dirt-samples'); * s("[bd ~]*2, [~ hh]*2, ~ sd") diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 52ed9bff8..873fdfa5d 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -91,6 +91,8 @@ async function aliasBankPath(path) { * 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} alias - The alias to use for the bank + * + * @tags samples */ export async function aliasBank(...args) { switch (args.length) { @@ -109,6 +111,7 @@ export async function aliasBank(...args) { /** * Register an alias for a sound. + * @tags samples * @param {string} original - The original sound name * @param {string} alias - The alias to use for the sound */ diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 44367f786..cfc669c83 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -180,6 +180,7 @@ export function registerWaveTable(key, tables, params) { * Loads a collection of wavetables to use with `s` * * @name tables + * @tags effects */ export const tables = async (url, frameLen, json, options = {}) => { if (json !== undefined) return _processTables(json, url, frameLen); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index ccfaf5107..3e8276225 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -635,14 +635,18 @@ class PhaseVocoderProcessor extends OLAProcessor { this.timeCursor += this.hopSize; } - /** Apply Hann window in-place */ + /** Apply Hann window in-place + * @tags internals + */ applyHannWindow(input) { for (var i = 0; i < this.blockSize; i++) { input[i] = input[i] * this.hannWindow[i] * 1.62; } } - /** Compute squared magnitudes for peak finding **/ + /** Compute squared magnitudes for peak finding + * @tags internals + **/ computeMagnitudes() { var i = 0, j = 0; @@ -656,7 +660,9 @@ class PhaseVocoderProcessor extends OLAProcessor { } } - /** Find peaks in spectrum magnitudes **/ + /** Find peaks in spectrum magnitudes + * @tags internals + **/ findPeaks() { this.nbPeaks = 0; 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) { // zero-fill new spectrum this.freqComplexBufferShifted.fill(0); @@ -843,7 +851,9 @@ class PulseOscillatorProcessor extends AudioWorkletProcessor { registerProcessor('pulse-oscillator', PulseOscillatorProcessor); -/** BYTE BEATS */ +/** BYTE BEATS + * @tags internals + */ const chyx = { /*bit*/ bitC: function (x, y, z) { return x & y ? z : 0; diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index ae75ab690..613ba51e0 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -92,6 +92,7 @@ function scaleOffset(scale, offset, note) { * - 5P = perfect fifth * - 5d = diminished fifth * + * @tags music_theory * @param {string | number} amount Either number of semitones or interval string. * @returns Pattern * @memberof Pattern @@ -146,6 +147,7 @@ export const { transpose, trans } = register(['transpose', 'trans'], function tr * * @memberof Pattern * @name scaleTranspose + * @tags music_theory * @param {offset} offset number of steps inside the scale * @returns Pattern * @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. * * @name scale + * @tags music_theory * @param {string} scale Name of scale * @returns Pattern * @example diff --git a/packages/tonal/voicings.mjs b/packages/tonal/voicings.mjs index d81911e01..6dce6ca8b 100644 --- a/packages/tonal/voicings.mjs +++ b/packages/tonal/voicings.mjs @@ -90,6 +90,7 @@ export const setVoicingRange = (name, range) => addVoicings(name, voicingRegistr * Adds a new custom voicing dictionary. * * @name addVoicings + * @tags music_theory * @memberof Pattern * @param {string} name identifier for the voicing dictionary * @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). * * @name voicings + * @tags music_theory * @memberof Pattern * @param {string} dictionary which voicing dictionary to use. * @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. * * @name rootNotes + * @tags music_theory * @memberof Pattern * @param {octave} octave octave to use * @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. * * @name voicing + * @tags music_theory * @returns Pattern * @example * n("0 1 2 3").chord("").voicing() diff --git a/packages/webaudio/scope.mjs b/packages/webaudio/scope.mjs index e423b20fc..866e0a435 100644 --- a/packages/webaudio/scope.mjs +++ b/packages/webaudio/scope.mjs @@ -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. * @name fscope + * @tags visualization * @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} 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. * @name scope * @synonyms tscope + * @tags visualization * @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 {string} color line color as hex or color name. defaults to white. diff --git a/packages/webaudio/spectrum.mjs b/packages/webaudio/spectrum.mjs index 2ddd214fa..c67e321b5 100644 --- a/packages/webaudio/spectrum.mjs +++ b/packages/webaudio/spectrum.mjs @@ -5,6 +5,7 @@ import { analysers, getAnalyzerData } from 'superdough'; /** * Renders a spectrum analyzer for the incoming audio signal. * @name spectrum + * @tags visualization * @param {object} config optional config with options: * @param {integer} thickness line thickness in px (default 3) * @param {integer} speed scroll speed (default 1) From ee1a894f3ba2dc468fbf6510afc50c3a7387e2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 12 Oct 2025 16:28:05 +0200 Subject: [PATCH 08/26] Show tags in reference, more compact functions list --- .../src/repl/components/panel/Reference.jsx | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 3faa5c6f1..d1157ba26 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -11,6 +11,7 @@ const availableFunctions = (() => { for (const doc of jsdocJson.docs) { if (!isValid(doc)) continue; if (seen.has(doc.name)) continue; + doc.tags = doc.tags?.filter((t) => t && typeof t === 'string') || []; functions.push(doc); const synonyms = doc.synonyms || []; seen.add(doc.name); @@ -113,7 +114,7 @@ export function Reference() { return (
-
+
@@ -134,19 +135,21 @@ export function Reference() { ))}
- @@ -161,8 +164,17 @@ export function Reference() { that you can already make music with a small set of functions!

{visibleFunctions.map((entry, i) => ( -
-

{entry.name}

+
+
+

+ {entry.name} +

+ {entry.tags && ( + + {entry.tags.join(', ')} + + )} +
{!!entry.synonyms_text && (

Synonyms: {entry.synonyms_text} From a4212589e5e0a2d3d6e9a31bf196f30e557b24e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 12 Oct 2025 16:33:07 +0200 Subject: [PATCH 09/26] Recategorize --- packages/core/controls.mjs | 36 ++++++++++++++-------------- packages/core/pattern.mjs | 20 ++++++++-------- packages/core/signal.mjs | 48 +++++++++++++++++++------------------- 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 4e60fc487..db689e1a2 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1621,7 +1621,7 @@ export const { fadeInTime } = registerControl('fadeInTime'); * Set frequency of sound. * * @name freq - * @tags transforms + * @tags temporal * @param {number | Pattern} frequency in Hz. the audible range is between 20 and 20000 Hz * @example * freq("220 110 440 110").s("superzow").osc() @@ -2205,7 +2205,7 @@ export const { cps } = registerControl('cps'); * Multiplies the duration with the given number. Also cuts samples off at the end if they exceed the duration. * * @name clip - * @tags transforms + * @tags temporal * @synonyms legato * @param {number | Pattern} factor >= 0 * @example @@ -2218,7 +2218,7 @@ export const { clip, legato } = registerControl('clip', 'legato'); * Sets the duration of the event in cycles. Similar to clip / legato, it also cuts samples off at the end if they exceed the duration. * * @name duration - * @tags transforms + * @tags temporal * @synonyms dur * @param {number | Pattern} seconds >= 0 * @example @@ -2297,7 +2297,7 @@ export const ar = register('ar', (t, pat) => { * MIDI channel: Sets the MIDI channel for the event. * * @name midichan - * @tags examples + * @tags external_io * @param {number | Pattern} channel MIDI channel number (0-15) * @example * note("c4").midichan(1).midi() @@ -2310,7 +2310,7 @@ export const { midimap } = registerControl('midimap'); * MIDI port: Sets the MIDI port for the event. * * @name midiport - * @tags examples + * @tags external_io * @param {number | Pattern} port MIDI port * @example * note("c a f e").midiport("<0 1 2 3>").midi() @@ -2321,7 +2321,7 @@ export const { midiport } = registerControl('midiport'); * MIDI command: Sends a MIDI command message. * * @name midicmd - * @tags examples + * @tags external_io * @param {number | Pattern} command MIDI command * @example * midicmd("clock*48,/2").midi() @@ -2332,7 +2332,7 @@ export const { midicmd } = registerControl('midicmd'); * MIDI control: Sends a MIDI control change message. * * @name control - * @tags examples + * @tags external_io * @param {number | Pattern} MIDI control number (0-127) * @param {number | Pattern} MIDI controller value (0-127) */ @@ -2348,7 +2348,7 @@ export const control = register('control', (args, pat) => { * MIDI control number: Sends a MIDI control change message. * * @name ccn - * @tags examples + * @tags external_io * @param {number | Pattern} MIDI control number (0-127) */ export const { ccn } = registerControl('ccn'); @@ -2356,7 +2356,7 @@ export const { ccn } = registerControl('ccn'); * MIDI control value: Sends a MIDI control change message. * * @name ccv - * @tags examples + * @tags external_io * @param {number | Pattern} MIDI control value (0-127) */ export const { ccv } = registerControl('ccv'); @@ -2366,7 +2366,7 @@ export const { ctlNum } = registerControl('ctlNum'); /** * MIDI NRPN non-registered parameter number: Sends a MIDI NRPN non-registered parameter number message. * @name nrpnn - * @tags examples + * @tags external_io * @param {number | Pattern} nrpnn MIDI NRPN non-registered parameter number (0-127) * @example * note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi() @@ -2375,7 +2375,7 @@ export const { nrpnn } = registerControl('nrpnn'); /** * MIDI NRPN non-registered parameter value: Sends a MIDI NRPN non-registered parameter value message. * @name nrpv - * @tags examples + * @tags external_io * @param {number | Pattern} nrpv MIDI NRPN non-registered parameter value (0-127) * @example * note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi() @@ -2386,7 +2386,7 @@ export const { nrpv } = registerControl('nrpv'); * MIDI program number: Sends a MIDI program change message. * * @name progNum - * @tags examples + * @tags external_io * @param {number | Pattern} program MIDI program number (0-127) * @example * note("c4").progNum(10).midichan(1).midi() @@ -2396,7 +2396,7 @@ export const { progNum } = registerControl('progNum'); /** * MIDI sysex: Sends a MIDI sysex message. * @name sysex - * @tags examples + * @tags external_io * @param {number | Pattern} id Sysex ID * @param {number | Pattern} data Sysex data * @example @@ -2412,7 +2412,7 @@ export const sysex = register('sysex', (args, pat) => { /** * MIDI sysex ID: Sends a MIDI sysex identifier message. * @name sysexid - * @tags examples + * @tags external_io * @param {number | Pattern} id Sysex ID * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2421,7 +2421,7 @@ export const { sysexid } = registerControl('sysexid'); /** * MIDI sysex data: Sends a MIDI sysex message. * @name sysexdata - * @tags examples + * @tags external_io * @param {number | Pattern} data Sysex data * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2431,7 +2431,7 @@ export const { sysexdata } = registerControl('sysexdata'); /** * MIDI pitch bend: Sends a MIDI pitch bend message. * @name midibend - * @tags examples + * @tags external_io * @param {number | Pattern} midibend MIDI pitch bend (-1 - 1) * @example * note("c4").midibend(sine.slow(4).range(-0.4,0.4)).midi() @@ -2440,7 +2440,7 @@ export const { midibend } = registerControl('midibend'); /** * MIDI key after touch: Sends a MIDI key after touch message. * @name miditouch - * @tags examples + * @tags external_io * @param {number | Pattern} miditouch MIDI key after touch (0-1) * @example * note("c4").miditouch(sine.slow(4).range(0,1)).midi() @@ -2461,7 +2461,7 @@ export const getControlName = (alias) => { * Sets properties in a batch. * * @name as - * @tags transforms + * @tags temporal * @param {String | Array} mapping the control names that are set * @example * "c:.5 a:1 f:.25 e:.8".as("note:clip") diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 2d6459a89..4a0dbe58f 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -978,7 +978,7 @@ Pattern.prototype.collect = function () { /** * Selects indices in in stacked notes. - * @tags transforms + * @tags temporal * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arpWith(haps => haps[2]) @@ -993,7 +993,7 @@ export const arpWith = register('arpWith', (func, pat) => { /** * Selects indices in in stacked notes. - * @tags transforms + * @tags temporal * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arp("0 [0,2] 1 [0,2]") @@ -1342,7 +1342,7 @@ export function reify(thing) { /** * Takes a list of patterns, and returns a pattern of lists. * - * @tags transforms + * @tags temporal */ export function sequenceP(pats) { let result = pure([]); @@ -3354,7 +3354,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 transforms + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3385,7 +3385,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 transforms + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3404,7 +3404,7 @@ export const striate = register('striate', function (n, pat) { /** * Makes the sample fit the given number of cycles by changing the speed. * @name loopAt - * @tags transforms + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3423,7 +3423,7 @@ const _loopAt = function (factor, pat, cps = 0.5) { * 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 transforms + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3477,7 +3477,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 transforms + * @tags temporal * @example * samples('github:tidalcycles/dirt-samples') * s("breaks165") @@ -3515,7 +3515,7 @@ export const { loopAt, loopat } = register(['loopAt', 'loopat'], function (facto * Makes the sample fit its event duration. Good for rhythmical loops like drum breaks. * Similar to `loopAt`. * @name fit - * @tags transforms + * @tags temporal * @example * samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' }) * s("rhodes/2").fit() @@ -3541,7 +3541,7 @@ export const fit = register('fit', (pat) => * given by a global clock and this function will be * deprecated/removed. * @name loopAtCps - * @tags transforms + * @tags temporal * @memberof Pattern * @returns Pattern * @example diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 2c3a63324..ce17fdeae 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -300,7 +300,7 @@ const _rearrangeWith = (ipat, n, pat) => { * Slices a pattern into the given number of parts, then plays those parts in random order. * Each part will be played exactly once per cycle. * @name shuffle - * @tags transforms + * @tags temporal * @example * note("c d e f").sound("piano").shuffle(4) * @example @@ -314,7 +314,7 @@ export const shuffle = register('shuffle', (n, pat) => { * Slices a pattern into the given number of parts, then plays those parts at random. Similar to `shuffle`, * but parts might be played more than once, or not at all, per cycle. * @name scramble - * @tags transforms + * @tags temporal * @example * note("c d e f").sound("piano").scramble(4) * @example @@ -393,7 +393,7 @@ export const __chooseWith = (pat, xs) => { /** * Choose from the list of values (or patterns of values) using the given * pattern of numbers, which should be in the range of 0..1 - * @tags transforms + * @tags temporal * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -407,7 +407,7 @@ export const chooseWith = (pat, xs) => { /** * As with {chooseWith}, but the structure comes from the chosen values, rather * than the pattern you're using to choose with. - * @tags transforms + * @tags temporal * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -418,7 +418,7 @@ export const chooseInWith = (pat, xs) => { /** * Chooses randomly from the given list of elements. - * @tags transforms + * @tags temporal * @param {...any} xs values / patterns to choose from. * @returns {Pattern} - a continuous pattern. * @example @@ -434,7 +434,7 @@ export const chooseOut = choose; * Chooses from the given list of values (or patterns of values), according * to the pattern that the method is called on. The pattern should be in * the range 0 .. 1. - * @tags transforms + * @tags temporal * @param {...any} xs * @returns {Pattern} */ @@ -445,7 +445,7 @@ Pattern.prototype.choose = function (...xs) { /** * As with choose, but the pattern that this method is called on should be * in the range -1 .. 1 - * @tags transforms + * @tags temporal * @param {...any} xs * @returns {Pattern} */ @@ -455,7 +455,7 @@ Pattern.prototype.choose2 = function (...xs) { /** * Picks one of the elements at random each cycle. - * @tags transforms + * @tags temporal * @synonyms randcat * @returns {Pattern} * @example @@ -498,7 +498,7 @@ const wchooseWith = (...args) => _wchooseWith(...args).outerJoin(); /** * Chooses randomly from the given list of elements by giving a probability to each element - * @tags transforms + * @tags temporal * @param {...any} pairs arrays of value and weight * @returns {Pattern} - a continuous pattern. * @example @@ -508,7 +508,7 @@ export const wchoose = (...pairs) => wchooseWith(rand, ...pairs); /** * Picks one of the elements at random each cycle by giving a probability to each element - * @tags transforms + * @tags temporal * @synonyms wrandcat * @returns {Pattern} * @example @@ -590,7 +590,7 @@ export const degradeByWith = register( * 0 = 0% chance of removal * 1 = 100% chance of removal * - * @tags transforms + * @tags temporal * @name degradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -616,7 +616,7 @@ export const degradeBy = register( * * Randomly removes 50% of events from the pattern. Shorthand for `.degradeBy(0.5)` * - * @tags transforms + * @tags temporal * @name degrade * @memberof Pattern * @returns Pattern @@ -633,7 +633,7 @@ export const degrade = register('degrade', (pat) => pat._degradeBy(0.5), true, t * 1 = 0% chance of removal * Events that would be removed by degradeBy are let through by undegradeBy and vice versa (see second example). * - * @tags transforms + * @tags temporal * @name undegradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -662,7 +662,7 @@ export const undegradeBy = register( * Inverse of `degrade`: Randomly removes 50% of events from the pattern. Shorthand for `.undegradeBy(0.5)` * Events that would be removed by degrade are let through by undegrade and vice versa (see second example). * - * @tags transforms + * @tags temporal * @name undegrade * @memberof Pattern * @returns Pattern @@ -681,7 +681,7 @@ export const undegrade = register('undegrade', (pat) => pat._undegradeBy(0.5), t * Randomly applies the given function by the given probability. * Similar to `someCyclesBy` * - * @tags transforms + * @tags temporal * @name sometimesBy * @memberof Pattern * @param {number | Pattern} probability - a number between 0 and 1 @@ -701,7 +701,7 @@ export const sometimesBy = register('sometimesBy', function (patx, func, pat) { * * Applies the given function with a 50% chance * - * @tags transforms + * @tags temporal * @name sometimes * @memberof Pattern * @param {function} function - the transformation to apply @@ -723,7 +723,7 @@ export const sometimes = register('sometimes', function (func, pat) { * @param {number | Pattern} probability - a number between 0 and 1 * @param {function} function - the transformation to apply * @returns Pattern - * @tags transforms + * @tags temporal * @example * s("bd,hh*8").someCyclesBy(.3, x=>x.speed("0.5")) */ @@ -746,7 +746,7 @@ export const someCyclesBy = register('someCyclesBy', function (patx, func, pat) * @name someCycles * @memberof Pattern * @returns Pattern - * @tags transforms + * @tags temporal * @example * s("bd,hh*8").someCycles(x=>x.speed("0.5")) */ @@ -761,7 +761,7 @@ export const someCycles = register('someCycles', function (func, pat) { * @name often * @memberof Pattern * @returns Pattern - * @tags transforms + * @tags temporal * @example * s("hh*8").often(x=>x.speed("0.5")) */ @@ -776,7 +776,7 @@ export const often = register('often', function (func, pat) { * @name rarely * @memberof Pattern * @returns Pattern - * @tags transforms + * @tags temporal * @example * s("hh*8").rarely(x=>x.speed("0.5")) */ @@ -788,7 +788,7 @@ export const rarely = register('rarely', function (func, pat) { * * Shorthand for `.sometimesBy(0.1, fn)` * - * @tags transforms + * @tags temporal * @name almostNever * @memberof Pattern * @returns Pattern @@ -803,7 +803,7 @@ export const almostNever = register('almostNever', function (func, pat) { * * Shorthand for `.sometimesBy(0.9, fn)` * - * @tags transforms + * @tags temporal * @name almostAlways * @memberof Pattern * @returns Pattern @@ -818,7 +818,7 @@ export const almostAlways = register('almostAlways', function (func, pat) { * * Shorthand for `.sometimesBy(0, fn)` (never calls fn) * - * @tags transforms + * @tags temporal * @name never * @memberof Pattern * @returns Pattern @@ -833,7 +833,7 @@ export const never = register('never', function (_, pat) { * * Shorthand for `.sometimesBy(1, fn)` (always calls fn) * - * @tags transforms + * @tags temporal * @name always * @memberof Pattern * @returns Pattern From b952e4c735a9f77592824e5542a6e3e93e9530aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 19 Oct 2025 20:54:22 +0200 Subject: [PATCH 10/26] Add superdough tags --- packages/core/controls.mjs | 132 ++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index db689e1a2..2add9e416 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -351,7 +351,7 @@ export const { warpsync } = registerControl('warpsync'); * Define a custom webaudio node to use as a sound source. * * @name source - * @tags external_io + * @tags external_io, superdough * @synonyms src * @param {function} getSource * @synonyms src @@ -411,7 +411,7 @@ export const { accelerate } = registerControl('accelerate'); * Sets the velocity from 0 to 1. Is multiplied together with gain. * * @name velocity - * @tags effects + * @tags effects, superdough * @example * s("hh*8") * .gain(".4!2 1 .4!2 1 .4 1") @@ -422,7 +422,7 @@ export const { velocity } = registerControl('velocity'); * Controls the gain by an exponential amount. * * @name gain - * @tags effects + * @tags effects, superdough * @param {number | Pattern} amount gain. * @example * s("hh*8").gain(".4!2 1 .4!2 1 .4 1").fast(2) @@ -433,7 +433,7 @@ export const { gain } = registerControl('gain'); * Gain applied after all effects have been processed. * * @name postgain - * @tags effects + * @tags effects, superdough * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02").postgain(1.5) @@ -581,7 +581,7 @@ export const { fmvelocity } = registerControl('fmvelocity'); * Select the sound bank to use. To be used together with `s`. The bank name (+ "_") will be prepended to the value of `s`. * * @name bank - * @tags samples + * @tags samples, superdough * @param {string | Pattern} bank the name of the bank * @example * s("bd sd [~ bd] sd").bank('RolandTR909') // = s("RolandTR909_bd RolandTR909_sd") @@ -635,7 +635,7 @@ export const { sustain, sus } = registerControl('sustain', 'sus'); * Amplitude envelope release time: The time it takes after the offset to go from sustain level to zero. * * @name release - * @tags effects + * @tags effects, superdough * @param {number | Pattern} time release time in seconds * @synonyms rel * @example @@ -650,7 +650,7 @@ export const { hold } = registerControl('hold'); * can also optionally supply the 'bpq' parameter separated by ':'. * * @name bpf - * @tags effects + * @tags effects, superdough * @param {number | Pattern} frequency center frequency * @synonyms bandf, bp * @example @@ -663,7 +663,7 @@ export const { bandf, bpf, bp } = registerControl(['bandf', 'bandq', 'bpenv'], ' * Sets the **b**and-**p**ass **q**-factor (resonance). * * @name bpq - * @tags effects + * @tags effects, superdough * @param {number | Pattern} q q factor * @synonyms bandq * @example @@ -743,7 +743,7 @@ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); * Bit crusher effect. * * @name crush - * @tags effects + * @tags effects, superdough * @param {number | Pattern} depth between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction). * @example * s(",hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>") @@ -755,7 +755,7 @@ export const { crush } = registerControl('crush'); * Fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers * * @name coarse - * @tags effects + * @tags effects, superdough * @param {number | Pattern} factor 1 for original 2 for half, 3 for a third and so on. * @example * s("bd sd [~ bd] sd,hh*8").coarse("<1 4 8 16 32>") @@ -767,7 +767,7 @@ export const { coarse } = registerControl('coarse'); * Modulate the amplitude of a sound with a continuous waveform * * @name tremolo - * @tags effects + * @tags effects, superdough * @synonyms trem * @param {number | Pattern} speed modulation speed in HZ * @example @@ -780,7 +780,7 @@ export const { tremolo } = registerControl(['tremolo', 'tremolodepth', 'tremolos * Modulate the amplitude of a sound with a continuous waveform * * @name tremolosync - * @tags effects + * @tags effects, superdough * @synonyms tremsync * @param {number | Pattern} cycles modulation speed in cycles * @example @@ -796,7 +796,7 @@ export const { tremolosync } = registerControl( * Depth of amplitude modulation * * @name tremolodepth - * @tags effects + * @tags effects, superdough * @synonyms tremdepth * @param {number | Pattern} depth * @example @@ -808,7 +808,7 @@ export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth'); * Alter the shape of the modulation waveform * * @name tremoloskew - * @tags effects + * @tags effects, superdough * @synonyms tremskew * @param {number | Pattern} amount between 0 & 1, the shape of the waveform * @example @@ -821,7 +821,7 @@ export const { tremoloskew } = registerControl('tremoloskew', 'tremskew'); * Alter the phase of the modulation waveform * * @name tremolophase - * @tags effects + * @tags effects, superdough * @synonyms tremphase * @param {number | Pattern} offset the offset in cycles of the modulation * @example @@ -834,7 +834,7 @@ export const { tremolophase } = registerControl('tremolophase', 'tremphase'); * Shape of amplitude modulation * * @name tremoloshape - * @tags effects + * @tags effects, superdough * @synonyms tremshape * @param {number | Pattern} shape tri | square | sine | saw | ramp * @example @@ -846,7 +846,7 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); * Filter overdrive for supported filter types * * @name drive - * @tags effects + * @tags effects, superdough * @param {number | Pattern} amount * @example * note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>") @@ -860,7 +860,7 @@ export const { drive } = registerControl('drive'); * Can be applied to multiple orbits with the ':' mininotation, e.g. `duckorbit("2:3")` * * @name duckorbit - * @tags effects + * @tags effects, superdough * @synonyms duck * @param {number | Pattern} orbit target orbit * @example @@ -881,7 +881,7 @@ export const { duck } = registerControl('duckorbit', 'duck'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckdepth - * @tags effects + * @tags effects, superdough * @param {number | Pattern} depth depth of modulation from 0 to 1 * @example * stack( n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2), s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack(0.2).duckdepth("<1 .9 .6 0>")) @@ -901,7 +901,7 @@ export const { duckdepth } = registerControl('duckdepth'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckonset - * @tags effects + * @tags effects, superdough * @synonyms duckons * * @param {number | Pattern} time The onset time in seconds @@ -929,7 +929,7 @@ export const { duckonset } = registerControl('duckonset', 'duckons'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckattack - * @tags effects + * @tags effects, superdough * @synonyms duckatt * * @param {number | Pattern} time The attack time in seconds @@ -1028,7 +1028,7 @@ export const { pwsweep } = registerControl('pwsweep'); * Phaser audio effect that approximates popular guitar pedals. * * @name phaser - * @tags effects + * @tags effects, superdough * @synonyms ph * @param {number | Pattern} speed speed of modulation * @example @@ -1046,7 +1046,7 @@ export const { phaserrate, ph, phaser } = registerControl( * The frequency sweep range of the lfo for the phaser effect. Defaults to 2000 * * @name phasersweep - * @tags effects + * @tags effects, superdough * @synonyms phs * @param {number | Pattern} phasersweep most useful values are between 0 and 4000 * @example @@ -1060,7 +1060,7 @@ export const { phasersweep, phs } = registerControl('phasersweep', 'phs'); * The center frequency of the phaser in HZ. Defaults to 1000 * * @name phasercenter - * @tags effects + * @tags effects, superdough * @synonyms phc * @param {number | Pattern} centerfrequency in HZ * @example @@ -1075,7 +1075,7 @@ export const { phasercenter, phc } = registerControl('phasercenter', 'phc'); * The amount the signal is affected by the phaser effect. Defaults to 0.75 * * @name phaserdepth - * @tags effects + * @tags effects, superdough * @synonyms phd, phasdp * @param {number | Pattern} depth number between 0 and 1 * @example @@ -1112,7 +1112,7 @@ export const { cut } = registerControl('cut'); * When using mininotation, you can also optionally add the 'lpq' parameter, separated by ':'. * * @name lpf - * @tags effects + * @tags effects, superdough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms cutoff, ctf, lp * @example @@ -1126,7 +1126,7 @@ export const { cutoff, ctf, lpf, lp } = registerControl(['cutoff', 'resonance', /** * Sets the lowpass filter envelope modulation depth. * @name lpenv - * @tags effects + * @tags effects, superdough * @param {number | Pattern} modulation depth of the lowpass filter envelope between 0 and _n_ * @synonyms lpe * @example @@ -1140,7 +1140,7 @@ export const { lpenv, lpe } = registerControl('lpenv', 'lpe'); /** * Sets the highpass filter envelope modulation depth. * @name hpenv - * @tags effects + * @tags effects, superdough * @param {number | Pattern} modulation depth of the highpass filter envelope between 0 and _n_ * @synonyms hpe * @example @@ -1154,7 +1154,7 @@ export const { hpenv, hpe } = registerControl('hpenv', 'hpe'); /** * Sets the bandpass filter envelope modulation depth. * @name bpenv - * @tags effects + * @tags effects, superdough * @param {number | Pattern} modulation depth of the bandpass filter envelope between 0 and _n_ * @synonyms bpe * @example @@ -1168,7 +1168,7 @@ export const { bpenv, bpe } = registerControl('bpenv', 'bpe'); /** * Sets the attack duration for the lowpass filter envelope. * @name lpattack - * @tags effects + * @tags effects, superdough * @param {number | Pattern} attack time of the filter envelope * @synonyms lpa * @example @@ -1182,7 +1182,7 @@ export const { lpattack, lpa } = registerControl('lpattack', 'lpa'); /** * Sets the attack duration for the highpass filter envelope. * @name hpattack - * @tags effects + * @tags effects, superdough * @param {number | Pattern} attack time of the highpass filter envelope * @synonyms hpa * @example @@ -1196,7 +1196,7 @@ export const { hpattack, hpa } = registerControl('hpattack', 'hpa'); /** * Sets the attack duration for the bandpass filter envelope. * @name bpattack - * @tags effects + * @tags effects, superdough * @param {number | Pattern} attack time of the bandpass filter envelope * @synonyms bpa * @example @@ -1210,7 +1210,7 @@ export const { bpattack, bpa } = registerControl('bpattack', 'bpa'); /** * Sets the decay duration for the lowpass filter envelope. * @name lpdecay - * @tags effects + * @tags effects, superdough * @param {number | Pattern} decay time of the filter envelope * @synonyms lpd * @example @@ -1224,7 +1224,7 @@ export const { lpdecay, lpd } = registerControl('lpdecay', 'lpd'); /** * Sets the decay duration for the highpass filter envelope. * @name hpdecay - * @tags effects + * @tags effects, superdough * @param {number | Pattern} decay time of the highpass filter envelope * @synonyms hpd * @example @@ -1239,7 +1239,7 @@ export const { hpdecay, hpd } = registerControl('hpdecay', 'hpd'); /** * Sets the decay duration for the bandpass filter envelope. * @name bpdecay - * @tags effects + * @tags effects, superdough * @param {number | Pattern} decay time of the bandpass filter envelope * @synonyms bpd * @example @@ -1254,7 +1254,7 @@ export const { bpdecay, bpd } = registerControl('bpdecay', 'bpd'); /** * Sets the sustain amplitude for the lowpass filter envelope. * @name lpsustain - * @tags effects + * @tags effects, superdough * @param {number | Pattern} sustain amplitude of the lowpass filter envelope * @synonyms lps * @example @@ -1269,7 +1269,7 @@ export const { lpsustain, lps } = registerControl('lpsustain', 'lps'); /** * Sets the sustain amplitude for the highpass filter envelope. * @name hpsustain - * @tags effects + * @tags effects, superdough * @param {number | Pattern} sustain amplitude of the highpass filter envelope * @synonyms hps * @example @@ -1284,7 +1284,7 @@ export const { hpsustain, hps } = registerControl('hpsustain', 'hps'); /** * Sets the sustain amplitude for the bandpass filter envelope. * @name bpsustain - * @tags effects + * @tags effects, superdough * @param {number | Pattern} sustain amplitude of the bandpass filter envelope * @synonyms bps * @example @@ -1299,7 +1299,7 @@ export const { bpsustain, bps } = registerControl('bpsustain', 'bps'); /** * Sets the release time for the lowpass filter envelope. * @name lprelease - * @tags effects + * @tags effects, superdough * @param {number | Pattern} release time of the filter envelope * @synonyms lpr * @example @@ -1315,7 +1315,7 @@ export const { lprelease, lpr } = registerControl('lprelease', 'lpr'); /** * Sets the release time for the highpass filter envelope. * @name hprelease - * @tags effects + * @tags effects, superdough * @param {number | Pattern} release time of the highpass filter envelope * @synonyms hpr * @example @@ -1331,7 +1331,7 @@ export const { hprelease, hpr } = registerControl('hprelease', 'hpr'); /** * Sets the release time for the bandpass filter envelope. * @name bprelease - * @tags effects + * @tags effects, superdough * @param {number | Pattern} release time of the bandpass filter envelope * @synonyms bpr * @example @@ -1363,7 +1363,7 @@ export const { ftype } = registerControl('ftype'); /** * controls the center of the filter envelope. 0 is unipolar positive, .5 is bipolar, 1 is unipolar negative * @name fanchor - * @tags effects + * @tags effects, superdough * @param {number | Pattern} center 0 to 1 * @example * note("{f g g c d a a#}%8").s("sawtooth").lpf("{1000}%2") @@ -1376,7 +1376,7 @@ export const { fanchor } = registerControl('fanchor'); * When using mininotation, you can also optionally add the 'hpq' parameter, separated by ':'. * * @name hpf - * @tags effects + * @tags effects, superdough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms hp, hcutoff * @example @@ -1438,7 +1438,7 @@ export const { hcutoff, hpf, hp } = registerControl(['hcutoff', 'hresonance', 'h * Controls the **h**igh-**p**ass **q**-value. * * @name hpq - * @tags effects + * @tags effects, superdough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms hresonance * @example @@ -1450,7 +1450,7 @@ export const { hresonance, hpq } = registerControl('hresonance', 'hpq'); * Controls the **l**ow-**p**ass **q**-value. * * @name lpq - * @tags effects + * @tags effects, superdough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms resonance * @example @@ -1463,7 +1463,7 @@ export const { resonance, lpq } = registerControl('resonance', 'lpq'); * DJ filter, below 0.5 is low pass filter, above is high pass filter. * * @name djf - * @tags effects + * @tags effects, superdough * @param {number | Pattern} cutoff below 0.5 is low pass filter, above is high pass filter * @example * n(irand(16).seg(8)).scale("d:phrygian").s("supersaw").djf("<.5 .3 .2 .75>") @@ -1480,7 +1480,7 @@ export const { djf } = registerControl('djf'); * * * @name delay - * @tags effects + * @tags effects, superdough * @param {number | Pattern} level between 0 and 1 * @example * s("bd bd").delay("<0 .25 .5 1>") @@ -1494,7 +1494,7 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @tags effects + * @tags effects, superdough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1508,7 +1508,7 @@ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @tags effects + * @tags effects, superdough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1533,7 +1533,7 @@ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', * Sets the time of the delay effect in cycles. * * @name delaysync - * @tags effects + * @tags effects, superdough * @param {number | Pattern} cycles delay length in cycles * @synonyms delayt, dt * @example @@ -1595,7 +1595,7 @@ export const { spread } = registerControl('spread'); * Set dryness of reverb. See `room` and `size` for more information about reverb. * * @name dry - * @tags effects + * @tags effects, superdough * @param {number | Pattern} dry 0 = wet, 1 = dry * @example * n("[0,3,7](3,8)").s("superpiano").room(.7).dry("<0 .5 .75 1>").osc() @@ -1814,7 +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. * * @name orbit - * @tags effects + * @tags effects, superdough * @param {number | Pattern} number * @example * stack( @@ -1831,7 +1831,7 @@ export const { overshape } = registerControl('overshape'); * Sets position in stereo. * * @name pan - * @tags effects + * @tags effects, superdough * @param {number | Pattern} pan between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel) * @example * s("[bd hh]*2").pan("<.5 1 .5 0>") @@ -1897,7 +1897,7 @@ export const { mode } = registerControl(['mode', 'anchor']); * When using mininotation, you can also optionally add the 'size' parameter, separated by ':'. * * @name room - * @tags effects + * @tags effects, superdough * @param {number | Pattern} level between 0 and 1 * @example * s("bd sd [~ bd] sd").room("<0 .2 .4 .6 .8 1>") @@ -1911,7 +1911,7 @@ export const { room } = registerControl(['room', 'size']); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomlp - * @tags effects + * @tags effects, superdough * @synonyms rlp * @param {number} frequency between 0 and 20000hz * @example @@ -1925,7 +1925,7 @@ export const { roomlp, rlp } = registerControl('roomlp', 'rlp'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomdim - * @tags effects + * @tags effects, superdough * @synonyms rdim * @param {number} frequency between 0 and 20000hz * @example @@ -1940,7 +1940,7 @@ export const { roomdim, rdim } = registerControl('roomdim', 'rdim'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomfade - * @tags effects + * @tags effects, superdough * @synonyms rfade * @param {number} seconds for the reverb to fade * @example @@ -1953,7 +1953,7 @@ export const { roomfade, rfade } = registerControl('roomfade', 'rfade'); /** * Sets the sample to use as an impulse response for the reverb. * @name iresponse - * @tags effects + * @tags effects, superdough * @param {string | Pattern} sample to use as an impulse response * @synonyms ir * @example @@ -1965,7 +1965,7 @@ export const { ir, iresponse } = registerControl(['ir', 'i'], 'iresponse'); /** * Sets speed of the sample for the impulse response. * @name irspeed - * @tags effects + * @tags effects, superdough * @param {string | Pattern} speed * @example * samples('github:switchangel/pad') @@ -1977,7 +1977,7 @@ export const { irspeed } = registerControl('irspeed'); /** * Sets the beginning of the IR response sample * @name irbegin - * @tags effects + * @tags effects, superdough * @param {string | Pattern} begin between 0 and 1 * @synonyms ir * @example @@ -1991,7 +1991,7 @@ export const { irbegin } = registerControl('irbegin'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomsize - * @tags effects + * @tags effects, superdough * @param {number | Pattern} size between 0 and 10 * @synonyms rsize, sz, size * @example @@ -2015,7 +2015,7 @@ export const { roomsize, size, sz, rsize } = registerControl('roomsize', 'size', * * * @name shape - * @tags effects + * @tags effects, superdough * @param {number | Pattern} distortion between 0 and 1 * @example * s("bd sd [~ bd] sd,hh*8").shape("<0 .2 .4 .6 .8>") @@ -2028,7 +2028,7 @@ export const { shape } = registerControl(['shape', 'shapevol']); * Most useful values are usually between 0 and 10 (depending on source gain). If you are feeling adventurous, you can turn it up to 11 and beyond ;) * * @name distort - * @tags effects + * @tags effects, superdough * @synonyms dist * @param {number | Pattern} distortion * @example @@ -2043,7 +2043,7 @@ export const { distort, dist } = registerControl(['distort', 'distortvol'], 'dis * More info [here](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) * * @name compressor - * @tags effects + * @tags effects, superdough * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02") @@ -2129,7 +2129,7 @@ export const { squiz } = registerControl('squiz'); * Formant filter to make things sound like vowels. * * @name vowel - * @tags effects + * @tags effects, superdough * @param {string | Pattern} vowel You can use a e i o u ae aa oe ue y uh un en an on, corresponding to [a] [e] [i] [o] [u] [æ] [ɑ] [ø] [y] [ɯ] [ʌ] [œ̃] [ɛ̃] [ɑ̃] [ɔ̃]. Aliases: aa = å = ɑ, oe = ø = ö, y = ı, ae = æ. * @example * note("[c2 >]*2").s('sawtooth') @@ -2154,7 +2154,7 @@ export const { waveloss } = registerControl('waveloss'); * Noise crackle density * * @name density - * @tags effects + * @tags effects, superdough * @param {number | Pattern} density between 0 and x * @example * s("crackle*4").density("<0.01 0.04 0.2 0.5>".slow(4)) From 96d0f2053e7fc0afbf515668945f3a4f3346fca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 19 Oct 2025 21:13:14 +0200 Subject: [PATCH 11/26] Add supradough controls --- packages/core/controls.mjs | 96 +++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 2add9e416..dda12767d 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -411,7 +411,7 @@ export const { accelerate } = registerControl('accelerate'); * Sets the velocity from 0 to 1. Is multiplied together with gain. * * @name velocity - * @tags effects, superdough + * @tags effects, superdough, supradough * @example * s("hh*8") * .gain(".4!2 1 .4!2 1 .4 1") @@ -422,7 +422,7 @@ export const { velocity } = registerControl('velocity'); * Controls the gain by an exponential amount. * * @name gain - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} amount gain. * @example * s("hh*8").gain(".4!2 1 .4!2 1 .4 1").fast(2) @@ -433,7 +433,7 @@ export const { gain } = registerControl('gain'); * Gain applied after all effects have been processed. * * @name postgain - * @tags effects, superdough + * @tags effects, superdough, supradough * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02").postgain(1.5) @@ -456,7 +456,7 @@ export const { amp } = registerControl('amp'); * Amplitude envelope attack time: Specifies how long it takes for the sound to reach its peak value, relative to the onset. * * @name attack - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} attack time in seconds. * @synonyms att * @example @@ -472,7 +472,7 @@ export const { attack, att } = registerControl('attack', 'att'); * while decimal numbers and complex ratios sound metallic. * * @name fmh - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} harmonicity * @example * note("c e g b g e") @@ -487,7 +487,7 @@ export const { fmh } = registerControl(['fmh', 'fmi'], 'fmh'); * Controls the modulation index, which defines the brightness of the sound. * * @name fm - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} brightness modulation index * @synonyms fmi * @example @@ -502,7 +502,7 @@ export const { fmi, fm } = registerControl(['fmi', 'fmh'], 'fm'); * Ramp type of fm envelope. Exp might be a bit broken.. * * @name fmenv - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} type lin | exp * @example * note("c e g b g e") @@ -518,7 +518,7 @@ export const { fmenv } = registerControl('fmenv'); * Attack time for the FM envelope: time it takes to reach maximum modulation * * @name fmattack - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} time attack time * @example * note("c e g b g e") @@ -533,7 +533,7 @@ export const { fmattack } = registerControl('fmattack'); * Waveform of the fm modulator * * @name fmwave - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} wave waveform * @example * n("0 1 2 3".fast(4)).scale("d:minor").s("sine").fmwave("").fm(4).fmh(2.01) @@ -547,7 +547,7 @@ export const { fmwave } = registerControl('fmwave'); * Decay time for the FM envelope: seconds until the sustain level is reached after the attack phase. * * @name fmdecay - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} time decay time * @example * note("c e g b g e") @@ -562,7 +562,7 @@ export const { fmdecay } = registerControl('fmdecay'); * Sustain level for the FM envelope: how much modulation is applied after the decay phase * * @name fmsustain - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} level sustain level * @example * note("c e g b g e") @@ -611,7 +611,7 @@ export const { fft } = registerControl('fft'); * Note that the decay is only audible if the sustain value is lower than 1. * * @name decay - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} time decay time in seconds * @synonyms dec * @example @@ -623,7 +623,7 @@ export const { decay, dec } = registerControl('decay', 'dec'); * Amplitude envelope sustain level: The level which is reached after attack / decay, being sustained until the offset. * * @name sustain - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} gain sustain level between 0 and 1 * @synonyms sus * @example @@ -635,7 +635,7 @@ export const { sustain, sus } = registerControl('sustain', 'sus'); * Amplitude envelope release time: The time it takes after the offset to go from sustain level to zero. * * @name release - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} time release time in seconds * @synonyms rel * @example @@ -650,7 +650,7 @@ export const { hold } = registerControl('hold'); * can also optionally supply the 'bpq' parameter separated by ':'. * * @name bpf - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} frequency center frequency * @synonyms bandf, bp * @example @@ -663,7 +663,7 @@ export const { bandf, bpf, bp } = registerControl(['bandf', 'bandq', 'bpenv'], ' * Sets the **b**and-**p**ass **q**-factor (resonance). * * @name bpq - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} q q factor * @synonyms bandq * @example @@ -743,7 +743,7 @@ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); * Bit crusher effect. * * @name crush - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} depth between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction). * @example * s(",hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>") @@ -755,7 +755,7 @@ export const { crush } = registerControl('crush'); * Fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers * * @name coarse - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} factor 1 for original 2 for half, 3 for a third and so on. * @example * s("bd sd [~ bd] sd,hh*8").coarse("<1 4 8 16 32>") @@ -1112,7 +1112,7 @@ export const { cut } = registerControl('cut'); * When using mininotation, you can also optionally add the 'lpq' parameter, separated by ':'. * * @name lpf - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms cutoff, ctf, lp * @example @@ -1126,7 +1126,7 @@ export const { cutoff, ctf, lpf, lp } = registerControl(['cutoff', 'resonance', /** * Sets the lowpass filter envelope modulation depth. * @name lpenv - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} modulation depth of the lowpass filter envelope between 0 and _n_ * @synonyms lpe * @example @@ -1140,7 +1140,7 @@ export const { lpenv, lpe } = registerControl('lpenv', 'lpe'); /** * Sets the highpass filter envelope modulation depth. * @name hpenv - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} modulation depth of the highpass filter envelope between 0 and _n_ * @synonyms hpe * @example @@ -1154,7 +1154,7 @@ export const { hpenv, hpe } = registerControl('hpenv', 'hpe'); /** * Sets the bandpass filter envelope modulation depth. * @name bpenv - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} modulation depth of the bandpass filter envelope between 0 and _n_ * @synonyms bpe * @example @@ -1168,7 +1168,7 @@ export const { bpenv, bpe } = registerControl('bpenv', 'bpe'); /** * Sets the attack duration for the lowpass filter envelope. * @name lpattack - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} attack time of the filter envelope * @synonyms lpa * @example @@ -1182,7 +1182,7 @@ export const { lpattack, lpa } = registerControl('lpattack', 'lpa'); /** * Sets the attack duration for the highpass filter envelope. * @name hpattack - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} attack time of the highpass filter envelope * @synonyms hpa * @example @@ -1196,7 +1196,7 @@ export const { hpattack, hpa } = registerControl('hpattack', 'hpa'); /** * Sets the attack duration for the bandpass filter envelope. * @name bpattack - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} attack time of the bandpass filter envelope * @synonyms bpa * @example @@ -1210,7 +1210,7 @@ export const { bpattack, bpa } = registerControl('bpattack', 'bpa'); /** * Sets the decay duration for the lowpass filter envelope. * @name lpdecay - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} decay time of the filter envelope * @synonyms lpd * @example @@ -1224,7 +1224,7 @@ export const { lpdecay, lpd } = registerControl('lpdecay', 'lpd'); /** * Sets the decay duration for the highpass filter envelope. * @name hpdecay - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} decay time of the highpass filter envelope * @synonyms hpd * @example @@ -1239,7 +1239,7 @@ export const { hpdecay, hpd } = registerControl('hpdecay', 'hpd'); /** * Sets the decay duration for the bandpass filter envelope. * @name bpdecay - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} decay time of the bandpass filter envelope * @synonyms bpd * @example @@ -1254,7 +1254,7 @@ export const { bpdecay, bpd } = registerControl('bpdecay', 'bpd'); /** * Sets the sustain amplitude for the lowpass filter envelope. * @name lpsustain - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} sustain amplitude of the lowpass filter envelope * @synonyms lps * @example @@ -1269,7 +1269,7 @@ export const { lpsustain, lps } = registerControl('lpsustain', 'lps'); /** * Sets the sustain amplitude for the highpass filter envelope. * @name hpsustain - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} sustain amplitude of the highpass filter envelope * @synonyms hps * @example @@ -1284,7 +1284,7 @@ export const { hpsustain, hps } = registerControl('hpsustain', 'hps'); /** * Sets the sustain amplitude for the bandpass filter envelope. * @name bpsustain - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} sustain amplitude of the bandpass filter envelope * @synonyms bps * @example @@ -1299,7 +1299,7 @@ export const { bpsustain, bps } = registerControl('bpsustain', 'bps'); /** * Sets the release time for the lowpass filter envelope. * @name lprelease - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} release time of the filter envelope * @synonyms lpr * @example @@ -1315,7 +1315,7 @@ export const { lprelease, lpr } = registerControl('lprelease', 'lpr'); /** * Sets the release time for the highpass filter envelope. * @name hprelease - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} release time of the highpass filter envelope * @synonyms hpr * @example @@ -1331,7 +1331,7 @@ export const { hprelease, hpr } = registerControl('hprelease', 'hpr'); /** * Sets the release time for the bandpass filter envelope. * @name bprelease - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} release time of the bandpass filter envelope * @synonyms bpr * @example @@ -1376,7 +1376,7 @@ export const { fanchor } = registerControl('fanchor'); * When using mininotation, you can also optionally add the 'hpq' parameter, separated by ':'. * * @name hpf - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms hp, hcutoff * @example @@ -1391,7 +1391,7 @@ export const { fanchor } = registerControl('fanchor'); * Applies a vibrato to the frequency of the oscillator. * * @name vib - * @tags effects + * @tags effects, superdough, supradough * @synonyms vibrato, v * @param {number | Pattern} frequency of the vibrato in hertz * @example @@ -1419,7 +1419,7 @@ export const { noise } = registerControl('noise'); * Sets the vibrato depth in semitones. Only has an effect if `vibrato` | `vib` | `v` is is also set * * @name vibmod - * @tags effects + * @tags effects, superdough, supradough * @synonyms vmod * @param {number | Pattern} depth of vibrato (in semitones) * @example @@ -1438,7 +1438,7 @@ export const { hcutoff, hpf, hp } = registerControl(['hcutoff', 'hresonance', 'h * Controls the **h**igh-**p**ass **q**-value. * * @name hpq - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms hresonance * @example @@ -1450,7 +1450,7 @@ export const { hresonance, hpq } = registerControl('hresonance', 'hpq'); * Controls the **l**ow-**p**ass **q**-value. * * @name lpq - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms resonance * @example @@ -1480,7 +1480,7 @@ export const { djf } = registerControl('djf'); * * * @name delay - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} level between 0 and 1 * @example * s("bd bd").delay("<0 .25 .5 1>") @@ -1494,7 +1494,7 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1508,7 +1508,7 @@ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1635,7 +1635,7 @@ export const { freq } = registerControl('freq'); * Attack time of pitch envelope. * * @name pattack - * @tags effects + * @tags effects, superdough, supradough * @synonyms patt * @param {number | Pattern} time time in seconds * @example @@ -1647,7 +1647,7 @@ export const { pattack, patt } = registerControl('pattack', 'patt'); * Decay time of pitch envelope. * * @name pdecay - * @tags effects + * @tags effects, superdough, supradough * @synonyms pdec * @param {number | Pattern} time time in seconds * @example @@ -1661,7 +1661,7 @@ export const { psustain, psus } = registerControl('psustain', 'psus'); * Release time of pitch envelope * * @name prelease - * @tags effects + * @tags effects, superdough, supradough * @synonyms prel * @param {number | Pattern} time time in seconds * @example @@ -1676,7 +1676,7 @@ export const { prelease, prel } = registerControl('prelease', 'prel'); * If you don't set other pitch envelope controls, `pattack:.2` will be the default. * * @name penv - * @tags effects + * @tags effects, superdough, supradough * @param {number | Pattern} semitones change in semitones * @example * note("c") @@ -1831,7 +1831,7 @@ export const { overshape } = registerControl('overshape'); * Sets position in stereo. * * @name pan - * @tags effects, superdough + * @tags effects, superdough, supradough * @param {number | Pattern} pan between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel) * @example * s("[bd hh]*2").pan("<.5 1 .5 0>") @@ -2028,7 +2028,7 @@ export const { shape } = registerControl(['shape', 'shapevol']); * Most useful values are usually between 0 and 10 (depending on source gain). If you are feeling adventurous, you can turn it up to 11 and beyond ;) * * @name distort - * @tags effects, superdough + * @tags effects, superdough, supradough * @synonyms dist * @param {number | Pattern} distortion * @example From 69360b3ec8731e75045f44b9f08840739fbc7e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 19 Oct 2025 21:17:25 +0200 Subject: [PATCH 12/26] Also tag "noise" --- packages/core/controls.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index dda12767d..c6ff8d79b 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1409,7 +1409,7 @@ export const { vib, vibrato, v } = registerControl(['vib', 'vibmod'], 'vibrato', * Adds pink noise to the mix * * @name noise - * @tags generators + * @tags generators, superdough, supradough * @param {number | Pattern} wet wet amount * @example * sound("/2") From 2483c673a4ae08ac33fc60eb2155fdcd4ba091cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 19 Oct 2025 21:19:42 +0200 Subject: [PATCH 13/26] Effects -> fx, untag "crossfade" --- packages/core/controls.mjs | 262 +++++++++++++++--------------- packages/superdough/wavetable.mjs | 2 +- packages/supradough/dough.mjs | 2 +- 3 files changed, 133 insertions(+), 133 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index c6ff8d79b..1bfd5a892 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -92,7 +92,7 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); * Position in the wavetable of the wavetable oscillator * * @name wt - * @tags effects + * @tags fx * @param {number | Pattern} position Position in the wavetable from 0 to 1 * @synonyms wavetablePosition * @example @@ -104,7 +104,7 @@ export const { wt, wavetablePosition } = registerControl('wt', 'wavetablePositio * Amount of envelope applied wavetable oscillator's position envelope * * @name wtenv - * @tags effects + * @tags fx * @param {number | Pattern} amount between 0 and 1 */ export const { wtenv } = registerControl('wtenv'); @@ -112,7 +112,7 @@ export const { wtenv } = registerControl('wtenv'); * Attack time of the wavetable oscillator's position envelope * * @name wtattack - * @tags effects + * @tags fx * @synonyms wtatt * @param {number | Pattern} time attack time in seconds */ @@ -122,7 +122,7 @@ export const { wtattack, wtatt } = registerControl('wtattack', 'wtatt'); * Decay time of the wavetable oscillator's position envelope * * @name wtdecay - * @tags effects + * @tags fx * @synonyms wtdec * @param {number | Pattern} time decay time in seconds */ @@ -132,7 +132,7 @@ export const { wtdecay, wtdec } = registerControl('wtdecay', 'wtdec'); * Sustain time of the wavetable oscillator's position envelope * * @name wtsustain - * @tags effects + * @tags fx * @synonyms wtsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -142,7 +142,7 @@ export const { wtsustain, wtsus } = registerControl('wtsustain', 'wtsus'); * Release time of the wavetable oscillator's position envelope * * @name wtrelease - * @tags effects + * @tags fx * @synonyms wtrel * @param {number | Pattern} time release time in seconds */ @@ -152,7 +152,7 @@ export const { wtrelease, wtrel } = registerControl('wtrelease', 'wtrel'); * Rate of the LFO for the wavetable oscillator's position * * @name wtrate - * @tags effects + * @tags fx * @param {number | Pattern} rate rate in hertz */ export const { wtrate } = registerControl('wtrate'); @@ -160,7 +160,7 @@ export const { wtrate } = registerControl('wtrate'); * cycle synced rate of the LFO for the wavetable oscillator's position * * @name wtsync - * @tags effects + * @tags fx * @param {number | Pattern} rate rate in cycles */ export const { wtsync } = registerControl('wtsync'); @@ -169,7 +169,7 @@ export const { wtsync } = registerControl('wtsync'); * Depth of the LFO for the wavetable oscillator's position * * @name wtdepth - * @tags effects + * @tags fx * @param {number | Pattern} depth depth of modulation */ export const { wtdepth } = registerControl('wtdepth'); @@ -178,7 +178,7 @@ export const { wtdepth } = registerControl('wtdepth'); * Shape of the LFO for the wavetable oscillator's position * * @name wtshape - * @tags effects + * @tags fx * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { wtshape } = registerControl('wtshape'); @@ -187,7 +187,7 @@ export const { wtshape } = registerControl('wtshape'); * DC offset of the LFO for the wavetable oscillator's position * * @name wtdc - * @tags effects + * @tags fx * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { wtdc } = registerControl('wtdc'); @@ -196,7 +196,7 @@ export const { wtdc } = registerControl('wtdc'); * Skew of the LFO for the wavetable oscillator's position * * @name wtskew - * @tags effects + * @tags fx * @param {number | Pattern} skew How much to bend the LFO shape */ export const { wtskew } = registerControl('wtskew'); @@ -205,7 +205,7 @@ export const { wtskew } = registerControl('wtskew'); * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator * * @name warp - * @tags effects + * @tags fx * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 * @synonyms wavetableWarp * @example @@ -218,7 +218,7 @@ export const { warp, wavetableWarp } = registerControl('warp', 'wavetableWarp'); * Attack time of the wavetable oscillator's warp envelope * * @name warpattack - * @tags effects + * @tags fx * @synonyms warpatt * @param {number | Pattern} time attack time in seconds */ @@ -228,7 +228,7 @@ export const { warpattack, warpatt } = registerControl('warpattack', 'warpatt'); * Decay time of the wavetable oscillator's warp envelope * * @name warpdecay - * @tags effects + * @tags fx * @synonyms warpdec * @param {number | Pattern} time decay time in seconds */ @@ -238,7 +238,7 @@ export const { warpdecay, warpdec } = registerControl('warpdecay', 'warpdec'); * Sustain time of the wavetable oscillator's warp envelope * * @name warpsustain - * @tags effects + * @tags fx * @synonyms warpsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -248,7 +248,7 @@ export const { warpsustain, warpsus } = registerControl('warpsustain', 'warpsus' * Release time of the wavetable oscillator's warp envelope * * @name warprelease - * @tags effects + * @tags fx * @synonyms warprel * @param {number | Pattern} time release time in seconds */ @@ -258,7 +258,7 @@ export const { warprelease, warprel } = registerControl('warprelease', 'warprel' * Rate of the LFO for the wavetable oscillator's warp * * @name warprate - * @tags effects + * @tags fx * @param {number | Pattern} rate rate in hertz */ export const { warprate } = registerControl('warprate'); @@ -267,7 +267,7 @@ export const { warprate } = registerControl('warprate'); * Depth of the LFO for the wavetable oscillator's warp * * @name warpdepth - * @tags effects + * @tags fx * @param {number | Pattern} depth depth of modulation */ export const { warpdepth } = registerControl('warpdepth'); @@ -276,7 +276,7 @@ export const { warpdepth } = registerControl('warpdepth'); * Shape of the LFO for the wavetable oscillator's warp * * @name warpshape - * @tags effects + * @tags fx * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { warpshape } = registerControl('warpshape'); @@ -285,7 +285,7 @@ export const { warpshape } = registerControl('warpshape'); * DC offset of the LFO for the wavetable oscillator's warp * * @name warpdc - * @tags effects + * @tags fx * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { warpdc } = registerControl('warpdc'); @@ -294,7 +294,7 @@ export const { warpdc } = registerControl('warpdc'); * Skew of the LFO for the wavetable oscillator's warp * * @name warpskew - * @tags effects + * @tags fx * @param {number | Pattern} skew How much to bend the LFO shape */ export const { warpskew } = registerControl('warpskew'); @@ -306,7 +306,7 @@ export const { warpskew } = registerControl('warpskew'); * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * * @name warpmode - * @tags effects + * @tags fx * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode * @example @@ -320,7 +320,7 @@ export const { warpmode, wavetableWarpMode } = registerControl('warpmode', 'wave * Amount of randomness of the initial phase of the wavetable oscillator. * * @name wtphaserand - * @tags effects + * @tags fx * @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random) * @synonyms wavetablePhaseRand * @example @@ -333,7 +333,7 @@ export const { wtphaserand, wavetablePhaseRand } = registerControl('wtphaserand' * Amount of envelope applied wavetable oscillator's position envelope * * @name warpenv - * @tags effects + * @tags fx * @param {number | Pattern} amount between 0 and 1 */ export const { warpenv } = registerControl('warpenv'); @@ -342,7 +342,7 @@ export const { warpenv } = registerControl('warpenv'); * cycle synced rate of the LFO for the wavetable warp position * * @name warpsync - * @tags effects + * @tags fx * @param {number | Pattern} rate rate in cycles */ export const { warpsync } = registerControl('warpsync'); @@ -411,7 +411,7 @@ export const { accelerate } = registerControl('accelerate'); * Sets the velocity from 0 to 1. Is multiplied together with gain. * * @name velocity - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @example * s("hh*8") * .gain(".4!2 1 .4!2 1 .4 1") @@ -422,7 +422,7 @@ export const { velocity } = registerControl('velocity'); * Controls the gain by an exponential amount. * * @name gain - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} amount gain. * @example * s("hh*8").gain(".4!2 1 .4!2 1 .4 1").fast(2) @@ -433,7 +433,7 @@ export const { gain } = registerControl('gain'); * Gain applied after all effects have been processed. * * @name postgain - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02").postgain(1.5) @@ -444,7 +444,7 @@ export const { postgain } = registerControl('postgain'); * Like `gain`, but linear. * * @name amp - * @tags effects + * @tags fx * @param {number | Pattern} amount gain. * @superdirtOnly * @example @@ -456,7 +456,7 @@ export const { amp } = registerControl('amp'); * Amplitude envelope attack time: Specifies how long it takes for the sound to reach its peak value, relative to the onset. * * @name attack - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} attack time in seconds. * @synonyms att * @example @@ -472,7 +472,7 @@ export const { attack, att } = registerControl('attack', 'att'); * while decimal numbers and complex ratios sound metallic. * * @name fmh - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} harmonicity * @example * note("c e g b g e") @@ -487,7 +487,7 @@ export const { fmh } = registerControl(['fmh', 'fmi'], 'fmh'); * Controls the modulation index, which defines the brightness of the sound. * * @name fm - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} brightness modulation index * @synonyms fmi * @example @@ -502,7 +502,7 @@ export const { fmi, fm } = registerControl(['fmi', 'fmh'], 'fm'); * Ramp type of fm envelope. Exp might be a bit broken.. * * @name fmenv - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} type lin | exp * @example * note("c e g b g e") @@ -518,7 +518,7 @@ export const { fmenv } = registerControl('fmenv'); * Attack time for the FM envelope: time it takes to reach maximum modulation * * @name fmattack - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} time attack time * @example * note("c e g b g e") @@ -533,7 +533,7 @@ export const { fmattack } = registerControl('fmattack'); * Waveform of the fm modulator * * @name fmwave - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} wave waveform * @example * n("0 1 2 3".fast(4)).scale("d:minor").s("sine").fmwave("").fm(4).fmh(2.01) @@ -547,7 +547,7 @@ export const { fmwave } = registerControl('fmwave'); * Decay time for the FM envelope: seconds until the sustain level is reached after the attack phase. * * @name fmdecay - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} time decay time * @example * note("c e g b g e") @@ -562,7 +562,7 @@ export const { fmdecay } = registerControl('fmdecay'); * Sustain level for the FM envelope: how much modulation is applied after the decay phase * * @name fmsustain - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} level sustain level * @example * note("c e g b g e") @@ -593,7 +593,7 @@ export const { bank } = registerControl('bank'); * mix control for the chorus effect * * @name chorus - * @tags effects + * @tags fx * @param {string | Pattern} chorus mix amount between 0 and 1 * @example * note("d d a# a").s("sawtooth").chorus(.5) @@ -611,7 +611,7 @@ export const { fft } = registerControl('fft'); * Note that the decay is only audible if the sustain value is lower than 1. * * @name decay - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} time decay time in seconds * @synonyms dec * @example @@ -623,7 +623,7 @@ export const { decay, dec } = registerControl('decay', 'dec'); * Amplitude envelope sustain level: The level which is reached after attack / decay, being sustained until the offset. * * @name sustain - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} gain sustain level between 0 and 1 * @synonyms sus * @example @@ -635,7 +635,7 @@ export const { sustain, sus } = registerControl('sustain', 'sus'); * Amplitude envelope release time: The time it takes after the offset to go from sustain level to zero. * * @name release - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} time release time in seconds * @synonyms rel * @example @@ -650,7 +650,7 @@ export const { hold } = registerControl('hold'); * can also optionally supply the 'bpq' parameter separated by ':'. * * @name bpf - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} frequency center frequency * @synonyms bandf, bp * @example @@ -663,7 +663,7 @@ export const { bandf, bpf, bp } = registerControl(['bandf', 'bandq', 'bpenv'], ' * Sets the **b**and-**p**ass **q**-factor (resonance). * * @name bpq - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} q q factor * @synonyms bandq * @example @@ -743,7 +743,7 @@ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); * Bit crusher effect. * * @name crush - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} depth between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction). * @example * s(",hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>") @@ -755,7 +755,7 @@ export const { crush } = registerControl('crush'); * Fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers * * @name coarse - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} factor 1 for original 2 for half, 3 for a third and so on. * @example * s("bd sd [~ bd] sd,hh*8").coarse("<1 4 8 16 32>") @@ -767,7 +767,7 @@ export const { coarse } = registerControl('coarse'); * Modulate the amplitude of a sound with a continuous waveform * * @name tremolo - * @tags effects, superdough + * @tags fx, superdough * @synonyms trem * @param {number | Pattern} speed modulation speed in HZ * @example @@ -780,7 +780,7 @@ export const { tremolo } = registerControl(['tremolo', 'tremolodepth', 'tremolos * Modulate the amplitude of a sound with a continuous waveform * * @name tremolosync - * @tags effects, superdough + * @tags fx, superdough * @synonyms tremsync * @param {number | Pattern} cycles modulation speed in cycles * @example @@ -796,7 +796,7 @@ export const { tremolosync } = registerControl( * Depth of amplitude modulation * * @name tremolodepth - * @tags effects, superdough + * @tags fx, superdough * @synonyms tremdepth * @param {number | Pattern} depth * @example @@ -808,7 +808,7 @@ export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth'); * Alter the shape of the modulation waveform * * @name tremoloskew - * @tags effects, superdough + * @tags fx, superdough * @synonyms tremskew * @param {number | Pattern} amount between 0 & 1, the shape of the waveform * @example @@ -821,7 +821,7 @@ export const { tremoloskew } = registerControl('tremoloskew', 'tremskew'); * Alter the phase of the modulation waveform * * @name tremolophase - * @tags effects, superdough + * @tags fx, superdough * @synonyms tremphase * @param {number | Pattern} offset the offset in cycles of the modulation * @example @@ -834,7 +834,7 @@ export const { tremolophase } = registerControl('tremolophase', 'tremphase'); * Shape of amplitude modulation * * @name tremoloshape - * @tags effects, superdough + * @tags fx, superdough * @synonyms tremshape * @param {number | Pattern} shape tri | square | sine | saw | ramp * @example @@ -846,7 +846,7 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); * Filter overdrive for supported filter types * * @name drive - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} amount * @example * note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>") @@ -860,7 +860,7 @@ export const { drive } = registerControl('drive'); * Can be applied to multiple orbits with the ':' mininotation, e.g. `duckorbit("2:3")` * * @name duckorbit - * @tags effects, superdough + * @tags fx, superdough * @synonyms duck * @param {number | Pattern} orbit target orbit * @example @@ -881,7 +881,7 @@ export const { duck } = registerControl('duckorbit', 'duck'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckdepth - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} depth depth of modulation from 0 to 1 * @example * stack( n(run(8)).scale("c:minor").s("sawtooth").delay(.7).orbit(2), s("bd:4!4").beat("0,4,8,11,14",16).duckorbit(2).duckattack(0.2).duckdepth("<1 .9 .6 0>")) @@ -901,7 +901,7 @@ export const { duckdepth } = registerControl('duckdepth'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckonset - * @tags effects, superdough + * @tags fx, superdough * @synonyms duckons * * @param {number | Pattern} time The onset time in seconds @@ -929,7 +929,7 @@ export const { duckonset } = registerControl('duckonset', 'duckons'); * Note: this requires first applying the effect to multiple orbits with e.g. `duckorbit("2:3")`. * * @name duckattack - * @tags effects, superdough + * @tags fx, superdough * @synonyms duckatt * * @param {number | Pattern} time The attack time in seconds @@ -949,7 +949,7 @@ export const { duckattack } = registerControl('duckattack', 'duckatt'); * * @name byteBeatExpression * @synonyms bbexpr - * @tags effects + * @tags fx * * @param {number | Pattern} byteBeatExpression bitwise expression for creating bytebeat * @example @@ -963,7 +963,7 @@ export const { byteBeatExpression, bbexpr } = registerControl('byteBeatExpressio * * @name byteBeatStartTime * @synonyms bbst - * @tags effects + * @tags fx * * @param {number | Pattern} byteBeatStartTime in samples (t) * @example @@ -990,7 +990,7 @@ export const { channels, ch } = registerControl('channels', 'ch'); * Controls the pulsewidth of the pulse oscillator * * @name pw - * @tags effects + * @tags fx * @param {number | Pattern} pulsewidth * @example * note("{f a c e}%16").s("pulse").pw(".8:1:.2") @@ -1003,7 +1003,7 @@ export const { pw } = registerControl(['pw', 'pwrate', 'pwsweep']); * Controls the lfo rate for the pulsewidth of the pulse oscillator * * @name pwrate - * @tags effects + * @tags fx * @param {number | Pattern} rate * @example * n(run(8)).scale("D:pentatonic").s("pulse").pw("0.5").pwrate("<5 .1 25>").pwsweep("<0.3 .8>") @@ -1016,7 +1016,7 @@ export const { pwrate } = registerControl('pwrate'); * Controls the lfo sweep for the pulsewidth of the pulse oscillator * * @name pwsweep - * @tags effects + * @tags fx * @param {number | Pattern} sweep * @example * n(run(8)).scale("D:pentatonic").s("pulse").pw("0.5").pwrate("<5 .1 25>").pwsweep("<0.3 .8>") @@ -1028,7 +1028,7 @@ export const { pwsweep } = registerControl('pwsweep'); * Phaser audio effect that approximates popular guitar pedals. * * @name phaser - * @tags effects, superdough + * @tags fx, superdough * @synonyms ph * @param {number | Pattern} speed speed of modulation * @example @@ -1046,7 +1046,7 @@ export const { phaserrate, ph, phaser } = registerControl( * The frequency sweep range of the lfo for the phaser effect. Defaults to 2000 * * @name phasersweep - * @tags effects, superdough + * @tags fx, superdough * @synonyms phs * @param {number | Pattern} phasersweep most useful values are between 0 and 4000 * @example @@ -1060,7 +1060,7 @@ export const { phasersweep, phs } = registerControl('phasersweep', 'phs'); * The center frequency of the phaser in HZ. Defaults to 1000 * * @name phasercenter - * @tags effects, superdough + * @tags fx, superdough * @synonyms phc * @param {number | Pattern} centerfrequency in HZ * @example @@ -1075,7 +1075,7 @@ export const { phasercenter, phc } = registerControl('phasercenter', 'phc'); * The amount the signal is affected by the phaser effect. Defaults to 0.75 * * @name phaserdepth - * @tags effects, superdough + * @tags fx, superdough * @synonyms phd, phasdp * @param {number | Pattern} depth number between 0 and 1 * @example @@ -1090,7 +1090,7 @@ export const { phaserdepth, phd, phasdp } = registerControl('phaserdepth', 'phd' * Choose the channel the pattern is sent to in superdirt * * @name channel - * @tags effects + * @tags fx * @param {number | Pattern} channel channel number * */ @@ -1099,7 +1099,7 @@ export const { channel } = registerControl('channel'); * In the style of classic drum-machines, `cut` will stop a playing sample as soon as another samples with in same cutgroup is to be played. An example would be an open hi-hat followed by a closed one, essentially muting the open. * * @name cut - * @tags effects + * @tags fx * @param {number | Pattern} group cut group number * @example * s("[oh hh]*4").cut(1) @@ -1112,7 +1112,7 @@ export const { cut } = registerControl('cut'); * When using mininotation, you can also optionally add the 'lpq' parameter, separated by ':'. * * @name lpf - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms cutoff, ctf, lp * @example @@ -1126,7 +1126,7 @@ export const { cutoff, ctf, lpf, lp } = registerControl(['cutoff', 'resonance', /** * Sets the lowpass filter envelope modulation depth. * @name lpenv - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} modulation depth of the lowpass filter envelope between 0 and _n_ * @synonyms lpe * @example @@ -1140,7 +1140,7 @@ export const { lpenv, lpe } = registerControl('lpenv', 'lpe'); /** * Sets the highpass filter envelope modulation depth. * @name hpenv - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} modulation depth of the highpass filter envelope between 0 and _n_ * @synonyms hpe * @example @@ -1154,7 +1154,7 @@ export const { hpenv, hpe } = registerControl('hpenv', 'hpe'); /** * Sets the bandpass filter envelope modulation depth. * @name bpenv - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} modulation depth of the bandpass filter envelope between 0 and _n_ * @synonyms bpe * @example @@ -1168,7 +1168,7 @@ export const { bpenv, bpe } = registerControl('bpenv', 'bpe'); /** * Sets the attack duration for the lowpass filter envelope. * @name lpattack - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} attack time of the filter envelope * @synonyms lpa * @example @@ -1182,7 +1182,7 @@ export const { lpattack, lpa } = registerControl('lpattack', 'lpa'); /** * Sets the attack duration for the highpass filter envelope. * @name hpattack - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} attack time of the highpass filter envelope * @synonyms hpa * @example @@ -1196,7 +1196,7 @@ export const { hpattack, hpa } = registerControl('hpattack', 'hpa'); /** * Sets the attack duration for the bandpass filter envelope. * @name bpattack - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} attack time of the bandpass filter envelope * @synonyms bpa * @example @@ -1210,7 +1210,7 @@ export const { bpattack, bpa } = registerControl('bpattack', 'bpa'); /** * Sets the decay duration for the lowpass filter envelope. * @name lpdecay - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} decay time of the filter envelope * @synonyms lpd * @example @@ -1224,7 +1224,7 @@ export const { lpdecay, lpd } = registerControl('lpdecay', 'lpd'); /** * Sets the decay duration for the highpass filter envelope. * @name hpdecay - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} decay time of the highpass filter envelope * @synonyms hpd * @example @@ -1239,7 +1239,7 @@ export const { hpdecay, hpd } = registerControl('hpdecay', 'hpd'); /** * Sets the decay duration for the bandpass filter envelope. * @name bpdecay - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} decay time of the bandpass filter envelope * @synonyms bpd * @example @@ -1254,7 +1254,7 @@ export const { bpdecay, bpd } = registerControl('bpdecay', 'bpd'); /** * Sets the sustain amplitude for the lowpass filter envelope. * @name lpsustain - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} sustain amplitude of the lowpass filter envelope * @synonyms lps * @example @@ -1269,7 +1269,7 @@ export const { lpsustain, lps } = registerControl('lpsustain', 'lps'); /** * Sets the sustain amplitude for the highpass filter envelope. * @name hpsustain - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} sustain amplitude of the highpass filter envelope * @synonyms hps * @example @@ -1284,7 +1284,7 @@ export const { hpsustain, hps } = registerControl('hpsustain', 'hps'); /** * Sets the sustain amplitude for the bandpass filter envelope. * @name bpsustain - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} sustain amplitude of the bandpass filter envelope * @synonyms bps * @example @@ -1299,7 +1299,7 @@ export const { bpsustain, bps } = registerControl('bpsustain', 'bps'); /** * Sets the release time for the lowpass filter envelope. * @name lprelease - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} release time of the filter envelope * @synonyms lpr * @example @@ -1315,7 +1315,7 @@ export const { lprelease, lpr } = registerControl('lprelease', 'lpr'); /** * Sets the release time for the highpass filter envelope. * @name hprelease - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} release time of the highpass filter envelope * @synonyms hpr * @example @@ -1331,7 +1331,7 @@ export const { hprelease, hpr } = registerControl('hprelease', 'hpr'); /** * Sets the release time for the bandpass filter envelope. * @name bprelease - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} release time of the bandpass filter envelope * @synonyms bpr * @example @@ -1347,7 +1347,7 @@ export const { bprelease, bpr } = registerControl('bprelease', 'bpr'); /** * Sets the filter type. The ladder filter is more aggressive. More types might be added in the future. * @name ftype - * @tags effects + * @tags fx * @param {number | Pattern} type 12db (0), ladder (1), or 24db (2) * @example * note("{f g g c d a a#}%8").s("sawtooth").lpenv(4).lpf(500).ftype("<0 1 2>").lpq(1) @@ -1363,7 +1363,7 @@ export const { ftype } = registerControl('ftype'); /** * controls the center of the filter envelope. 0 is unipolar positive, .5 is bipolar, 1 is unipolar negative * @name fanchor - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} center 0 to 1 * @example * note("{f g g c d a a#}%8").s("sawtooth").lpf("{1000}%2") @@ -1376,7 +1376,7 @@ export const { fanchor } = registerControl('fanchor'); * When using mininotation, you can also optionally add the 'hpq' parameter, separated by ':'. * * @name hpf - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms hp, hcutoff * @example @@ -1391,7 +1391,7 @@ export const { fanchor } = registerControl('fanchor'); * Applies a vibrato to the frequency of the oscillator. * * @name vib - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @synonyms vibrato, v * @param {number | Pattern} frequency of the vibrato in hertz * @example @@ -1419,7 +1419,7 @@ export const { noise } = registerControl('noise'); * Sets the vibrato depth in semitones. Only has an effect if `vibrato` | `vib` | `v` is is also set * * @name vibmod - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @synonyms vmod * @param {number | Pattern} depth of vibrato (in semitones) * @example @@ -1438,7 +1438,7 @@ export const { hcutoff, hpf, hp } = registerControl(['hcutoff', 'hresonance', 'h * Controls the **h**igh-**p**ass **q**-value. * * @name hpq - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms hresonance * @example @@ -1450,7 +1450,7 @@ export const { hresonance, hpq } = registerControl('hresonance', 'hpq'); * Controls the **l**ow-**p**ass **q**-value. * * @name lpq - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms resonance * @example @@ -1463,7 +1463,7 @@ export const { resonance, lpq } = registerControl('resonance', 'lpq'); * DJ filter, below 0.5 is low pass filter, above is high pass filter. * * @name djf - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} cutoff below 0.5 is low pass filter, above is high pass filter * @example * n(irand(16).seg(8)).scale("d:phrygian").s("supersaw").djf("<.5 .3 .2 .75>") @@ -1480,7 +1480,7 @@ export const { djf } = registerControl('djf'); * * * @name delay - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} level between 0 and 1 * @example * s("bd bd").delay("<0 .25 .5 1>") @@ -1494,7 +1494,7 @@ export const { delay } = registerControl(['delay', 'delaytime', 'delayfeedback'] * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1508,7 +1508,7 @@ export const { delayfeedback, delayfb, dfb } = registerControl('delayfeedback', * Caution: Values >= 1 will result in a signal that gets louder and louder! Don't do it * * @name delayfeedback - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1520,7 +1520,7 @@ export const { delayspeed } = registerControl('delayspeed'); * Sets the time of the delay effect. * * @name delayspeed - * @tags effects + * @tags fx * @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @synonyms delayt, dt * @example @@ -1533,7 +1533,7 @@ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', * Sets the time of the delay effect in cycles. * * @name delaysync - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} cycles delay length in cycles * @synonyms delayt, dt * @example @@ -1546,7 +1546,7 @@ export const { delaysync } = registerControl('delaysync'); * Specifies whether delaytime is calculated relative to cps. * * @name lock - * @tags effects + * @tags fx * @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle. * @superdirtOnly * @example @@ -1560,7 +1560,7 @@ export const { lock } = registerControl('lock'); * Set detune for stacked voices of supported oscillators * * @name detune - * @tags effects + * @tags fx * @param {number | Pattern} amount * @synonyms det * @example @@ -1572,7 +1572,7 @@ export const { detune, det } = registerControl('detune', 'det'); * Set number of stacked voices for supported oscillators * * @name unison - * @tags effects + * @tags fx * @param {number | Pattern} numvoices * @example * note("d f a a# a d3").fast(2).s("supersaw").unison("<1 2 7>") @@ -1584,7 +1584,7 @@ export const { unison } = registerControl('unison'); * Set the stereo pan spread for supported oscillators * * @name spread - * @tags effects + * @tags fx * @param {number | Pattern} spread between 0 and 1 * @example * note("d f a a# a d3").fast(2).s("supersaw").spread("<0 .3 1>") @@ -1595,7 +1595,7 @@ export const { spread } = registerControl('spread'); * Set dryness of reverb. See `room` and `size` for more information about reverb. * * @name dry - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} dry 0 = wet, 1 = dry * @example * n("[0,3,7](3,8)").s("superpiano").room(.7).dry("<0 .5 .75 1>").osc() @@ -1635,7 +1635,7 @@ export const { freq } = registerControl('freq'); * Attack time of pitch envelope. * * @name pattack - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @synonyms patt * @param {number | Pattern} time time in seconds * @example @@ -1647,7 +1647,7 @@ export const { pattack, patt } = registerControl('pattack', 'patt'); * Decay time of pitch envelope. * * @name pdecay - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @synonyms pdec * @param {number | Pattern} time time in seconds * @example @@ -1661,7 +1661,7 @@ export const { psustain, psus } = registerControl('psustain', 'psus'); * Release time of pitch envelope * * @name prelease - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @synonyms prel * @param {number | Pattern} time time in seconds * @example @@ -1676,7 +1676,7 @@ export const { prelease, prel } = registerControl('prelease', 'prel'); * If you don't set other pitch envelope controls, `pattack:.2` will be the default. * * @name penv - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} semitones change in semitones * @example * note("c") @@ -1688,7 +1688,7 @@ export const { penv } = registerControl('penv'); * Curve of envelope. Defaults to linear. exponential is good for kicks * * @name pcurve - * @tags effects + * @tags fx * @param {number | Pattern} type 0 = linear, 1 = exponential * @example * note("g1*4") @@ -1705,7 +1705,7 @@ export const { pcurve } = registerControl('pcurve'); * If you don't set an anchor, the value will default to the psustain value. * * @name panchor - * @tags effects + * @tags fx * @param {number | Pattern} anchor anchor offset * @example * note("c c4").penv(12).panchor("<0 .5 1 .5>") @@ -1727,7 +1727,7 @@ export const { gate, gat } = registerControl('gate', 'gat'); * Emulation of a Leslie speaker: speakers rotating in a wooden amplified cabinet. * * @name leslie - * @tags effects + * @tags fx * @param {number | Pattern} wet between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie("<0 .4 .6 1>").osc() @@ -1739,7 +1739,7 @@ export const { leslie } = registerControl('leslie'); * Rate of modulation / rotation for leslie effect * * @name lrate - * @tags effects + * @tags fx * @param {number | Pattern} rate 6.7 for fast, 0.7 for slow * @example * n("0,4,7").s("supersquare").leslie(1).lrate("<1 2 4 8>").osc() @@ -1752,7 +1752,7 @@ export const { lrate } = registerControl('lrate'); * Physical size of the cabinet in meters. Be careful, it might be slightly larger than your computer. Affects the Doppler amount (pitch warble) * * @name lsize - * @tags effects + * @tags fx * @param {number | Pattern} meters somewhere between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie(1).lrate(2).lsize("<.1 .5 1>").osc() @@ -1814,7 +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. * * @name orbit - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} number * @example * stack( @@ -1831,7 +1831,7 @@ export const { overshape } = registerControl('overshape'); * Sets position in stereo. * * @name pan - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @param {number | Pattern} pan between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel) * @example * s("[bd hh]*2").pan("<.5 1 .5 0>") @@ -1897,7 +1897,7 @@ export const { mode } = registerControl(['mode', 'anchor']); * When using mininotation, you can also optionally add the 'size' parameter, separated by ':'. * * @name room - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} level between 0 and 1 * @example * s("bd sd [~ bd] sd").room("<0 .2 .4 .6 .8 1>") @@ -1911,7 +1911,7 @@ export const { room } = registerControl(['room', 'size']); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomlp - * @tags effects, superdough + * @tags fx, superdough * @synonyms rlp * @param {number} frequency between 0 and 20000hz * @example @@ -1925,7 +1925,7 @@ export const { roomlp, rlp } = registerControl('roomlp', 'rlp'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomdim - * @tags effects, superdough + * @tags fx, superdough * @synonyms rdim * @param {number} frequency between 0 and 20000hz * @example @@ -1940,7 +1940,7 @@ export const { roomdim, rdim } = registerControl('roomdim', 'rdim'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomfade - * @tags effects, superdough + * @tags fx, superdough * @synonyms rfade * @param {number} seconds for the reverb to fade * @example @@ -1953,7 +1953,7 @@ export const { roomfade, rfade } = registerControl('roomfade', 'rfade'); /** * Sets the sample to use as an impulse response for the reverb. * @name iresponse - * @tags effects, superdough + * @tags fx, superdough * @param {string | Pattern} sample to use as an impulse response * @synonyms ir * @example @@ -1965,7 +1965,7 @@ export const { ir, iresponse } = registerControl(['ir', 'i'], 'iresponse'); /** * Sets speed of the sample for the impulse response. * @name irspeed - * @tags effects, superdough + * @tags fx, superdough * @param {string | Pattern} speed * @example * samples('github:switchangel/pad') @@ -1977,7 +1977,7 @@ export const { irspeed } = registerControl('irspeed'); /** * Sets the beginning of the IR response sample * @name irbegin - * @tags effects, superdough + * @tags fx, superdough * @param {string | Pattern} begin between 0 and 1 * @synonyms ir * @example @@ -1991,7 +1991,7 @@ export const { irbegin } = registerControl('irbegin'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomsize - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} size between 0 and 10 * @synonyms rsize, sz, size * @example @@ -2015,7 +2015,7 @@ export const { roomsize, size, sz, rsize } = registerControl('roomsize', 'size', * * * @name shape - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} distortion between 0 and 1 * @example * s("bd sd [~ bd] sd,hh*8").shape("<0 .2 .4 .6 .8>") @@ -2028,7 +2028,7 @@ export const { shape } = registerControl(['shape', 'shapevol']); * Most useful values are usually between 0 and 10 (depending on source gain). If you are feeling adventurous, you can turn it up to 11 and beyond ;) * * @name distort - * @tags effects, superdough, supradough + * @tags fx, superdough, supradough * @synonyms dist * @param {number | Pattern} distortion * @example @@ -2043,7 +2043,7 @@ export const { distort, dist } = registerControl(['distort', 'distortvol'], 'dis * More info [here](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) * * @name compressor - * @tags effects, superdough + * @tags fx, superdough * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02") @@ -2064,7 +2064,7 @@ export const { compressorRelease } = registerControl('compressorRelease'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name speed - * @tags effects + * @tags fx * @param {number | Pattern} speed -inf to inf, negative numbers play the sample backwards. * @example * s("bd*6").speed("1 2 4 1 -2 -4") @@ -2078,7 +2078,7 @@ export const { speed } = registerControl('speed'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name stretch - * @tags effects + * @tags fx * @param {number | Pattern} factor -inf to inf, negative numbers play the sample backwards. * @example * s("gm_flute").stretch("1 2 .5") @@ -2089,7 +2089,7 @@ export const { stretch } = registerControl('stretch'); * Used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`. * * @name unit - * @tags effects + * @tags fx * @param {number | string | Pattern} unit see description above * @example * speed("1 2 .5 3").s("bd").unit("c").osc() @@ -2104,7 +2104,7 @@ export const { unit } = registerControl('unit'); * "A simplistic pitch-raising algorithm. It's not meant to sound natural; its sound is reminiscent of some weird mixture of filter, ring-modulator and pitch-shifter, depending on the input. The algorithm works by cutting the signal into fragments (delimited by upwards-going zero-crossings) and squeezing those fragments in the time domain (i.e. simply playing them back faster than they came in), leaving silences inbetween. All the parameters apart from memlen can be modulated." * * @name squiz - * @tags effects + * @tags fx * @param {number | Pattern} squiz Try passing multiples of 2 to it - 2, 4, 8 etc. * @example * squiz("2 4/2 6 [8 16]").s("bd").osc() @@ -2129,7 +2129,7 @@ export const { squiz } = registerControl('squiz'); * Formant filter to make things sound like vowels. * * @name vowel - * @tags effects, superdough + * @tags fx, superdough * @param {string | Pattern} vowel You can use a e i o u ae aa oe ue y uh un en an on, corresponding to [a] [e] [i] [o] [u] [æ] [ɑ] [ø] [y] [ɯ] [ʌ] [œ̃] [ɛ̃] [ɑ̃] [ɔ̃]. Aliases: aa = å = ɑ, oe = ø = ö, y = ı, ae = æ. * @example * note("[c2 >]*2").s('sawtooth') @@ -2154,7 +2154,7 @@ export const { waveloss } = registerControl('waveloss'); * Noise crackle density * * @name density - * @tags effects, superdough + * @tags fx, superdough * @param {number | Pattern} density between 0 and x * @example * s("crackle*4").density("<0.01 0.04 0.2 0.5>".slow(4)) @@ -2262,7 +2262,7 @@ export let createParams = (...names) => * ADSR envelope: Combination of Attack, Decay, Sustain, and Release. * * @name adsr - * @tags effects + * @tags fx * @param {number | Pattern} time attack time in seconds * @param {number | Pattern} time decay time in seconds * @param {number | Pattern} gain sustain level (0 to 1) diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index cfc669c83..677d83628 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -180,7 +180,7 @@ export function registerWaveTable(key, tables, params) { * Loads a collection of wavetables to use with `s` * * @name tables - * @tags effects + * @tags fx */ export const tables = async (url, frameLen, json, options = {}) => { if (json !== undefined) return _processTables(json, url, frameLen); diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 23dfbee09..9b5bf189e 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -18,7 +18,7 @@ function applyGainCurve(val) { * @param {number} a - Signal A (can be a single value or an array value in buffer processing). * @param {number} b - Signal B (can be a single value or an array value in buffer processing). * @param {number} m - Crossfade parameter (0.0 = all A, 1.0 = all B, 0.5 = equal mix). - * @tags effects + * @noAutocomplete * @returns {number} Crossfaded output value. */ function crossfade(a, b, m) { From 7e4cbefc8fa812769f35eb9da29d3f50839518e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 19 Oct 2025 21:22:57 +0200 Subject: [PATCH 14/26] Tag crossfade as internals --- packages/supradough/dough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/supradough/dough.mjs b/packages/supradough/dough.mjs index 9b5bf189e..a31097339 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -18,7 +18,7 @@ function applyGainCurve(val) { * @param {number} a - Signal A (can be a single value or an array value in buffer processing). * @param {number} b - Signal B (can be a single value or an array value in buffer processing). * @param {number} m - Crossfade parameter (0.0 = all A, 1.0 = all B, 0.5 = equal mix). - * @noAutocomplete + * @tags internals * @returns {number} Crossfaded output value. */ function crossfade(a, b, m) { From 466bf819d883b7f2e35a5dc617727c53765d71cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 19 Oct 2025 21:38:46 +0200 Subject: [PATCH 15/26] Fix formatting (trailing space) --- packages/superdough/worklets.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 3e8276225..b99b9caf6 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -852,7 +852,7 @@ class PulseOscillatorProcessor extends AudioWorkletProcessor { registerProcessor('pulse-oscillator', PulseOscillatorProcessor); /** BYTE BEATS - * @tags internals + * @tags internals */ const chyx = { /*bit*/ bitC: function (x, y, z) { From 0830a9df69ddd49bcec08f25b58b390a103bbb74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 1 Nov 2025 20:19:57 +0100 Subject: [PATCH 16/26] Add superdirt tags --- packages/core/controls.mjs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 1bfd5a892..da5337ecf 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -399,7 +399,7 @@ export const { note } = registerControl(['note', 'n']); * A pattern of numbers that speed up (or slow down) samples while they play. Currently only supported by osc / superdirt. * * @name accelerate - * @tags samples + * @tags samples, superdirt * @param {number | Pattern} amount acceleration. * @superdirtOnly * @example @@ -444,7 +444,7 @@ export const { postgain } = registerControl('postgain'); * Like `gain`, but linear. * * @name amp - * @tags fx + * @tags fx, superdirt * @param {number | Pattern} amount gain. * @superdirtOnly * @example @@ -1075,7 +1075,7 @@ export const { phasercenter, phc } = registerControl('phasercenter', 'phc'); * The amount the signal is affected by the phaser effect. Defaults to 0.75 * * @name phaserdepth - * @tags fx, superdough + * @tags fx, superdough, superdirt * @synonyms phd, phasdp * @param {number | Pattern} depth number between 0 and 1 * @example @@ -1546,7 +1546,7 @@ export const { delaysync } = registerControl('delaysync'); * Specifies whether delaytime is calculated relative to cps. * * @name lock - * @tags fx + * @tags fx, superdirt * @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle. * @superdirtOnly * @example @@ -1595,7 +1595,7 @@ export const { spread } = registerControl('spread'); * Set dryness of reverb. See `room` and `size` for more information about reverb. * * @name dry - * @tags fx, superdough + * @tags fx, superdough, superdirt * @param {number | Pattern} dry 0 = wet, 1 = dry * @example * n("[0,3,7](3,8)").s("superpiano").room(.7).dry("<0 .5 .75 1>").osc() @@ -1727,7 +1727,7 @@ export const { gate, gat } = registerControl('gate', 'gat'); * Emulation of a Leslie speaker: speakers rotating in a wooden amplified cabinet. * * @name leslie - * @tags fx + * @tags fx, superdirt * @param {number | Pattern} wet between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie("<0 .4 .6 1>").osc() @@ -1739,7 +1739,7 @@ export const { leslie } = registerControl('leslie'); * Rate of modulation / rotation for leslie effect * * @name lrate - * @tags fx + * @tags fx, superdirt * @param {number | Pattern} rate 6.7 for fast, 0.7 for slow * @example * n("0,4,7").s("supersquare").leslie(1).lrate("<1 2 4 8>").osc() @@ -1752,7 +1752,7 @@ export const { lrate } = registerControl('lrate'); * Physical size of the cabinet in meters. Be careful, it might be slightly larger than your computer. Affects the Doppler amount (pitch warble) * * @name lsize - * @tags fx + * @tags fx, superdirt * @param {number | Pattern} meters somewhere between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie(1).lrate(2).lsize("<.1 .5 1>").osc() @@ -1801,6 +1801,7 @@ export const { nudge } = registerControl('nudge'); * Sets the default octave of a synth. * * @name octave + * @tags fx, superdirt * @param {number | Pattern} octave octave number * @example * n("0,4,7").s('supersquare').octave("<3 4 5 6>").osc() @@ -2089,7 +2090,7 @@ export const { stretch } = registerControl('stretch'); * Used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`. * * @name unit - * @tags fx + * @tags fx, superdirt * @param {number | string | Pattern} unit see description above * @example * speed("1 2 .5 3").s("bd").unit("c").osc() @@ -2104,7 +2105,7 @@ export const { unit } = registerControl('unit'); * "A simplistic pitch-raising algorithm. It's not meant to sound natural; its sound is reminiscent of some weird mixture of filter, ring-modulator and pitch-shifter, depending on the input. The algorithm works by cutting the signal into fragments (delimited by upwards-going zero-crossings) and squeezing those fragments in the time domain (i.e. simply playing them back faster than they came in), leaving silences inbetween. All the parameters apart from memlen can be modulated." * * @name squiz - * @tags fx + * @tags fx, superdirt * @param {number | Pattern} squiz Try passing multiples of 2 to it - 2, 4, 8 etc. * @example * squiz("2 4/2 6 [8 16]").s("bd").osc() From b7827cb89f16624773f9c5717d64419d1a729154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 1 Nov 2025 21:11:57 +0100 Subject: [PATCH 17/26] Tag new functions --- packages/core/controls.mjs | 4 ++ packages/core/pattern.mjs | 9 ++++ .../src/repl/components/panel/Reference.jsx | 42 ++++--------------- 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 50a494864..7c66b4002 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -2049,6 +2049,7 @@ export const { distort, dist } = registerControl(['distort', 'distortvol', 'dist * * @name distortvol * @synonyms distvol + * @tags fx, superdough, supradough * @param {number | Pattern} volume linear postgain of the distortion * @example * s("bd*4").bank("tr909").distort(2).distortvol(0.8) @@ -2059,6 +2060,7 @@ export const { distortvol } = registerControl('distortvol', 'distvol'); * Type of waveshaping distortion to apply. * * @name distorttype + * @tags fx, superdough, supradough * @synonyms disttype * @param {number | string | Pattern} type type of distortion to apply * @example @@ -2487,6 +2489,7 @@ export const { polyTouch } = registerControl('polyTouch'); /** * The host to send open sound control messages to. Requires running the OSC bridge. * @name oschost + * @tags external_io * @param {string | Pattern} oschost e.g. 'localhost' * @example * note("c4").oschost('127.0.0.1').oscport(57120).osc(); @@ -2496,6 +2499,7 @@ export const { oschost } = registerControl('oschost'); /** * The port to send open sound control messages to. Requires running the OSC bridge. * @name oscport + * @tags external_io * @param {number | Pattern} oscport e.g. 57120 * @example * note("c4").oschost('127.0.0.1').oscport(57120).osc(); diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 8cb30e155..e8cd3d23f 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -3128,6 +3128,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 * @example * stepcat( * sound("bd bd - cp").replicate(2), @@ -3697,6 +3698,7 @@ export const morph = (frompat, topat, bypat) => { * Soft-clipping distortion * * @name soft + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3705,6 +3707,7 @@ export const morph = (frompat, topat, bypat) => { * Hard-clipping distortion * * @name hard + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3713,6 +3716,7 @@ export const morph = (frompat, topat, bypat) => { * Cubic polynomial distortion * * @name cubic + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3721,6 +3725,7 @@ export const morph = (frompat, topat, bypat) => { * Diode-emulating distortion * * @name diode + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3729,6 +3734,7 @@ export const morph = (frompat, topat, bypat) => { * Asymmetrical diode distortion * * @name asym + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3737,6 +3743,7 @@ export const morph = (frompat, topat, bypat) => { * Wavefolding distortion * * @name fold + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3745,6 +3752,7 @@ export const morph = (frompat, topat, bypat) => { * Wavefolding distortion composed with sinusoid * * @name sinefold + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3753,6 +3761,7 @@ export const morph = (frompat, topat, bypat) => { * Distortion via Chebyshev polynomials * * @name chebyshev + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 2a7dcc2a8..3053f03dc 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -11,8 +11,13 @@ const availableFunctions = (() => { for (const doc of jsdocJson.docs) { if (!isValid(doc)) continue; if (seen.has(doc.name)) continue; - doc.tags = doc.tags?.filter((t) => t && typeof t === 'string') || []; + + // 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. + // If nothing is specified, we default to "untagged" for debugging + doc.tags = doc.tags?.filter((t) => t && typeof t === 'string') || ['untagged']; functions.push(doc); + const synonyms = doc.synonyms || []; seen.add(doc.name); for (const s of synonyms) { @@ -38,16 +43,6 @@ const getInnerText = (html) => { return div.textContent || div.innerText || ''; }; -const GROUP_DISPLAY_NAMES = { - external_io: 'External I/O', - effects: 'Effects', - untagged: 'Untagged', - structure: 'Structure', - transforms: 'Transforms', -}; - -const GROUP_ORDER = ['effects', 'transforms', 'structure', 'untagged', 'external_io']; - export function Reference() { const [search, setSearch] = useState(''); const [selectedTag, setSelectedTag] = useState(null); @@ -80,29 +75,6 @@ export function Reference() { }); }, [search, selectedTag]); - const visibleFunctionsByGroup = (() => { - const groups = {}; - for (const doc of visibleFunctions) { - const group = (doc.tags || ['untagged'])[0]; - if (!groups[group]) { - groups[group] = []; - } - groups[group].push(doc); - } - return groups; - })(); - // console.log(visibleFunctionsByGroup); - - // Sort and map group entries - const sortedGroups = Object.entries(visibleFunctionsByGroup).sort(([a], [b]) => { - const ai = GROUP_ORDER.indexOf(a); - const bi = GROUP_ORDER.indexOf(b); - if (ai === -1 && bi === -1) return a.localeCompare(b); - if (ai === -1) return 1; - if (bi === -1) return -1; - return ai - bi; - }); - const tagCounts = {}; for (const doc of availableFunctions) { (doc.tags || ['untagged']).forEach((t) => { @@ -114,7 +86,7 @@ export function Reference() { return (

-
+
From 2fa8ed14245b45cce91708495befa82afe50745b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 9 Nov 2025 20:21:19 +0100 Subject: [PATCH 18/26] Revert seq synonym refactor --- packages/core/pattern.mjs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index e8cd3d23f..b8376c8ff 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -1566,6 +1566,11 @@ export function fastcat(...pats) { return result; } +/** See `fastcat` */ +export function sequence(...pats) { + return fastcat(...pats); +} + /** Like **cat**, but the items are crammed into one cycle. * @tags combiners * @synonyms seq, fastcat @@ -1579,9 +1584,6 @@ export function fastcat(...pats) { * note("c4(5,8)") * ) */ -export function sequence(...pats) { - return fastcat(...pats); -} export function seq(...pats) { return fastcat(...pats); From 726e5ef14a6de2aab36202434ac52ae45c5e551f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 10 Jan 2026 07:18:29 -0800 Subject: [PATCH 19/26] Fix formatting --- packages/midi/midi.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index 9b32f6de4..63faeaf41 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -488,7 +488,7 @@ const refsByChan = {}; * MIDI input: Opens a MIDI input port to receive MIDI control change messages. * * The output is a function that accepts a midi cc value to query as well as (optionally) a midi channel - * @tags external_io + * @tags external_io * @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) From 550d7ff6cb84fe3273256c2153cb869bc27d1263 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 11 Jan 2026 12:32:54 +0100 Subject: [PATCH 20/26] fix: react error --- website/src/repl/components/panel/Reference.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 3053f03dc..34701036d 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from 'react'; +import { useMemo, useState, Fragment } from 'react'; import jsdocJson from '../../../../../doc.json'; import { Textbox } from '../textbox/Textbox'; @@ -109,9 +109,8 @@ export function Reference() {
From 9ffd0e496fcb71fcbc46add25eef7e40f56d4fb6 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 11 Jan 2026 12:33:03 +0100 Subject: [PATCH 21/26] fix: all doc --- packages/core/repl.mjs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 047989f7f..9fe8eef81 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -120,7 +120,9 @@ export function repl({ // TODO - not documented as jsdoc examples as the test framework doesn't simulate enough context for `each` and `all`.. - /** Applies a function to all the running patterns. Note that the patterns are groups together into a single `stack` before the function is applied. This is probably what you want, but see `each` for + let allTransforms = []; + /** + * Applies a function to all the running patterns. Note that the patterns are groups together into a single `stack` before the function is applied. This is probably what you want, but see `each` for * a version that applies the function to each pattern separately. * ``` * $: sound("bd - cp sd") @@ -135,7 +137,6 @@ export function repl({ * * @tags combiners */ - let allTransforms = []; const all = function (transform) { allTransforms.push(transform); return silence; From 77076a1c3eeed4a1d9f070336c8805ed9d6349b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 17 Jan 2026 19:12:23 +0100 Subject: [PATCH 22/26] Improve reference search/filtering semantics --- .../src/repl/components/panel/Reference.jsx | 125 +++++++++++++----- 1 file changed, 92 insertions(+), 33 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index c943db144..24d4a6773 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import jsdocJson from '../../../../../doc.json'; import { Textbox } from '../textbox/Textbox'; @@ -46,6 +46,7 @@ const getInnerText = (html) => { export function Reference() { const [search, setSearch] = useState(''); const [selectedTag, setSelectedTag] = useState(null); + const [selectedFunction, setSelectedFunction] = useState(null); const toggleTag = (tag) => { if (selectedTag === tag) { @@ -55,7 +56,7 @@ export function Reference() { } }; - const visibleFunctions = useMemo(() => { + const searchVisibleFunctions = useMemo(() => { return availableFunctions.filter((entry) => { if (selectedTag) { if (!(entry.tags || ['untagged']).includes(selectedTag)) { @@ -63,6 +64,14 @@ export function Reference() { } } + // if (entry.name === selectedFunction) { + // return true; + // } + + // if (!selectedTag) { + // return false; + // } + if (!search) { return true; } @@ -75,6 +84,19 @@ export function Reference() { }); }, [search, selectedTag]); + const detailVisibleFunctions = useMemo(() => { + return searchVisibleFunctions.filter((x) => { + if (selectedTag === null) { + if (search) { + return true; + } + return x.name === selectedFunction; + } else { + return true; + } + }); + }, [searchVisibleFunctions, selectedFunction, selectedTag]); + const tagCounts = {}; for (const doc of availableFunctions) { (doc.tags || ['untagged']).forEach((t) => { @@ -84,42 +106,60 @@ export function Reference() { }); } + const onSearchTagFilterClick = () => { + const container = document.getElementById('reference-container'); + container.scrollTo(0, 0); + setSelectedTag(null); + setSelectedFunction(null); + }; + + useEffect(() => { + if (selectedFunction) { + const el = document.getElementById(`doc-${selectedFunction}`); + const container = document.getElementById('reference-container'); + container.scrollTo(0, el.offsetTop); + } + }, [selectedFunction]); + return ( - //
- //
- //
-
+
- -
- {Object.entries(tagCounts) - .sort(([a], [b]) => a.localeCompare(b)) - .map(([t, count]) => ( - - toggleTag(t)} - > - {t} ({count}) - {' '} - - ))} -
+ { + setSelectedFunction(null); + setSearch(e); + }} + />
-
- {visibleFunctions.map((entry, i) => ( + {selectedTag && ( +
+ + {selectedTag ? selectedTag + ' x' : 'Filter by tag'} + +
+ )} +
+ {searchVisibleFunctions.map((entry, i) => ( <> { - const el = document.getElementById(`doc-${entry.name}`); - const container = document.getElementById('reference-container'); - container.scrollTo(0, el.offsetTop); + if (entry.name === selectedFunction) { + setSelectedFunction(null); + } else { + setSelectedFunction(entry.name); + } }} > {entry.name} @@ -134,11 +174,28 @@ export function Reference() { >

API Reference

-

+

This is the long list of functions you can use. Remember that you don't need to remember all of those and that you can already make music with a small set of functions!

- {visibleFunctions.map((entry, i) => ( +
+ {detailVisibleFunctions.map((entry, i) => (

@@ -170,7 +227,9 @@ export function Reference() { ))}

- ))} + )) ||

Searcb or select a tag to get started.

} + {detailVisibleFunctions.length > 0 &&
} + {/* {!selectedTag &&

Select a tag to see the functions.

} */}
From 42d0bfadceba9cae8b276eba55aea578ddc28436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 17 Jan 2026 20:08:23 +0100 Subject: [PATCH 23/26] Clean up --- .../src/repl/components/panel/Reference.jsx | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 8a018ff90..950949b90 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -25,13 +25,13 @@ const availableFunctions = (() => { seen.add(s); // Swap `doc.name` in for `s` in the list of synonyms const synonymsWithDoc = [doc.name, ...synonyms].filter((x) => x && x !== s); - // functions.push({ - // ...doc, - // name: s, // update names for the synonym - // longname: s, - // synonyms: synonymsWithDoc, - // synonyms_text: synonymsWithDoc.join(', '), - // }); + functions.push({ + ...doc, + name: s, // update names for the synonym + longname: s, + synonyms: synonymsWithDoc, + synonyms_text: synonymsWithDoc.join(', '), + }); } } return functions.sort((a, b) => /* a.meta.filename.localeCompare(b.meta.filename) + */ a.name.localeCompare(b.name)); @@ -64,14 +64,6 @@ export function Reference() { } } - // if (entry.name === selectedFunction) { - // return true; - // } - - // if (!selectedTag) { - // return false; - // } - if (!search) { return true; } @@ -228,7 +220,6 @@ export function Reference() {
)) ||

Searcb or select a tag to get started.

} {detailVisibleFunctions.length > 0 &&
} - {/* {!selectedTag &&

Select a tag to see the functions.

} */}
From 99cf256ee253b12057775e689dfd3c73c943b504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sat, 17 Jan 2026 20:11:26 +0100 Subject: [PATCH 24/26] Clean up 2 --- website/src/repl/components/panel/Reference.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx index 950949b90..e5bb56000 100644 --- a/website/src/repl/components/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -99,8 +99,6 @@ export function Reference() { } const onSearchTagFilterClick = () => { - const container = document.getElementById('reference-container'); - container.scrollTo(0, 0); setSelectedTag(null); setSelectedFunction(null); }; @@ -133,7 +131,7 @@ export function Reference() { className="text-foreground border-2 border-gray-500 px-1 py-0.5 my-2 rounded-md cursor-pointer font-sans" onClick={onSearchTagFilterClick} > - {selectedTag ? selectedTag + ' x' : 'Filter by tag'} + {selectedTag}
)} From 6e36bdfff7995fcd93c3b3575b00003f6a60958a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 18 Jan 2026 12:08:12 +0100 Subject: [PATCH 25/26] Add tags for some of the new functions --- packages/core/controls.mjs | 34 ++++++++++++++++++++++++++++++ packages/core/pattern.mjs | 8 ++++++- packages/core/signal.mjs | 3 +++ packages/midi/midi.mjs | 1 + packages/superdough/superdough.mjs | 2 ++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 59d9f1aa3..834d963c3 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -702,6 +702,7 @@ export const { * any of the 8 individual FMs (e.g. `fmrel8`) * * @name fmrelease + * @tags fx, superdough, supradough * @synonyms fmrel * @param {number | Pattern} time release time * @@ -1553,6 +1554,7 @@ export const { fanchor } = registerControl('fanchor'); * Rate of the LFO for the lowpass filter * * @name lprate + * @tags fx, superdough * @param {number | Pattern} rate rate in hertz * @example * note("*16").s("sawtooth").lpf(600).lprate("<4 8 2 1>") @@ -1563,6 +1565,7 @@ export const { lprate } = registerControl('lprate'); * Cycle-synced rate of the LFO for the lowpass filter * * @name lpsync + * @tags fx, superdough * @param {number | Pattern} rate rate in cycles * @example * note("*16").s("sawtooth").lpf(600).lpsync("<4 8 2 1>") @@ -1573,6 +1576,7 @@ export const { lpsync } = registerControl('lpsync'); * Depth of the LFO for the lowpass filter * * @name lpdepth + * @tags fx, superdough * @param {number | Pattern} depth depth of modulation * @example * note("*16").s("sawtooth").lpf(600).lpdepth("<1 .5 1.8 0>") @@ -1583,6 +1587,7 @@ export const { lpdepth } = registerControl('lpdepth'); * Depth of the LFO for the lowpass filter, in HZ * * @name lpdepthfrequency + * @tags fx, superdough * @synonyms lpdepthfreq * @param {number | Pattern} depth depth of modulation * @example @@ -1595,6 +1600,7 @@ export const { lpdepthfrequency, lpdepthfreq } = registerControl('lpdepthfrequen * Shape of the LFO for the lowpass filter * * @name lpshape + * @tags fx, superdough * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { lpshape } = registerControl('lpshape'); @@ -1603,6 +1609,7 @@ export const { lpshape } = registerControl('lpshape'); * DC offset of the LFO for the lowpass filter * * @name lpdc + * @tags fx, superdough * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { lpdc } = registerControl('lpdc'); @@ -1611,6 +1618,7 @@ export const { lpdc } = registerControl('lpdc'); * Skew of the LFO for the lowpass filter * * @name lpskew + * @tags fx, superdough * @param {number | Pattern} skew How much to bend the LFO shape */ export const { lpskew } = registerControl('lpskew'); @@ -1619,6 +1627,7 @@ export const { lpskew } = registerControl('lpskew'); * Rate of the LFO for the bandpass filter * * @name bprate + * @tags fx, superdough * @param {number | Pattern} rate rate in hertz */ export const { bprate } = registerControl('bprate'); @@ -1627,6 +1636,7 @@ export const { bprate } = registerControl('bprate'); * Cycle-synced rate of the LFO for the bandpass filter * * @name bpsync + * @tags fx, superdough * @param {number | Pattern} rate rate in cycles */ export const { bpsync } = registerControl('bpsync'); @@ -1635,6 +1645,7 @@ export const { bpsync } = registerControl('bpsync'); * Depth of the LFO for the bandpass filter * * @name bpdepth + * @tags fx, superdough * @param {number | Pattern} depth depth of modulation */ export const { bpdepth } = registerControl('bpdepth'); @@ -1643,6 +1654,7 @@ export const { bpdepth } = registerControl('bpdepth'); * Depth of the LFO for the bandpass filter, in HZ * * @name bpdepthfrequency + * @tags fx, superdough * @synonyms bpdepthfreq * @param {number | Pattern} depth depth of modulation * @example @@ -1655,6 +1667,7 @@ export const { bpdepthfrequency, bpdepthfreq } = registerControl('bpdepthfrequen * Shape of the LFO for the bandpass filter * * @name bpshape + * @tags fx, superdough * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { bpshape } = registerControl('bpshape'); @@ -1663,6 +1676,7 @@ export const { bpshape } = registerControl('bpshape'); * DC offset of the LFO for the bandpass filter * * @name bpdc + * @tags fx, superdough * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { bpdc } = registerControl('bpdc'); @@ -1671,6 +1685,7 @@ export const { bpdc } = registerControl('bpdc'); * Skew of the LFO for the bandpass filter * * @name bpskew + * @tags fx, superdough * @param {number | Pattern} skew How much to bend the LFO shape */ export const { bpskew } = registerControl('bpskew'); @@ -1679,6 +1694,7 @@ export const { bpskew } = registerControl('bpskew'); * Rate of the LFO for the highpass filter * * @name hprate + * @tags fx, superdough * @param {number | Pattern} rate rate in hertz */ export const { hprate } = registerControl('hprate'); @@ -1687,6 +1703,7 @@ export const { hprate } = registerControl('hprate'); * Cycle-synced rate of the LFO for the highpass filter * * @name hpsync + * @tags fx, superdough * @param {number | Pattern} rate rate in cycles */ export const { hpsync } = registerControl('hpsync'); @@ -1695,6 +1712,7 @@ export const { hpsync } = registerControl('hpsync'); * Depth of the LFO for the highpass filter * * @name hpdepth + * @tags fx, superdough * @param {number | Pattern} depth depth of modulation */ export const { hpdepth } = registerControl('hpdepth'); @@ -1703,6 +1721,7 @@ export const { hpdepth } = registerControl('hpdepth'); * Depth of the LFO for the hipass filter, in hz * * @name hpdepthfrequency + * @tags fx, superdough * @synonyms hpdepthfreq * @param {number | Pattern} depth depth of modulation * @example @@ -1715,6 +1734,7 @@ export const { hpdepthfrequency, hpdepthfreq } = registerControl('hpdepthfrequen * Shape of the LFO for the highpass filter * * @name hpshape + * @tags fx, superdough * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { hpshape } = registerControl('hpshape'); @@ -1723,6 +1743,7 @@ export const { hpshape } = registerControl('hpshape'); * DC offset of the LFO for the highpass filter * * @name hpdc + * @tags fx, superdough * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { hpdc } = registerControl('hpdc'); @@ -1731,6 +1752,7 @@ export const { hpdc } = registerControl('hpdc'); * Skew of the LFO for the highpass filter * * @name hpskew + * @tags fx, superdough * @param {number | Pattern} skew How much to bend the LFO shape */ export const { hpskew } = registerControl('hpskew'); @@ -2182,6 +2204,7 @@ export const { orbit } = registerControl('orbit', 'o'); * otherPat.bmod(..) (to modulate another pattern with the bus) * * @name bus + * @tags fx, superdough * @param {number | Pattern} number */ export const { bus } = registerControl('bus'); @@ -2190,6 +2213,7 @@ export const { bus } = registerControl('bus'); * Postgain multiplier prior to sending the signal to the audio bus. * * @name busgain + * @tags fx, superdough * @synonyms bgain * @param {number | Pattern} number */ @@ -2252,6 +2276,7 @@ export const { voice } = registerControl('voice'); /** * The chord to voice * @name chord + * @tags music_theory * @param {string | Pattern} symbols chord symbols to voice e.g., C, Eb, Fm7, G7. The symbols can be defined via addVoicings * @example * chord("").voicing() @@ -2261,6 +2286,7 @@ export const { chord } = registerControl('chord'); * Which dictionary to use for the voicings. This falls back to the default dictionary if not provided * * @name dictionary + * @tags music_theory * @param {string} dictionaryName which dictionary (having been defined with `addVoicings`) to use * @example * addVoicings('house', { @@ -2275,6 +2301,7 @@ export const { dictionary, dict } = registerControl('dictionary', 'dict'); /** The top note to align the voicing to. Defaults to c5 * * @name anchor + * @tags music_theory * @param {string | Pattern} anchorNote the note to align the voicings to * @example * anchor("").chord("C").voicing() @@ -2284,6 +2311,7 @@ export const { anchor } = registerControl('anchor'); * Sets how the voicing is offset from the anchored position * * @name offset + * @tags music_theory * @param {number | Pattern} shift the amount to shift the voicing up or down * @example * chord("").offset("<0 1 2 3 4 5>") // alter the voicing each time @@ -2293,6 +2321,7 @@ export const { offset } = registerControl('offset'); * How many octaves are voicing steps spread apart, defaults to 1 * * @name octaves + * @tags music_theory * @param {number | Pattern} count the number of octaves * @example * chord("").octaves("<2 4>").voicing() @@ -2302,6 +2331,7 @@ export const { octaves } = registerControl('octaves'); * Remove anchor note from the voicing. Useful for melody harmonization * * @name mode + * @tags music_theory * @param {string | Pattern} modeName one of {below | above | duck | root} * @example * mode("").chord("C").voicing() @@ -3097,6 +3127,7 @@ Pattern.prototype.modulate = function (type, config, idPat) { * a `sometimes`. See example below. * * @name lfo + * @tags fx, superdough * @param {Object} config LFO configuration. * @param {string | Pattern} [config.control] Node to modulate. Aliases: c * @param {string | Pattern} [config.subControl] Sub-control name to append to the control key. Aliases: sc @@ -3150,6 +3181,7 @@ export const lfo = (config) => pure({}).lfo(config); * a `sometimes`. See example below. * * @name env + * @tags fx, superdough * @param {Object} config Envelope configuration. * @param {string | Pattern} [config.control] Node to modulate. Aliases: c * @param {string | Pattern} [config.subControl] Sub-control name to append to the control key. Aliases: sc @@ -3210,6 +3242,7 @@ export const env = (config) => pure({}).env(config); * a `sometimes`. See example below. * * @name bmod + * @tags fx, superdough * @param {Object} config Bus modulation configuration. * @param {string | Pattern} [config.bus] Bus to get modulation signal from * @param {string | Pattern} [config.control] Node to modulate. Aliases: c @@ -3236,6 +3269,7 @@ export const bmod = (config) => pure({}).bmod(config); * and sustains * * @name transient + * @tags fx, superdough * @param {number | Pattern} attack Emphasis on transients; between -1 (deaccentuate) and 1 (accentuate) * @param {number | Pattern} sustain Emphasis on the sustains; between -1 (deaccentuate) and 1 (accentuate) * @example diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index f22b29ff3..2b78a68f0 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -1572,7 +1572,10 @@ export function fastcat(...pats) { return result; } -/** See `fastcat` */ +/** See `fastcat` + * @name sequence + * @tags combiners + */ export function sequence(...pats) { return fastcat(...pats); } @@ -2377,6 +2380,7 @@ export const rev = register( * Reverse a whole pattern. See also `rev` for reversing each cycle. * * @name revv + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3903,6 +3907,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 * @memberof Pattern * @returns Pattern * @example @@ -3953,6 +3958,7 @@ const _asArrayPattern = (pats) => { * by wrapping them inside a function in K (see example). * * @name K + * @tags generators, fx, superdough * @param {KabelsalatExpression | Function} expr Kabelsalat graph definition * @memberof Pattern * @returns Pattern diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 18090bbd8..9827ddd21 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -286,6 +286,7 @@ export const getRandsAtTime = (t, n = 1, seed = 0) => { * precise RNG, try `useRNG('precise')`. * * @name useRNG + * @tags generators, internals * @param {string} mod - Mode. One of 'legacy', 'precise' * @example * useRNG('legacy') @@ -341,6 +342,7 @@ export const binaryN = (n, nBits = 16) => { * Creates a binary list pattern from a number. * * @name binaryL + * @tags generators * @param {number} n - input number to convert to binary * s("saw").seg(8) * .partials(binaryL(irand(4096).add(1))) @@ -354,6 +356,7 @@ export const binaryL = (n) => { * Creates a binary list pattern from a number, padded to n bits long. * * @name binaryNL + * @tags generators * @param {number} n - input number to convert to binary * @param {number} nBits - pattern length, defaults to 16 */ diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index e03dcbd05..8ce26c2a6 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -577,6 +577,7 @@ export async function midin(input) { * note durations * * @name midikeys + * @tags external_io * @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, diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 45c77d676..bcf235f3c 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -40,6 +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 * @param {number} Max polyphony. Defaults to 128 * @example * setMaxPolyphony(4) @@ -73,6 +74,7 @@ export function applyGainCurve(val) { * quadratic, exponential, etc. rather than linear * * @name setGainCurve + * @tags fx, superdough * @param {Function} function to apply to all gain values * @example * setGainCurve((x) => x * x) // quadratic gain From f8750901f0e08d7c7ff43daed5efa04daa47344f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Volhejn?= Date: Sun, 18 Jan 2026 12:16:50 +0100 Subject: [PATCH 26/26] Tag the remaining functions --- packages/core/pattern.mjs | 4 ++++ packages/core/signal.mjs | 9 ++++++++- packages/superdough/util.mjs | 4 +++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 2b78a68f0..b7a047bfc 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -1653,6 +1653,7 @@ export const func = curry((a, b) => reify(b).func(a)); /** * Registers a new pattern method. The method is added to the Pattern class + the standalone function is returned from register. * + * @tags functional * @param {string | string[]} name name of the function, or an array of names to be used as synonyms * @param {function} func function with 1 or more params, where last is the current pattern * @param {bool} patternify defaults to true; if set to false, you will have more control over the arguments to `func` as they will be @@ -3843,6 +3844,7 @@ export const chebyshev = _distortWithAlg('chebyshev'); * Turns a list of patterns into a single pattern which outputs list-values * * @name parray + * @tags combiners * @returns Pattern */ export const parray = (pats) => { @@ -3865,6 +3867,7 @@ const _ensureListPattern = (list) => { * Can also be used to create a new synth via `s('user').partials(...)` * * @name partials + * @tags fx, 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") @@ -3886,6 +3889,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 * @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 diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 9827ddd21..2f9fe4b18 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -286,7 +286,7 @@ export const getRandsAtTime = (t, n = 1, seed = 0) => { * precise RNG, try `useRNG('precise')`. * * @name useRNG - * @tags generators, internals + * @tags generators, math * @param {string} mod - Mode. One of 'legacy', 'precise' * @example * useRNG('legacy') @@ -376,6 +376,7 @@ export const binaryNL = (n, nBits = 16) => { * Creates a list of random numbers of the given length * * @name randL + * @tags generators * @param {number} n Number of random numbers to sample * @example * s("saw").seg(16).n(irand(12)).scale("F1:minor") @@ -434,6 +435,7 @@ export const scramble = register('scramble', (n, pat) => { /** * Modify a pattern by applying a function to the `randomSeed` control if present * + * @tags math * @param {Function} func Function from seed (or undefined) to seed (or undefined) * @param {Pattern} pat Pattern to update * @returns Pattern @@ -453,6 +455,7 @@ export const withSeed = (func, pat) => { * that use randomness, like `shuffle` and `sometimes`. * * @name seed + * @tags math * @param {number} n A new seed. Can be any number. * @example * $: s("hh*4").degrade(); @@ -1031,6 +1034,8 @@ export const keyDown = register('keyDown', function (pat) { * event durations, from the pattern that it is combined with. * For example `cyclesPer.struct("1 1 [1 1] 1")` would give the same as `"0.25 0.25 [0.125 0.125] 0.25"`. * See also its reciprocal, `per`, also known as `perCycle`. + * + * @tags temporal * @example * // Shorter events are lower in pitch * sound("saw saw [saw saw] saw") @@ -1049,6 +1054,7 @@ export const cyclesPer = new Pattern(function (state) { * event durations, from the pattern that it is combined with. * For example `per.struct("1 1 [1 1] 1")` would give the same as `"4 4 [8 8] 4"`. * See also its reciprocal, `cyclesPer`. + * @tags temporal * @synonyms perCycle * @example * // Shorter events are more distorted @@ -1066,6 +1072,7 @@ export const perCycle = per; * particular, where the event duration halves, the * returned value increases by one. `perx.struct("1 1 [1 [1 1]] 1")` would therefore be * the same as `"3 3 [4 [5 5]] 3"`. + * @tags temporal */ export const perx = new Pattern(function (state) { const n = Fraction(1).div(state.span.duration); diff --git a/packages/superdough/util.mjs b/packages/superdough/util.mjs index 48830541a..caa58fa80 100644 --- a/packages/superdough/util.mjs +++ b/packages/superdough/util.mjs @@ -110,7 +110,9 @@ export function getCommonSampleInfo(hapValue, bank) { return { transpose, url, index, midi, label }; } -/** Selects entries from `source` and renames them via `map` */ +/** Selects entries from `source` and renames them via `map` + * @tags internals + */ export const pickAndRename = (source, map) => { return Object.fromEntries(Object.entries(map).map(([newKey, oldKey]) => [newKey, source[oldKey]])); };