From 2e3356978610400136a983740d013cb7305809c4 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 30 Jun 2025 05:48:08 +0200 Subject: [PATCH 01/14] add setDefault + resetDefaults to superdough --- packages/superdough/superdough.mjs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 14f46711..0db5e2b9 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -150,6 +150,17 @@ const defaultDefaultValues = { fft: 8, }; +const defaultDefaultDefaultValues = Object.freeze({ ...defaultDefaultValues }); + +export function setDefault(control, value) { + const main = getControlName(control); + defaultDefaultValues[main] = value; +} + +export function resetDefaults() { + defaultDefaultValues = { ...defaultDefaultDefaultValues }; +} + let defaultControls = new Map(Object.entries(defaultDefaultValues)); export function setDefaultValue(key, value) { From c063fb6b1ca7f2cd32fe626b9545702e8b65ec24 Mon Sep 17 00:00:00 2001 From: tj-mueller Date: Mon, 30 Jun 2025 11:51:39 +0200 Subject: [PATCH 02/14] correct rd to cr --- website/src/pages/de/workshop/first-sounds.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index 3695843b..64a58db0 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -95,7 +95,7 @@ Diese Kombinationen von Buchstaben stehen für verschiedene Teile eines Schlagze - `mt` = **m**iddle tom - `ht` = **h**igh tom - `rd` = **r**i**d**e cymbal -- `rd` = **cr**ash cymbal +- `cr` = **cr**ash cymbal Probier verschiedene Sounds aus! From 504fe9ed4029438ba0214a5b730ab869a4eaaa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aurel=20B=C3=ADl=C3=BD?= Date: Mon, 30 Jun 2025 12:17:24 +0200 Subject: [PATCH 03/14] document setcps in cycles reference --- website/src/pages/understand/cycles.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/src/pages/understand/cycles.mdx b/website/src/pages/understand/cycles.mdx index 1c0a778a..bcf987c4 100644 --- a/website/src/pages/understand/cycles.mdx +++ b/website/src/pages/understand/cycles.mdx @@ -67,6 +67,8 @@ Or using 2 beats per cycle: s("bd sd, hh*4")`} /> +You can use the `setcps` method to set the global tempo in cycles per second. `setcpm(x)` is the same as `setcps(x / 60)`. + To set a specific bpm, use `setcpm(bpm/bpc)` From 168269a839f54ca95dab38097f9ecbb87b90259c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 4 Jul 2025 22:29:18 +0200 Subject: [PATCH 04/14] disable fm for supersaw --- packages/superdough/synth.mjs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 13cfa13a..88e14e5a 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -121,7 +121,10 @@ export function registerSynthSounds() { const gainAdjustment = 1 / Math.sqrt(voices); getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend); const vibratoOscillator = getVibratoOscillator(o.parameters.get('detune'), value, begin); - const fm = applyFM(o.parameters.get('frequency'), value, begin); + // const fm = applyFM(o.parameters.get('frequency'), value, begin); + // https://codeberg.org/uzu/strudel/issues/1428 + // if you think about re-enabling this, please test with fm > 1 first + // it's like 10x gain, so it's really dangerous let envGain = gainNode(1); envGain = o.connect(envGain); @@ -133,7 +136,7 @@ export function registerSynthSounds() { destroyAudioWorkletNode(o); envGain.disconnect(); onended(); - fm?.stop(); + // fm?.stop(); vibratoOscillator?.stop(); }, begin, From 05bcd5e32fd706969aa9c9c343ed7bf43cc528e3 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 5 Jul 2025 09:01:48 +0100 Subject: [PATCH 05/14] Fix randrun and deps including shuffle. Fixes #1441 --- packages/core/signal.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index c933e7fe..6bd6fde6 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -264,7 +264,7 @@ export const randrun = (n) => { const rands = timeToRands(t.floor().add(0.5), n); const nums = rands .map((n, i) => [n, i]) - .sort((a, b) => a[0] > b[0] - a[0] < b[0]) + .sort((a, b) => (a[0] > b[0]) - (a[0] < b[0])) .map((x) => x[1]); const i = t.cyclePos().mul(n).floor() % n; return nums[i]; From 82b14b529201f72b35e9603da43a62de22bb19ad Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 5 Jul 2025 11:13:40 +0200 Subject: [PATCH 06/14] fix: lint --- packages/superdough/superdough.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 0db5e2b9..8ff64ca8 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -126,7 +126,7 @@ export const getAudioDevices = async () => { return devicesMap; }; -const defaultDefaultValues = { +let defaultDefaultValues = { s: 'triangle', gain: 0.8, postgain: 1, @@ -153,8 +153,8 @@ const defaultDefaultValues = { const defaultDefaultDefaultValues = Object.freeze({ ...defaultDefaultValues }); export function setDefault(control, value) { - const main = getControlName(control); - defaultDefaultValues[main] = value; + // const main = getControlName(control); // we cant do this because superdough is independent of strudel/core + defaultDefaultValues[control] = value; } export function resetDefaults() { From a901e2e3875288626ab2136b85ab969ec60847e6 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 5 Jul 2025 10:28:20 +0100 Subject: [PATCH 07/14] snapshot --- test/__snapshots__/examples.test.mjs.snap | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index cc45848b..36c7ca58 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -8813,46 +8813,46 @@ exports[`runs examples > example "shrink" example index 3 1`] = ` exports[`runs examples > example "shuffle" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:c s:piano ]", + "[ 0/1 → 1/4 | note:e s:piano ]", "[ 1/4 → 1/2 | note:d s:piano ]", - "[ 1/2 → 3/4 | note:e s:piano ]", - "[ 3/4 → 1/1 | note:f s:piano ]", - "[ 1/1 → 5/4 | note:c s:piano ]", - "[ 5/4 → 3/2 | note:d s:piano ]", - "[ 3/2 → 7/4 | note:e s:piano ]", - "[ 7/4 → 2/1 | note:f s:piano ]", - "[ 2/1 → 9/4 | note:c s:piano ]", - "[ 9/4 → 5/2 | note:d s:piano ]", + "[ 1/2 → 3/4 | note:f s:piano ]", + "[ 3/4 → 1/1 | note:c s:piano ]", + "[ 1/1 → 5/4 | note:e s:piano ]", + "[ 5/4 → 3/2 | note:c s:piano ]", + "[ 3/2 → 7/4 | note:f s:piano ]", + "[ 7/4 → 2/1 | note:d s:piano ]", + "[ 2/1 → 9/4 | note:d s:piano ]", + "[ 9/4 → 5/2 | note:c s:piano ]", "[ 5/2 → 11/4 | note:e s:piano ]", "[ 11/4 → 3/1 | note:f s:piano ]", "[ 3/1 → 13/4 | note:c s:piano ]", - "[ 13/4 → 7/2 | note:d s:piano ]", - "[ 7/2 → 15/4 | note:e s:piano ]", - "[ 15/4 → 4/1 | note:f s:piano ]", + "[ 13/4 → 7/2 | note:e s:piano ]", + "[ 7/2 → 15/4 | note:f s:piano ]", + "[ 15/4 → 4/1 | note:d s:piano ]", ] `; exports[`runs examples > example "shuffle" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | note:c s:piano ]", + "[ 0/1 → 1/8 | note:e s:piano ]", "[ 1/8 → 1/4 | note:d s:piano ]", - "[ 1/4 → 3/8 | note:e s:piano ]", - "[ 3/8 → 1/2 | note:f s:piano ]", + "[ 1/4 → 3/8 | note:f s:piano ]", + "[ 3/8 → 1/2 | note:c s:piano ]", "[ 1/2 → 1/1 | note:g s:piano ]", - "[ 1/1 → 9/8 | note:c s:piano ]", - "[ 9/8 → 5/4 | note:d s:piano ]", - "[ 5/4 → 11/8 | note:e s:piano ]", - "[ 11/8 → 3/2 | note:f s:piano ]", + "[ 1/1 → 9/8 | note:e s:piano ]", + "[ 9/8 → 5/4 | note:c s:piano ]", + "[ 5/4 → 11/8 | note:f s:piano ]", + "[ 11/8 → 3/2 | note:d s:piano ]", "[ 3/2 → 2/1 | note:g s:piano ]", - "[ 2/1 → 17/8 | note:c s:piano ]", - "[ 17/8 → 9/4 | note:d s:piano ]", + "[ 2/1 → 17/8 | note:d s:piano ]", + "[ 17/8 → 9/4 | note:c s:piano ]", "[ 9/4 → 19/8 | note:e s:piano ]", "[ 19/8 → 5/2 | note:f s:piano ]", "[ 5/2 → 3/1 | note:g s:piano ]", "[ 3/1 → 25/8 | note:c s:piano ]", - "[ 25/8 → 13/4 | note:d s:piano ]", - "[ 13/4 → 27/8 | note:e s:piano ]", - "[ 27/8 → 7/2 | note:f s:piano ]", + "[ 25/8 → 13/4 | note:e s:piano ]", + "[ 13/4 → 27/8 | note:f s:piano ]", + "[ 27/8 → 7/2 | note:d s:piano ]", "[ 7/2 → 4/1 | note:g s:piano ]", ] `; From 664d76cf1b1756f1cd01155c3120642793297f62 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 5 Jul 2025 11:32:16 +0200 Subject: [PATCH 08/14] resetDefaults when editor is reset --- website/src/repl/useReplContext.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 12621c50..ac30fe34 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -13,6 +13,7 @@ import { resetGlobalEffects, resetLoadedSounds, initAudioOnFirstClick, + resetDefaults, } from '@strudel/webaudio'; import { setVersionDefaultsFrom } from './util.mjs'; import { StrudelMirror, defaultSettings } from '@strudel/codemirror'; @@ -181,6 +182,7 @@ export function useReplContext() { const resetEditor = async () => { (await getModule('@strudel/tonal'))?.resetVoicings(); + resetDefaults(); resetGlobalEffects(); clearCanvas(); clearHydra(); From a7a283a99e1505005e45ccf0e7df0f5be83391e2 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 6 Jul 2025 17:00:33 +0200 Subject: [PATCH 09/14] doc: add version tagging guide to contributing.md --- CONTRIBUTING.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f455741f..a7f65b5b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -150,6 +150,7 @@ Important: Always publish with `pnpm`, as `npm` does not support overriding main ## useful commands + ```sh #regenerate the test snapshots (ex: when updating or creating new pattern functions) pnpm snapshot @@ -160,6 +161,81 @@ pnpm run osc #build the standalone version pnpm tauri build ``` + +## version tag patching + +here's a little guide on how to patch patterns in the database to prevent breaking old patterns due to breaking changes in newer versions. + +the general tactic is to use `// @version x.y` to tag a pattern with a specific strudel version. when a pattern is evaluated, this metadata will de-activate any breaking changes that came after the specified version. +for example, in version 1.1, the default value for `fanchor` was changed from `0.5` to `0`. +if play a pattern that was made before that change, sounds that use filter evenlopes can sound very different, so by adding `// @version 1.0` will make it sound like it used to. +before releasing a new version with breaking changes, we can edit all patterns in the database, inserting the version tag they were created under: + +as an example, to release version 1.2, do the following: + +1. get date range + +```sh +# get date of last version: +git log -1 --format=%aI @strudel/core@1.1.0 +# 2024-05-31T23:07:26+02:00 + +# get date of current version: +git log -1 --format=%aI @strudel/core@1.2.0 +# 2025-05-01T12:39:24+02:00 +# might also use todays timestamp if version is not yet released +``` + +now we know, all patterns between these 2 dates have to receive a version tag (unless they already have one). + +2. get patterns in question + +```sql +SELECT * +FROM code_v1 +WHERE code NOT LIKE '%@version%' +AND created_at > '2024-05-31T23:07:26+02:00' +AND created_at < '2025-05-01T12:39:24+02:00' +ORDER BY created_at ASC; +``` + +this gives us all unversioned patterns that were saved between 1.1.0 and 1.2.0. in this case, it's 9373 patterns! + +3. insert version tags + +we are now ready to insert the version tag to these patterns. +before updating thousands of patterns, it's probably a good idea to test if a single one gets udpated: + +```sql +UPDATE code_v1 +SET code = code || E'\n// @version 1.1' +WHERE hash = 'Ns2sMB40yIw4'; +``` + +after [verifying](https://strudel.cc/?Ns2sMB40yIw4) that the version tag has been added, let's insert it everywhere: + +```sql +UPDATE code_v1 +SET code = code || E'\n// @version 1.1' +WHERE code NOT LIKE '%@version%' +AND created_at > '2024-05-31T23:07:26+02:00' +AND created_at < '2025-05-01T12:39:24+02:00' +``` + +4. verify + +we can verify that the edits worked by querying all patterns that contain the new version tag: + +```sql +SELECT * +FROM code_v1 +WHERE code LIKE '%@version 1.1%' +AND created_at > '2024-05-31T23:07:26+02:00' +AND created_at < '2025-05-01T12:39:24+02:00' +ORDER BY created_at ASC; +``` + + ## Have Fun Remember to have fun, and that this project is driven by the passion of volunteers! From 72b582c605bd68beae398877a9c8f41e8dffc716 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 7 Jul 2025 22:20:04 +0200 Subject: [PATCH 10/14] fix: remove github contributor avatars --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index d54302ac..854e2c31 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,6 @@ Licensing info for the default sound banks can be found over on the [dough-sampl There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md). - - - - -Made with [contrib.rocks](https://contrib.rocks). - ## Community There is a #strudel channel on the TidalCycles discord: From 81a9811803bfdbe89f721da1bbf5a327173d267a Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 7 Jul 2025 22:23:16 +0200 Subject: [PATCH 11/14] add logo --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 854e2c31..640fc24c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # strudel + + Live coding patterns on the web https://strudel.cc/ From 681eed3d0e544062099a78089912aaad82f8670e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 7 Jul 2025 22:23:40 +0200 Subject: [PATCH 12/14] revert add logo --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 640fc24c..854e2c31 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # strudel - - Live coding patterns on the web https://strudel.cc/ From a6ad58a3755cda9e049c1378002b735311c3be11 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 7 Jul 2025 23:12:15 +0200 Subject: [PATCH 13/14] fix: remove first gm_synth_bass_1, as it doesn't work in safari --- packages/soundfonts/gm.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/soundfonts/gm.mjs b/packages/soundfonts/gm.mjs index c0e57dcb..d8b7687d 100644 --- a/packages/soundfonts/gm.mjs +++ b/packages/soundfonts/gm.mjs @@ -537,7 +537,7 @@ export default { ], gm_synth_bass_1: [ // Synth Bass 1: Bass - '0380_Aspirin_sf2_file', + // '0380_Aspirin_sf2_file', // broken in safari https://codeberg.org/uzu/strudel/issues/1384 '0380_Chaos_sf2_file', '0380_FluidR3_GM_sf2_file', // 0380_GeneralUserGS_sf2_file // laut From 671a22fc221e920e9550f8c8ee13abda1b3d6f96 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 7 Jul 2025 23:28:41 +0200 Subject: [PATCH 14/14] chore: add link to contributors --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 854e2c31..4aa90fd3 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Licensing info for the default sound banks can be found over on the [dough-sampl ## Contributing -There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md). +There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md). You can find the full list of contributors [here](https://codeberg.org/uzu/strudel/activity/contributors). ## Community