From e4b00117c311dd309fbe0e969a5053911264b8d7 Mon Sep 17 00:00:00 2001 From: "Alexandre G.-Raymond" Date: Sat, 11 Nov 2023 14:22:52 +0100 Subject: [PATCH 01/17] Parse the synonyms tag in source documentation --- jsdoc-synonyms.js | 17 +++++++++++++++++ jsdoc.config.json | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 jsdoc-synonyms.js diff --git a/jsdoc-synonyms.js b/jsdoc-synonyms.js new file mode 100644 index 00000000..29aed7b2 --- /dev/null +++ b/jsdoc-synonyms.js @@ -0,0 +1,17 @@ +/* +jsdoc-synonyms.js - Add support for @synonym tag +Copyright (C) 2023 Strudel contributors - see +This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . +*/ + +function defineTags(dictionary) { + dictionary.defineTag('synonyms', { + mustHaveValue: true, + onTagged: function(doclet, tag) { + doclet.synonyms_text = tag.value; + doclet.synonyms = doclet.synonyms_text.split(/[ ,]+/); + } +}); +}; + +module.exports = {defineTags: defineTags} \ No newline at end of file diff --git a/jsdoc.config.json b/jsdoc.config.json index ca9c3d81..4098a5c5 100644 --- a/jsdoc.config.json +++ b/jsdoc.config.json @@ -3,7 +3,7 @@ "includePattern": ".+\\.(js(doc|x)?|mjs)$", "excludePattern": "node_modules|shift-parser|shift-reducer|shift-traverser|dist" }, - "plugins": ["plugins/markdown"], + "plugins": ["plugins/markdown", "jsdoc-synonyms"], "opts": { "destination": "./out/", "recurse": true From bbc292561f20b3fc04637c135693a55f1a77d734 Mon Sep 17 00:00:00 2001 From: "Alexandre G.-Raymond" Date: Sat, 11 Nov 2023 14:23:30 +0100 Subject: [PATCH 02/17] Use synonyms in Tooltip --- packages/react/src/components/Tooltip.jsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/react/src/components/Tooltip.jsx b/packages/react/src/components/Tooltip.jsx index a443c123..a508e761 100644 --- a/packages/react/src/components/Tooltip.jsx +++ b/packages/react/src/components/Tooltip.jsx @@ -31,6 +31,9 @@ window.addEventListener( export const strudelTooltip = hoverTooltip( (view, pos, side) => { // Word selection from CodeMirror Hover Tooltip example https://codemirror.net/examples/tooltip/#hover-tooltips + if (!ctrlDown) { + return null; + } let { from, to, text } = view.state.doc.lineAt(pos); let start = pos, end = pos; @@ -47,11 +50,14 @@ export const strudelTooltip = hoverTooltip( // Get entry from Strudel documentation let entry = jsdoc.docs.filter((doc) => getDocLabel(doc) === word)[0]; if (!entry) { - return null; - } - if (!ctrlDown) { - return null; + // Try for synonyms + entry = jsdoc.docs.filter((doc) => doc.synonyms && doc.synonyms.includes(word))[0]; + if (!entry) { + return null; + } + entry.name = word; } + return { pos: start, end, From 6ba2b767b0145e1f5463f4c49bae1d1670735066 Mon Sep 17 00:00:00 2001 From: "Alexandre G.-Raymond" Date: Sat, 11 Nov 2023 14:23:55 +0100 Subject: [PATCH 03/17] Show synonyms in API reference --- website/src/repl/Reference.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/src/repl/Reference.jsx b/website/src/repl/Reference.jsx index cf6fd5b1..b43f365e 100644 --- a/website/src/repl/Reference.jsx +++ b/website/src/repl/Reference.jsx @@ -37,6 +37,11 @@ export function Reference() { {visibleFunctions.map((entry, i) => (

{entry.name}

+ {!!entry.synonyms_text && ( +

+ Synonyms: {entry.synonyms_text} +

+ )} {/* {entry.meta.filename} */}

    From 2aff31fe06bcaf3bbfce7df12ef91c847466eccc Mon Sep 17 00:00:00 2001 From: "Alexandre G.-Raymond" Date: Sat, 11 Nov 2023 14:24:20 +0100 Subject: [PATCH 04/17] Simplify JSDoc --- website/src/docs/JsDoc.jsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/website/src/docs/JsDoc.jsx b/website/src/docs/JsDoc.jsx index 1ba80e0a..1a7a034f 100644 --- a/website/src/docs/JsDoc.jsx +++ b/website/src/docs/JsDoc.jsx @@ -2,19 +2,15 @@ import jsdoc from '../../../doc.json'; // doc.json is built with `npm run jsdoc- const docs = jsdoc.docs.reduce((acc, obj) => Object.assign(acc, { [obj.longname]: obj }), {}); import { MiniRepl } from './MiniRepl'; -const getTag = (title, item) => item.tags?.find((t) => t.title === title)?.text; - export function JsDoc({ name, h = 3, hideDescription, punchcard, canvasHeight }) { const item = docs[name]; if (!item) { console.warn('Not found: ' + name); return
    ; } - const synonyms = getTag('synonyms', item)?.split(', ') || []; const CustomHeading = `h${h}`; const description = item.description?.replaceAll(/\{@link ([a-zA-Z\.]+)?#?([a-zA-Z]*)\}/g, (_, a, b) => { - // console.log(_, 'a', a, 'b', b); return `${a}${b ? `#${b}` : ''}`; }) || ''; return ( @@ -22,9 +18,9 @@ export function JsDoc({ name, h = 3, hideDescription, punchcard, canvasHeight }) {!!h && {item.longname}} {!hideDescription && ( <> - {!!synonyms.length && ( + {!!item.synonyms_text && ( - Synonyms: {synonyms.join(', ')} + Synonyms: {item.synonyms_text} )}
    From bfff38a262f46daf0b9186fac35672740bdf7f2c Mon Sep 17 00:00:00 2001 From: "Alexandre G.-Raymond" Date: Sat, 11 Nov 2023 15:44:15 +0100 Subject: [PATCH 05/17] Fix code format of JSDoc synonym plugin --- jsdoc-synonyms.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jsdoc-synonyms.js b/jsdoc-synonyms.js index 29aed7b2..09190846 100644 --- a/jsdoc-synonyms.js +++ b/jsdoc-synonyms.js @@ -7,11 +7,11 @@ This program is free software: you can redistribute it and/or modify it under th function defineTags(dictionary) { dictionary.defineTag('synonyms', { mustHaveValue: true, - onTagged: function(doclet, tag) { + onTagged: function (doclet, tag) { doclet.synonyms_text = tag.value; doclet.synonyms = doclet.synonyms_text.split(/[ ,]+/); - } -}); -}; + }, + }); +} -module.exports = {defineTags: defineTags} \ No newline at end of file +module.exports = { defineTags: defineTags }; From 24e18818768b8109a6978b869fe08b78f14fc0d2 Mon Sep 17 00:00:00 2001 From: "Alexandre G.-Raymond" Date: Sat, 11 Nov 2023 15:53:03 +0100 Subject: [PATCH 06/17] Ignore jsdoc-synonyms by eslint --- .eslintignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index 92c95c85..7d807b65 100644 --- a/.eslintignore +++ b/.eslintignore @@ -20,4 +20,5 @@ vite.config.js **/dist /src-tauri/target/**/* reverbGen.mjs -hydra.mjs \ No newline at end of file +hydra.mjs +jsdoc-synonyms.js \ No newline at end of file From 476bda812e93380d633800d0a99ab280e914ed39 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Fri, 17 Nov 2023 12:55:17 +0100 Subject: [PATCH 07/17] Initial work on crackle --- packages/superdough/noise.mjs | 17 +++++++++++++---- packages/superdough/synth.mjs | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/superdough/noise.mjs b/packages/superdough/noise.mjs index 2c8c1d4a..6a2d418c 100644 --- a/packages/superdough/noise.mjs +++ b/packages/superdough/noise.mjs @@ -4,7 +4,7 @@ import { getAudioContext } from './superdough.mjs'; let noiseCache = {}; // lazy generates noise buffers and keeps them forever -function getNoiseBuffer(type) { +function getNoiseBuffer(type, density) { const ac = getAudioContext(); if (noiseCache[type]) { return noiseCache[type]; @@ -34,17 +34,26 @@ function getNoiseBuffer(type) { output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; output[i] *= 0.11; b6 = white * 0.115926; + } else if (type === 'crackle') { + if (Math.random() < (Math.random() * (density - 0.001) + density).toFixed(4)) { + output[i] = Math.random() * 2 - 1; + } else { + output[i] = 0; + } } } - noiseCache[type] = noiseBuffer; + + // Prevent caching to randomize crackles + if (type !== "crackle") + noiseCache[type] = noiseBuffer; return noiseBuffer; } // expects one of noises as type -export function getNoiseOscillator(type = 'white', t) { +export function getNoiseOscillator(type = 'white', t, density = 0.02) { const ac = getAudioContext(); const o = ac.createBufferSource(); - o.buffer = getNoiseBuffer(type); + o.buffer = getNoiseBuffer(type, density); o.loop = true; o.start(t); return { diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index dafc2e7c..53f462d5 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -22,7 +22,7 @@ const fm = (osc, harmonicityRatio, modulationIndex, wave = 'sine') => { }; const waveforms = ['sine', 'square', 'triangle', 'sawtooth']; -const noises = ['pink', 'white', 'brown']; +const noises = ['pink', 'white', 'brown', 'crackle']; export function registerSynthSounds() { [...waveforms, ...noises].forEach((s) => { @@ -36,7 +36,7 @@ export function registerSynthSounds() { if (waveforms.includes(s)) { sound = getOscillator(s, t, value); } else { - sound = getNoiseOscillator(s, t); + sound = getNoiseOscillator(s, t, 0.002); } let { node: o, stop, triggerRelease } = sound; From fb28083ce616de5b3a14e36a9cc415d6802b5be8 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Fri, 17 Nov 2023 13:18:49 +0100 Subject: [PATCH 08/17] Fixing density and adding documentation --- packages/core/controls.mjs | 15 +++++++++++++-- packages/superdough/noise.mjs | 3 ++- packages/superdough/superdough.mjs | 1 + packages/superdough/synth.mjs | 3 ++- website/src/pages/learn/synths.mdx | 4 ++++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index a03658a8..a14f06df 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1214,6 +1214,17 @@ const generic_params = [ * @name waveloss */ ['waveloss'], + /* + * + * Noise crackle density + * + * @name density + * @param {number | Pattern} density between 0 and x + * @example + * s("crackle*4").density("<0.01 0.04 0.2 0.5>".slow(4)) + * + */ + ['density'], // TODO: midi effects? ['dur'], // ['modwheel'], @@ -1308,7 +1319,7 @@ const generic_params = [ ]; // TODO: slice / splice https://www.youtube.com/watch?v=hKhPdO0RKDQ&list=PL2lW1zNIIwj3bDkh-Y3LUGDuRcoUigoDs&index=13 -controls.createParam = function (names) { +controls.createParam = function(names) { const name = Array.isArray(names) ? names[0] : names; var withVal; @@ -1332,7 +1343,7 @@ controls.createParam = function (names) { const func = (...pats) => sequence(...pats).withValue(withVal); - const setter = function (...pats) { + const setter = function(...pats) { if (!pats.length) { return this.fmap(withVal); } diff --git a/packages/superdough/noise.mjs b/packages/superdough/noise.mjs index 6a2d418c..8993f470 100644 --- a/packages/superdough/noise.mjs +++ b/packages/superdough/noise.mjs @@ -35,7 +35,8 @@ function getNoiseBuffer(type, density) { output[i] *= 0.11; b6 = white * 0.115926; } else if (type === 'crackle') { - if (Math.random() < (Math.random() * (density - 0.001) + density).toFixed(4)) { + const probability = density * 0.01 + if (Math.random() < probability) { output[i] = Math.random() * 2 - 1; } else { output[i] = 0; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 00e2f42c..ed133366 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -241,6 +241,7 @@ export const superdough = async (value, deadline, hapDuration) => { source, gain = 0.8, postgain = 1, + density = 0.03, // filters ftype = '12db', fanchor = 0.5, diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 53f462d5..edc3c01e 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -36,7 +36,8 @@ export function registerSynthSounds() { if (waveforms.includes(s)) { sound = getOscillator(s, t, value); } else { - sound = getNoiseOscillator(s, t, 0.002); + let { density } = value; + sound = getNoiseOscillator(s, t, density); } let { node: o, stop, triggerRelease } = sound; diff --git a/website/src/pages/learn/synths.mdx b/website/src/pages/learn/synths.mdx index 432276ef..abb74c2f 100644 --- a/website/src/pages/learn/synths.mdx +++ b/website/src/pages/learn/synths.mdx @@ -42,6 +42,10 @@ Some amount of pink noise can also be added to any oscillator by using the `nois ").scope()`} /> +You can also use the `crackle` type to play some subtle noise crackles. You can control noise amount by using the `density` parameter: + + + ### Additive Synthesis To tame the harsh sound of the basic waveforms, we can set the `n` control to limit the overtones of the waveform: From 2a18df61cda07a2e4328b53fddd27e091293861a Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Fri, 17 Nov 2023 13:23:54 +0100 Subject: [PATCH 09/17] Fix documentation --- packages/core/controls.mjs | 1 - website/src/pages/learn/synths.mdx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index a14f06df..1cd69e81 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1215,7 +1215,6 @@ const generic_params = [ */ ['waveloss'], /* - * * Noise crackle density * * @name density diff --git a/website/src/pages/learn/synths.mdx b/website/src/pages/learn/synths.mdx index abb74c2f..d6ac5061 100644 --- a/website/src/pages/learn/synths.mdx +++ b/website/src/pages/learn/synths.mdx @@ -44,7 +44,7 @@ Some amount of pink noise can also be added to any oscillator by using the `nois You can also use the `crackle` type to play some subtle noise crackles. You can control noise amount by using the `density` parameter: - +".slow(4)).scope()`} /> ### Additive Synthesis From 6e92c4915aaad88590fbb8d9ff0b3c8e398d28f7 Mon Sep 17 00:00:00 2001 From: Raphael Forment Date: Fri, 17 Nov 2023 13:37:16 +0100 Subject: [PATCH 10/17] Run prettier --- packages/core/controls.mjs | 4 ++-- packages/superdough/noise.mjs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 1cd69e81..6449969e 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1318,7 +1318,7 @@ const generic_params = [ ]; // TODO: slice / splice https://www.youtube.com/watch?v=hKhPdO0RKDQ&list=PL2lW1zNIIwj3bDkh-Y3LUGDuRcoUigoDs&index=13 -controls.createParam = function(names) { +controls.createParam = function (names) { const name = Array.isArray(names) ? names[0] : names; var withVal; @@ -1342,7 +1342,7 @@ controls.createParam = function(names) { const func = (...pats) => sequence(...pats).withValue(withVal); - const setter = function(...pats) { + const setter = function (...pats) { if (!pats.length) { return this.fmap(withVal); } diff --git a/packages/superdough/noise.mjs b/packages/superdough/noise.mjs index 8993f470..24779470 100644 --- a/packages/superdough/noise.mjs +++ b/packages/superdough/noise.mjs @@ -35,7 +35,7 @@ function getNoiseBuffer(type, density) { output[i] *= 0.11; b6 = white * 0.115926; } else if (type === 'crackle') { - const probability = density * 0.01 + const probability = density * 0.01; if (Math.random() < probability) { output[i] = Math.random() * 2 - 1; } else { @@ -45,8 +45,7 @@ function getNoiseBuffer(type, density) { } // Prevent caching to randomize crackles - if (type !== "crackle") - noiseCache[type] = noiseBuffer; + if (type !== 'crackle') noiseCache[type] = noiseBuffer; return noiseBuffer; } From c0f56be2a9d4eb0de18094fbebed77a9200a5cfc Mon Sep 17 00:00:00 2001 From: Kaspars Date: Fri, 17 Nov 2023 20:41:37 +0100 Subject: [PATCH 11/17] add options param to initHydra --- packages/hydra/hydra.mjs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/hydra/hydra.mjs b/packages/hydra/hydra.mjs index 692e4c14..3e86504c 100644 --- a/packages/hydra/hydra.mjs +++ b/packages/hydra/hydra.mjs @@ -1,13 +1,19 @@ import { getDrawContext } from '@strudel.cycles/core'; -export async function initHydra() { +export async function initHydra( + options = { + src: 'https://unpkg.com/hydra-synth', + detectAudio: false, + }, +) { if (!document.getElementById('hydra-canvas')) { const { canvas: testCanvas } = getDrawContext(); - await import('https://unpkg.com/hydra-synth'); + const { src, ...opts } = options; + await import(src); const hydraCanvas = testCanvas.cloneNode(true); hydraCanvas.id = 'hydra-canvas'; testCanvas.after(hydraCanvas); - new Hydra({ canvas: hydraCanvas, detectAudio: false }); + new Hydra(Object.assign({ canvas: hydraCanvas }, opts)); s0.init({ src: testCanvas }); } } From d71877f915aa0cd11a1d58999dd60e7a926b1cd2 Mon Sep 17 00:00:00 2001 From: Alexandre Gravel-Raymond Date: Wed, 22 Nov 2023 20:35:19 +0100 Subject: [PATCH 12/17] Move jsdoc files to subfolder --- jsdoc-synonyms.js => jsdoc/jsdoc-synonyms.js | 0 jsdoc.config.json => jsdoc/jsdoc.config.json | 2 +- undocumented.mjs => jsdoc/undocumented.mjs | 4 ++-- package.json | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename jsdoc-synonyms.js => jsdoc/jsdoc-synonyms.js (100%) rename jsdoc.config.json => jsdoc/jsdoc.config.json (78%) rename undocumented.mjs => jsdoc/undocumented.mjs (91%) diff --git a/jsdoc-synonyms.js b/jsdoc/jsdoc-synonyms.js similarity index 100% rename from jsdoc-synonyms.js rename to jsdoc/jsdoc-synonyms.js diff --git a/jsdoc.config.json b/jsdoc/jsdoc.config.json similarity index 78% rename from jsdoc.config.json rename to jsdoc/jsdoc.config.json index 4098a5c5..073b16c5 100644 --- a/jsdoc.config.json +++ b/jsdoc/jsdoc.config.json @@ -3,7 +3,7 @@ "includePattern": ".+\\.(js(doc|x)?|mjs)$", "excludePattern": "node_modules|shift-parser|shift-reducer|shift-traverser|dist" }, - "plugins": ["plugins/markdown", "jsdoc-synonyms"], + "plugins": ["plugins/markdown", "jsdoc/jsdoc-synonyms"], "opts": { "destination": "./out/", "recurse": true diff --git a/undocumented.mjs b/jsdoc/undocumented.mjs similarity index 91% rename from undocumented.mjs rename to jsdoc/undocumented.mjs index 281d27d8..657fdea6 100644 --- a/undocumented.mjs +++ b/jsdoc/undocumented.mjs @@ -65,7 +65,7 @@ async function getUndocumented(path, docs) { } // read doc.json file -const { docs } = JSON.parse(await readFile(resolve(__dirname, 'doc.json'), 'utf8')); +const { docs } = JSON.parse(await readFile(resolve(__dirname, '..', 'doc.json'), 'utf8')); const paths = dependencyTree.toList({ filename: 'index.mjs', @@ -76,7 +76,7 @@ const paths = dependencyTree.toList({ // const paths = ['../packages/core/pattern.mjs', '../packages/core/hap.mjs'].map((rel) => resolve(__dirname, rel)); const undocumented = Object.fromEntries( - await Promise.all(paths.map(async (path) => [path, await getUndocumented(path, docs)])), + await Promise.all(paths.map(async (path) => [path.replace(resolve(__dirname, '..'), ''), await getUndocumented(path, docs)])), ); console.log(JSON.stringify(undocumented, null, 2)); diff --git a/package.json b/package.json index 36229611..172832ee 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,12 @@ "build": "npm run prebuild && cd website && npm run build", "preview": "cd website && npm run preview", "osc": "cd packages/osc && npm run server", - "jsdoc": "jsdoc packages/ -c jsdoc.config.json", - "jsdoc-json": "jsdoc packages/ --template ./node_modules/jsdoc-json --destination doc.json -c jsdoc.config.json", + "jsdoc": "jsdoc packages/ -c jsdoc/jsdoc.config.json", + "jsdoc-json": "jsdoc packages/ --template ./node_modules/jsdoc-json --destination doc.json -c jsdoc/jsdoc.config.json", "lint": "eslint . --ext mjs,js --quiet", "codeformat": "prettier --write .", "format-check": "prettier --check .", - "report-undocumented": "npm run jsdoc-json && node undocumented.mjs > undocumented.json", + "report-undocumented": "npm run jsdoc-json && node jsdoc/undocumented.mjs > undocumented.json", "check": "npm run format-check && npm run lint && npm run test", "iclc": "cd paper && pandoc --template=pandoc/iclc.html --citeproc --number-sections iclc2023.md -o iclc2023.html && pandoc --template=pandoc/iclc.latex --citeproc --number-sections iclc2023.md -o iclc2023.pdf" }, From 2868a5ff4fc21f208d83ce8ce9a4934305e284e1 Mon Sep 17 00:00:00 2001 From: Alexandre Gravel-Raymond Date: Wed, 22 Nov 2023 20:36:01 +0100 Subject: [PATCH 13/17] Update the undocumented functions file --- undocumented.json | 210 +++++++++++++++++++++++++++++----------------- 1 file changed, 134 insertions(+), 76 deletions(-) diff --git a/undocumented.json b/undocumented.json index 0d28835d..0a807c90 100644 --- a/undocumented.json +++ b/undocumented.json @@ -1,17 +1,17 @@ { - "/home/felix/projects/strudel/packages/core/fraction.mjs": [ + "/packages/core/fraction.mjs": [ "gcd" ], - "/home/felix/projects/strudel/packages/core/timespan.mjs": [ + "/packages/core/timespan.mjs": [ "TimeSpan" ], - "/home/felix/projects/strudel/packages/core/hap.mjs": [ + "/packages/core/hap.mjs": [ "Hap" ], - "/home/felix/projects/strudel/packages/core/state.mjs": [ + "/packages/core/state.mjs": [ "State" ], - "/home/felix/projects/strudel/packages/core/util.mjs": [ + "/packages/core/util.mjs": [ "isNoteWithOctave", "isNote", "tokenizeNote", @@ -34,23 +34,31 @@ "mapArgs", "numeralArgs", "parseFractional", - "fractionalArgs" + "fractionalArgs", + "splitAt", + "zipWith", + "clamp", + "sol2note" ], - "/home/felix/projects/strudel/packages/core/value.mjs": [ + "/packages/core/value.mjs": [ "unionWithObj", "valued", "Value", "map" ], - "/home/felix/projects/strudel/packages/core/drawLine.mjs": [], - "/home/felix/projects/strudel/packages/core/logger.mjs": [ + "/packages/core/drawLine.mjs": [], + "/packages/core/logger.mjs": [ "logKey", "logger" ], - "/home/felix/projects/strudel/packages/core/pattern.mjs": [ + "/packages/core/pattern.mjs": [ "setStringParser", + "polyrhythm", + "pr", + "pm", "isPattern", "reify", + "fastcat", "set", "keep", "keepif", @@ -74,22 +82,33 @@ "func", "compressSpan", "compressspan", + "fastgap", "focusSpan", "focusspan", + "density", + "sparsity", "zoomArc", "zoomarc", + "inv", + "juxby", + "echowith", + "stutWith", + "stutwith", + "iterback", + "chunkback", "bypass", "duration", - "color", "colour", - "striate" + "loopat", + "loopatcps" ], - "/home/felix/projects/strudel/packages/core/controls.mjs": [], - "/home/felix/projects/strudel/packages/core/euclid.mjs": [ + "/packages/core/controls.mjs": [], + "/packages/core/euclid.mjs": [ + "bjork", "euclidrot", "euclidLegatoRot" ], - "/home/felix/projects/strudel/packages/core/signal.mjs": [ + "/packages/core/signal.mjs": [ "steady", "signal", "isaw", @@ -112,34 +131,37 @@ "degradeByWith", "undegrade" ], - "/home/felix/projects/strudel/packages/core/speak.mjs": [ + "/packages/core/speak.mjs": [ "speak" ], - "/home/felix/projects/strudel/packages/core/evaluate.mjs": [ + "/packages/core/evaluate.mjs": [ "evalScope", "evaluate" ], - "/home/felix/projects/strudel/packages/core/zyklus.mjs": [], - "/home/felix/projects/strudel/packages/core/cyclist.mjs": [ + "/packages/core/zyklus.mjs": [], + "/packages/core/cyclist.mjs": [ "Cyclist" ], - "/home/felix/projects/strudel/packages/core/time.mjs": [ + "/packages/core/time.mjs": [ "getTime", "setTime" ], - "/home/felix/projects/strudel/packages/core/repl.mjs": [ - "repl" + "/packages/core/repl.mjs": [ + "repl", + "getTrigger" ], - "/home/felix/projects/strudel/packages/core/draw.mjs": [ + "/packages/core/draw.mjs": [ "getDrawContext", - "cleanupDraw" + "cleanupDraw", + "Framer", + "Drawer" ], - "/home/felix/projects/strudel/packages/core/animate.mjs": [ + "/packages/core/animate.mjs": [ "x", "y", "w", "h", - "a", + "angle", "r", "fill", "smear", @@ -147,85 +169,121 @@ "moveXY", "zoomIn" ], - "/home/felix/projects/strudel/packages/core/pianoroll.mjs": [ - "pianoroll" + "/packages/core/pianoroll.mjs": [ + "getDrawOptions", + "drawPianoroll" ], - "/home/felix/projects/strudel/packages/core/ui.mjs": [ + "/packages/core/spiral.mjs": [], + "/packages/core/ui.mjs": [ "backgroundImage", "cleanupUi" ], - "/home/felix/projects/strudel/packages/core/gist.js": [], - "/home/felix/projects/strudel/packages/core/index.mjs": [], - "/home/felix/projects/strudel/packages/midi/midi.mjs": [ + "/packages/core/gist.js": [], + "/packages/core/index.mjs": [], + "/packages/csound/index.mjs": [ + "loadCSound", + "loadcsound", + "loadCsound", + "csound", + "loadOrc" + ], + "/packages/desktopbridge/utils.mjs": [ + "Invoke", + "isTauri" + ], + "/packages/desktopbridge/midibridge.mjs": [], + "/packages/desktopbridge/oscbridge.mjs": [], + "/packages/desktopbridge/index.mjs": [], + "/packages/midi/midi.mjs": [ "WebMidi", - "enableWebMidi" + "enableWebMidi", + "midin" ], - "/home/felix/projects/strudel/packages/midi/index.mjs": [], - "/home/felix/projects/strudel/packages/mini/krill-parser.js": [], - "/home/felix/projects/strudel/packages/mini/mini.mjs": [ + "/packages/midi/index.mjs": [], + "/packages/mini/krill-parser.js": [], + "/packages/mini/mini.mjs": [ "patternifyAST", + "getLeafLocation", + "mini2ast", + "getLeaves", + "getLeafLocations", "mini", + "m", "h", - "minify" + "minify", + "miniAllStrings" ], - "/home/felix/projects/strudel/packages/mini/index.mjs": [], - "/home/felix/projects/strudel/packages/soundfonts/fontloader.mjs": [ + "/packages/mini/index.mjs": [], + "/packages/soundfonts/gm.mjs": [], + "/packages/soundfonts/fontloader.mjs": [ "getFontBufferSource", - "getFontPitch" + "getFontPitch", + "registerSoundfonts" ], - "/home/felix/projects/strudel/packages/soundfonts/list.mjs": [ + "/packages/soundfonts/list.mjs": [ "instruments", "drums", "instrumentNames" ], - "/home/felix/projects/strudel/packages/soundfonts/sfumato.mjs": [ + "/packages/soundfonts/sfumato.mjs": [ "loadSoundfont" ], - "/home/felix/projects/strudel/packages/soundfonts/index.mjs": [], - "/home/felix/projects/strudel/packages/tonal/tonal.mjs": [], - "/home/felix/projects/strudel/packages/tonal/voicings.mjs": [ - "voicingRegistry", - "setVoicingRange" + "/packages/soundfonts/index.mjs": [], + "/packages/tonal/tonal.mjs": [], + "/packages/tonal/tonleiter.mjs": [ + "pc2chroma", + "rotateChroma", + "chroma2pc", + "tokenizeChord", + "note2pc", + "note2oct", + "note2chroma", + "midi2chroma", + "pitch2chroma", + "step2semitones", + "x2midi", + "scaleStep", + "renderVoicing", + "accidentalOffset", + "Step", + "Note" ], - "/home/felix/projects/strudel/packages/tonal/index.mjs": [], - "/home/felix/projects/strudel/packages/transpiler/transpiler.mjs": [ + "/packages/tonal/ireal.mjs": [ + "simple", + "complex" + ], + "/packages/tonal/voicings.mjs": [ + "voicingRegistry", + "setVoicingRange", + "registerVoicings", + "voicingAlias" + ], + "/packages/tonal/index.mjs": [], + "/packages/transpiler/transpiler.mjs": [ "transpiler" ], - "/home/felix/projects/strudel/packages/transpiler/index.mjs": [ + "/packages/transpiler/index.mjs": [ "evaluate" ], - "/home/felix/projects/strudel/packages/webaudio/feedbackdelay.mjs": [], - "/home/felix/projects/strudel/packages/webaudio/reverb.mjs": [], - "/home/felix/projects/strudel/packages/webaudio/sampler.mjs": [ - "getCachedBuffer", - "getSampleBufferSource", - "loadBuffer", - "reverseBuffer", - "getLoadedBuffer", - "resetLoadedSamples", - "getLoadedSamples" - ], - "/home/felix/projects/strudel/packages/webaudio/vowel.mjs": [ - "vowelFormant" - ], - "/home/felix/projects/strudel/packages/webaudio/webaudio.mjs": [ - "getAudioContext", - "panic", - "initAudio", - "initAudioOnFirstClick", + "/packages/webaudio/webaudio.mjs": [ + "webaudioOutputTrigger", "webaudioOutput", - "webaudioOutputTrigger" + "webaudioScheduler" ], - "/home/felix/projects/strudel/packages/webaudio/index.mjs": [], - "/home/felix/projects/strudel/packages/xen/xen.mjs": [ + "/packages/webaudio/scope.mjs": [ + "drawTimeScope", + "drawFrequencyScope" + ], + "/packages/webaudio/index.mjs": [], + "/packages/xen/xen.mjs": [ "edo", "xen", "tuning" ], - "/home/felix/projects/strudel/packages/xen/tunejs.js": [], - "/home/felix/projects/strudel/packages/xen/tune.mjs": [ + "/packages/xen/tunejs.js": [], + "/packages/xen/tune.mjs": [ "tune" ], - "/home/felix/projects/strudel/packages/xen/index.mjs": [], - "/home/felix/projects/strudel/index.mjs": [] + "/packages/xen/index.mjs": [], + "/index.mjs": [] } From ecc8e0a108abe03da8138f457596a3ca1585a01c Mon Sep 17 00:00:00 2001 From: Alexandre Gravel-Raymond Date: Wed, 22 Nov 2023 20:38:25 +0100 Subject: [PATCH 14/17] More code beauty please --- jsdoc/undocumented.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jsdoc/undocumented.mjs b/jsdoc/undocumented.mjs index 657fdea6..9376a8b6 100644 --- a/jsdoc/undocumented.mjs +++ b/jsdoc/undocumented.mjs @@ -76,7 +76,9 @@ const paths = dependencyTree.toList({ // const paths = ['../packages/core/pattern.mjs', '../packages/core/hap.mjs'].map((rel) => resolve(__dirname, rel)); const undocumented = Object.fromEntries( - await Promise.all(paths.map(async (path) => [path.replace(resolve(__dirname, '..'), ''), await getUndocumented(path, docs)])), + await Promise.all( + paths.map(async (path) => [path.replace(resolve(__dirname, '..'), ''), await getUndocumented(path, docs)]), + ), ); console.log(JSON.stringify(undocumented, null, 2)); From 4fd3e6e99c45e8e4992a1ec9bfc78df42a8ea714 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 24 Nov 2023 09:37:11 +0100 Subject: [PATCH 15/17] fix: entry.name mutation bug --- packages/react/src/components/Autocomplete.jsx | 4 ++-- packages/react/src/components/Tooltip.jsx | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/react/src/components/Autocomplete.jsx b/packages/react/src/components/Autocomplete.jsx index 677baa6e..fe15ee9d 100644 --- a/packages/react/src/components/Autocomplete.jsx +++ b/packages/react/src/components/Autocomplete.jsx @@ -8,10 +8,10 @@ const getInnerText = (html) => { return div.textContent || div.innerText || ''; }; -export function Autocomplete({ doc }) { +export function Autocomplete({ doc, label }) { return (
    -

    {getDocLabel(doc)}

    +

    {label || getDocLabel(doc)}

      {doc.params?.map(({ name, type, description }, i) => ( diff --git a/packages/react/src/components/Tooltip.jsx b/packages/react/src/components/Tooltip.jsx index a508e761..43a53476 100644 --- a/packages/react/src/components/Tooltip.jsx +++ b/packages/react/src/components/Tooltip.jsx @@ -55,7 +55,6 @@ export const strudelTooltip = hoverTooltip( if (!entry) { return null; } - entry.name = word; } return { @@ -66,7 +65,7 @@ export const strudelTooltip = hoverTooltip( create(view) { let dom = document.createElement('div'); dom.className = 'strudel-tooltip'; - createRoot(dom).render(); + createRoot(dom).render(); return { dom }; }, }; From 458c97b92709254b6f05bfe55865a521c20c8143 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 24 Nov 2023 09:37:26 +0100 Subject: [PATCH 16/17] list synonyms in Autocomplete --- packages/react/src/components/Autocomplete.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react/src/components/Autocomplete.jsx b/packages/react/src/components/Autocomplete.jsx index fe15ee9d..b8abfc0a 100644 --- a/packages/react/src/components/Autocomplete.jsx +++ b/packages/react/src/components/Autocomplete.jsx @@ -11,7 +11,12 @@ const getInnerText = (html) => { export function Autocomplete({ doc, label }) { return (
      -

      {label || getDocLabel(doc)}

      +

      {label || getDocLabel(doc)}

      {' '} + {!!doc.synonyms_text && ( + + Synonyms: {doc.synonyms_text} + + )}
        {doc.params?.map(({ name, type, description }, i) => ( From 18e9ceb5013181ae7b19063c3f856bf52173c7a6 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 24 Nov 2023 09:52:39 +0100 Subject: [PATCH 17/17] populate autocomplete with all synonyms + properly display synonyms based on label --- .../react/src/components/Autocomplete.jsx | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/react/src/components/Autocomplete.jsx b/packages/react/src/components/Autocomplete.jsx index b8abfc0a..9a0b9de4 100644 --- a/packages/react/src/components/Autocomplete.jsx +++ b/packages/react/src/components/Autocomplete.jsx @@ -2,19 +2,21 @@ import { createRoot } from 'react-dom/client'; import jsdoc from '../../../../doc.json'; const getDocLabel = (doc) => doc.name || doc.longname; +const getDocSynonyms = (doc) => [getDocLabel(doc), ...(doc.synonyms || [])]; const getInnerText = (html) => { var div = document.createElement('div'); div.innerHTML = html; return div.textContent || div.innerText || ''; }; -export function Autocomplete({ doc, label }) { +export function Autocomplete({ doc, label = getDocLabel(doc) }) { + const synonyms = getDocSynonyms(doc).filter((a) => a !== label); return (
        -

        {label || getDocLabel(doc)}

        {' '} - {!!doc.synonyms_text && ( +

        {label}

        {' '} + {!!synonyms.length && ( - Synonyms: {doc.synonyms_text} + Synonyms: {synonyms.join(', ')} )}
        @@ -53,18 +55,24 @@ const jsdocCompletions = jsdoc.docs !['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)), ) // https://codemirror.net/docs/ref/#autocomplete.Completion - .map((doc) /*: Completion */ => ({ - label: getDocLabel(doc), - // detail: 'xxx', // An optional short piece of information to show (with a different style) after the label. - info: () => { - const node = document.createElement('div'); - // if Autocomplete is non-interactive, it could also be rendered at build time.. - // .. using renderToStaticMarkup - createRoot(node).render(); - return node; - }, - type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type - })); + .reduce( + (acc, doc) /*: Completion */ => + acc.concat( + [getDocLabel(doc), ...(doc.synonyms || [])].map((label) => ({ + label, + // detail: 'xxx', // An optional short piece of information to show (with a different style) after the label. + info: () => { + const node = document.createElement('div'); + // if Autocomplete is non-interactive, it could also be rendered at build time.. + // .. using renderToStaticMarkup + createRoot(node).render(); + return node; + }, + type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type + })), + ), + [], + ); export const strudelAutocomplete = (context /* : CompletionContext */) => { let word = context.matchBefore(/\w*/);