diff --git a/.astro/settings.json b/.astro/settings.json new file mode 100644 index 000000000..bf82959bd --- /dev/null +++ b/.astro/settings.json @@ -0,0 +1,5 @@ +{ + "devToolbar": { + "enabled": false + } +} \ No newline at end of file diff --git a/jsdoc/jsdoc-synonyms.js b/jsdoc/jsdoc-synonyms.js index d59c8dac4..c5860626a 100644 --- a/jsdoc/jsdoc-synonyms.js +++ b/jsdoc/jsdoc-synonyms.js @@ -12,6 +12,13 @@ function defineTags(dictionary) { doclet.synonyms = doclet.synonyms_text.split(/[ ,]+/); }, }); + + dictionary.defineTag('tags', { + mustHaveValue: true, + onTagged: function (doclet, tag) { + doclet.tags = tag.value.split(/[ ,]+/); + }, + }); } module.exports = { defineTags: defineTags }; diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 5dcd26455..9acd77c1c 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -489,6 +489,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/codemirror/themes.mjs b/packages/codemirror/themes.mjs index 1a523b391..dd561d30b 100644 --- a/packages/codemirror/themes.mjs +++ b/packages/codemirror/themes.mjs @@ -198,6 +198,7 @@ export function activateTheme(name) { const themeSettings = settings[name] || settings.strudelTheme; // set css variables themeStyle.innerHTML = `:root { + color-scheme: ${themeSettings.light ? 'light' : 'dark'}; ${Object.entries(themeSettings) // important to override fallback .map(([key, value]) => `--${key}: ${value} !important;`) diff --git a/packages/codemirror/themes/CutiePi.mjs b/packages/codemirror/themes/CutiePi.mjs index 64b38eaa7..f535a2dad 100644 --- a/packages/codemirror/themes/CutiePi.mjs +++ b/packages/codemirror/themes/CutiePi.mjs @@ -17,13 +17,15 @@ export const settings = { background: 'white', lineBackground: 'transparent', foreground: deepPurple, + muted: deepPurple + '50', caret: '#797977', selection: yellowPink, selectionMatch: '#2B323D', - gutterBackground: grey, + gutterBackground: pinkAccent, gutterForeground: lightGrey, gutterBorder: 'transparent', lineHighlight: pinkAccent, + light: true, }; export default createTheme({ diff --git a/packages/codemirror/themes/algoboy.mjs b/packages/codemirror/themes/algoboy.mjs index 049ed596d..5eb90ff79 100644 --- a/packages/codemirror/themes/algoboy.mjs +++ b/packages/codemirror/themes/algoboy.mjs @@ -31,6 +31,7 @@ const palette = palettes['Sour Watermelon B']; export const settings = { background: palette[3], foreground: palette[1], + muted: palette[1] + '50', caret: palette[0], selection: palette[0], selectionMatch: palette[1], diff --git a/packages/codemirror/themes/androidstudio.mjs b/packages/codemirror/themes/androidstudio.mjs index 77c16c331..35b5b7464 100644 --- a/packages/codemirror/themes/androidstudio.mjs +++ b/packages/codemirror/themes/androidstudio.mjs @@ -8,6 +8,7 @@ export const settings = { background: '#282b2e', lineBackground: '#282b2e99', foreground: '#a9b7c6', + muted: '#a9b7c650', caret: '#00FF00', selection: '#343739', selectionMatch: '#343739', @@ -19,6 +20,7 @@ export default createTheme({ settings: { background: '#282b2e', foreground: '#a9b7c6', + muted: '#a9b7c650', caret: '#00FF00', selection: '#4e5254', selectionMatch: '#4e5254', diff --git a/packages/codemirror/themes/archBtw.mjs b/packages/codemirror/themes/archBtw.mjs index 87546569c..3bc5684ea 100644 --- a/packages/codemirror/themes/archBtw.mjs +++ b/packages/codemirror/themes/archBtw.mjs @@ -12,6 +12,7 @@ export const settings = { background: hex[0], lineBackground: 'transparent', foreground: hex[1], + muted: hex[2], selection: hex[2], selectionMatch: hex[0], gutterBackground: hex[0], diff --git a/packages/codemirror/themes/atomone.mjs b/packages/codemirror/themes/atomone.mjs index ab9cd3607..bc7a3254a 100644 --- a/packages/codemirror/themes/atomone.mjs +++ b/packages/codemirror/themes/atomone.mjs @@ -11,6 +11,7 @@ export const settings = { background: '#272C35', lineBackground: '#272C3599', foreground: 'hsl(220, 14%, 71%)', + muted: 'hsl(220, 14%, 41%)', caret: '#797977', selection: '#ffffff30', selectionMatch: '#2B323D', @@ -25,6 +26,7 @@ export default createTheme({ settings: { background: '#272C35', foreground: '#9d9b97', + muted: 'hsl(220, 14%, 41%)', caret: '#797977', selection: '#3d4c64', selectionMatch: '#3d4c64', diff --git a/packages/codemirror/themes/aura.mjs b/packages/codemirror/themes/aura.mjs index b42a5839b..08bb5ea24 100644 --- a/packages/codemirror/themes/aura.mjs +++ b/packages/codemirror/themes/aura.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#21202e', lineBackground: '#21202e99', foreground: '#edecee', + muted: '#edecee50', caret: '#a277ff', selection: '#3d375e7f', selectionMatch: '#3d375e7f', @@ -18,6 +19,7 @@ export default createTheme({ settings: { background: '#21202e', foreground: '#edecee', + muted: '#edecee50', caret: '#a277ff', selection: '#5a51898f', selectionMatch: '#5a51898f', diff --git a/packages/codemirror/themes/bbedit.mjs b/packages/codemirror/themes/bbedit.mjs index 535bf9eaa..0555ac1a4 100644 --- a/packages/codemirror/themes/bbedit.mjs +++ b/packages/codemirror/themes/bbedit.mjs @@ -6,6 +6,7 @@ export const settings = { background: '#FFFFFF', lineBackground: '#FFFFFF99', foreground: '#000000', + muted: '#00000050', caret: '#FBAC52', selection: '#FFD420', selectionMatch: '#FFD420', @@ -20,6 +21,7 @@ export default createTheme({ settings: { background: '#FFFFFF', foreground: '#000000', + muted: '#00000050', caret: '#FBAC52', selection: '#FFD420', selectionMatch: '#FFD420', diff --git a/packages/codemirror/themes/blackscreen.mjs b/packages/codemirror/themes/blackscreen.mjs index 2c45df11b..462dc200b 100644 --- a/packages/codemirror/themes/blackscreen.mjs +++ b/packages/codemirror/themes/blackscreen.mjs @@ -2,7 +2,8 @@ import { tags as t } from '@lezer/highlight'; import { createTheme } from './theme-helper.mjs'; export const settings = { background: 'black', - foreground: 'white', // whats that? + foreground: 'white', + muted: '#ffffff50', caret: 'white', selection: '#ffffff20', selectionMatch: '#036dd626', diff --git a/packages/codemirror/themes/bluescreen.mjs b/packages/codemirror/themes/bluescreen.mjs index 97d165c9d..a3b9648d8 100644 --- a/packages/codemirror/themes/bluescreen.mjs +++ b/packages/codemirror/themes/bluescreen.mjs @@ -3,7 +3,8 @@ import { createTheme } from './theme-helper.mjs'; export const settings = { background: '#051DB5', lineBackground: '#051DB550', - foreground: 'white', // whats that? + foreground: 'white', + muted: '#ffffff50', caret: 'white', selection: 'rgba(128, 203, 196, 0.5)', selectionMatch: '#036dd626', diff --git a/packages/codemirror/themes/bluescreenlight.mjs b/packages/codemirror/themes/bluescreenlight.mjs index 031a3da33..7e10659fa 100644 --- a/packages/codemirror/themes/bluescreenlight.mjs +++ b/packages/codemirror/themes/bluescreenlight.mjs @@ -11,6 +11,7 @@ export const settings = { background: hex[0], lineBackground: 'transparent', foreground: hex[2], + muted: hex[3], selection: hex[3], selectionMatch: hex[0], gutterBackground: hex[0], diff --git a/packages/codemirror/themes/darcula.mjs b/packages/codemirror/themes/darcula.mjs index ead66e663..ee510764b 100644 --- a/packages/codemirror/themes/darcula.mjs +++ b/packages/codemirror/themes/darcula.mjs @@ -9,6 +9,7 @@ export const settings = { background: '#242424', lineBackground: '#24242499', foreground: '#f8f8f2', + muted: '#f8f8f250', caret: '#FFFFFF', selection: 'rgba(255, 255, 255, 0.1)', selectionMatch: 'rgba(255, 255, 255, 0.2)', @@ -23,6 +24,7 @@ export default createTheme({ settings: { background: '#242424', foreground: '#f8f8f2', + muted: '#f8f8f250', caret: '#FFFFFF', selection: 'rgba(255, 255, 255, 0.1)', selectionMatch: 'rgba(255, 255, 255, 0.2)', diff --git a/packages/codemirror/themes/dracula.mjs b/packages/codemirror/themes/dracula.mjs index bdd9617de..514b63719 100644 --- a/packages/codemirror/themes/dracula.mjs +++ b/packages/codemirror/themes/dracula.mjs @@ -11,6 +11,7 @@ export const settings = { background: '#282a36', lineBackground: '#282a3699', foreground: '#f8f8f2', + muted: '#f8f8f250', caret: '#f8f8f0', selection: 'rgba(255, 255, 255, 0.1)', selectionMatch: 'rgba(255, 255, 255, 0.2)', @@ -27,6 +28,7 @@ export default createTheme({ settings: { background: '#282a36', foreground: '#f8f8f2', + muted: '#f8f8f250', caret: '#f8f8f0', selection: 'rgba(255, 255, 255, 0.1)', selectionMatch: 'rgba(255, 255, 255, 0.2)', diff --git a/packages/codemirror/themes/duotoneDark.mjs b/packages/codemirror/themes/duotoneDark.mjs index f54973e85..72e07cd66 100644 --- a/packages/codemirror/themes/duotoneDark.mjs +++ b/packages/codemirror/themes/duotoneDark.mjs @@ -10,6 +10,7 @@ export const settings = { background: '#2a2734', lineBackground: '#2a273499', foreground: '#eeebff', + muted: '#eeebff50', caret: '#ffad5c', selection: 'rgba(255, 255, 255, 0.1)', gutterBackground: '#2a2734', @@ -22,6 +23,7 @@ export default createTheme({ settings: { background: '#2a2734', foreground: '#6c6783', + muted: '#eeebff50', caret: '#ffad5c', selection: '#9a86fd', selectionMatch: '#9a86fd', diff --git a/packages/codemirror/themes/eclipse.mjs b/packages/codemirror/themes/eclipse.mjs index 8082b59da..8c3671eb7 100644 --- a/packages/codemirror/themes/eclipse.mjs +++ b/packages/codemirror/themes/eclipse.mjs @@ -6,6 +6,7 @@ export const settings = { background: '#fff', lineBackground: '#ffffff99', foreground: '#000', + muted: '#00000050', caret: '#FFFFFF', selection: '#d7d4f0', selectionMatch: '#d7d4f0', @@ -20,6 +21,7 @@ export default createTheme({ settings: { background: '#fff', foreground: '#000', + muted: '#00000050', caret: '#FFFFFF', selection: '#d7d4f0', selectionMatch: '#d7d4f0', diff --git a/packages/codemirror/themes/fruitDaw.mjs b/packages/codemirror/themes/fruitDaw.mjs index c9e557796..68b7857e7 100644 --- a/packages/codemirror/themes/fruitDaw.mjs +++ b/packages/codemirror/themes/fruitDaw.mjs @@ -23,6 +23,7 @@ export const settings = { background: hex[0], lineBackground: 'transparent', foreground: hex[10], + muted: hex[7], selection: hex[8], selectionMatch: hex[0], gutterBackground: hex[3], diff --git a/packages/codemirror/themes/githubDark.mjs b/packages/codemirror/themes/githubDark.mjs index 477e7d7b8..3b11eac38 100644 --- a/packages/codemirror/themes/githubDark.mjs +++ b/packages/codemirror/themes/githubDark.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#0d1117', lineBackground: '#0d111799', foreground: '#c9d1d9', + muted: '#c9d1d950', caret: '#c9d1d9', selection: '#003d73', selectionMatch: '#003d73', @@ -16,6 +17,7 @@ export default createTheme({ settings: { background: '#0d1117', foreground: '#c9d1d9', + muted: '#c9d1d950', caret: '#c9d1d9', selection: '#003d73', selectionMatch: '#003d73', diff --git a/packages/codemirror/themes/githubLight.mjs b/packages/codemirror/themes/githubLight.mjs index 2ccec93b6..26b1d5725 100644 --- a/packages/codemirror/themes/githubLight.mjs +++ b/packages/codemirror/themes/githubLight.mjs @@ -6,6 +6,7 @@ export const settings = { background: '#fff', lineBackground: '#ffffff99', foreground: '#24292e', + muted: '#24292e50', selection: '#BBDFFF', selectionMatch: '#BBDFFF', gutterBackground: '#fff', @@ -17,6 +18,7 @@ export default createTheme({ settings: { background: '#fff', foreground: '#24292e', + muted: '#24292e50', selection: '#BBDFFF', selectionMatch: '#BBDFFF', gutterBackground: '#fff', diff --git a/packages/codemirror/themes/green-text.mjs b/packages/codemirror/themes/green-text.mjs index 08c7a4bbe..7d3a47fb2 100644 --- a/packages/codemirror/themes/green-text.mjs +++ b/packages/codemirror/themes/green-text.mjs @@ -13,6 +13,7 @@ export const settings = { background: hex[0], lineBackground: 'transparent', foreground: hex[2], + muted: hex[2] + '50', selection: hex[4], selectionMatch: hex[0], gutterBackground: hex[0], diff --git a/packages/codemirror/themes/gruvboxDark.mjs b/packages/codemirror/themes/gruvboxDark.mjs index 67d8bffc1..2cc9274e1 100644 --- a/packages/codemirror/themes/gruvboxDark.mjs +++ b/packages/codemirror/themes/gruvboxDark.mjs @@ -10,6 +10,7 @@ export const settings = { background: '#282828', lineBackground: '#28282899', foreground: '#ebdbb2', + muted: '#ebdbb250', caret: '#ebdbb2', selection: '#bdae93', selectionMatch: '#bdae93', @@ -23,6 +24,7 @@ export default createTheme({ settings: { background: '#282828', foreground: '#ebdbb2', + muted: '#ebdbb250', caret: '#ebdbb2', selection: '#b99d555c', selectionMatch: '#b99d555c', diff --git a/packages/codemirror/themes/gruvboxLight.mjs b/packages/codemirror/themes/gruvboxLight.mjs index 5d4b4ec01..8e529b21d 100644 --- a/packages/codemirror/themes/gruvboxLight.mjs +++ b/packages/codemirror/themes/gruvboxLight.mjs @@ -11,6 +11,7 @@ export const settings = { background: '#fbf1c7', lineBackground: '#fbf1c799', foreground: '#3c3836', + muted: '#3c383650', caret: '#af3a03', selection: '#ebdbb2', selectionMatch: '#bdae93', @@ -25,6 +26,7 @@ export default createTheme({ settings: { background: '#fbf1c7', foreground: '#3c3836', + muted: '#3c383650', caret: '#af3a03', selection: '#bdae9391', selectionMatch: '#bdae9391', diff --git a/packages/codemirror/themes/materialDark.mjs b/packages/codemirror/themes/materialDark.mjs index f13412885..0c4ef0545 100644 --- a/packages/codemirror/themes/materialDark.mjs +++ b/packages/codemirror/themes/materialDark.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#212121', lineBackground: '#21212199', foreground: '#bdbdbd', + muted: '#bdbdbd50', caret: '#a0a4ae', selection: '#d7d4f0', selectionMatch: '#d7d4f0', @@ -19,6 +20,7 @@ export default createTheme({ settings: { background: '#212121', foreground: '#bdbdbd', + muted: '#bdbdbd50', caret: '#a0a4ae', selection: '#d7d4f063', selectionMatch: '#d7d4f063', diff --git a/packages/codemirror/themes/materialLight.mjs b/packages/codemirror/themes/materialLight.mjs index d2598c649..798842bf2 100644 --- a/packages/codemirror/themes/materialLight.mjs +++ b/packages/codemirror/themes/materialLight.mjs @@ -5,7 +5,8 @@ export const settings = { light: true, background: '#FAFAFA', lineBackground: '#FAFAFA99', - foreground: '#90A4AE', + foreground: '#6182B8', + muted: '#6182B850', caret: '#272727', selection: '#80CBC440', selectionMatch: '#FAFAFA', @@ -19,6 +20,7 @@ export default createTheme({ settings: { background: '#FAFAFA', foreground: '#90A4AE', + muted: '#6182B850', caret: '#272727', selection: '#80CBC440', selectionMatch: '#80CBC440', diff --git a/packages/codemirror/themes/monokai.mjs b/packages/codemirror/themes/monokai.mjs index 294b946b5..926e38219 100644 --- a/packages/codemirror/themes/monokai.mjs +++ b/packages/codemirror/themes/monokai.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#272822', lineBackground: '#27282299', foreground: '#FFFFFF', + muted: '#FFFFFF50', caret: '#FFFFFF', selection: '#49483E', selectionMatch: '#49483E', @@ -18,6 +19,7 @@ export default createTheme({ settings: { background: '#272822', foreground: '#FFFFFF', + muted: '#FFFFFF50', caret: '#FFFFFF', selection: '#49483E', selectionMatch: '#49483E', diff --git a/packages/codemirror/themes/noctisLilac.mjs b/packages/codemirror/themes/noctisLilac.mjs index b11c6b40b..398043394 100644 --- a/packages/codemirror/themes/noctisLilac.mjs +++ b/packages/codemirror/themes/noctisLilac.mjs @@ -6,6 +6,7 @@ export const settings = { background: '#f2f1f8', lineBackground: '#f2f1f899', foreground: '#0c006b', + muted: '#0c006b50', caret: '#5c49e9', selection: '#d5d1f2', selectionMatch: '#d5d1f2', @@ -19,6 +20,7 @@ export default createTheme({ settings: { background: '#f2f1f8', foreground: '#0c006b', + muted: '#0c006b50', caret: '#5c49e9', selection: '#d5d1f2', selectionMatch: '#d5d1f2', diff --git a/packages/codemirror/themes/nord.mjs b/packages/codemirror/themes/nord.mjs index ce96bca57..efa4b6bf5 100644 --- a/packages/codemirror/themes/nord.mjs +++ b/packages/codemirror/themes/nord.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#2e3440', lineBackground: '#2e344099', foreground: '#FFFFFF', + muted: '#FFFFFF50', caret: '#FFFFFF', selection: '#3b4252', selectionMatch: '#e5e9f0', @@ -20,6 +21,7 @@ export default createTheme({ settings: { background: '#2e3440', foreground: '#FFFFFF', + muted: '#FFFFFF50', caret: '#FFFFFF', selection: '#00000073', selectionMatch: '#00000073', diff --git a/packages/codemirror/themes/red-text.mjs b/packages/codemirror/themes/red-text.mjs index 44dda5dc0..5ba9d2152 100644 --- a/packages/codemirror/themes/red-text.mjs +++ b/packages/codemirror/themes/red-text.mjs @@ -13,6 +13,7 @@ export const settings = { background: hex[0], lineBackground: 'transparent', foreground: hex[2], + muted: hex[2] + '50', selection: hex[4], selectionMatch: hex[0], gutterBackground: hex[0], diff --git a/packages/codemirror/themes/solarizedDark.mjs b/packages/codemirror/themes/solarizedDark.mjs index c6b645f7a..6848b537e 100644 --- a/packages/codemirror/themes/solarizedDark.mjs +++ b/packages/codemirror/themes/solarizedDark.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#002b36', lineBackground: '#002b3699', foreground: '#93a1a1', + muted: '#93a1a150', caret: '#839496', selection: '#173541', selectionMatch: '#aafe661a', @@ -45,6 +46,7 @@ export default createTheme({ settings: { background: c.background, foreground: c.foreground, + muted: c.muted, caret: c.cursor, selection: c.selection, selectionMatch: c.selection, diff --git a/packages/codemirror/themes/solarizedLight.mjs b/packages/codemirror/themes/solarizedLight.mjs index b6828ff6c..0a0c61a12 100644 --- a/packages/codemirror/themes/solarizedLight.mjs +++ b/packages/codemirror/themes/solarizedLight.mjs @@ -8,6 +8,7 @@ export const settings = { background: '#fdf6e3', lineBackground: '#fdf6e399', foreground: '#657b83', + muted: '#657b8350', caret: '#586e75', selection: '#dfd9c8', selectionMatch: '#dfd9c8', @@ -19,6 +20,7 @@ export const settings = { const c = { background: '#FDF6E3', foreground: '#657B83', + muted: '#657b8350', selection: '#EEE8D5', selectionMatch: '#EEE8D5', cursor: '#657B83', diff --git a/packages/codemirror/themes/sonic-pink.mjs b/packages/codemirror/themes/sonic-pink.mjs index 5a19555ab..19c5e5e87 100644 --- a/packages/codemirror/themes/sonic-pink.mjs +++ b/packages/codemirror/themes/sonic-pink.mjs @@ -13,6 +13,7 @@ export const settings = { background: '#000000', lineBackground: 'transparent', foreground: hex[4], + muted: hex[6], selection: hex[6], gutterBackground: hex[0], gutterForeground: hex[5], diff --git a/packages/codemirror/themes/strudel-theme.mjs b/packages/codemirror/themes/strudel-theme.mjs index 7c4a3a919..658a682f1 100644 --- a/packages/codemirror/themes/strudel-theme.mjs +++ b/packages/codemirror/themes/strudel-theme.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#222', lineBackground: '#22222299', foreground: '#fff', + muted: '#ffffff50', caret: '#ffcc00', selection: 'rgba(128, 203, 196, 0.5)', selectionMatch: '#036dd626', diff --git a/packages/codemirror/themes/sublime.mjs b/packages/codemirror/themes/sublime.mjs index 068b9bac9..111f1e505 100644 --- a/packages/codemirror/themes/sublime.mjs +++ b/packages/codemirror/themes/sublime.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#303841', lineBackground: '#30384199', foreground: '#FFFFFF', + muted: '#FFFFFF50', caret: '#FBAC52', selection: '#4C5964', selectionMatch: '#3A546E', @@ -18,6 +19,7 @@ export default createTheme({ settings: { background: '#303841', foreground: '#FFFFFF', + muted: '#FFFFFF50', caret: '#FBAC52', selection: '#4C5964', selectionMatch: '#3A546E', diff --git a/packages/codemirror/themes/teletext.mjs b/packages/codemirror/themes/teletext.mjs index 7857cb133..280eda979 100644 --- a/packages/codemirror/themes/teletext.mjs +++ b/packages/codemirror/themes/teletext.mjs @@ -9,7 +9,8 @@ let colorD = '#f8fc55'; export const settings = { background: '#000000', - foreground: colorA, // whats that? + foreground: colorA, + muted: colorA + '50', caret: colorC, selection: colorD, selectionMatch: colorA, diff --git a/packages/codemirror/themes/tokioNightStorm.mjs b/packages/codemirror/themes/tokioNightStorm.mjs index be973d52f..ab940da01 100644 --- a/packages/codemirror/themes/tokioNightStorm.mjs +++ b/packages/codemirror/themes/tokioNightStorm.mjs @@ -4,7 +4,8 @@ import { createTheme } from './theme-helper.mjs'; export const settings = { background: '#24283b', lineBackground: '#24283b99', - foreground: '#7982a9', + foreground: '#f9f2f9', + muted: '#f9f2f950', caret: '#c0caf5', selection: '#6f7bb630', selectionMatch: '#1f2335', @@ -18,7 +19,8 @@ export default createTheme({ theme: 'dark', settings: { background: '#24283b', - foreground: '#7982a9', + foreground: '#f9f2f9', + muted: '#f9f2f950', caret: '#c0caf5', selection: '#6f7bb630', selectionMatch: '#343b5f', diff --git a/packages/codemirror/themes/tokyoNight.mjs b/packages/codemirror/themes/tokyoNight.mjs index c325b4ad7..29a656676 100644 --- a/packages/codemirror/themes/tokyoNight.mjs +++ b/packages/codemirror/themes/tokyoNight.mjs @@ -4,7 +4,8 @@ import { createTheme } from './theme-helper.mjs'; export const settings = { background: '#1a1b26', lineBackground: '#1a1b2699', - foreground: '#787c99', + foreground: '#f8fcf9', + muted: '#f8fcf950', caret: '#c0caf5', selection: '#515c7e40', selectionMatch: '#16161e', @@ -18,7 +19,8 @@ export default createTheme({ theme: 'dark', settings: { background: '#1a1b26', - foreground: '#787c99', + foreground: '#f8fcf9', + muted: '#f8fcf950', caret: '#c0caf5', selection: '#515c7e40', selectionMatch: '#16161e', diff --git a/packages/codemirror/themes/tokyoNightDay.mjs b/packages/codemirror/themes/tokyoNightDay.mjs index 1cd58a412..a8f5f75b0 100644 --- a/packages/codemirror/themes/tokyoNightDay.mjs +++ b/packages/codemirror/themes/tokyoNightDay.mjs @@ -6,6 +6,7 @@ export const settings = { background: '#e1e2e7', lineBackground: '#e1e2e799', foreground: '#3760bf', + muted: '#3760bf50', caret: '#3760bf', selection: '#99a7df', selectionMatch: '#99a7df', @@ -20,6 +21,7 @@ export default createTheme({ settings: { background: '#e1e2e7', foreground: '#3760bf', + muted: '#3760bf50', caret: '#3760bf', selection: '#99a7df', selectionMatch: '#99a7df', diff --git a/packages/codemirror/themes/vscodeDark.mjs b/packages/codemirror/themes/vscodeDark.mjs index 703790fd5..9ccc4d078 100644 --- a/packages/codemirror/themes/vscodeDark.mjs +++ b/packages/codemirror/themes/vscodeDark.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#1e1e1e', lineBackground: '#1e1e1e99', foreground: '#fff', + muted: '#ffffff50', caret: '#c6c6c6', selection: '#6199ff2f', selectionMatch: '#72a1ff59', @@ -19,6 +20,7 @@ export default createTheme({ settings: { background: '#1e1e1e', foreground: '#fff', + muted: '#ffffff50', caret: '#c6c6c6', selection: '#6199ff2f', selectionMatch: '#72a1ff59', diff --git a/packages/codemirror/themes/vscodeLight.mjs b/packages/codemirror/themes/vscodeLight.mjs index 9a7345114..71817e8a6 100644 --- a/packages/codemirror/themes/vscodeLight.mjs +++ b/packages/codemirror/themes/vscodeLight.mjs @@ -5,6 +5,7 @@ export const settings = { background: '#ffffff', lineBackground: '#ffffff50', foreground: '#383a42', + muted: '#383a4250', caret: '#000', selection: '#add6ff', selectionMatch: '#a8ac94', @@ -20,6 +21,7 @@ export default createTheme({ settings: { background: '#ffffff', foreground: '#383a42', + muted: '#383a4250', caret: '#000', selection: '#add6ff', selectionMatch: '#a8ac94', diff --git a/packages/codemirror/themes/whitescreen.mjs b/packages/codemirror/themes/whitescreen.mjs index a2937c380..fa034fb80 100644 --- a/packages/codemirror/themes/whitescreen.mjs +++ b/packages/codemirror/themes/whitescreen.mjs @@ -2,7 +2,8 @@ import { tags as t } from '@lezer/highlight'; import { createTheme } from './theme-helper.mjs'; export const settings = { background: 'white', - foreground: 'black', // whats that? + foreground: 'black', + muted: '#00000050', caret: 'black', selection: 'rgba(128, 203, 196, 0.5)', selectionMatch: '#ffffff26', diff --git a/packages/codemirror/themes/xcodeLight.mjs b/packages/codemirror/themes/xcodeLight.mjs index 8977c133e..b2c857988 100644 --- a/packages/codemirror/themes/xcodeLight.mjs +++ b/packages/codemirror/themes/xcodeLight.mjs @@ -6,6 +6,7 @@ export const settings = { background: '#fff', lineBackground: '#ffffff99', foreground: '#3D3D3D', + muted: '#3D3D3D50', selection: '#BBDFFF', selectionMatch: '#BBDFFF', gutterBackground: '#fff', @@ -18,6 +19,7 @@ export default createTheme({ settings: { background: '#fff', foreground: '#3D3D3D', + muted: '#3D3D3D50', selection: '#BBDFFF', selectionMatch: '#BBDFFF', gutterBackground: '#fff', diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index f15b3d4cd..a5a1c0a12 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -99,6 +99,7 @@ export function registerMultiControl(names, maxControls, ...aliases) { * separated by ':'. * * @name s + * @tags samples * @param {string | Pattern} sound The sound / pattern of sounds to pick * @synonyms sound * @example @@ -113,6 +114,7 @@ export const { s, sound } = registerControl(['s', 'n', 'gain'], 'sound'); * Position in the wavetable of the wavetable oscillator * * @name wt + * @tags fx * @param {number | Pattern} position Position in the wavetable from 0 to 1 * @synonyms wavetablePosition * @example @@ -124,6 +126,7 @@ export const { wt, wavetablePosition } = registerControl('wt', 'wavetablePositio * Amount of envelope applied wavetable oscillator's position envelope * * @name wtenv + * @tags fx * @param {number | Pattern} amount between 0 and 1 */ export const { wtenv } = registerControl('wtenv'); @@ -131,6 +134,7 @@ export const { wtenv } = registerControl('wtenv'); * Attack time of the wavetable oscillator's position envelope * * @name wtattack + * @tags fx * @synonyms wtatt * @param {number | Pattern} time attack time in seconds */ @@ -140,6 +144,7 @@ export const { wtattack, wtatt } = registerControl('wtattack', 'wtatt'); * Decay time of the wavetable oscillator's position envelope * * @name wtdecay + * @tags fx * @synonyms wtdec * @param {number | Pattern} time decay time in seconds */ @@ -149,6 +154,7 @@ export const { wtdecay, wtdec } = registerControl('wtdecay', 'wtdec'); * Sustain time of the wavetable oscillator's position envelope * * @name wtsustain + * @tags fx * @synonyms wtsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -158,6 +164,7 @@ export const { wtsustain, wtsus } = registerControl('wtsustain', 'wtsus'); * Release time of the wavetable oscillator's position envelope * * @name wtrelease + * @tags fx * @synonyms wtrel * @param {number | Pattern} time release time in seconds */ @@ -167,6 +174,7 @@ export const { wtrelease, wtrel } = registerControl('wtrelease', 'wtrel'); * Rate of the LFO for the wavetable oscillator's position * * @name wtrate + * @tags fx * @param {number | Pattern} rate rate in hertz */ export const { wtrate } = registerControl('wtrate'); @@ -174,6 +182,7 @@ export const { wtrate } = registerControl('wtrate'); * cycle synced rate of the LFO for the wavetable oscillator's position * * @name wtsync + * @tags fx * @param {number | Pattern} rate rate in cycles */ export const { wtsync } = registerControl('wtsync'); @@ -182,6 +191,7 @@ export const { wtsync } = registerControl('wtsync'); * Depth of the LFO for the wavetable oscillator's position * * @name wtdepth + * @tags fx * @param {number | Pattern} depth depth of modulation */ export const { wtdepth } = registerControl('wtdepth'); @@ -190,6 +200,7 @@ export const { wtdepth } = registerControl('wtdepth'); * Shape of the LFO for the wavetable oscillator's position * * @name wtshape + * @tags fx * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { wtshape } = registerControl('wtshape'); @@ -198,6 +209,7 @@ export const { wtshape } = registerControl('wtshape'); * DC offset of the LFO for the wavetable oscillator's position * * @name wtdc + * @tags fx * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { wtdc } = registerControl('wtdc'); @@ -206,6 +218,7 @@ export const { wtdc } = registerControl('wtdc'); * Skew of the LFO for the wavetable oscillator's position * * @name wtskew + * @tags fx * @param {number | Pattern} skew How much to bend the LFO shape */ export const { wtskew } = registerControl('wtskew'); @@ -214,6 +227,7 @@ export const { wtskew } = registerControl('wtskew'); * Amount of warp (alteration of the waveform) to apply to the wavetable oscillator * * @name warp + * @tags fx * @param {number | Pattern} amount Warp of the wavetable from 0 to 1 * @synonyms wavetableWarp * @example @@ -226,6 +240,7 @@ export const { warp, wavetableWarp } = registerControl('warp', 'wavetableWarp'); * Attack time of the wavetable oscillator's warp envelope * * @name warpattack + * @tags fx * @synonyms warpatt * @param {number | Pattern} time attack time in seconds */ @@ -235,6 +250,7 @@ export const { warpattack, warpatt } = registerControl('warpattack', 'warpatt'); * Decay time of the wavetable oscillator's warp envelope * * @name warpdecay + * @tags fx * @synonyms warpdec * @param {number | Pattern} time decay time in seconds */ @@ -244,6 +260,7 @@ export const { warpdecay, warpdec } = registerControl('warpdecay', 'warpdec'); * Sustain time of the wavetable oscillator's warp envelope * * @name warpsustain + * @tags fx * @synonyms warpsus * @param {number | Pattern} gain sustain level (0 to 1) */ @@ -253,6 +270,7 @@ export const { warpsustain, warpsus } = registerControl('warpsustain', 'warpsus' * Release time of the wavetable oscillator's warp envelope * * @name warprelease + * @tags fx * @synonyms warprel * @param {number | Pattern} time release time in seconds */ @@ -262,6 +280,7 @@ export const { warprelease, warprel } = registerControl('warprelease', 'warprel' * Rate of the LFO for the wavetable oscillator's warp * * @name warprate + * @tags fx * @param {number | Pattern} rate rate in hertz */ export const { warprate } = registerControl('warprate'); @@ -270,6 +289,7 @@ export const { warprate } = registerControl('warprate'); * Depth of the LFO for the wavetable oscillator's warp * * @name warpdepth + * @tags fx * @param {number | Pattern} depth depth of modulation */ export const { warpdepth } = registerControl('warpdepth'); @@ -278,6 +298,7 @@ export const { warpdepth } = registerControl('warpdepth'); * Shape of the LFO for the wavetable oscillator's warp * * @name warpshape + * @tags fx * @param {number | Pattern} shape Shape of the lfo (0, 1, 2, ..) */ export const { warpshape } = registerControl('warpshape'); @@ -286,6 +307,7 @@ export const { warpshape } = registerControl('warpshape'); * DC offset of the LFO for the wavetable oscillator's warp * * @name warpdc + * @tags fx * @param {number | Pattern} dcoffset dc offset. set to 0 for unipolar */ export const { warpdc } = registerControl('warpdc'); @@ -294,6 +316,7 @@ export const { warpdc } = registerControl('warpdc'); * Skew of the LFO for the wavetable oscillator's warp * * @name warpskew + * @tags fx * @param {number | Pattern} skew How much to bend the LFO shape */ export const { warpskew } = registerControl('warpskew'); @@ -305,6 +328,7 @@ export const { warpskew } = registerControl('warpskew'); * spin, chaos, primes, binary, brownian, reciprocal, wormhole, logistic, sigmoid, fractal, flip * * @name warpmode + * @tags fx * @param {number | string | Pattern} mode Warp mode * @synonyms wavetableWarpMode * @example @@ -318,6 +342,7 @@ export const { warpmode, wavetableWarpMode } = registerControl('warpmode', 'wave * Amount of randomness of the initial phase of the wavetable oscillator. * * @name wtphaserand + * @tags fx * @param {number | Pattern} amount Randomness of the initial phase. Between 0 (not random) and 1 (fully random) * @synonyms wavetablePhaseRand * @example @@ -330,6 +355,7 @@ export const { wtphaserand, wavetablePhaseRand } = registerControl('wtphaserand' * Amount of envelope applied wavetable oscillator's position envelope * * @name warpenv + * @tags fx * @param {number | Pattern} amount between 0 and 1 */ export const { warpenv } = registerControl('warpenv'); @@ -338,6 +364,7 @@ export const { warpenv } = registerControl('warpenv'); * cycle synced rate of the LFO for the wavetable warp position * * @name warpsync + * @tags fx * @param {number | Pattern} rate rate in cycles */ export const { warpsync } = registerControl('warpsync'); @@ -346,6 +373,7 @@ export const { warpsync } = registerControl('warpsync'); * Define a custom webaudio node to use as a sound source. * * @name source + * @tags external_io, superdough * @synonyms src * @param {function} getSource * @synonyms src @@ -358,6 +386,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 + * @tags samples * @param {number | Pattern} value sample index starting from 0 * @example * s("bd sd [~ bd] sd,hh*6").n("<0 1>") @@ -376,6 +405,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 + * @tags music_theory * @example * note("c a f e") * @example @@ -391,6 +421,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, superdirt * @param {number | Pattern} amount acceleration. * @superdirtOnly * @example @@ -402,6 +433,7 @@ export const { accelerate } = registerControl('accelerate'); * Sets the velocity from 0 to 1. Is multiplied together with gain. * * @name velocity + * @tags fx, superdough, supradough * @synonyms vel * @example * s("hh*8") @@ -413,6 +445,7 @@ export const { velocity, vel } = registerControl('velocity', 'vel'); * Controls the gain by an exponential amount. * * @name gain + * @tags fx, superdough, supradough * @param {number | Pattern} amount gain. * @example * s("hh*8").gain(".4!2 1 .4!2 1 .4 1").fast(2) @@ -423,6 +456,7 @@ export const { gain } = registerControl('gain'); * Gain applied after all effects have been processed. * * @name postgain + * @tags fx, superdough, supradough * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02").postgain(1.5) @@ -433,6 +467,7 @@ export const { postgain } = registerControl('postgain'); * Like `gain`, but linear. * * @name amp + * @tags fx, superdirt * @param {number | Pattern} amount gain. * @superdirtOnly * @example @@ -444,6 +479,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 fx, superdough, supradough * @param {number | Pattern} attack time in seconds. * @synonyms att * @example @@ -462,6 +498,7 @@ export const { attack, att } = registerControl('attack', 'att'); * any of the 8 individual FMs (e.g. `fmh2`) * * @name fmh + * @tags fx, superdough, supradough * @param {number | Pattern} harmonicity * @example * note("c e g b g e") @@ -482,6 +519,7 @@ export const { fmh, fmh1, fmh2, fmh3, fmh4, fmh5, fmh6, fmh7, fmh8 } = registerM * `fm3` * * @name fmi + * @tags fx, superdough, supradough * @param {number | Pattern} brightness modulation index * @synonyms fm * @example @@ -505,6 +543,7 @@ export const { fmi, fmi1, fmi2, fmi3, fmi4, fmi5, fmi6, fmi7, fmi8, fm, fm1, fm2 * any of the 8 individual FMs (e.g. `fmenv4`) * * @name fmenv + * @tags fx, superdough, supradough * @param {number | Pattern} type lin | exp * @example * note("c e g b g e") @@ -527,6 +566,7 @@ export const { fmenv, fmenv1, fmenv2, fmenv3, fmenv4, fmenv5, fmenv6, fmenv7, fm * any of the 8 individual FMs (e.g. `fmatt5`) * * @name fmattack + * @tags fx, superdough, supradough * @synonyms fmatt * @param {number | Pattern} time attack time * @example @@ -564,6 +604,7 @@ export const { * any of the 8 individual FMs (e.g. `fmwave6`) * * @name fmwave + * @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) @@ -583,6 +624,7 @@ export const { fmwave, fmwave1, fmwave2, fmwave3, fmwave4, fmwave5, fmwave6, fmw * any of the 8 individual FMs (e.g. `fmdec6`) * * @name fmdecay + * @tags fx, superdough, supradough * @synonyms fmdec * @param {number | Pattern} time decay time * @example @@ -621,6 +663,7 @@ export const { * any of the 8 individual FMs (e.g. `fmsus7`) * * @name fmsustain + * @tags fx, superdough, supradough * @synonyms fmsus * @param {number | Pattern} level sustain level * @example @@ -659,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 * @@ -699,6 +743,7 @@ for (let i = 0; i <= 8; i++) { * 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, superdough * @param {string | Pattern} bank the name of the bank * @example * s("bd sd [~ bd] sd").bank('RolandTR909') // = s("RolandTR909_bd RolandTR909_sd") @@ -710,6 +755,7 @@ export const { bank } = registerControl('bank'); * mix control for the chorus effect * * @name chorus + * @tags fx * @param {string | Pattern} chorus mix amount between 0 and 1 * @example * note("d d a# a").s("sawtooth").chorus(.5) @@ -727,6 +773,7 @@ export const { fft } = registerControl('fft'); * Note that the decay is only audible if the sustain value is lower than 1. * * @name decay + * @tags fx, superdough, supradough * @param {number | Pattern} time decay time in seconds * @synonyms dec * @example @@ -738,6 +785,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 fx, superdough, supradough * @param {number | Pattern} gain sustain level between 0 and 1 * @synonyms sus * @example @@ -749,6 +797,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 fx, superdough, supradough * @param {number | Pattern} time release time in seconds * @synonyms rel * @example @@ -763,6 +812,7 @@ export const { hold } = registerControl('hold'); * can also optionally supply the 'bpq' parameter separated by ':'. * * @name bpf + * @tags fx, superdough, supradough * @param {number | Pattern} frequency center frequency * @synonyms bandf, bp * @example @@ -775,6 +825,7 @@ export const { bandf, bpf, bp } = registerControl(['bandf', 'bandq', 'bpenv'], ' * Sets the **b**and-**p**ass **q**-factor (resonance). * * @name bpq + * @tags fx, superdough, supradough * @param {number | Pattern} q q factor * @synonyms bandq * @example @@ -789,6 +840,7 @@ export const { bandq, bpq } = registerControl('bandq', 'bpq'); * * @memberof Pattern * @name begin + * @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') @@ -801,6 +853,7 @@ export const { begin } = registerControl('begin'); * * @memberof Pattern * @name end + * @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) @@ -813,6 +866,7 @@ export const { end } = registerControl('end'); * To change the loop region, use loopBegin / loopEnd. * * @name loop + * @tags samples * @param {number | Pattern} on If 1, the sample is looped * @example * s("casio").loop(1) @@ -825,6 +879,7 @@ export const { loop } = registerControl('loop'); * Note: Samples starting with wt_ will automatically loop! (wt = wavetable) * * @name loopBegin + * @tags samples * @param {number | Pattern} time between 0 and 1, where 1 is the length of the sample * @synonyms loopb * @example @@ -838,6 +893,7 @@ export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb'); * Note that the loop point must be inbetween `begin` and `end`, and after `loopBegin`! * * @name loopEnd + * @tags samples * @param {number | Pattern} time between 0 and 1, where 1 is the length of the sample * @synonyms loope * @example @@ -849,6 +905,7 @@ export const { loopEnd, loope } = registerControl('loopEnd', 'loope'); * Bit crusher effect. * * @name crush + * @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>") @@ -860,6 +917,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 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>") @@ -871,6 +929,7 @@ export const { coarse } = registerControl('coarse'); * Modulate the amplitude of a sound with a continuous waveform * * @name tremolo + * @tags fx, superdough * @synonyms trem * @param {number | Pattern} speed modulation speed in HZ * @example @@ -883,6 +942,7 @@ export const { tremolo, trem } = registerControl(['tremolo', 'tremolodepth', 'tr * Modulate the amplitude of a sound with a continuous waveform * * @name tremolosync + * @tags fx, superdough * @synonyms tremsync * @param {number | Pattern} cycles modulation speed in cycles * @example @@ -898,6 +958,7 @@ export const { tremolosync } = registerControl( * Depth of amplitude modulation * * @name tremolodepth + * @tags fx, superdough * @synonyms tremdepth * @param {number | Pattern} depth * @example @@ -909,6 +970,7 @@ export const { tremolodepth } = registerControl('tremolodepth', 'tremdepth'); * Alter the shape of the modulation waveform * * @name tremoloskew + * @tags fx, superdough * @synonyms tremskew * @param {number | Pattern} amount between 0 & 1, the shape of the waveform * @example @@ -921,6 +983,7 @@ export const { tremoloskew } = registerControl('tremoloskew', 'tremskew'); * Alter the phase of the modulation waveform * * @name tremolophase + * @tags fx, superdough * @synonyms tremphase * @param {number | Pattern} offset the offset in cycles of the modulation * @example @@ -933,6 +996,7 @@ export const { tremolophase } = registerControl('tremolophase', 'tremphase'); * Shape of amplitude modulation * * @name tremoloshape + * @tags fx, superdough * @synonyms tremshape * @param {number | Pattern} shape tri | square | sine | saw | ramp * @example @@ -944,6 +1008,7 @@ export const { tremoloshape } = registerControl('tremoloshape', 'tremshape'); * Filter overdrive for supported filter types * * @name drive + * @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>") @@ -957,6 +1022,7 @@ export const { drive } = registerControl('drive'); * Can be applied to multiple orbits with the ':' mininotation, e.g. `duckorbit("2:3")` * * @name duckorbit + * @tags fx, superdough * @synonyms duck * @param {number | Pattern} orbit target orbit * @example @@ -977,6 +1043,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 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>")) @@ -996,6 +1063,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 fx, superdough * @synonyms duckons * * @param {number | Pattern} time The onset time in seconds @@ -1023,6 +1091,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 fx, superdough * @synonyms duckatt * * @param {number | Pattern} time The attack time in seconds @@ -1042,6 +1111,7 @@ export const { duckattack } = registerControl('duckattack', 'duckatt'); * * @name byteBeatExpression * @synonyms bbexpr + * @tags fx * * @param {number | Pattern} byteBeatExpression bitwise expression for creating bytebeat * @example @@ -1055,6 +1125,7 @@ export const { byteBeatExpression, bbexpr } = registerControl('byteBeatExpressio * * @name byteBeatStartTime * @synonyms bbst + * @tags fx * * @param {number | Pattern} byteBeatStartTime in samples (t) * @example @@ -1067,6 +1138,7 @@ export const { byteBeatStartTime, bbst } = registerControl('byteBeatStartTime', * Allows you to set the output channels on the interface * * @name channels + * @tags external_io * @synonyms ch * * @param {number | Pattern} channels pattern the output channels @@ -1080,6 +1152,7 @@ export const { channels, ch } = registerControl('channels', 'ch'); * Controls the pulsewidth of the pulse oscillator * * @name pw + * @tags fx * @param {number | Pattern} pulsewidth * @example * note("{f a c e}%16").s("pulse").pw(".8:1:.2") @@ -1092,6 +1165,7 @@ export const { pw } = registerControl(['pw', 'pwrate', 'pwsweep']); * Controls the lfo rate for the pulsewidth of the pulse oscillator * * @name pwrate + * @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>") @@ -1104,6 +1178,7 @@ export const { pwrate } = registerControl('pwrate'); * Controls the lfo sweep for the pulsewidth of the pulse oscillator * * @name pwsweep + * @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>") @@ -1115,6 +1190,7 @@ export const { pwsweep } = registerControl('pwsweep'); * Phaser audio effect that approximates popular guitar pedals. * * @name phaser + * @tags fx, superdough * @synonyms ph * @param {number | Pattern} speed speed of modulation * @example @@ -1132,6 +1208,7 @@ export const { phaserrate, ph, phaser } = registerControl( * The frequency sweep range of the lfo for the phaser effect. Defaults to 2000 * * @name phasersweep + * @tags fx, superdough * @synonyms phs * @param {number | Pattern} phasersweep most useful values are between 0 and 4000 * @example @@ -1145,6 +1222,7 @@ export const { phasersweep, phs } = registerControl('phasersweep', 'phs'); * The center frequency of the phaser in HZ. Defaults to 1000 * * @name phasercenter + * @tags fx, superdough * @synonyms phc * @param {number | Pattern} centerfrequency in HZ * @example @@ -1159,6 +1237,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, superdirt * @synonyms phd, phasdp * @param {number | Pattern} depth number between 0 and 1 * @example @@ -1173,6 +1252,7 @@ export const { phaserdepth, phd, phasdp } = registerControl('phaserdepth', 'phd' * Choose the channel the pattern is sent to in superdirt * * @name channel + * @tags fx * @param {number | Pattern} channel channel number * */ @@ -1181,6 +1261,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 fx * @param {number | Pattern} group cut group number * @example * s("[oh hh]*4").cut(1) @@ -1193,6 +1274,7 @@ export const { cut } = registerControl('cut'); * When using mininotation, you can also optionally add the 'lpq' parameter, separated by ':'. * * @name lpf + * @tags fx, superdough, supradough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms cutoff, ctf, lp * @example @@ -1206,6 +1288,7 @@ export const { cutoff, ctf, lpf, lp } = registerControl(['cutoff', 'resonance', /** * Sets the lowpass filter envelope modulation depth. * @name lpenv + * @tags fx, superdough, supradough * @param {number | Pattern} modulation depth of the lowpass filter envelope between 0 and _n_ * @synonyms lpe * @example @@ -1219,6 +1302,7 @@ export const { lpenv, lpe } = registerControl('lpenv', 'lpe'); /** * Sets the highpass filter envelope modulation depth. * @name hpenv + * @tags fx, superdough, supradough * @param {number | Pattern} modulation depth of the highpass filter envelope between 0 and _n_ * @synonyms hpe * @example @@ -1232,6 +1316,7 @@ export const { hpenv, hpe } = registerControl('hpenv', 'hpe'); /** * Sets the bandpass filter envelope modulation depth. * @name bpenv + * @tags fx, superdough, supradough * @param {number | Pattern} modulation depth of the bandpass filter envelope between 0 and _n_ * @synonyms bpe * @example @@ -1245,6 +1330,7 @@ export const { bpenv, bpe } = registerControl('bpenv', 'bpe'); /** * Sets the attack duration for the lowpass filter envelope. * @name lpattack + * @tags fx, superdough, supradough * @param {number | Pattern} attack time of the filter envelope * @synonyms lpa * @example @@ -1258,6 +1344,7 @@ export const { lpattack, lpa } = registerControl('lpattack', 'lpa'); /** * Sets the attack duration for the highpass filter envelope. * @name hpattack + * @tags fx, superdough, supradough * @param {number | Pattern} attack time of the highpass filter envelope * @synonyms hpa * @example @@ -1271,6 +1358,7 @@ export const { hpattack, hpa } = registerControl('hpattack', 'hpa'); /** * Sets the attack duration for the bandpass filter envelope. * @name bpattack + * @tags fx, superdough, supradough * @param {number | Pattern} attack time of the bandpass filter envelope * @synonyms bpa * @example @@ -1284,6 +1372,7 @@ export const { bpattack, bpa } = registerControl('bpattack', 'bpa'); /** * Sets the decay duration for the lowpass filter envelope. * @name lpdecay + * @tags fx, superdough, supradough * @param {number | Pattern} decay time of the filter envelope * @synonyms lpd * @example @@ -1297,6 +1386,7 @@ export const { lpdecay, lpd } = registerControl('lpdecay', 'lpd'); /** * Sets the decay duration for the highpass filter envelope. * @name hpdecay + * @tags fx, superdough, supradough * @param {number | Pattern} decay time of the highpass filter envelope * @synonyms hpd * @example @@ -1311,6 +1401,7 @@ export const { hpdecay, hpd } = registerControl('hpdecay', 'hpd'); /** * Sets the decay duration for the bandpass filter envelope. * @name bpdecay + * @tags fx, superdough, supradough * @param {number | Pattern} decay time of the bandpass filter envelope * @synonyms bpd * @example @@ -1325,6 +1416,7 @@ export const { bpdecay, bpd } = registerControl('bpdecay', 'bpd'); /** * Sets the sustain amplitude for the lowpass filter envelope. * @name lpsustain + * @tags fx, superdough, supradough * @param {number | Pattern} sustain amplitude of the lowpass filter envelope * @synonyms lps * @example @@ -1339,6 +1431,7 @@ export const { lpsustain, lps } = registerControl('lpsustain', 'lps'); /** * Sets the sustain amplitude for the highpass filter envelope. * @name hpsustain + * @tags fx, superdough, supradough * @param {number | Pattern} sustain amplitude of the highpass filter envelope * @synonyms hps * @example @@ -1353,6 +1446,7 @@ export const { hpsustain, hps } = registerControl('hpsustain', 'hps'); /** * Sets the sustain amplitude for the bandpass filter envelope. * @name bpsustain + * @tags fx, superdough, supradough * @param {number | Pattern} sustain amplitude of the bandpass filter envelope * @synonyms bps * @example @@ -1367,6 +1461,7 @@ export const { bpsustain, bps } = registerControl('bpsustain', 'bps'); /** * Sets the release time for the lowpass filter envelope. * @name lprelease + * @tags fx, superdough, supradough * @param {number | Pattern} release time of the filter envelope * @synonyms lpr * @example @@ -1382,6 +1477,7 @@ export const { lprelease, lpr } = registerControl('lprelease', 'lpr'); /** * Sets the release time for the highpass filter envelope. * @name hprelease + * @tags fx, superdough, supradough * @param {number | Pattern} release time of the highpass filter envelope * @synonyms hpr * @example @@ -1397,6 +1493,7 @@ export const { hprelease, hpr } = registerControl('hprelease', 'hpr'); /** * Sets the release time for the bandpass filter envelope. * @name bprelease + * @tags fx, superdough, supradough * @param {number | Pattern} release time of the bandpass filter envelope * @synonyms bpr * @example @@ -1412,6 +1509,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 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) @@ -1427,6 +1525,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 fx, superdough * @param {number | Pattern} center 0 to 1 * @example * note("{f g g c d a a#}%8").s("sawtooth").lpf("{1000}%2") @@ -1439,6 +1538,7 @@ export const { fanchor } = registerControl('fanchor'); * When using mininotation, you can also optionally add the 'hpq' parameter, separated by ':'. * * @name hpf + * @tags fx, superdough, supradough * @param {number | Pattern} frequency audible between 0 and 20000 * @synonyms hp, hcutoff * @example @@ -1454,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>") @@ -1464,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>") @@ -1474,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>") @@ -1484,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 @@ -1496,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'); @@ -1504,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'); @@ -1512,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'); @@ -1520,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'); @@ -1528,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'); @@ -1536,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'); @@ -1544,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 @@ -1556,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'); @@ -1564,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'); @@ -1572,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'); @@ -1580,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'); @@ -1588,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'); @@ -1596,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'); @@ -1604,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 @@ -1616,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'); @@ -1624,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'); @@ -1632,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'); @@ -1640,6 +1761,7 @@ export const { hpskew } = registerControl('hpskew'); * Applies a vibrato to the frequency of the oscillator. * * @name vib + * @tags fx, superdough, supradough * @synonyms vibrato, v * @param {number | Pattern} frequency of the vibrato in hertz * @example @@ -1657,6 +1779,7 @@ export const { vib, vibrato, v } = registerControl(['vib', 'vibmod'], 'vibrato', * Adds pink noise to the mix * * @name noise + * @tags generators, superdough, supradough * @param {number | Pattern} wet wet amount * @example * sound("/2") @@ -1666,6 +1789,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 fx, superdough, supradough * @synonyms vmod * @param {number | Pattern} depth of vibrato (in semitones) * @example @@ -1684,6 +1808,7 @@ export const { hcutoff, hpf, hp } = registerControl(['hcutoff', 'hresonance', 'h * Controls the **h**igh-**p**ass **q**-value. * * @name hpq + * @tags fx, superdough, supradough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms hresonance * @example @@ -1695,6 +1820,7 @@ export const { hresonance, hpq } = registerControl('hresonance', 'hpq'); * Controls the **l**ow-**p**ass **q**-value. * * @name lpq + * @tags fx, superdough, supradough * @param {number | Pattern} q resonance factor between 0 and 50 * @synonyms resonance * @example @@ -1707,6 +1833,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 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>") @@ -1723,6 +1850,7 @@ export const { djf } = registerControl('djf'); * * * @name delay + * @tags fx, superdough, supradough * @param {number | Pattern} level between 0 and 1 * @example * s("bd bd").delay("<0 .25 .5 1>") @@ -1736,6 +1864,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 fx, superdough, supradough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1749,6 +1878,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 fx, superdough, supradough * @param {number | Pattern} feedback between 0 and 1 * @synonyms delayfb, dfb * @example @@ -1760,6 +1890,7 @@ export const { delayspeed } = registerControl('delayspeed'); * Sets the time of the delay effect. * * @name delayspeed + * @tags fx * @param {number | Pattern} delayspeed controls the pitch of the delay feedback * @synonyms delayt, dt * @example @@ -1772,6 +1903,7 @@ export const { delaytime, delayt, dt } = registerControl('delaytime', 'delayt', * Sets the time of the delay effect in cycles. * * @name delaysync + * @tags fx, superdough * @param {number | Pattern} cycles delay length in cycles * @synonyms delayt, dt * @example @@ -1784,6 +1916,7 @@ export const { delaysync } = registerControl('delaysync'); * Specifies whether delaytime is calculated relative to cps. * * @name lock + * @tags fx, superdirt * @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle. * @superdirtOnly * @example @@ -1797,6 +1930,7 @@ export const { lock } = registerControl('lock'); * Set detune for stacked voices of supported oscillators * * @name detune + * @tags fx * @param {number | Pattern} amount * @synonyms det * @example @@ -1808,6 +1942,7 @@ export const { detune, det } = registerControl('detune', 'det'); * Set number of stacked voices for supported oscillators * * @name unison + * @tags fx * @param {number | Pattern} numvoices * @example * note("d f a a# a d3").fast(2).s("supersaw").unison("<1 2 7>") @@ -1819,6 +1954,7 @@ export const { unison } = registerControl('unison'); * Set the stereo pan spread for supported oscillators * * @name spread + * @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>") @@ -1829,6 +1965,7 @@ export const { spread } = registerControl('spread'); * Set dryness of reverb. See `room` and `size` for more information about reverb. * * @name dry + * @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() @@ -1854,6 +1991,7 @@ export const { fadeInTime } = registerControl('fadeInTime'); * Set frequency of sound. * * @name freq + * @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() @@ -1867,6 +2005,7 @@ export const { freq } = registerControl('freq'); * Attack time of pitch envelope. * * @name pattack + * @tags fx, superdough, supradough * @synonyms patt * @param {number | Pattern} time time in seconds * @example @@ -1878,6 +2017,7 @@ export const { pattack, patt } = registerControl('pattack', 'patt'); * Decay time of pitch envelope. * * @name pdecay + * @tags fx, superdough, supradough * @synonyms pdec * @param {number | Pattern} time time in seconds * @example @@ -1891,6 +2031,7 @@ export const { psustain, psus } = registerControl('psustain', 'psus'); * Release time of pitch envelope * * @name prelease + * @tags fx, superdough, supradough * @synonyms prel * @param {number | Pattern} time time in seconds * @example @@ -1905,6 +2046,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 fx, superdough, supradough * @param {number | Pattern} semitones change in semitones * @example * note("c") @@ -1916,6 +2058,7 @@ export const { penv } = registerControl('penv'); * Curve of envelope. Defaults to linear. exponential is good for kicks * * @name pcurve + * @tags fx * @param {number | Pattern} type 0 = linear, 1 = exponential * @example * note("g1*4") @@ -1932,6 +2075,7 @@ export const { pcurve } = registerControl('pcurve'); * If you don't set an anchor, the value will default to the psustain value. * * @name panchor + * @tags fx * @param {number | Pattern} anchor anchor offset * @example * note("c c4").penv(12).panchor("<0 .5 1 .5>") @@ -1953,6 +2097,7 @@ export const { gate, gat } = registerControl('gate', 'gat'); * Emulation of a Leslie speaker: speakers rotating in a wooden amplified cabinet. * * @name leslie + * @tags fx, superdirt * @param {number | Pattern} wet between 0 and 1 * @example * n("0,4,7").s("supersquare").leslie("<0 .4 .6 1>").osc() @@ -1964,6 +2109,7 @@ export const { leslie } = registerControl('leslie'); * Rate of modulation / rotation for leslie effect * * @name lrate + * @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() @@ -1976,6 +2122,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, 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() @@ -1987,6 +2134,7 @@ export const { lsize } = registerControl('lsize'); * Sets the displayed text for an event on the pianoroll * * @name label + * @tags visualization * @param {string} label text to display */ export const { activeLabel } = registerControl('activeLabel'); @@ -2023,6 +2171,7 @@ export const { nudge } = registerControl('nudge'); * Sets the default octave of a synth. * * @name octave + * @tags fx, superdirt * @synonyms oct * @param {number | Pattern} octave octave number * @example @@ -2036,6 +2185,7 @@ export const { octave, oct } = registerControl('octave', 'oct'); * An `orbit` is a global parameter context for patterns. Patterns with the same orbit will share the same global effects. * * @name orbit + * @tags fx, superdough * @synonyms o * @param {number | Pattern} number * @example @@ -2054,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'); @@ -2062,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 */ @@ -2075,6 +2227,7 @@ export const { overshape } = registerControl('overshape'); * Sets position in stereo. * * @name pan + * @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>") @@ -2123,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() @@ -2132,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', { @@ -2146,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() @@ -2155,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 @@ -2164,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() @@ -2173,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() @@ -2186,6 +2345,7 @@ export const { mode } = registerControl(['mode', 'anchor']); * When using mininotation, you can also optionally add the 'size' parameter, separated by ':'. * * @name room + * @tags fx, superdough * @param {number | Pattern} level between 0 and 1 * @example * s("bd sd [~ bd] sd").room("<0 .2 .4 .6 .8 1>") @@ -2199,6 +2359,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 fx, superdough * @synonyms rlp * @param {number} frequency between 0 and 20000hz * @example @@ -2212,6 +2373,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 fx, superdough * @synonyms rdim * @param {number} frequency between 0 and 20000hz * @example @@ -2226,6 +2388,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 fx, superdough * @synonyms rfade * @param {number} seconds for the reverb to fade * @example @@ -2238,6 +2401,7 @@ export const { roomfade, rfade } = registerControl('roomfade', 'rfade'); /** * Sets the sample to use as an impulse response for the reverb. * @name iresponse + * @tags fx, superdough * @param {string | Pattern} sample to use as an impulse response * @synonyms ir * @example @@ -2249,6 +2413,7 @@ export const { ir, iresponse } = registerControl(['ir', 'i'], 'iresponse'); /** * Sets speed of the sample for the impulse response. * @name irspeed + * @tags fx, superdough * @param {string | Pattern} speed * @example * samples('github:switchangel/pad') @@ -2260,6 +2425,7 @@ export const { irspeed } = registerControl('irspeed'); /** * Sets the beginning of the IR response sample * @name irbegin + * @tags fx, superdough * @param {string | Pattern} begin between 0 and 1 * @synonyms ir * @example @@ -2273,6 +2439,7 @@ export const { irbegin } = registerControl('irbegin'); * When this property is changed, the reverb will be recaculated, so only change this sparsely.. * * @name roomsize + * @tags fx, superdough * @param {number | Pattern} size between 0 and 10 * @synonyms rsize, sz, size * @example @@ -2296,6 +2463,7 @@ export const { roomsize, size, sz, rsize } = registerControl('roomsize', 'size', * * * @name shape + * @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>") @@ -2308,6 +2476,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 fx, superdough, supradough * @synonyms dist * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion @@ -2327,6 +2496,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) @@ -2337,6 +2507,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 @@ -2355,6 +2526,7 @@ export const { distorttype } = registerControl('distorttype', 'disttype'); * More info [here](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) * * @name compressor + * @tags fx, superdough * @example * s("bd sd [~ bd] sd,hh*8") * .compressor("-20:20:10:.002:.02") @@ -2375,6 +2547,7 @@ export const { compressorRelease } = registerControl('compressorRelease'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name speed + * @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") @@ -2388,6 +2561,7 @@ export const { speed } = registerControl('speed'); * Changes the speed of sample playback, i.e. a cheap way of changing pitch. * * @name stretch + * @tags fx * @param {number | Pattern} factor -inf to inf, negative numbers play the sample backwards. * @example * s("gm_flute").stretch("1 2 .5") @@ -2398,6 +2572,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, superdirt * @param {number | string | Pattern} unit see description above * @example * speed("1 2 .5 3").s("bd").unit("c").osc() @@ -2412,6 +2587,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, 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() @@ -2436,6 +2612,7 @@ export const { squiz } = registerControl('squiz'); * Formant filter to make things sound like vowels. * * @name vowel + * @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') @@ -2460,6 +2637,7 @@ export const { waveloss } = registerControl('waveloss'); * Noise crackle density * * @name density + * @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)) @@ -2509,6 +2687,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 temporal * @synonyms legato * @param {number | Pattern} factor >= 0 * @example @@ -2521,6 +2700,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 temporal * @synonyms dur * @param {number | Pattern} seconds >= 0 * @example @@ -2548,6 +2728,7 @@ export const { zzfx } = registerControl('zzfx'); /** * Sets the color of the hap in visualizations like pianoroll or highlighting. * @name color + * @tags visualization * @synonyms colour * @param {string} color Hexadecimal or CSS color name */ @@ -2562,6 +2743,7 @@ export let createParams = (...names) => * ADSR envelope: Combination of Attack, Decay, Sustain, and Release. * * @name adsr + * @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) @@ -2596,6 +2778,7 @@ export const ar = register('ar', (t, pat) => { * MIDI channel: Sets the MIDI channel for the event. * * @name midichan + * @tags external_io * @param {number | Pattern} channel MIDI channel number (0-15) * @example * note("c4").midichan(1).midi() @@ -2608,6 +2791,7 @@ export const { midimap } = registerControl('midimap'); * MIDI port: Sets the MIDI port for the event. * * @name midiport + * @tags external_io * @param {number | Pattern} port MIDI port * @example * note("c a f e").midiport("<0 1 2 3>").midi() @@ -2618,6 +2802,7 @@ export const { midiport } = registerControl('midiport'); * MIDI command: Sends a MIDI command message. * * @name midicmd + * @tags external_io * @param {number | Pattern} command MIDI command * @example * midicmd("clock*48,/2").midi() @@ -2628,6 +2813,7 @@ export const { midicmd } = registerControl('midicmd'); * MIDI control: Sends a MIDI control change message. * * @name control + * @tags external_io * @param {number | Pattern} MIDI control number (0-127) * @param {number | Pattern} MIDI controller value (0-127) */ @@ -2643,6 +2829,7 @@ export const control = register('control', (args, pat) => { * MIDI control number: Sends a MIDI control change message. * * @name ccn + * @tags external_io * @param {number | Pattern} MIDI control number (0-127) */ export const { ccn } = registerControl('ccn'); @@ -2650,6 +2837,7 @@ export const { ccn } = registerControl('ccn'); * MIDI control value: Sends a MIDI control change message. * * @name ccv + * @tags external_io * @param {number | Pattern} MIDI control value (0-127) */ export const { ccv } = registerControl('ccv'); @@ -2659,6 +2847,7 @@ export const { ctlNum } = registerControl('ctlNum'); /** * MIDI NRPN non-registered parameter number: Sends a MIDI NRPN non-registered parameter number message. * @name nrpnn + * @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() @@ -2667,6 +2856,7 @@ export const { nrpnn } = registerControl('nrpnn'); /** * MIDI NRPN non-registered parameter value: Sends a MIDI NRPN non-registered parameter value message. * @name nrpv + * @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() @@ -2677,6 +2867,7 @@ export const { nrpv } = registerControl('nrpv'); * MIDI program number: Sends a MIDI program change message. * * @name progNum + * @tags external_io * @param {number | Pattern} program MIDI program number (0-127) * @example * note("c4").progNum(10).midichan(1).midi() @@ -2686,6 +2877,7 @@ export const { progNum } = registerControl('progNum'); /** * MIDI sysex: Sends a MIDI sysex message. * @name sysex + * @tags external_io * @param {number | Pattern} id Sysex ID * @param {number | Pattern} data Sysex data * @example @@ -2701,6 +2893,7 @@ export const sysex = register('sysex', (args, pat) => { /** * MIDI sysex ID: Sends a MIDI sysex identifier message. * @name sysexid + * @tags external_io * @param {number | Pattern} id Sysex ID * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2709,6 +2902,7 @@ export const { sysexid } = registerControl('sysexid'); /** * MIDI sysex data: Sends a MIDI sysex message. * @name sysexdata + * @tags external_io * @param {number | Pattern} data Sysex data * @example * note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi() @@ -2718,6 +2912,7 @@ export const { sysexdata } = registerControl('sysexdata'); /** * MIDI pitch bend: Sends a MIDI pitch bend message. * @name midibend + * @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() @@ -2726,6 +2921,7 @@ export const { midibend } = registerControl('midibend'); /** * MIDI key after touch: Sends a MIDI key after touch message. * @name miditouch + * @tags external_io * @param {number | Pattern} miditouch MIDI key after touch (0-1) * @example * note("c4").miditouch(sine.slow(4).range(0,1)).midi() @@ -2738,6 +2934,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(); @@ -2747,6 +2944,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(); @@ -2764,6 +2962,7 @@ export const getControlName = (alias) => { * Sets properties in a batch. * * @name as + * @tags temporal * @param {String | Array} mapping the control names that are set * @example * "c:.5 a:1 f:.25 e:.8".as("note:clip") @@ -2788,6 +2987,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 + * @tags samples * @memberof Pattern * @returns Pattern * @example @@ -2846,6 +3046,7 @@ registerSubControls('lfo', [ ['skew', 'sk'], ['curve', 'cu'], ['sync', 's'], + ['retrig', 'rt'], ['fxi'], ]); registerSubControls('env', [ @@ -2927,17 +3128,19 @@ 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 * @param {number | Pattern} [config.rate] Modulation rate. Aliases: r + * @param {number | Pattern} [config.sync] Tempo-synced modulation rate. Aliases: s * @param {number | Pattern} [config.depth] Relative modulation depth. Aliases: dep, dr * @param {number | Pattern} [config.depthabs] Absolute modulation depth. Aliases: da * @param {number | Pattern} [config.dcoffset] DC offset / bias for the waveform. Aliases: dc * @param {number | Pattern} [config.shape] Shape index. Aliases: sh * @param {number | Pattern} [config.skew] Skew amount. Aliases: sk * @param {number | Pattern} [config.curve] Exponential curve amount. Aliases: cu - * @param {number | Pattern} [config.sync] Tempo-synced modulation rate. Aliases: s + * @param {number | Pattern} [config.retrig] If > 0.5, the LFO will retrigger on each event. Aliases: rt * @param {number | Pattern} [config.fxi] FX index to target * @param {string | Pattern} id ID to use for this modulator * @returns Pattern @@ -2980,6 +3183,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 @@ -3040,6 +3244,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 @@ -3066,6 +3271,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/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 98c21a116..49f96384b 100644 --- a/packages/core/euclid.mjs +++ b/packages/core/euclid.mjs @@ -61,6 +61,7 @@ export const bjorklund = 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 bjorklund = 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/package.json b/packages/core/package.json index e558c574c..9316ec496 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,6 @@ }, "homepage": "https://strudel.cc", "dependencies": { - "@kabelsalat/web": "^0.4.1", "fraction.js": "^5.2.1" }, "gitHead": "0e26d4e741500f5bae35b023608f062a794905c2", diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 7466f594b..b7a047bfc 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -85,6 +85,7 @@ export class Pattern { /** * Returns a new pattern, with the function applied to the value of * each hap. It has the alias `fmap`. + * @tags functional * @synonyms fmap * @param {Function} func to to apply to the value * @returns Pattern @@ -114,6 +115,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. + * @tags functional * @param {Function} whole_func * @param {Function} func * @noAutocomplete @@ -151,6 +153,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. + * @tags functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -178,6 +181,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). + * @tags functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -211,6 +215,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. + * @tags functional * @param {Pattern} pat_val * @noAutocomplete * @returns Pattern @@ -401,6 +406,7 @@ export class Pattern { /** * Query haps inside the given time span. * + * @tags internals * @param {Fraction | number} begin from time * @param {Fraction | number} end to time * @returns Hap[] @@ -424,6 +430,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. + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -438,6 +445,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. + * @tags internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -460,6 +468,7 @@ export class Pattern { /** * As with `withQuerySpan`, but the function is applied to both the * begin and end time of the query timespan. + * @tags internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -472,6 +481,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). + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -483,6 +493,7 @@ export class Pattern { /** * As with `withHapSpan`, but the function is applied to both the * begin and end time of the hap timespans. + * @tags internals * @param {Function} func the function to apply * @returns Pattern * @noAutocomplete @@ -493,6 +504,7 @@ export class Pattern { /** * Returns a new pattern with the given function applied to the list of haps returned by every query. + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -505,6 +517,7 @@ export class Pattern { /** * As with `withHaps`, but applies the function to every hap, rather than every list of haps. + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -515,6 +528,7 @@ export class Pattern { /** * Returns a new pattern with the context field set to every hap set to the given value. + * @tags internals * @param {*} context * @returns Pattern * @noAutocomplete @@ -525,6 +539,7 @@ export class Pattern { /** * Returns a new pattern with the given function applied to the context field of every hap. + * @tags internals * @param {Function} func * @returns Pattern * @noAutocomplete @@ -540,6 +555,7 @@ export class Pattern { /** * Returns a new pattern with the context field of every hap set to an empty object. + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -550,6 +566,7 @@ export class Pattern { /** * Returns a new pattern with the given location information added to the * context of every hap. + * @tags internals * @param {Number} start start offset * @param {Number} end end offset * @returns Pattern @@ -573,6 +590,7 @@ export class Pattern { /** * Returns a new Pattern, which only returns haps that meet the given test. + * @tags internals * @param {Function} hap_test - a function which returns false for haps to be removed from the pattern * @returns Pattern * @example @@ -585,6 +603,7 @@ export class Pattern { /** * As with `filterHaps`, but the function is applied to values * inside haps. + * @tags internals * @param {Function} value_test * @returns Pattern * @example @@ -600,6 +619,7 @@ export class Pattern { /** * Returns a new pattern, with haps containing undefined values removed from * query results. + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -611,6 +631,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. + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -624,6 +645,7 @@ export class Pattern { /** * Returns a new pattern, with 'continuous' haps (those without 'whole' * timespans) removed from query results. + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -635,6 +657,7 @@ export class Pattern { /** * Combines adjacent haps with the same value and whole. Only * intended for use in tests. + * @tags internals * @noAutocomplete */ defragmentHaps() { @@ -687,6 +710,7 @@ export class Pattern { /** * Queries the pattern for the first cycle, returning Haps. Mainly of use when * debugging a pattern. + * @tags internals * @param {Boolean} with_context - set to true, otherwise the context field * will be stripped from the resulting haps. * @returns [Hap] @@ -702,6 +726,7 @@ export class Pattern { /** * Accessor for a list of values returned by querying the first cycle. + * @tags internals * @noAutocomplete */ get firstCycleValues() { @@ -710,6 +735,7 @@ export class Pattern { /** * More human-readable version of the `firstCycleValues` accessor. + * @tags internals * @noAutocomplete */ get showFirstCycle() { @@ -721,6 +747,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. + * @tags internals * @returns Pattern * @noAutocomplete */ @@ -735,6 +762,10 @@ export class Pattern { ); } + /** + * Returns a new pattern with all values parsed as numerals. + * @tags internals + */ asNumber() { return this.fmap(parseNumeral); } @@ -785,6 +816,7 @@ export class Pattern { /** * Layers the result of the given function(s). Like `superimpose`, but without the original pattern: * @name layer + * @tags combiners * @memberof Pattern * @synonyms apply * @returns Pattern @@ -800,6 +832,7 @@ export class Pattern { /** * Superimposes the result of the given function(s) on top of the original pattern: * @name superimpose + * @tags combiners * @memberof Pattern * @returns Pattern * @example @@ -859,6 +892,7 @@ export class Pattern { /** * Writes the content of the current event to the console (visible in the side menu). + * @tags visualization * @name log * @memberof Pattern * @example @@ -873,6 +907,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 visualization * @name logValues * @memberof Pattern * @example @@ -906,6 +941,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 temporal * @name into * @memberof Pattern * @example @@ -945,6 +981,7 @@ Pattern.prototype.collect = function () { /** * Selects indices in in stacked notes. + * @tags temporal * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arpWith(haps => haps[2]) @@ -959,6 +996,7 @@ export const arpWith = register('arpWith', (func, pat) => { /** * Selects indices in in stacked notes. + * @tags temporal * @example * note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>") * .arp("0 [0,2] 1 [0,2]") @@ -1031,6 +1069,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") @@ -1048,6 +1087,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. @@ -1058,6 +1098,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() */ @@ -1067,6 +1108,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)], @@ -1153,6 +1195,7 @@ function _composeOp(a, b, func) { /** * Applies the given structure to the pattern: * + * @tags temporal * @example * note("c,eb,g") * .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~") @@ -1167,6 +1210,7 @@ function _composeOp(a, b, func) { /** * Returns silence when mask is 0 or "~" * + * @tags temporal * @example * note("c [eb,g] d [eb,g]").mask("<1 [0 1]>") */ @@ -1179,6 +1223,7 @@ function _composeOp(a, b, func) { /** * Resets the pattern to the start of the cycle for each onset of the reset pattern. * + * @tags temporal * @example * s("[ sd]*2, hh*8").reset("") */ @@ -1192,6 +1237,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 temporal * @example * s("[ sd]*2, hh*8").restart("") */ @@ -1232,6 +1278,7 @@ export const pm = polymeter; /** * Does absolutely nothing, but with a given metrical 'steps' * @name gap + * @tags generators * @param {number} steps * @example * gap(3) // "~@3" @@ -1241,6 +1288,7 @@ export const gap = (steps) => new Pattern(() => [], steps); /** * Does absolutely nothing.. * @name silence + * @tags generators * @example * silence // "~" */ @@ -1252,6 +1300,7 @@ export const nothing = gap(0); /** * A discrete value that repeats once per cycle. * + * @tags generators * @returns {Pattern} * @example * pure('e4') // "e4" @@ -1293,7 +1342,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. + * + * @tags temporal */ export function sequenceP(pats) { let result = pure([]); @@ -1306,6 +1358,7 @@ export function sequenceP(pats) { /** * The given items are played at the same time at the same length. * + * @tags temporal * @return {Pattern} * @synonyms polyrhythm, pr * @example @@ -1390,6 +1443,7 @@ export function stackBy(by, ...pats) { /** * Concatenation: combines a list of patterns, switching between them successively, one per cycle. * + * @tags combiners * @return {Pattern} * @synonyms cat * @example @@ -1423,6 +1477,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. + * @tags combiners * @param {...any} items - The items to concatenate * @return {Pattern} */ @@ -1438,6 +1493,7 @@ export function slowcatPrime(...pats) { /** The given items are con**cat**enated, where each one takes one cycle. * + * @tags combiners * @param {...any} items - The items to concatenate * @synonyms slowcat * @return {Pattern} @@ -1459,6 +1515,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. * + * @tags combiners * @return {Pattern} * @example * arrange( @@ -1476,6 +1533,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. + * @tags combiners * @return {Pattern} * @example seqPLoop([0, 2, "bd(3,8)"], @@ -1514,13 +1572,17 @@ export function fastcat(...pats) { return result; } -/** See `fastcat` */ +/** See `fastcat` + * @name sequence + * @tags combiners + */ export function sequence(...pats) { return fastcat(...pats); } /** Like **cat**, but the items are crammed into one cycle. - * @synonyms sequence, fastcat + * @tags combiners + * @synonyms seq, fastcat * @example * seq("e5", "b4", ["d5", "c5"]).note() * // "e5 b4 [d5 c5]".note() @@ -1591,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 @@ -1701,6 +1764,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 + * @tags math * @memberof Pattern * @returns Pattern * @example @@ -1709,13 +1773,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 + * @tags math * @returns Pattern * @example * note("42 42.1 42.5 43".floor()) @@ -1730,6 +1794,7 @@ export const floor = register('floor', function (pat) { * replaced with `-4`. * @name ceil * @memberof Pattern + * @tags math * @returns Pattern * @example * note("42 42.1 42.5 43".ceil()) @@ -1740,6 +1805,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 + * @tags math * @returns Pattern * @noAutocomplete */ @@ -1750,6 +1816,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 + * @tags math * @returns Pattern * @noAutocomplete */ @@ -1763,6 +1830,7 @@ export const fromBipolar = register('fromBipolar', function (pat) { * Most useful in combination with continuous patterns. * @name range * @memberof Pattern + * @tags math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1778,6 +1846,7 @@ export const range = register('range', function (min, max, pat) { * following an exponential curve. * @name rangex * @memberof Pattern + * @tags math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1792,6 +1861,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 + * @tags math * @returns Pattern * @example * s("[bd sd]*2,hh*8") @@ -1806,6 +1876,7 @@ export const range2 = register('range2', function (min, max, pat) { * Returns a new pattern with just numbers. * @name ratio * @memberof Pattern + * @tags math * @returns Pattern * @example * ratio("1, 5:4, 3:2").mul(110) @@ -1824,6 +1895,7 @@ export const ratio = register('ratio', (pat) => // Structural and temporal transformations /** Compress each cycle into the given timespan, leaving a gap + * @tags temporal * @example * cat( * s("bd sd").compress(.25,.75), @@ -1845,6 +1917,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 temporal * @name fastGap * @synonyms fastgap * @example @@ -1882,6 +1955,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 temporal * @example * s("bd hh sd hh").focus(1/4, 3/4) */ @@ -1899,6 +1973,7 @@ export const { focusSpan, focusspan } = register(['focusSpan', 'focusspan'], fun }); /** The ply function repeats each event the given number of times. + * @tags temporal * @example * s("bd ~ sd cp").ply("<1 2 3>") */ @@ -1913,6 +1988,7 @@ export const ply = register('ply', function (factor, pat) { /** * Speed up a pattern by the given factor. Used by "*" in mini notation. * + * @tags temporal * @name fast * @synonyms density * @memberof Pattern @@ -1937,6 +2013,7 @@ export const { fast, density } = register( /** * Both speeds up the pattern (like 'fast') and the sample playback (like 'speed'). + * @tags temporal * @example * s("bd sd:2").hurry("<1 2 4 3>").slow(1.5) */ @@ -1947,6 +2024,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 temporal * @name slow * @synonyms sparsity * @memberof Pattern @@ -1964,6 +2042,7 @@ export const { slow, sparsity } = register(['slow', 'sparsity'], function (facto /** * Carries out an operation 'inside' a cycle. + * @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() @@ -1974,6 +2053,7 @@ export const inside = register('inside', function (factor, f, pat) { /** * Carries out an operation 'outside' a cycle. + * @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() @@ -1984,6 +2064,7 @@ export const outside = register('outside', function (factor, f, pat) { /** * Applies the given function every n cycles, starting from the last cycle. + * @tags temporal * @name lastOf * @memberof Pattern * @param {number} n how many cycles @@ -2000,6 +2081,7 @@ export const lastOf = register('lastOf', function (n, func, pat) { /** * Applies the given function every n cycles, starting from the first cycle. + * @tags temporal * @name firstOf * @memberof Pattern * @param {number} n how many cycles @@ -2011,6 +2093,7 @@ export const lastOf = register('lastOf', function (n, func, pat) { /** * An alias for `firstOf` + * @tags temporal * @name every * @memberof Pattern * @param {number} n how many cycles @@ -2027,8 +2110,8 @@ export const { firstOf, every } = register(['firstOf', 'every'], function (n, fu /** * Like layer, but with a single function: + * @tags temporal * @name apply - * @memberof Pattern * @example * "".scale('C minor').apply(scaleTranspose("0,2,4")).note() */ @@ -2039,6 +2122,7 @@ export const apply = register('apply', function (func, pat) { /** * Plays the pattern at the given cycles per minute. + * @tags temporal * @deprecated * @example * s(",hh*2").cpm(90) // = 90 bpm @@ -2051,6 +2135,7 @@ export const cpm = register('cpm', function (cpm, pat) { /** * Nudge a pattern to start earlier in time. Equivalent of Tidal's <~ operator * + * @tags temporal * @name early * @memberof Pattern * @param {number | Pattern} cycles number of cycles to nudge left @@ -2071,6 +2156,7 @@ export const early = register( /** * Nudge a pattern to start later in time. Equivalent of Tidal's ~> operator * + * @tags temporal * @name late * @memberof Pattern * @param {number | Pattern} cycles number of cycles to nudge right @@ -2091,6 +2177,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 temporal * @example * s("bd*2 hh*3 [sd bd]*2 perc").zoom(0.25, 0.75) * // s("hh*3 [sd bd]*2") // equivalent @@ -2117,6 +2204,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 temporal * @param {number} number of slices * @param {number} slices to play * @example @@ -2144,6 +2232,7 @@ export const bite = register( /** * Selects the given fraction of the pattern and repeats that part to fill the remainder of the cycle. + * @tags temporal * @param {number} fraction fraction to select * @example * s("lt ht mt cp, [hh oh]*2").linger("<1 .5 .25 .125>") @@ -2164,6 +2253,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 temporal * @name segment * @synonyms seg * @param {number} segments number of segments per cycle @@ -2176,6 +2266,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 temporal * @param {number} subdivision * @param {number} offset * @example @@ -2185,6 +2276,7 @@ export const swingBy = register('swingBy', (swing, n, pat) => pat.inside(n, late /** * Shorthand for swingBy with 1/3: + * @tags temporal * @param {number} subdivision * @example * s("hh*8").swing(4) @@ -2194,6 +2286,7 @@ export const swing = register('swing', (n, pat) => pat.swingBy(1 / 3, n)); /** * Swaps 1s and 0s in a binary pattern. + * @tags temporal * @name invert * @synonyms inv * @example @@ -2211,6 +2304,7 @@ export const { invert, inv } = register( /** * Applies the given function whenever the given pattern is in a true state. + * @tags temporal * @name when * @memberof Pattern * @param {Pattern} binary_pat @@ -2225,6 +2319,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 temporal * @name off * @memberof Pattern * @param {Pattern | number} time offset time @@ -2241,6 +2336,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 temporal * @returns Pattern */ export const brak = register('brak', function (pat) { @@ -2250,6 +2346,7 @@ export const brak = register('brak', function (pat) { /** * Reverse all cycles in a pattern. See also `revv` for reversing a whole pattern. * + * @tags temporal * @name rev * @memberof Pattern * @returns Pattern @@ -2284,6 +2381,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 @@ -2300,6 +2398,7 @@ export const revv = register('revv', function (pat) { /** 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 temporal * @example * stack(s("hh*4"), * s("bd mt sd ht").pressBy("<0 0.5 0.25>") @@ -2311,6 +2410,7 @@ export const pressBy = register('pressBy', function (r, pat) { /** * Syncopates a rhythm, by shifting each event halfway into its timespan. + * @tags temporal * @example * stack(s("hh*4"), * s("bd mt sd ht").every(4, press) @@ -2322,6 +2422,7 @@ export const press = register('press', function (pat) { /** * Silences a pattern. + * @tags temporal * @example * stack( * s("bd").hush(), @@ -2334,6 +2435,7 @@ Pattern.prototype.hush = function () { /** * Applies `rev` to a pattern every other cycle, so that the pattern alternates between forwards and backwards. + * @tags temporal * @example * note("c d e g").palindrome() */ @@ -2348,6 +2450,7 @@ export const palindrome = register( /** * Jux with adjustable stereo width. 0 = mono, 1 = full stereo. + * @tags temporal * @name juxBy * @synonyms juxby * @example @@ -2369,6 +2472,7 @@ export const { juxBy, juxby } = register(['juxBy', 'juxby'], function (by, func, /** * The jux function creates strange stereo effects, by applying a function to a pattern, but only in the right-hand channel. + * @tags temporal * @example * s("bd lt [~ ht] mt cp ~ bd hh").jux(rev) * @example @@ -2382,6 +2486,7 @@ export const jux = register('jux', function (func, pat) { /** * Superimpose and offset multiple times, applying the given function each time. + * @tags temporal * @name echoWith * @synonyms echowith, stutWith, stutwith * @param {number} times how many times to repeat @@ -2401,6 +2506,7 @@ export const { echoWith, echowith, stutWith, stutwith } = register( /** * Superimpose and offset multiple times, gradually decreasing the velocity + * @tags temporal * @name echo * @memberof Pattern * @returns Pattern @@ -2416,6 +2522,7 @@ export const echo = register('echo', function (times, time, feedback, pat) { /** * Deprecated. Like echo, but the last 2 parameters are flipped. + * @tags temporal * @name stut * @param {number} times how many times to repeat * @param {number} feedback velocity multiplicator for each iteration @@ -2437,6 +2544,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 temporal * @name plyWith * @synonyms plywith * @param {number} factor how many times to repeat @@ -2459,6 +2567,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 temporal * @name plyForEach * @synonyms plyforeach * @param {number} factor how many times to repeat @@ -2480,6 +2589,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 temporal * @name iter * @memberof Pattern * @returns Pattern @@ -2507,6 +2617,7 @@ export const iter = register( /** * Like `iter`, but plays the subdivisions in reverse order. Known as iter' in tidalcycles + * @tags temporal * @name iterBack * @synonyms iterback * @memberof Pattern @@ -2525,6 +2636,7 @@ export const { iterBack, iterback } = register( /** * Repeats each cycle the given number of times. + * @tags temporal * @name repeatCycles * @memberof Pattern * @returns Pattern @@ -2548,6 +2660,7 @@ export const { repeatCycles } = register( /** * Divides a pattern into a given number of parts, then cycles through those parts in turn, applying the given function to each part in turn (one part per cycle). + * @tags temporal * @name chunk * @synonyms slowChunk, slowchunk * @memberof Pattern @@ -2579,6 +2692,7 @@ export const { chunk, slowchunk, slowChunk } = register( /** * Like `chunk`, but cycles through the parts in reverse order. Known as chunk' in tidalcycles + * @tags temporal * @name chunkBack * @synonyms chunkback * @memberof Pattern @@ -2599,6 +2713,7 @@ export const { chunkBack, chunkback } = register( /** * Like `chunk`, but the cycles of the source pattern aren't repeated * for each set of chunks. + * @tags temporal * @name fastChunk * @synonyms fastchunk * @memberof Pattern @@ -2619,6 +2734,7 @@ export const { fastchunk, fastChunk } = register( /** * Like `chunk`, but the function is applied to a looped subcycle of the source pattern. + * @tags temporal * @name chunkInto * @synonyms chunkinto * @memberof Pattern @@ -2632,6 +2748,7 @@ export const { chunkinto, chunkInto } = register(['chunkinto', 'chunkInto'], fun /** * Like `chunkInto`, but moves backwards through the chunks. + * @tags temporal * @name chunkBackInto * @synonyms chunkbackinto * @memberof Pattern @@ -2662,6 +2779,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 temporal * @name ribbon * @synonyms rib * @param {number} offset start point of loop in cycles @@ -2690,6 +2808,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 temporal * @param {string} tag anything unique * @example * s("saw!16").note("F1") @@ -2705,6 +2824,7 @@ Pattern.prototype.tag = function (tag) { /** * Filters haps using the given function * @name filter + * @tags temporal * @param {Function} test function to test Hap * @example * s("hh!7 oh").filter(hap => hap.value.s === 'hh') @@ -2714,6 +2834,7 @@ export const filter = register('filter', (test, pat) => pat.withHaps((haps) => h /** * Filters haps by their begin time * @name filterWhen + * @tags temporal * @param {Function} test function to test Hap.whole.begin * @example * oneCycle: s("bd*4").filterWhen((t) => t < 1) @@ -2723,6 +2844,7 @@ export const filterWhen = register('filterWhen', (test, pat) => pat.filter((h) = /** * Use within to apply a function to only a part of a pattern. * @name within + * @tags temporal * @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 @@ -2797,6 +2919,7 @@ export function _match(span, hap_p) { * *Experimental* * * Speeds a pattern up or down, to fit to the given number of steps per cycle. + * @tags temporal * @example * sound("bd sd cp").pace(4) * // The same as sound("{bd sd cp}%4") or sound("*4") @@ -2838,6 +2961,7 @@ export function _polymeterListSteps(steps, ...args) { * *Experimental* * * Aligns the steps of the patterns, creating polymeters. The patterns are repeated until they all fit the cycle. For example, in the below the first pattern is repeated twice, and the second is repeated three times, to fit the lowest common multiple of six steps. + * @tags temporal * @synonyms pm * @example * // The same as note("{c eb g, c2 g2}%6") @@ -2870,6 +2994,7 @@ export function polymeter(...args) { * The steps can either be inferred from the pattern, or provided as a [length, pattern] pair. * Has the alias `timecat`. * @name stepcat + * @tags combiners * @synonyms timeCat, timecat * @return {Pattern} * @example @@ -2927,6 +3052,7 @@ export function stepcat(...timepats) { * Concatenates patterns stepwise, according to an inferred 'steps per cycle'. * Similar to `stepcat`, but if an argument is a list, the whole pattern will alternate between the elements in the list. * + * @tags combiners * @return {Pattern} * @example * stepalt(["bd cp", "mt"], "bd").sound() @@ -2953,6 +3079,7 @@ export function stepalt(...groups) { * * Takes the given number of steps from a pattern (dropping the rest). * A positive number will take steps from the start of a pattern, and a negative number from the end. + * @tags temporal * @return {Pattern} * @example * "bd cp ht mt".take("2").sound() @@ -2997,6 +3124,7 @@ export const take = stepRegister('take', function (i, pat) { * * Drops the given number of steps from a pattern. * A positive number will drop steps from the start of a pattern, and a negative number from the end. + * @tags temporal * @return {Pattern} * @example * "tha dhi thom nam".drop("1").sound().bank("mridangam") @@ -3025,6 +3153,7 @@ export const drop = stepRegister('drop', function (i, pat) { * `extend` is similar to `fast` in that it increases its density, but it also increases the step count * accordingly. So `stepcat("a b".extend(2), "c d")` would be the same as `"a b a b c d"`, whereas * `stepcat("a b".fast(2), "c d")` would be the same as `"[a b] [a b] c d"`. + * @tags temporal * @example * stepcat( * sound("bd bd - cp").extend(2), @@ -3043,6 +3172,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), @@ -3057,6 +3187,7 @@ export const replicate = stepRegister('replicate', function (factor, pat) { * *Experimental* * * Expands the step size of the pattern by the given factor. + * @tags temporal * @example * sound("tha dhi thom nam").bank("mridangam").expand("3 2 1 1 2 3").pace(8) */ @@ -3068,6 +3199,7 @@ export const expand = stepRegister('expand', function (factor, pat) { * *Experimental* * * Contracts the step size of the pattern by the given factor. See also `expand`. + * @tags temporal * @example * sound("tha dhi thom nam").bank("mridangam").contract("3 2 1 1 2 3").pace(8) */ @@ -3122,6 +3254,7 @@ export const shrinklist = (amount, pat) => pat.shrinklist(amount); * Progressively shrinks the pattern by 'n' steps until there's nothing left, or if a second value is given (using mininotation list syntax with `:`), * that number of times. * A positive number will progressively drop steps from the start of a pattern, and a negative number from the end. + * @tags temporal * @return {Pattern} * @example * "tha dhi thom nam".shrink("1").sound() @@ -3161,6 +3294,7 @@ export const shrink = register( * Progressively grows the pattern by 'n' steps until the full pattern is played, or if a second value is given (using mininotation list syntax with `:`), * that number of times. * A positive number will progressively grow steps from the start of a pattern, and a negative number from the end. + * @tags temporal * @return {Pattern} * @example * "tha dhi thom nam".grow("1").sound() @@ -3200,7 +3334,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. - * + * + * @tags combiners * @return {Pattern} * @example * "[c g]".tour("e f", "e f g", "g f e c").note() @@ -3227,6 +3362,7 @@ Pattern.prototype.tour = function (...many) { * 'zips' together the steps of the provided patterns. This can create a long repetition, taking place over a single, dense cycle. * Using `pace` to set the number of steps per cycle is therefore usually recommended. * + * @tags combiners * @returns {Pattern} * @example * zip("e f", "e f g", "g [f e] a f4 c").note() @@ -3278,6 +3414,7 @@ Pattern.prototype.steps = Pattern.prototype.pace; * Cuts each sample into the given number of parts, allowing you to explore a technique known as 'granular synthesis'. * It turns a pattern of samples into a pattern of parts of samples. * @name chop + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3308,6 +3445,7 @@ export const chop = register('chop', function (n, pat) { /** * Cuts each sample into the given number of parts, triggering progressive portions of each sample at each loop. * @name striate + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3326,6 +3464,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 temporal * @memberof Pattern * @returns Pattern * @example @@ -3344,6 +3483,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 temporal * @memberof Pattern * @returns Pattern * @example @@ -3379,6 +3519,7 @@ export const slice = register( * make something happen on event time * uses browser timeout which is innacurate for audio tasks * @name onTriggerTime + * @tags external_io * @memberof Pattern * @returns Pattern * @example @@ -3396,6 +3537,7 @@ Pattern.prototype.onTriggerTime = function (func) { /** * Works the same as slice, but changes the playback speed of each slice to match the duration of its step. * @name splice + * @tags temporal * @example * samples('github:tidalcycles/dirt-samples') * s("breaks165") @@ -3433,6 +3575,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 temporal * @example * samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' }) * s("rhodes/2").fit() @@ -3458,6 +3601,7 @@ export const fit = register('fit', (pat) => * given by a global clock and this function will be * deprecated/removed. * @name loopAtCps + * @tags temporal * @memberof Pattern * @returns Pattern * @example @@ -3469,7 +3613,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())) @@ -3484,6 +3630,7 @@ let fadeGain = (p) => (p < 0.5 ? 1 : 1 - (p - 0.5) / 0.5); * - 1 = (no left, full right) * * @name xfade + * @tags combiners * @example * xfade(s("bd*2"), "<0 .25 .5 .75 1>", s("hh*8")) */ @@ -3505,6 +3652,7 @@ Pattern.prototype.xfade = function (pos, b) { * creates a structure pattern from divisions of a cycle * especially useful for creating rhythms * @name beat + * @tags temporal * @example * s("bd").beat("0,7,10", 16) * @example @@ -3581,6 +3729,7 @@ export const _morph = (from, to, by) => { * sine.slow(8) // slowly morph between the rhythms * ) * ) + * @tags temporal */ export const morph = (frompat, topat, bypat) => { frompat = reify(frompat); @@ -3607,6 +3756,7 @@ const _distortWithAlg = function (name) { * 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 * @@ -3617,6 +3767,7 @@ export const soft = _distortWithAlg('soft'); * 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 * @@ -3627,6 +3778,7 @@ export const hard = _distortWithAlg('hard'); * 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 * @@ -3637,6 +3789,7 @@ export const cubic = _distortWithAlg('cubic'); * 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 * @@ -3647,6 +3800,7 @@ export const diode = _distortWithAlg('diode'); * 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 * @@ -3657,6 +3811,7 @@ export const asym = _distortWithAlg('asym'); * Wavefolding distortion * * @name fold + * @tags fx * @param {number | Pattern} distortion amount of distortion to apply * @param {number | Pattern} volume linear postgain of the distortion * @@ -3667,6 +3822,7 @@ export const fold = _distortWithAlg('fold'); * 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 * @@ -3677,6 +3833,7 @@ export const sinefold = _distortWithAlg('sinefold'); * 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 * @@ -3687,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) => { @@ -3709,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") @@ -3730,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 @@ -3751,6 +3911,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 @@ -3801,6 +3962,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/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 ec6a0d981..bf86ba494 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -12,7 +12,6 @@ import { import { evalScope } from './evaluate.mjs'; import { register, Pattern, isPattern, silence, stack } from './pattern.mjs'; import { reset_state } from './impure.mjs'; -import { SalatRepl } from '@kabelsalat/web'; export function repl({ defaultOutput, @@ -31,7 +30,6 @@ export function repl({ id, mondo = false, }) { - const kabel = new SalatRepl({ localScope: true }); const state = { schedulerError: undefined, evalError: undefined, @@ -89,11 +87,6 @@ export function repl({ return silence; }; - const compileKabel = (code) => { - const node = kabel.evaluate(code); - return node.compile({ log: false }); - }; - // helper to get a patternified pure value out function unpure(pat) { if (pat._Pattern) { @@ -123,6 +116,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 @@ -136,7 +130,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") @@ -148,18 +144,21 @@ export function repl({ * $: sound("hh*8") * all(x => x.pianoroll()) * ``` + * + * @tags combiners */ - let allTransforms = []; const all = function (transform) { allTransforms.push(transform); 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; @@ -215,7 +214,6 @@ export function repl({ setcps: setCps, setCpm, setcpm: setCpm, - compileKabel, }); }; diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index c9ed21663..2f9fe4b18 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} + * @tags 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} + * @tags 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} + * @tags 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} + * @tags 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} + * @tags generators */ export const sine2 = signal((t) => Math.sin(Math.PI * 2 * t)); /** * A sine signal between 0 and 1. * @return {Pattern} + * @tags 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} + * @tags 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} + * @tags generators */ export const cosine2 = sine2._early(Fraction(1).div(4)); /** * A square signal between 0 and 1. * @return {Pattern} + * @tags 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} + * @tags generators */ export const square2 = square.toBipolar(); @@ -117,6 +127,7 @@ export const square2 = square.toBipolar(); * A triangle signal between 0 and 1. * * @return {Pattern} + * @tags 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} + * @tags 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} + * @tags 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} + * @tags 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} + * @tags 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} + * @tags 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} + * @tags external_io * @example * n(mousey.segment(4).range(0,7)).scale("C:minor") * @@ -269,6 +286,7 @@ export const getRandsAtTime = (t, n = 1, seed = 0) => { * precise RNG, try `useRNG('precise')`. * * @name useRNG + * @tags generators, math * @param {string} mod - Mode. One of 'legacy', 'precise' * @example * useRNG('legacy') @@ -280,6 +298,7 @@ export const useRNG = (mode = 'legacy') => (RNG_MODE = mode); /** * A discrete pattern of numbers from 0 to n-1 + * @tags generators * @example * n(run(4)).scale("C4:pentatonic") * // n("0 1 2 3").scale("C4:pentatonic") @@ -290,6 +309,7 @@ export const run = (n) => saw.range(0, n).round().segment(n); * Creates a binary pattern from a number. * * @name binary + * @tags generators * @param {number} n - input number to convert to binary * @example * "hh".s().struct(binary(5)) @@ -304,6 +324,7 @@ export const binary = (n) => { * Creates a binary pattern from a number, padded to n bits long. * * @name binaryN + * @tags generators * @param {number} n - input number to convert to binary * @param {number} nBits - pattern length, defaults to 16 * @example @@ -321,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))) @@ -334,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 */ @@ -353,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") @@ -384,6 +408,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 temporal * @example * note("c d e f").sound("piano").shuffle(4) * @example @@ -397,6 +422,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 temporal * @example * note("c d e f").sound("piano").scramble(4) * @example @@ -409,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 @@ -428,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(); @@ -441,6 +469,7 @@ export const seed = register('seed', (n, pat) => { * A continuous pattern of random numbers, between 0 and 1. * * @name rand + * @tags generators * @example * // randomly change the cutoff * s("bd*4,hh*8").cutoff(rand.range(500,8000)) @@ -449,6 +478,7 @@ export const seed = register('seed', (n, pat) => { export const rand = signal((t, controls) => getRandsAtTime(t, 1, controls.randSeed)); /** * A continuous pattern of random numbers, between -1 and 1 + * @tags generators */ export const rand2 = rand.toBipolar(); @@ -458,6 +488,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 + * @tags generators * @param {number} probability - a number between 0 and 1 * @example * s("hh*10").pan(brandBy(0.2)) @@ -468,6 +499,7 @@ export const brandBy = (pPat) => reify(pPat).fmap(_brandBy).innerJoin(); * A continuous pattern of 0 or 1 (binary random) * * @name brand + * @tags generators * @example * s("hh*10").pan(brand) */ @@ -479,6 +511,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 + * @tags generators * @param {number} n max value (exclusive) * @example * // randomly select scale notes from 0 - 7 (= C to C) @@ -501,6 +534,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 temporal * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -514,6 +548,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 temporal * @param {Pattern} pat * @param {*} xs * @returns {Pattern} @@ -524,6 +559,7 @@ export const chooseInWith = (pat, xs) => { /** * Chooses randomly from the given list of elements. + * @tags temporal * @param {...any} xs values / patterns to choose from. * @returns {Pattern} - a continuous pattern. * @example @@ -539,6 +575,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 temporal * @param {...any} xs * @returns {Pattern} */ @@ -549,6 +586,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 temporal * @param {...any} xs * @returns {Pattern} */ @@ -558,6 +596,7 @@ Pattern.prototype.choose2 = function (...xs) { /** * Picks one of the elements at random each cycle. + * @tags temporal * @synonyms randcat * @returns {Pattern} * @example @@ -600,6 +639,7 @@ const wchooseWith = (...args) => _wchooseWith(...args).outerJoin(); /** * Chooses randomly from the given list of elements by giving a probability to each element + * @tags temporal * @param {...any} pairs arrays of value and weight * @returns {Pattern} - a continuous pattern. * @example @@ -609,6 +649,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 temporal * @synonyms wrandcat * @returns {Pattern} * @example @@ -652,6 +693,7 @@ function _berlin(t, seed = 0) { /** * Generates a continuous pattern of [perlin noise](https://en.wikipedia.org/wiki/Perlin_noise), in the range 0..1. * + * @tags generators * @name perlin * @example * // randomly change the cutoff @@ -664,6 +706,7 @@ export const perlin = signal((t, controls) => _perlin(t, controls.randSeed)); * 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. * + * @tags generators * @name berlin * @example * // ascending arpeggios @@ -684,6 +727,7 @@ export const degradeByWith = register( * 0 = 0% chance of removal * 1 = 100% chance of removal * + * @tags temporal * @name degradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -709,6 +753,7 @@ export const degradeBy = register( * * Randomly removes 50% of events from the pattern. Shorthand for `.degradeBy(0.5)` * + * @tags temporal * @name degrade * @memberof Pattern * @returns Pattern @@ -725,6 +770,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 temporal * @name undegradeBy * @memberof Pattern * @param {number} amount - a number between 0 and 1 @@ -753,6 +799,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 temporal * @name undegrade * @memberof Pattern * @returns Pattern @@ -771,6 +818,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 temporal * @name sometimesBy * @memberof Pattern * @param {number | Pattern} probability - a number between 0 and 1 @@ -790,6 +838,7 @@ export const sometimesBy = register('sometimesBy', function (patx, func, pat) { * * Applies the given function with a 50% chance * + * @tags temporal * @name sometimes * @memberof Pattern * @param {function} function - the transformation to apply @@ -811,6 +860,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 temporal * @example * s("bd,hh*8").someCyclesBy(.3, x=>x.speed("0.5")) */ @@ -833,6 +883,7 @@ export const someCyclesBy = register('someCyclesBy', function (patx, func, pat) * @name someCycles * @memberof Pattern * @returns Pattern + * @tags temporal * @example * s("bd,hh*8").someCycles(x=>x.speed("0.5")) */ @@ -847,6 +898,7 @@ export const someCycles = register('someCycles', function (func, pat) { * @name often * @memberof Pattern * @returns Pattern + * @tags temporal * @example * s("hh*8").often(x=>x.speed("0.5")) */ @@ -861,6 +913,7 @@ export const often = register('often', function (func, pat) { * @name rarely * @memberof Pattern * @returns Pattern + * @tags temporal * @example * s("hh*8").rarely(x=>x.speed("0.5")) */ @@ -872,6 +925,7 @@ export const rarely = register('rarely', function (func, pat) { * * Shorthand for `.sometimesBy(0.1, fn)` * + * @tags temporal * @name almostNever * @memberof Pattern * @returns Pattern @@ -886,6 +940,7 @@ export const almostNever = register('almostNever', function (func, pat) { * * Shorthand for `.sometimesBy(0.9, fn)` * + * @tags temporal * @name almostAlways * @memberof Pattern * @returns Pattern @@ -900,6 +955,7 @@ export const almostAlways = register('almostAlways', function (func, pat) { * * Shorthand for `.sometimesBy(0, fn)` (never calls fn) * + * @tags temporal * @name never * @memberof Pattern * @returns Pattern @@ -914,6 +970,7 @@ export const never = register('never', function (_, pat) { * * Shorthand for `.sometimesBy(1, fn)` (always calls fn) * + * @tags temporal * @name always * @memberof Pattern * @returns Pattern @@ -942,6 +999,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) * + * @tags external_io * @name whenKey * @memberof Pattern * @returns Pattern @@ -958,6 +1016,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) * + * @tags external_io * @name keyDown * @memberof Pattern * @returns Pattern @@ -975,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") @@ -993,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 @@ -1010,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/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 d0a1ce18d..8ce26c2a6 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -138,6 +138,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(); @@ -151,6 +152,7 @@ let loadCache = {}; /** * Adds midimaps to the registry. Inside each midimap, control names (e.g. lpf) are mapped to cc numbers. + * @tags external_io * @example * midimaps({ mymap: { lpf: 74 } }) * $: note("c a f e") @@ -305,6 +307,7 @@ function sendNote(note, velocity, duration, device, midichan, targetTime) { /** * 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 @@ -526,6 +529,7 @@ async function _initialize(input) { * The output is a function that accepts a midi cc value to query as well as (optionally) a midi channel * * @name midin + * @tags external_io * @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) @@ -573,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/motion/motion.mjs b/packages/motion/motion.mjs index 875704eae..fed0fbe0c 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags 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 + * @tags external_io * @example * n(absoluteOrientationGamma.segment(4).range(0,7)).scale("C:minor") * diff --git a/packages/osc/osc.mjs b/packages/osc/osc.mjs index 68caab3a7..0744cb8c9 100644 --- a/packages/osc/osc.mjs +++ b/packages/osc/osc.mjs @@ -79,6 +79,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/modulators.mjs b/packages/superdough/modulators.mjs index 05674baa0..76fc4c7fd 100644 --- a/packages/superdough/modulators.mjs +++ b/packages/superdough/modulators.mjs @@ -98,6 +98,7 @@ export const connectLFO = (id, params, nodeTracker) => { fxi = 'main', depth = 1, depthabs, + retrig = 0, ...filteredParams } = params; const { targetParams, paramName } = getTargetParamsForControl(control, nodeTracker[fxi], subControl); @@ -109,7 +110,7 @@ export const connectLFO = (id, params, nodeTracker) => { const modParams = { ...filteredParams, frequency: sync !== undefined ? sync * cps : rate, - time: cycle / cps, + time: retrig > 0.5 ? 0 : cycle / cps, depth: depthValue, min, max, 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/package.json b/packages/superdough/package.json index 8e2ffad63..ce17ab5e5 100644 --- a/packages/superdough/package.json +++ b/packages/superdough/package.json @@ -37,6 +37,7 @@ }, "dependencies": { "@kabelsalat/lib": "^0.4.1", + "@kabelsalat/web": "^0.4.1", "nanostores": "^0.11.3" }, "engines": { diff --git a/packages/superdough/reverbGen.mjs b/packages/superdough/reverbGen.mjs index 0949a30d5..1a14718e1 100644 --- a/packages/superdough/reverbGen.mjs +++ b/packages/superdough/reverbGen.mjs @@ -18,6 +18,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 @@ -50,7 +51,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. @@ -81,7 +82,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. + @tags internals + */ var applyGradualLowpass = function (input, lpFreqStart, lpFreqEnd, lpFreqEndAt, callback) { if (lpFreqStart == 0) { callback(input); diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 25c34c641..e7aee294f 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -235,6 +235,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 03a4c3da8..79da4f916 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 @@ -128,6 +130,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) { @@ -146,6 +150,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 */ @@ -255,6 +260,14 @@ export function loadWorklets() { return workletsLoading; } +let kabel; +async function initKabelsalat() { + const { SalatRepl } = await import('@kabelsalat/web'); + logger('[kabelsalat] ready'); + kabel = new SalatRepl({ localScope: true }); + return kabel; +} + // this function should be called on first user interaction (to avoid console warning) export async function initAudio(options = {}) { const { @@ -301,6 +314,7 @@ export async function initAudio(options = {}) { } catch (err) { console.warn('could not load AudioWorklet effects', err); } + await initKabelsalat(); logger('[superdough] ready'); } let audioReady; @@ -436,6 +450,14 @@ class Chain { } } +const compileKabel = (code) => { + if (!kabel) { + throw new Error('kabelsalat not loaded'); + } + const node = kabel.evaluate(code); + return node.compile({ log: false }); +}; + export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) => { // mapping from main FX and numbered FX chains to nodes const nodes = { main: {} }; 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]])); }; diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 6ef1f0ebb..79519b5f0 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -186,6 +186,7 @@ export function registerWaveTable(key, tables, params) { * Loads a collection of wavetables to use with `s` * * @name tables + * @tags fx */ 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 26a0fa668..7155afb86 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -646,14 +646,18 @@ class PhaseVocoderProcessor extends OLAProcessor { this.timeCursor += this.hopSize; } - /** Apply Hann window in-place */ + /** Apply Hann window in-place + * @tags internals + */ applyHannWindow(input) { for (let i = 0; i < this.blockSize; i++) { input[i] *= this.hannWindow[i] * 1.62; } } - /** Compute squared magnitudes for peak finding **/ + /** Compute squared magnitudes for peak finding + * @tags internals + **/ computeMagnitudes() { let i = 0, j = 0; @@ -667,7 +671,9 @@ class PhaseVocoderProcessor extends OLAProcessor { } } - /** Find peaks in spectrum magnitudes **/ + /** Find peaks in spectrum magnitudes + * @tags internals + **/ findPeaks() { this.nbPeaks = 0; let i = 2; @@ -688,7 +694,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); @@ -841,7 +849,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/supradough/dough.mjs b/packages/supradough/dough.mjs index 7231792c9..f7eae6ef5 100644 --- a/packages/supradough/dough.mjs +++ b/packages/supradough/dough.mjs @@ -19,6 +19,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 internals * @returns {number} Crossfaded output value. */ function crossfade(a, b, m) { diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 951f0f7e6..2d197a7ed 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -100,6 +100,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 @@ -154,6 +155,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 @@ -244,6 +246,7 @@ function _getNearestScaleNote(scaleName, note, preferHigher = true) { * The root note defaults to octave 3, if no octave number is given. * * @name scale + * @tags music_theory * @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) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53437f8f5..468ceacf1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -234,9 +234,6 @@ importers: packages/core: dependencies: - '@kabelsalat/web': - specifier: ^0.4.1 - version: 0.4.1 fraction.js: specifier: ^5.2.1 version: 5.2.1 @@ -524,6 +521,9 @@ importers: '@kabelsalat/lib': specifier: ^0.4.1 version: 0.4.1 + '@kabelsalat/web': + specifier: ^0.4.1 + version: 0.4.1 nanostores: specifier: ^0.11.3 version: 0.11.3 diff --git a/website/src/components/HeadCommon.astro b/website/src/components/HeadCommon.astro index fe8d34bb2..550222e44 100644 --- a/website/src/components/HeadCommon.astro +++ b/website/src/components/HeadCommon.astro @@ -33,6 +33,7 @@ const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL