From 058d950121d8ae89656cf21dfd9568a0275585f9 Mon Sep 17 00:00:00 2001 From: Aria Date: Fri, 15 Aug 2025 22:57:59 -0500 Subject: [PATCH 01/66] Working version of updated randomness --- packages/core/signal.mjs | 62 +++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 6bd6fde67..2d3385ef0 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -188,36 +188,46 @@ export const mouseX = signal(() => _mouseX); // random signals -const xorwise = (x) => { - const a = (x << 13) ^ x; - const b = (a >> 17) ^ a; - return (b << 5) ^ b; -}; +// Produce "Avalanche effect" where flipping a single bit of x +// results in all output bits flipping with probability 0.5 +// See e.g. https://github.com/aappleby/smhasher/blob/0ff96f7835817a27d0487325b6c16033e2992eb5/src/MurmurHash3.cpp#L68-L77 +function _murmurHashFinalizer(x) { + x |= 0; + x ^= x >>> 16; + x = Math.imul(x, 0x85ebca6b); + x ^= x >>> 13; + x = Math.imul(x, 0xc2b2ae35); + x ^= x >>> 16; + return x >>> 0; // unsigned +} -// stretch 300 cycles over the range of [0,2**29 == 536870912) then apply the xorshift algorithm -const _frac = (x) => x - Math.trunc(x); +// Used to decorrelate nearby t and i prior to hashing +function _decorrelate(t, i = 0) { + // const T = Math.floor(t * 4096); // set 2^12 resolution + const T = Math.floor(t * 536870912); // set 2^29 resolution + const lowBits = (T >>> 0) >>> 0; + const highBits = Math.floor(T / 4294967296) >>> 0; // 2^32 + let key = lowBits ^ Math.imul(highBits ^ 0x85ebca6b, 0xc2b2ae35); + key ^= Math.imul(i ^ 0x7f4a7c15, 0x9e3779b9); + return key >>> 0; + // return (T ^ Math.imul(i ^ 0x7f4a7c15, 0x9e3779b9)) >>> 0; +} -const timeToIntSeed = (x) => xorwise(Math.trunc(_frac(x / 300) * 536870912)); +function randAt(t, i = 0) { + return _murmurHashFinalizer(_decorrelate(t, i)) / 4294967296; // 2^32 +} -const intSeedToRand = (x) => (x % 536870912) / 536870912; +// N samples at time t +function timeToRands(t, n) { + const out = new Array(n); + for (let i = 0; i < n; i++) out[i] = randAt(t, i); + return out; +} -const timeToRand = (x) => Math.abs(intSeedToRand(timeToIntSeed(x))); - -const timeToRandsPrime = (seed, n) => { - const result = []; - // eslint-disable-next-line - for (let i = 0; i < n; ++i) { - result.push(intSeedToRand(seed)); - seed = xorwise(seed); - } - return result; -}; - -const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n); - -/** - * - */ +// Single sample at time t +function timeToRand(t) { + return randAt(t, 0); +} /** * A discrete pattern of numbers from 0 to n-1 From 03271ec5fb10e37e09c11751bfeafe3b28401f20 Mon Sep 17 00:00:00 2001 From: Aria Date: Tue, 19 Aug 2025 18:15:24 -0500 Subject: [PATCH 02/66] Remove stray comments --- packages/core/signal.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 2d3385ef0..1c3ae464b 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -203,14 +203,12 @@ function _murmurHashFinalizer(x) { // Used to decorrelate nearby t and i prior to hashing function _decorrelate(t, i = 0) { - // const T = Math.floor(t * 4096); // set 2^12 resolution const T = Math.floor(t * 536870912); // set 2^29 resolution const lowBits = (T >>> 0) >>> 0; const highBits = Math.floor(T / 4294967296) >>> 0; // 2^32 let key = lowBits ^ Math.imul(highBits ^ 0x85ebca6b, 0xc2b2ae35); key ^= Math.imul(i ^ 0x7f4a7c15, 0x9e3779b9); return key >>> 0; - // return (T ^ Math.imul(i ^ 0x7f4a7c15, 0x9e3779b9)) >>> 0; } function randAt(t, i = 0) { From 5d5159a08f62c171ab4477ff4aeca87caa5f6ba9 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 24 Aug 2025 11:56:11 -0500 Subject: [PATCH 03/66] Add option to use old random and a benchmark --- packages/core/bench/signal.bench.mjs | 46 ++++++++++++++++++++++++++++ packages/core/signal.mjs | 35 ++++++++++++++++++++- website/src/repl/tunes.mjs | 19 ++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 packages/core/bench/signal.bench.mjs diff --git a/packages/core/bench/signal.bench.mjs b/packages/core/bench/signal.bench.mjs new file mode 100644 index 000000000..c79cedc05 --- /dev/null +++ b/packages/core/bench/signal.bench.mjs @@ -0,0 +1,46 @@ +import { describe, bench } from 'vitest'; + +import { calculateSteps, rand, useOldRandom } from '../index.mjs'; + +const testingResolution = 1024; + +const _generateRandomPattern = () => rand.iter(testingResolution).fast(testingResolution).firstCycle(); + +describe('random', () => { + calculateSteps(true); + bench( + '+tactus', + _generateRandomPattern, + { time: 1000 }, + ); + + calculateSteps(false); + bench( + '-tactus', + _generateRandomPattern, + { time: 1000 }, + ); +}); + +describe('old random', () => { + calculateSteps(true); + bench( + '+tactus', + () => { + useOldRandom(); + _generateRandomPattern(); + }, + { time: 1000 }, + ); + + calculateSteps(false); + bench( + '-tactus', + () => { + useOldRandom(); + _generateRandomPattern(); + }, + { time: 1000 }, + ); +}); +calculateSteps(true); diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 1c3ae464b..91901f86c 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -186,7 +186,7 @@ export const mouseY = signal(() => _mouseY); export const mousex = signal(() => _mouseX); export const mouseX = signal(() => _mouseX); -// random signals +// Random number generators // Produce "Avalanche effect" where flipping a single bit of x // results in all output bits flipping with probability 0.5 @@ -215,8 +215,38 @@ function randAt(t, i = 0) { return _murmurHashFinalizer(_decorrelate(t, i)) / 4294967296; // 2^32 } +// Deprecated: Old random signals. Configuration `useOldRandom` may be used for legacy songs + +// stretch 300 cycles over the range of [0,2**29 == 536870912) then apply the xorshift algorithm +const __xorwise = (x) => { + const a = (x << 13) ^ x; + const b = (a >> 17) ^ a; + return (b << 5) ^ b; +}; +const __frac = (x) => x - Math.trunc(x); +const __timeToIntSeed = (x) => __xorwise(Math.trunc(__frac(x / 300) * 536870912)); +const __intSeedToRand = (x) => (x % 536870912) / 536870912; +const __timeToRand = (x) => Math.abs(__intSeedToRand(__timeToIntSeed(x))); +const __timeToRandsPrime = (seed, n) => { + const result = []; + for (let i = 0; i < n; i++) { + result.push(__intSeedToRand(seed)); + seed = __xorwise(seed); + } + return result; +}; +const __timeToRands = (t, n) => __timeToRandsPrime(__timeToIntSeed(t), n); + +// End old random + +let useOldRandomBool = false; +export const useOldRandom = (b = true) => useOldRandomBool = b; + // N samples at time t function timeToRands(t, n) { + if (useOldRandomBool) { + return __timeToRands(t, n); + } const out = new Array(n); for (let i = 0; i < n; i++) out[i] = randAt(t, i); return out; @@ -224,6 +254,9 @@ function timeToRands(t, n) { // Single sample at time t function timeToRand(t) { + if (useOldRandomBool) { + return __timeToRand(t); + } return randAt(t, 0); } diff --git a/website/src/repl/tunes.mjs b/website/src/repl/tunes.mjs index f1c72b12d..23efb6062 100644 --- a/website/src/repl/tunes.mjs +++ b/website/src/repl/tunes.mjs @@ -393,6 +393,8 @@ samples({ bass: { d2: 'https://cdn.freesound.org/previews/608/608286_13074022-lq.mp3' } }) +useOldRandom(true) + stack( // bells n("0").euclidLegato(3,8) @@ -430,6 +432,7 @@ export const festivalOfFingers3 = `// "Festival of fingers 3" // @by Felix Roos setcps(1) +useOldRandom(true) n("[-7*3],0,2,6,[8 7]") .echoWith( @@ -454,6 +457,8 @@ export const meltingsubmarine = `// "Melting submarine" // @by Felix Roos samples('github:tidalcycles/dirt-samples') +useOldRandom(true) + stack( s("bd:5,[~ ],hh27(3,4,1)") // drums .speed(perlin.range(.7,.9)) // random sample speed variation @@ -602,6 +607,9 @@ export const belldub = `// "Belldub" samples({ bell: {b4:'https://cdn.freesound.org/previews/339/339809_5121236-lq.mp3'}}) // "Hand Bells, B, Single.wav" by InspectorJ (www.jshaw.co.uk) of Freesound.org + +useOldRandom(true) + stack( // bass note("[0 ~] [2 [0 2]] [4 4*2] [[4 ~] [2 ~] 0@2]".scale('g1 dorian').superimpose(x=>x.add(.02))) @@ -638,6 +646,7 @@ export const dinofunk = `// "Dinofunk" // @by Felix Roos setcps(1) +useOldRandom(true) samples({bass:'https://cdn.freesound.org/previews/614/614637_2434927-hq.mp3', dino:{b4:'https://cdn.freesound.org/previews/316/316403_5123851-hq.mp3'}}) @@ -666,6 +675,8 @@ export const sampleDemo = `// "Sample demo" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos +useOldRandom(true) + stack( // percussion s("[woodblock:1 woodblock:2*2] snare_rim:0,gong/8,brakedrum:1(3,8),~@3 cowbell:3") @@ -684,6 +695,8 @@ export const holyflute = `// "Holy flute" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos +useOldRandom(true) + "c3 eb3(3,8) c4/2 g3*2" .superimpose( x=>x.slow(2).add(12), @@ -699,6 +712,8 @@ export const flatrave = `// "Flatrave" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos +useOldRandom(true) + stack( s("bd*2,~ [cp,sd]").bank('RolandTR909'), @@ -727,6 +742,8 @@ export const amensister = `// "Amensister" samples('github:tidalcycles/dirt-samples') +useOldRandom(true) + stack( // amen n("0 1 2 3 4 5 6 7") @@ -834,6 +851,8 @@ export const arpoon = `// "Arpoon" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos +useOldRandom(true) + samples('github:tidalcycles/dirt-samples') n("[0,3] 2 [1,3] 2".fast(3).lastOf(4, fast(2))).clip(2) From b8423f0ed1a96891a2380d2436f6d929ea37c504 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 24 Aug 2025 12:01:12 -0500 Subject: [PATCH 04/66] Add docstring --- packages/core/signal.mjs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 91901f86c..78755bd98 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -240,6 +240,17 @@ const __timeToRands = (t, n) => __timeToRandsPrime(__timeToIntSeed(t), n); // End old random let useOldRandomBool = false; +/** + * Whether to use the old random number generator or not. Can be used to support legacy projects + * + * @name useOldRandom + * @param {boolean} b - Whether to use old RNG + * @example + * useOldRandom(true) + * // Repeats every 300 cycles + * $: n(irand(50)).seg(16).scale("C:minor").ribbon(88, 32)._punchcard() + * $: n(irand(50)).seg(16).scale("C:minor").ribbon(388, 32)._punchcard() + */ export const useOldRandom = (b = true) => useOldRandomBool = b; // N samples at time t From 5e4e678800315da210d75645a8e37c3d62b43d3e Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 24 Aug 2025 21:14:57 -0500 Subject: [PATCH 05/66] Test bleed, some docstrings --- packages/core/bench/signal.bench.mjs | 49 ++++++++++---------- packages/core/signal.mjs | 67 +++++++++++++++------------- packages/superdough/superdough.mjs | 22 +++++++++ vitest.config.mjs | 3 +- vitest.setup.mjs | 7 +++ 5 files changed, 92 insertions(+), 56 deletions(-) create mode 100644 vitest.setup.mjs diff --git a/packages/core/bench/signal.bench.mjs b/packages/core/bench/signal.bench.mjs index c79cedc05..d92840ef6 100644 --- a/packages/core/bench/signal.bench.mjs +++ b/packages/core/bench/signal.bench.mjs @@ -2,45 +2,48 @@ import { describe, bench } from 'vitest'; import { calculateSteps, rand, useOldRandom } from '../index.mjs'; -const testingResolution = 1024; +const testingResolution = 128; const _generateRandomPattern = () => rand.iter(testingResolution).fast(testingResolution).firstCycle(); -describe('random', () => { - calculateSteps(true); - bench( - '+tactus', - _generateRandomPattern, - { time: 1000 }, - ); - - calculateSteps(false); - bench( - '-tactus', - _generateRandomPattern, - { time: 1000 }, - ); -}); - describe('old random', () => { calculateSteps(true); bench( '+tactus', () => { - useOldRandom(); - _generateRandomPattern(); + useOldRandom(); + _generateRandomPattern(); + }, + { + time: 1000, + teardown() { + useOldRandom(false); + }, }, - { time: 1000 }, ); calculateSteps(false); bench( '-tactus', () => { - useOldRandom(); - _generateRandomPattern(); + useOldRandom(); + _generateRandomPattern(); + }, + { + time: 1000, + teardown() { + useOldRandom(false); + }, }, - { time: 1000 }, ); }); + +describe('random', () => { + calculateSteps(true); + bench('+tactus', _generateRandomPattern, { time: 1000 }); + + calculateSteps(false); + bench('-tactus', _generateRandomPattern, { time: 1000 }); +}); + calculateSteps(true); diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 78755bd98..492f6a7f0 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -201,9 +201,13 @@ function _murmurHashFinalizer(x) { return x >>> 0; // unsigned } -// Used to decorrelate nearby t and i prior to hashing -function _decorrelate(t, i = 0) { - const T = Math.floor(t * 536870912); // set 2^29 resolution +// Convert t to a 32 bit integer, preserving temporal resolution down to 1/2^29 +function _tToT(t) { + return Math.floor(t * 536870912); +} + +// Used to decorrelate nearby T and i prior to hashing +function _decorrelate(T, i = 0) { const lowBits = (T >>> 0) >>> 0; const highBits = Math.floor(T / 4294967296) >>> 0; // 2^32 let key = lowBits ^ Math.imul(highBits ^ 0x85ebca6b, 0xc2b2ae35); @@ -211,8 +215,19 @@ function _decorrelate(t, i = 0) { return key >>> 0; } -function randAt(t, i = 0) { - return _murmurHashFinalizer(_decorrelate(t, i)) / 4294967296; // 2^32 +function randAt(T, i = 0) { + return _murmurHashFinalizer(_decorrelate(T, i)) / 4294967296; // 2^32 +} + +// n samples at time t +function timeToRands(t, n) { + const T = _tToT(t); + if (n === 1) { + return randAt(T, 0); + } + const out = new Array(n); + for (let i = 0; i < n; i++) out[i] = randAt(T, i); + return out; } // Deprecated: Old random signals. Configuration `useOldRandom` may be used for legacy songs @@ -226,8 +241,10 @@ const __xorwise = (x) => { const __frac = (x) => x - Math.trunc(x); const __timeToIntSeed = (x) => __xorwise(Math.trunc(__frac(x / 300) * 536870912)); const __intSeedToRand = (x) => (x % 536870912) / 536870912; -const __timeToRand = (x) => Math.abs(__intSeedToRand(__timeToIntSeed(x))); const __timeToRandsPrime = (seed, n) => { + if (n === 1) { + return Math.abs(__intSeedToRand(seed)); + } const result = []; for (let i = 0; i < n; i++) { result.push(__intSeedToRand(seed)); @@ -240,6 +257,10 @@ const __timeToRands = (t, n) => __timeToRandsPrime(__timeToIntSeed(t), n); // End old random let useOldRandomBool = false; +const getRandsAtTime = (t, n = 1) => { + return useOldRandomBool ? __timeToRands(t, n) : timeToRands(t, n); +}; + /** * Whether to use the old random number generator or not. Can be used to support legacy projects * @@ -248,28 +269,10 @@ let useOldRandomBool = false; * @example * useOldRandom(true) * // Repeats every 300 cycles - * $: n(irand(50)).seg(16).scale("C:minor").ribbon(88, 32)._punchcard() - * $: n(irand(50)).seg(16).scale("C:minor").ribbon(388, 32)._punchcard() + * $: n(irand(50)).seg(16).scale("C:minor").ribbon(88, 32) + * $: n(irand(50)).seg(16).scale("C:minor").ribbon(388, 32) */ -export const useOldRandom = (b = true) => useOldRandomBool = b; - -// N samples at time t -function timeToRands(t, n) { - if (useOldRandomBool) { - return __timeToRands(t, n); - } - const out = new Array(n); - for (let i = 0; i < n; i++) out[i] = randAt(t, i); - return out; -} - -// Single sample at time t -function timeToRand(t) { - if (useOldRandomBool) { - return __timeToRand(t); - } - return randAt(t, 0); -} +export const useOldRandom = (b = true) => (useOldRandomBool = b); /** * A discrete pattern of numbers from 0 to n-1 @@ -313,7 +316,7 @@ export const binaryN = (n, nBits = 16) => { export const randrun = (n) => { return signal((t) => { // Without adding 0.5, the first cycle is always 0,1,2,3,... - const rands = timeToRands(t.floor().add(0.5), n); + const rands = getRandsAtTime(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])) @@ -363,7 +366,7 @@ export const scramble = register('scramble', (n, pat) => { * s("bd*4,hh*8").cutoff(rand.range(500,8000)) * */ -export const rand = signal(timeToRand); +export const rand = signal(getRandsAtTime); /** * A continuous pattern of random numbers, between -1 and 1 */ @@ -545,7 +548,7 @@ function _perlin(t) { let tb = ta + 1; const smootherStep = (x) => 6.0 * x ** 5 - 15.0 * x ** 4 + 10.0 * x ** 3; const interp = (x) => (a) => (b) => a + smootherStep(x) * (b - a); - const v = interp(t - ta)(timeToRand(ta))(timeToRand(tb)); + const v = interp(t - ta)(getRandsAtTime(ta))(getRandsAtTime(tb)); return v; } export const perlinWith = (tpat) => { @@ -556,8 +559,8 @@ function _berlin(t) { const prevRidgeStartIndex = Math.floor(t); const nextRidgeStartIndex = prevRidgeStartIndex + 1; - const prevRidgeBottomPoint = timeToRand(prevRidgeStartIndex); - const nextRidgeTopPoint = timeToRand(nextRidgeStartIndex) + prevRidgeBottomPoint; + const prevRidgeBottomPoint = getRandsAtTime(prevRidgeStartIndex); + const nextRidgeTopPoint = getRandsAtTime(nextRidgeStartIndex) + prevRidgeBottomPoint; const currentPercent = (t - prevRidgeStartIndex) / (nextRidgeStartIndex - prevRidgeStartIndex); const interp = (a, b, t) => { diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index eb1466d91..9b6b20746 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -19,6 +19,17 @@ const DEFAULT_AUDIO_DEVICE_NAME = 'System Standard'; let maxPolyphony = DEFAULT_MAX_POLYPHONY; +/** + * Set the max polyphony. If notes are ringing out via `release` then they will + * start to die out in first-in-first-out order once the max polyphony has been hit + * + * @name setMaxPolyphony + * @param {number} Max polyphony. Defaults to 128 + * @example + * setMaxPolyphony(4) + * n(irand(24).seg(8)).scale("C#3:minor").room(1).release(4).gain(0.5) + * + */ export function setMaxPolyphony(polyphony) { maxPolyphony = parseInt(polyphony) ?? DEFAULT_MAX_POLYPHONY; } @@ -48,6 +59,17 @@ export function applyGainCurve(val) { return gainCurveFunc(val); } +/** + * Apply a function to all gains provided in patterns. Can be used to rescale gain to be + * quadratic, exponential, etc. rather than linear + * + * @name setGainCurve + * @param {Function} function to apply to all gain values + * @example + * setGainCurve((x) => x * x) // quadratic gain + * s("bd*4").gain(0.5) // equivalent to 0.25 gain normally + * + */ export function setGainCurve(newGainCurveFunc) { gainCurveFunc = newGainCurveFunc; } diff --git a/vitest.config.mjs b/vitest.config.mjs index dcdde1133..392b17310 100644 --- a/vitest.config.mjs +++ b/vitest.config.mjs @@ -7,7 +7,7 @@ export default defineConfig({ test: { reporters: 'verbose', isolate: false, - silent: true, + silent: false, exclude: [ '**/node_modules/**', '**/dist/**', @@ -16,5 +16,6 @@ export default defineConfig({ '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress}.config.*', '**/shared.test.mjs', ], + setupFiles: './vitest.setup.mjs', }, }); diff --git a/vitest.setup.mjs b/vitest.setup.mjs new file mode 100644 index 000000000..bb9d24b07 --- /dev/null +++ b/vitest.setup.mjs @@ -0,0 +1,7 @@ +import { afterEach } from 'vitest'; +import { useOldRandom } from './packages/core/signal.mjs'; + +afterEach(() => { + // Avoid bleed between tests + useOldRandom(false); +}); From 969c9663ef4f3e661c1df8a01541c4ad258e4756 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 24 Aug 2025 21:15:11 -0500 Subject: [PATCH 06/66] Update tests for new randomness --- test/__snapshots__/examples.test.mjs.snap | 1421 +++++++++++---------- 1 file changed, 771 insertions(+), 650 deletions(-) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 398749359..77154de90 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -686,20 +686,20 @@ exports[`runs examples > example "almostAlways" example index 0 1`] = ` "[ 13/8 → 7/4 | s:hh speed:0.5 ]", "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh speed:0.5 ]", - "[ 2/1 → 17/8 | s:hh ]", - "[ 17/8 → 9/4 | s:hh ]", + "[ 2/1 → 17/8 | s:hh speed:0.5 ]", + "[ 17/8 → 9/4 | s:hh speed:0.5 ]", "[ 9/4 → 19/8 | s:hh speed:0.5 ]", "[ 19/8 → 5/2 | s:hh speed:0.5 ]", "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh speed:0.5 ]", - "[ 23/8 → 3/1 | s:hh speed:0.5 ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh speed:0.5 ]", "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 13/4 → 27/8 | s:hh speed:0.5 ]", "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", - "[ 29/8 → 15/4 | s:hh ]", + "[ 29/8 → 15/4 | s:hh speed:0.5 ]", "[ 15/4 → 31/8 | s:hh speed:0.5 ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] @@ -707,7 +707,7 @@ exports[`runs examples > example "almostAlways" example index 0 1`] = ` exports[`runs examples > example "almostNever" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh speed:0.5 ]", + "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", @@ -715,7 +715,7 @@ exports[`runs examples > example "almostNever" example index 0 1`] = ` "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh ]", + "[ 1/1 → 9/8 | s:hh speed:0.5 ]", "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh ]", @@ -728,17 +728,17 @@ exports[`runs examples > example "almostNever" example index 0 1`] = ` "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", - "[ 21/8 → 11/4 | s:hh ]", + "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh speed:0.5 ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", + "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -1053,70 +1053,70 @@ exports[`runs examples > example "begin" example index 0 1`] = ` exports[`runs examples > example "berlin" example index 0 1`] = ` [ - "[ 0/1 → 1/16 | note:D3 ]", - "[ 1/16 → 1/8 | note:E3 ]", - "[ 1/8 → 3/16 | note:F3 ]", - "[ 3/16 → 1/4 | note:G3 ]", - "[ 1/4 → 5/16 | note:A3 ]", - "[ 5/16 → 3/8 | note:C4 ]", - "[ 3/8 → 7/16 | note:D4 ]", - "[ 7/16 → 1/2 | note:F4 ]", - "[ 1/2 → 9/16 | note:D4 ]", - "[ 9/16 → 5/8 | note:E4 ]", - "[ 5/8 → 11/16 | note:E4 ]", - "[ 11/16 → 3/4 | note:E4 ]", - "[ 3/4 → 13/16 | note:F3 ]", - "[ 13/16 → 7/8 | note:F3 ]", - "[ 7/8 → 15/16 | note:F3 ]", - "[ 15/16 → 1/1 | note:F3 ]", - "[ 1/1 → 17/16 | note:E3 ]", - "[ 17/16 → 9/8 | note:E3 ]", - "[ 9/8 → 19/16 | note:E3 ]", - "[ 19/16 → 5/4 | note:F3 ]", - "[ 5/4 → 21/16 | note:E3 ]", - "[ 21/16 → 11/8 | note:F3 ]", - "[ 11/8 → 23/16 | note:G3 ]", - "[ 23/16 → 3/2 | note:A3 ]", - "[ 3/2 → 25/16 | note:A3 ]", - "[ 25/16 → 13/8 | note:Bb3 ]", - "[ 13/8 → 27/16 | note:Bb3 ]", - "[ 27/16 → 7/4 | note:Bb3 ]", + "[ 0/1 → 1/16 | note:A3 ]", + "[ 1/16 → 1/8 | note:A3 ]", + "[ 1/8 → 3/16 | note:A3 ]", + "[ 3/16 → 1/4 | note:A3 ]", + "[ 1/4 → 5/16 | note:E3 ]", + "[ 5/16 → 3/8 | note:F3 ]", + "[ 3/8 → 7/16 | note:F3 ]", + "[ 7/16 → 1/2 | note:G3 ]", + "[ 1/2 → 9/16 | note:A3 ]", + "[ 9/16 → 5/8 | note:Bb3 ]", + "[ 5/8 → 11/16 | note:Bb3 ]", + "[ 11/16 → 3/4 | note:C4 ]", + "[ 3/4 → 13/16 | note:G3 ]", + "[ 13/16 → 7/8 | note:A3 ]", + "[ 7/8 → 15/16 | note:A3 ]", + "[ 15/16 → 1/1 | note:Bb3 ]", + "[ 1/1 → 17/16 | note:F3 ]", + "[ 17/16 → 9/8 | note:G3 ]", + "[ 9/8 → 19/16 | note:G3 ]", + "[ 19/16 → 5/4 | note:A3 ]", + "[ 5/4 → 21/16 | note:G3 ]", + "[ 21/16 → 11/8 | note:Bb3 ]", + "[ 11/8 → 23/16 | note:D4 ]", + "[ 23/16 → 3/2 | note:E4 ]", + "[ 3/2 → 25/16 | note:D4 ]", + "[ 25/16 → 13/8 | note:E4 ]", + "[ 13/8 → 27/16 | note:E4 ]", + "[ 27/16 → 7/4 | note:E4 ]", "[ 7/4 → 29/16 | note:F3 ]", - "[ 29/16 → 15/8 | note:G3 ]", + "[ 29/16 → 15/8 | note:A3 ]", "[ 15/8 → 31/16 | note:Bb3 ]", "[ 31/16 → 2/1 | note:C4 ]", "[ 2/1 → 33/16 | note:C4 ]", - "[ 33/16 → 17/8 | note:D4 ]", - "[ 17/8 → 35/16 | note:F4 ]", - "[ 35/16 → 9/4 | note:G4 ]", - "[ 9/4 → 37/16 | note:Bb3 ]", - "[ 37/16 → 19/8 | note:Bb3 ]", - "[ 19/8 → 39/16 | note:Bb3 ]", - "[ 39/16 → 5/2 | note:C4 ]", - "[ 5/2 → 41/16 | note:F3 ]", - "[ 41/16 → 21/8 | note:F3 ]", - "[ 21/8 → 43/16 | note:G3 ]", - "[ 43/16 → 11/4 | note:A3 ]", - "[ 11/4 → 45/16 | note:A3 ]", - "[ 45/16 → 23/8 | note:A3 ]", - "[ 23/8 → 47/16 | note:A3 ]", + "[ 33/16 → 17/8 | note:E4 ]", + "[ 17/8 → 35/16 | note:G4 ]", + "[ 35/16 → 9/4 | note:A4 ]", + "[ 9/4 → 37/16 | note:D4 ]", + "[ 37/16 → 19/8 | note:F4 ]", + "[ 19/8 → 39/16 | note:G4 ]", + "[ 39/16 → 5/2 | note:A4 ]", + "[ 5/2 → 41/16 | note:Bb3 ]", + "[ 41/16 → 21/8 | note:C4 ]", + "[ 21/8 → 43/16 | note:C4 ]", + "[ 43/16 → 11/4 | note:C4 ]", + "[ 11/4 → 45/16 | note:F3 ]", + "[ 45/16 → 23/8 | note:G3 ]", + "[ 23/8 → 47/16 | note:G3 ]", "[ 47/16 → 3/1 | note:A3 ]", - "[ 3/1 → 49/16 | note:E3 ]", + "[ 3/1 → 49/16 | note:F3 ]", "[ 49/16 → 25/8 | note:G3 ]", - "[ 25/8 → 51/16 | note:Bb3 ]", - "[ 51/16 → 13/4 | note:C4 ]", - "[ 13/4 → 53/16 | note:D4 ]", - "[ 53/16 → 27/8 | note:E4 ]", - "[ 27/8 → 55/16 | note:G4 ]", - "[ 55/16 → 7/2 | note:A4 ]", - "[ 7/2 → 57/16 | note:Bb3 ]", - "[ 57/16 → 29/8 | note:Bb3 ]", - "[ 29/8 → 59/16 | note:C4 ]", - "[ 59/16 → 15/4 | note:C4 ]", - "[ 15/4 → 61/16 | note:F3 ]", - "[ 61/16 → 31/8 | note:G3 ]", - "[ 31/8 → 63/16 | note:G3 ]", - "[ 63/16 → 4/1 | note:A3 ]", + "[ 25/8 → 51/16 | note:G3 ]", + "[ 51/16 → 13/4 | note:A3 ]", + "[ 13/4 → 53/16 | note:G3 ]", + "[ 53/16 → 27/8 | note:A3 ]", + "[ 27/8 → 55/16 | note:C4 ]", + "[ 55/16 → 7/2 | note:E4 ]", + "[ 7/2 → 57/16 | note:D4 ]", + "[ 57/16 → 29/8 | note:E4 ]", + "[ 29/8 → 59/16 | note:F4 ]", + "[ 59/16 → 15/4 | note:G4 ]", + "[ 15/4 → 61/16 | note:Bb3 ]", + "[ 61/16 → 31/8 | note:C4 ]", + "[ 31/8 → 63/16 | note:D4 ]", + "[ 63/16 → 4/1 | note:E4 ]", ] `; @@ -1499,51 +1499,51 @@ exports[`runs examples > example "brand" example index 0 1`] = ` [ "[ 0/1 → 1/10 | s:hh pan:true ]", "[ 1/10 → 1/5 | s:hh pan:true ]", - "[ 1/5 → 3/10 | s:hh pan:false ]", + "[ 1/5 → 3/10 | s:hh pan:true ]", "[ 3/10 → 2/5 | s:hh pan:false ]", - "[ 2/5 → 1/2 | s:hh pan:false ]", + "[ 2/5 → 1/2 | s:hh pan:true ]", "[ 1/2 → 3/5 | s:hh pan:true ]", "[ 3/5 → 7/10 | s:hh pan:false ]", "[ 7/10 → 4/5 | s:hh pan:false ]", - "[ 4/5 → 9/10 | s:hh pan:true ]", - "[ 9/10 → 1/1 | s:hh pan:false ]", - "[ 1/1 → 11/10 | s:hh pan:false ]", + "[ 4/5 → 9/10 | s:hh pan:false ]", + "[ 9/10 → 1/1 | s:hh pan:true ]", + "[ 1/1 → 11/10 | s:hh pan:true ]", "[ 11/10 → 6/5 | s:hh pan:false ]", - "[ 6/5 → 13/10 | s:hh pan:true ]", + "[ 6/5 → 13/10 | s:hh pan:false ]", "[ 13/10 → 7/5 | s:hh pan:true ]", "[ 7/5 → 3/2 | s:hh pan:true ]", - "[ 3/2 → 8/5 | s:hh pan:false ]", - "[ 8/5 → 17/10 | s:hh pan:true ]", - "[ 17/10 → 9/5 | s:hh pan:true ]", + "[ 3/2 → 8/5 | s:hh pan:true ]", + "[ 8/5 → 17/10 | s:hh pan:false ]", + "[ 17/10 → 9/5 | s:hh pan:false ]", "[ 9/5 → 19/10 | s:hh pan:true ]", "[ 19/10 → 2/1 | s:hh pan:true ]", "[ 2/1 → 21/10 | s:hh pan:false ]", "[ 21/10 → 11/5 | s:hh pan:true ]", "[ 11/5 → 23/10 | s:hh pan:false ]", - "[ 23/10 → 12/5 | s:hh pan:false ]", - "[ 12/5 → 5/2 | s:hh pan:false ]", + "[ 23/10 → 12/5 | s:hh pan:true ]", + "[ 12/5 → 5/2 | s:hh pan:true ]", "[ 5/2 → 13/5 | s:hh pan:true ]", - "[ 13/5 → 27/10 | s:hh pan:true ]", + "[ 13/5 → 27/10 | s:hh pan:false ]", "[ 27/10 → 14/5 | s:hh pan:true ]", - "[ 14/5 → 29/10 | s:hh pan:false ]", + "[ 14/5 → 29/10 | s:hh pan:true ]", "[ 29/10 → 3/1 | s:hh pan:true ]", "[ 3/1 → 31/10 | s:hh pan:true ]", - "[ 31/10 → 16/5 | s:hh pan:true ]", + "[ 31/10 → 16/5 | s:hh pan:false ]", "[ 16/5 → 33/10 | s:hh pan:true ]", "[ 33/10 → 17/5 | s:hh pan:false ]", "[ 17/5 → 7/2 | s:hh pan:false ]", "[ 7/2 → 18/5 | s:hh pan:true ]", "[ 18/5 → 37/10 | s:hh pan:false ]", - "[ 37/10 → 19/5 | s:hh pan:false ]", - "[ 19/5 → 39/10 | s:hh pan:true ]", - "[ 39/10 → 4/1 | s:hh pan:true ]", + "[ 37/10 → 19/5 | s:hh pan:true ]", + "[ 19/5 → 39/10 | s:hh pan:false ]", + "[ 39/10 → 4/1 | s:hh pan:false ]", ] `; exports[`runs examples > example "brandBy" example index 0 1`] = ` [ - "[ 0/1 → 1/10 | s:hh pan:true ]", - "[ 1/10 → 1/5 | s:hh pan:true ]", + "[ 0/1 → 1/10 | s:hh pan:false ]", + "[ 1/10 → 1/5 | s:hh pan:false ]", "[ 1/5 → 3/10 | s:hh pan:false ]", "[ 3/10 → 2/5 | s:hh pan:false ]", "[ 2/5 → 1/2 | s:hh pan:false ]", @@ -1552,35 +1552,35 @@ exports[`runs examples > example "brandBy" example index 0 1`] = ` "[ 7/10 → 4/5 | s:hh pan:false ]", "[ 4/5 → 9/10 | s:hh pan:false ]", "[ 9/10 → 1/1 | s:hh pan:false ]", - "[ 1/1 → 11/10 | s:hh pan:false ]", + "[ 1/1 → 11/10 | s:hh pan:true ]", "[ 11/10 → 6/5 | s:hh pan:false ]", "[ 6/5 → 13/10 | s:hh pan:false ]", - "[ 13/10 → 7/5 | s:hh pan:false ]", - "[ 7/5 → 3/2 | s:hh pan:false ]", + "[ 13/10 → 7/5 | s:hh pan:true ]", + "[ 7/5 → 3/2 | s:hh pan:true ]", "[ 3/2 → 8/5 | s:hh pan:false ]", "[ 8/5 → 17/10 | s:hh pan:false ]", "[ 17/10 → 9/5 | s:hh pan:false ]", "[ 9/5 → 19/10 | s:hh pan:false ]", "[ 19/10 → 2/1 | s:hh pan:true ]", "[ 2/1 → 21/10 | s:hh pan:false ]", - "[ 21/10 → 11/5 | s:hh pan:false ]", + "[ 21/10 → 11/5 | s:hh pan:true ]", "[ 11/5 → 23/10 | s:hh pan:false ]", - "[ 23/10 → 12/5 | s:hh pan:false ]", + "[ 23/10 → 12/5 | s:hh pan:true ]", "[ 12/5 → 5/2 | s:hh pan:false ]", "[ 5/2 → 13/5 | s:hh pan:false ]", "[ 13/5 → 27/10 | s:hh pan:false ]", - "[ 27/10 → 14/5 | s:hh pan:false ]", - "[ 14/5 → 29/10 | s:hh pan:false ]", + "[ 27/10 → 14/5 | s:hh pan:true ]", + "[ 14/5 → 29/10 | s:hh pan:true ]", "[ 29/10 → 3/1 | s:hh pan:false ]", "[ 3/1 → 31/10 | s:hh pan:false ]", - "[ 31/10 → 16/5 | s:hh pan:true ]", + "[ 31/10 → 16/5 | s:hh pan:false ]", "[ 16/5 → 33/10 | s:hh pan:true ]", "[ 33/10 → 17/5 | s:hh pan:false ]", "[ 17/5 → 7/2 | s:hh pan:false ]", "[ 7/2 → 18/5 | s:hh pan:false ]", "[ 18/5 → 37/10 | s:hh pan:false ]", - "[ 37/10 → 19/5 | s:hh pan:false ]", - "[ 19/5 → 39/10 | s:hh pan:true ]", + "[ 37/10 → 19/5 | s:hh pan:true ]", + "[ 19/5 → 39/10 | s:hh pan:false ]", "[ 39/10 → 4/1 | s:hh pan:false ]", ] `; @@ -1712,99 +1712,99 @@ exports[`runs examples > example "channels" example index 0 1`] = ` exports[`runs examples > example "choose" example index 0 1`] = ` [ - "[ 0/1 → 1/5 | note:c2 s:sine ]", - "[ 1/5 → 2/5 | note:g2 s:bd n:6 ]", + "[ 0/1 → 1/5 | note:c2 s:triangle ]", + "[ 1/5 → 2/5 | note:g2 s:sine ]", "[ 2/5 → 3/5 | note:g2 s:triangle ]", "[ 3/5 → 4/5 | note:d2 s:bd n:6 ]", - "[ 4/5 → 1/1 | note:f1 s:sine ]", - "[ 1/1 → 6/5 | note:c2 s:triangle ]", - "[ 6/5 → 7/5 | note:g2 s:triangle ]", + "[ 4/5 → 1/1 | note:f1 s:bd n:6 ]", + "[ 1/1 → 6/5 | note:c2 s:sine ]", + "[ 6/5 → 7/5 | note:g2 s:bd n:6 ]", "[ 7/5 → 8/5 | note:g2 s:sine ]", - "[ 8/5 → 9/5 | note:d2 s:triangle ]", + "[ 8/5 → 9/5 | note:d2 s:bd n:6 ]", "[ 9/5 → 2/1 | note:f1 s:sine ]", - "[ 2/1 → 11/5 | note:c2 s:bd n:6 ]", + "[ 2/1 → 11/5 | note:c2 s:triangle ]", "[ 11/5 → 12/5 | note:g2 s:bd n:6 ]", - "[ 12/5 → 13/5 | note:g2 s:bd n:6 ]", - "[ 13/5 → 14/5 | note:d2 s:sine ]", - "[ 14/5 → 3/1 | note:f1 s:triangle ]", - "[ 3/1 → 16/5 | note:c2 s:sine ]", + "[ 12/5 → 13/5 | note:g2 s:sine ]", + "[ 13/5 → 14/5 | note:d2 s:bd n:6 ]", + "[ 14/5 → 3/1 | note:f1 s:sine ]", + "[ 3/1 → 16/5 | note:c2 s:triangle ]", "[ 16/5 → 17/5 | note:g2 s:sine ]", - "[ 17/5 → 18/5 | note:g2 s:triangle ]", + "[ 17/5 → 18/5 | note:g2 s:bd n:6 ]", "[ 18/5 → 19/5 | note:d2 s:triangle ]", - "[ 19/5 → 4/1 | note:f1 s:sine ]", + "[ 19/5 → 4/1 | note:f1 s:bd n:6 ]", ] `; exports[`runs examples > example "chooseCycles" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:bd ]", - "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:sd ]", - "[ 3/8 → 1/2 | s:bd ]", + "[ 0/1 → 1/8 | s:hh ]", + "[ 1/8 → 1/4 | s:bd ]", + "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:bd ]", - "[ 3/4 → 7/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:sd ]", "[ 7/8 → 1/1 | s:bd ]", "[ 1/1 → 9/8 | s:sd ]", - "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:bd ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 9/8 → 5/4 | s:sd ]", + "[ 5/4 → 11/8 | s:hh ]", + "[ 11/8 → 3/2 | s:bd ]", "[ 3/2 → 13/8 | s:bd ]", - "[ 13/8 → 7/4 | s:sd ]", - "[ 7/4 → 15/8 | s:hh ]", - "[ 15/8 → 2/1 | s:bd ]", - "[ 2/1 → 17/8 | s:bd ]", + "[ 13/8 → 7/4 | s:bd ]", + "[ 7/4 → 15/8 | s:sd ]", + "[ 15/8 → 2/1 | s:hh ]", + "[ 2/1 → 17/8 | s:sd ]", "[ 17/8 → 9/4 | s:sd ]", - "[ 9/4 → 19/8 | s:sd ]", - "[ 19/8 → 5/2 | s:bd ]", - "[ 5/2 → 21/8 | s:hh ]", - "[ 21/8 → 11/4 | s:bd ]", - "[ 11/4 → 23/8 | s:sd ]", + "[ 9/4 → 19/8 | s:bd ]", + "[ 19/8 → 5/2 | s:hh ]", + "[ 5/2 → 21/8 | s:bd ]", + "[ 21/8 → 11/4 | s:sd ]", + "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:bd ]", "[ 3/1 → 25/8 | s:sd ]", "[ 25/8 → 13/4 | s:sd ]", - "[ 13/4 → 27/8 | s:bd ]", + "[ 13/4 → 27/8 | s:sd ]", "[ 27/8 → 7/2 | s:bd ]", - "[ 7/2 → 29/8 | s:bd ]", - "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", + "[ 7/2 → 29/8 | s:sd ]", + "[ 29/8 → 15/4 | s:bd ]", + "[ 15/4 → 31/8 | s:bd ]", "[ 31/8 → 4/1 | s:bd ]", ] `; exports[`runs examples > example "chooseCycles" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | s:bd ]", - "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:sd ]", - "[ 3/8 → 1/2 | s:bd ]", + "[ 0/1 → 1/8 | s:hh ]", + "[ 1/8 → 1/4 | s:bd ]", + "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:bd ]", - "[ 3/4 → 7/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:sd ]", "[ 7/8 → 1/1 | s:bd ]", "[ 1/1 → 9/8 | s:sd ]", - "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:bd ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 9/8 → 5/4 | s:sd ]", + "[ 5/4 → 11/8 | s:hh ]", + "[ 11/8 → 3/2 | s:bd ]", "[ 3/2 → 13/8 | s:bd ]", - "[ 13/8 → 7/4 | s:sd ]", - "[ 7/4 → 15/8 | s:hh ]", - "[ 15/8 → 2/1 | s:bd ]", - "[ 2/1 → 17/8 | s:bd ]", + "[ 13/8 → 7/4 | s:bd ]", + "[ 7/4 → 15/8 | s:sd ]", + "[ 15/8 → 2/1 | s:hh ]", + "[ 2/1 → 17/8 | s:sd ]", "[ 17/8 → 9/4 | s:sd ]", - "[ 9/4 → 19/8 | s:sd ]", - "[ 19/8 → 5/2 | s:bd ]", - "[ 5/2 → 21/8 | s:hh ]", - "[ 21/8 → 11/4 | s:bd ]", - "[ 11/4 → 23/8 | s:sd ]", + "[ 9/4 → 19/8 | s:bd ]", + "[ 19/8 → 5/2 | s:hh ]", + "[ 5/2 → 21/8 | s:bd ]", + "[ 21/8 → 11/4 | s:sd ]", + "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:bd ]", "[ 3/1 → 25/8 | s:sd ]", "[ 25/8 → 13/4 | s:sd ]", - "[ 13/4 → 27/8 | s:bd ]", + "[ 13/4 → 27/8 | s:sd ]", "[ 27/8 → 7/2 | s:bd ]", - "[ 7/2 → 29/8 | s:bd ]", - "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", + "[ 7/2 → 29/8 | s:sd ]", + "[ 29/8 → 15/4 | s:bd ]", + "[ 15/4 → 31/8 | s:bd ]", "[ 31/8 → 4/1 | s:bd ]", ] `; @@ -2423,51 +2423,61 @@ exports[`runs examples > example "decay" example index 0 1`] = ` exports[`runs examples > example "degrade" example index 0 1`] = ` [ "[ 1/8 → 1/4 | s:hh ]", - "[ 1/1 → 9/8 | s:hh ]", + "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 3/2 → 13/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", + "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh ]", + "[ 25/8 → 13/4 | s:hh ]", + "[ 27/8 → 7/2 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", ] `; exports[`runs examples > example "degrade" example index 1 1`] = ` [ - "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", "[ 9/8 → 5/4 | s:hh ]", - "[ 13/8 → 7/4 | s:hh ]", + "[ 5/4 → 11/8 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", + "[ 15/8 → 2/1 | s:hh ]", + "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", - "[ 5/2 → 21/8 | s:hh ]", - "[ 11/4 → 23/8 | s:hh ]", + "[ 19/8 → 5/2 | s:hh ]", + "[ 21/8 → 11/4 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", + "[ 7/2 → 29/8 | s:hh ]", ] `; exports[`runs examples > example "degradeBy" example index 0 1`] = ` [ + "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh ]", "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", @@ -2478,74 +2488,89 @@ exports[`runs examples > example "degradeBy" example index 0 1`] = ` "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", ] `; exports[`runs examples > example "degradeBy" example index 1 1`] = ` [ - "[ 1/8 → 1/4 | s:hh ]", + "[ 0/1 → 1/8 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", + "[ 1/2 → 5/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", "[ 9/8 → 5/4 | s:hh ]", + "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", - "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", ] `; exports[`runs examples > example "degradeBy" example index 2 1`] = ` [ + "[ 0/1 → 1/16 | s:bd ]", + "[ 1/16 → 1/8 | s:bd ]", "[ 1/8 → 3/16 | s:bd ]", - "[ 1/4 → 5/16 | s:bd ]", - "[ 5/16 → 3/8 | s:bd ]", + "[ 3/8 → 7/16 | s:bd ]", "[ 1/2 → 9/16 | s:bd ]", "[ 9/16 → 5/8 | s:bd ]", + "[ 5/8 → 11/16 | s:bd ]", "[ 11/16 → 3/4 | s:bd ]", + "[ 3/4 → 13/16 | s:bd ]", "[ 15/16 → 1/1 | s:bd ]", + "[ 1/1 → 17/16 | s:bd ]", + "[ 17/16 → 9/8 | s:bd ]", "[ 9/8 → 19/16 | s:bd ]", - "[ 5/4 → 21/16 | s:bd ]", - "[ 21/16 → 11/8 | s:bd ]", + "[ 11/8 → 23/16 | s:bd ]", "[ 3/2 → 25/16 | s:bd ]", "[ 25/16 → 13/8 | s:bd ]", + "[ 13/8 → 27/16 | s:bd ]", "[ 27/16 → 7/4 | s:bd ]", + "[ 7/4 → 29/16 | s:bd ]", "[ 31/16 → 2/1 | s:bd ]", + "[ 2/1 → 33/16 | s:bd ]", + "[ 33/16 → 17/8 | s:bd ]", "[ 17/8 → 35/16 | s:bd ]", - "[ 9/4 → 37/16 | s:bd ]", - "[ 37/16 → 19/8 | s:bd ]", + "[ 19/8 → 39/16 | s:bd ]", "[ 5/2 → 41/16 | s:bd ]", "[ 41/16 → 21/8 | s:bd ]", + "[ 21/8 → 43/16 | s:bd ]", "[ 43/16 → 11/4 | s:bd ]", + "[ 11/4 → 45/16 | s:bd ]", "[ 47/16 → 3/1 | s:bd ]", + "[ 3/1 → 49/16 | s:bd ]", + "[ 49/16 → 25/8 | s:bd ]", "[ 25/8 → 51/16 | s:bd ]", - "[ 13/4 → 53/16 | s:bd ]", - "[ 53/16 → 27/8 | s:bd ]", + "[ 27/8 → 55/16 | s:bd ]", "[ 7/2 → 57/16 | s:bd ]", "[ 57/16 → 29/8 | s:bd ]", + "[ 29/8 → 59/16 | s:bd ]", "[ 59/16 → 15/4 | s:bd ]", + "[ 15/4 → 61/16 | s:bd ]", "[ 63/16 → 4/1 | s:bd ]", ] `; @@ -4844,34 +4869,34 @@ exports[`runs examples > example "invert" example index 0 1`] = ` exports[`runs examples > example "irand" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:C3 ]", - "[ 1/4 → 3/8 | note:Eb3 ]", - "[ 3/8 → 1/2 | note:F3 ]", - "[ 1/2 → 3/4 | note:Eb3 ]", - "[ 3/4 → 5/6 | note:D3 ]", - "[ 5/6 → 11/12 | note:C3 ]", + "[ 0/1 → 1/4 | note:F3 ]", + "[ 1/4 → 3/8 | note:G3 ]", + "[ 3/8 → 1/2 | note:G3 ]", + "[ 1/2 → 3/4 | note:F3 ]", + "[ 3/4 → 5/6 | note:Ab3 ]", + "[ 5/6 → 11/12 | note:Bb3 ]", "[ 11/12 → 1/1 | note:C4 ]", - "[ 1/1 → 5/4 | note:G3 ]", + "[ 1/1 → 5/4 | note:C3 ]", "[ 5/4 → 11/8 | note:Ab3 ]", - "[ 11/8 → 3/2 | note:D3 ]", - "[ 3/2 → 7/4 | note:G3 ]", - "[ 7/4 → 11/6 | note:D3 ]", + "[ 11/8 → 3/2 | note:Bb3 ]", + "[ 3/2 → 7/4 | note:D3 ]", + "[ 7/4 → 11/6 | note:Ab3 ]", "[ 11/6 → 23/12 | note:Bb3 ]", - "[ 23/12 → 2/1 | note:Eb3 ]", - "[ 2/1 → 9/4 | note:C4 ]", - "[ 9/4 → 19/8 | note:Eb3 ]", - "[ 19/8 → 5/2 | note:Bb3 ]", - "[ 5/2 → 11/4 | note:F3 ]", + "[ 23/12 → 2/1 | note:C3 ]", + "[ 2/1 → 9/4 | note:G3 ]", + "[ 9/4 → 19/8 | note:Ab3 ]", + "[ 19/8 → 5/2 | note:Ab3 ]", + "[ 5/2 → 11/4 | note:Eb3 ]", "[ 11/4 → 17/6 | note:Ab3 ]", - "[ 17/6 → 35/12 | note:D3 ]", - "[ 35/12 → 3/1 | note:F3 ]", - "[ 3/1 → 13/4 | note:D3 ]", - "[ 13/4 → 27/8 | note:C4 ]", - "[ 27/8 → 7/2 | note:F3 ]", - "[ 7/2 → 15/4 | note:F3 ]", - "[ 15/4 → 23/6 | note:Bb3 ]", + "[ 17/6 → 35/12 | note:Bb3 ]", + "[ 35/12 → 3/1 | note:Ab3 ]", + "[ 3/1 → 13/4 | note:F3 ]", + "[ 13/4 → 27/8 | note:Eb3 ]", + "[ 27/8 → 7/2 | note:Ab3 ]", + "[ 7/2 → 15/4 | note:Eb3 ]", + "[ 15/4 → 23/6 | note:C3 ]", "[ 23/6 → 47/12 | note:Ab3 ]", - "[ 47/12 → 4/1 | note:C3 ]", + "[ 47/12 → 4/1 | note:Ab3 ]", ] `; @@ -6503,36 +6528,36 @@ exports[`runs examples > example "off" example index 0 1`] = ` exports[`runs examples > example "often" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh speed:0.5 ]", - "[ 1/8 → 1/4 | s:hh speed:0.5 ]", + "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh speed:0.5 ]", "[ 3/8 → 1/2 | s:hh speed:0.5 ]", "[ 1/2 → 5/8 | s:hh speed:0.5 ]", - "[ 5/8 → 3/4 | s:hh speed:0.5 ]", + "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh speed:0.5 ]", + "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh speed:0.5 ]", - "[ 11/8 → 3/2 | s:hh speed:0.5 ]", + "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh speed:0.5 ]", "[ 7/4 → 15/8 | s:hh speed:0.5 ]", - "[ 15/8 → 2/1 | s:hh speed:0.5 ]", - "[ 2/1 → 17/8 | s:hh ]", + "[ 15/8 → 2/1 | s:hh ]", + "[ 2/1 → 17/8 | s:hh speed:0.5 ]", "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh speed:0.5 ]", - "[ 19/8 → 5/2 | s:hh ]", + "[ 19/8 → 5/2 | s:hh speed:0.5 ]", "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh speed:0.5 ]", - "[ 23/8 → 3/1 | s:hh speed:0.5 ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh speed:0.5 ]", "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 13/4 → 27/8 | s:hh speed:0.5 ]", "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", + "[ 15/4 → 31/8 | s:hh speed:0.5 ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -6785,54 +6810,54 @@ exports[`runs examples > example "penv" example index 0 1`] = ` exports[`runs examples > example "perlin" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh cutoff:500 ]", - "[ 0/1 → 1/4 | s:bd cutoff:500 ]", - "[ 1/8 → 1/4 | s:hh cutoff:562.5486401770559 ]", - "[ 1/4 → 3/8 | s:hh cutoff:903.3554895067937 ]", - "[ 1/4 → 1/2 | s:bd cutoff:903.3554895067937 ]", - "[ 3/8 → 1/2 | s:hh cutoff:1572.364329119182 ]", - "[ 1/2 → 5/8 | s:hh cutoff:2448.2831191271544 ]", - "[ 1/2 → 3/4 | s:bd cutoff:2448.2831191271544 ]", - "[ 5/8 → 3/4 | s:hh cutoff:3324.2019091351267 ]", - "[ 3/4 → 7/8 | s:hh cutoff:3993.210748747515 ]", - "[ 3/4 → 1/1 | s:bd cutoff:3993.210748747515 ]", - "[ 7/8 → 1/1 | s:hh cutoff:4334.017598077253 ]", - "[ 1/1 → 9/8 | s:hh cutoff:4396.566238254309 ]", - "[ 1/1 → 5/4 | s:bd cutoff:4396.566238254309 ]", - "[ 9/8 → 5/4 | s:hh cutoff:4449.536839055554 ]", - "[ 5/4 → 11/8 | s:hh cutoff:4738.156120227359 ]", - "[ 5/4 → 3/2 | s:bd cutoff:4738.156120227359 ]", - "[ 11/8 → 3/2 | s:hh cutoff:5304.71999875931 ]", - "[ 3/2 → 13/8 | s:hh cutoff:6046.5098191052675 ]", - "[ 3/2 → 7/4 | s:bd cutoff:6046.5098191052675 ]", - "[ 13/8 → 7/4 | s:hh cutoff:6788.299639451225 ]", - "[ 7/4 → 15/8 | s:hh cutoff:7354.863517983176 ]", - "[ 7/4 → 2/1 | s:bd cutoff:7354.863517983176 ]", - "[ 15/8 → 2/1 | s:hh cutoff:7643.482799154981 ]", - "[ 2/1 → 17/8 | s:hh cutoff:7696.453399956226 ]", - "[ 2/1 → 9/4 | s:bd cutoff:7696.453399956226 ]", - "[ 17/8 → 9/4 | s:hh cutoff:7607.093996059746 ]", - "[ 9/4 → 19/8 | s:hh cutoff:7120.204164182724 ]", - "[ 9/4 → 5/2 | s:bd cutoff:7120.204164182724 ]", - "[ 19/8 → 5/2 | s:hh cutoff:6164.432289046601 ]", - "[ 5/2 → 21/8 | s:hh cutoff:4913.0608648993075 ]", - "[ 5/2 → 11/4 | s:bd cutoff:4913.0608648993075 ]", - "[ 21/8 → 11/4 | s:hh cutoff:3661.6894407520135 ]", - "[ 11/4 → 23/8 | s:hh cutoff:2705.9175656158914 ]", - "[ 11/4 → 3/1 | s:bd cutoff:2705.9175656158914 ]", - "[ 23/8 → 3/1 | s:hh cutoff:2219.0277337388693 ]", - "[ 3/1 → 25/8 | s:hh cutoff:2129.6683298423886 ]", - "[ 3/1 → 13/4 | s:bd cutoff:2129.6683298423886 ]", - "[ 25/8 → 13/4 | s:hh cutoff:2113.2537022102156 ]", - "[ 13/4 → 27/8 | s:hh cutoff:2023.8158261763601 ]", - "[ 13/4 → 7/2 | s:bd cutoff:2023.8158261763601 ]", - "[ 27/8 → 7/2 | s:hh cutoff:1848.2479648482126 ]", - "[ 7/2 → 29/8 | s:hh cutoff:1618.380764964968 ]", - "[ 7/2 → 15/4 | s:bd cutoff:1618.380764964968 ]", - "[ 29/8 → 15/4 | s:hh cutoff:1388.5135650817233 ]", - "[ 15/4 → 31/8 | s:hh cutoff:1212.9457037535758 ]", - "[ 15/4 → 4/1 | s:bd cutoff:1212.9457037535758 ]", - "[ 31/8 → 4/1 | s:hh cutoff:1123.5078277197204 ]", + "[ 0/1 → 1/8 | s:hh cutoff:3801.944299018942 ]", + "[ 0/1 → 1/4 | s:bd cutoff:3801.944299018942 ]", + "[ 1/8 → 1/4 | s:hh cutoff:3752.180364182138 ]", + "[ 1/4 → 3/8 | s:hh cutoff:3481.0331450903504 ]", + "[ 1/4 → 1/2 | s:bd cutoff:3481.0331450903504 ]", + "[ 3/8 → 1/2 | s:hh cutoff:2948.767180467044 ]", + "[ 1/2 → 5/8 | s:hh cutoff:2251.8828762695193 ]", + "[ 1/2 → 3/4 | s:bd cutoff:2251.8828762695193 ]", + "[ 5/8 → 3/4 | s:hh cutoff:1554.9985720719947 ]", + "[ 3/4 → 7/8 | s:hh cutoff:1022.7326074486882 ]", + "[ 3/4 → 1/1 | s:bd cutoff:1022.7326074486882 ]", + "[ 7/8 → 1/1 | s:hh cutoff:751.5853883569008 ]", + "[ 1/1 → 9/8 | s:hh cutoff:701.8214535200968 ]", + "[ 1/1 → 5/4 | s:bd cutoff:701.8214535200968 ]", + "[ 9/8 → 5/4 | s:hh cutoff:758.9508705680288 ]", + "[ 5/4 → 11/8 | s:hh cutoff:1070.2301657379394 ]", + "[ 5/4 → 3/2 | s:bd cutoff:1070.2301657379394 ]", + "[ 11/8 → 3/2 | s:hh cutoff:1681.2759838209531 ]", + "[ 3/2 → 13/8 | s:hh cutoff:2481.3050446100533 ]", + "[ 3/2 → 7/4 | s:bd cutoff:2481.3050446100533 ]", + "[ 13/8 → 7/4 | s:hh cutoff:3281.3341053991535 ]", + "[ 7/4 → 15/8 | s:hh cutoff:3892.379923482167 ]", + "[ 7/4 → 2/1 | s:bd cutoff:3892.379923482167 ]", + "[ 15/8 → 2/1 | s:hh cutoff:4203.6592186520775 ]", + "[ 2/1 → 17/8 | s:hh cutoff:4260.78863570001 ]", + "[ 2/1 → 9/4 | s:bd cutoff:4260.78863570001 ]", + "[ 17/8 → 9/4 | s:hh cutoff:4250.943561981614 ]", + "[ 9/4 → 19/8 | s:hh cutoff:4197.301012025491 ]", + "[ 9/4 → 5/2 | s:bd cutoff:4197.301012025491 ]", + "[ 19/8 → 5/2 | s:hh cutoff:4091.9999003530734 ]", + "[ 5/2 → 21/8 | s:hh cutoff:3954.1314345551655 ]", + "[ 5/2 → 11/4 | s:bd cutoff:3954.1314345551655 ]", + "[ 21/8 → 11/4 | s:hh cutoff:3816.2629687572576 ]", + "[ 11/4 → 23/8 | s:hh cutoff:3710.9618570848397 ]", + "[ 11/4 → 3/1 | s:bd cutoff:3710.9618570848397 ]", + "[ 23/8 → 3/1 | s:hh cutoff:3657.3193071287164 ]", + "[ 3/1 → 25/8 | s:hh cutoff:3647.474233410321 ]", + "[ 3/1 → 13/4 | s:bd cutoff:3647.474233410321 ]", + "[ 25/8 → 13/4 | s:hh cutoff:3623.927675406968 ]", + "[ 13/4 → 27/8 | s:hh cutoff:3495.6302700122706 ]", + "[ 13/4 → 7/2 | s:bd cutoff:3495.6302700122706 ]", + "[ 27/8 → 7/2 | s:hh cutoff:3243.7805830790653 ]", + "[ 7/2 → 29/8 | s:hh cutoff:2914.039240393322 ]", + "[ 7/2 → 15/4 | s:bd cutoff:2914.039240393322 ]", + "[ 29/8 → 15/4 | s:hh cutoff:2584.2978977075786 ]", + "[ 15/4 → 31/8 | s:hh cutoff:2332.4482107743734 ]", + "[ 15/4 → 4/1 | s:bd cutoff:2332.4482107743734 ]", + "[ 31/8 → 4/1 | s:hh cutoff:2204.150805379676 ]", ] `; @@ -7596,54 +7621,54 @@ exports[`runs examples > example "queryArc" example index 0 1`] = `[]`; exports[`runs examples > example "rand" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh cutoff:500 ]", - "[ 0/1 → 1/4 | s:bd cutoff:500 ]", - "[ 1/8 → 1/4 | s:hh cutoff:5639.116775244474 ]", - "[ 1/4 → 3/8 | s:hh cutoff:3273.1976890936494 ]", - "[ 1/4 → 1/2 | s:bd cutoff:3273.1976890936494 ]", - "[ 3/8 → 1/2 | s:hh cutoff:3510.4438681155443 ]", - "[ 1/2 → 5/8 | s:hh cutoff:2453.604621812701 ]", - "[ 1/2 → 3/4 | s:bd cutoff:2453.604621812701 ]", - "[ 5/8 → 3/4 | s:hh cutoff:1517.2690078616142 ]", - "[ 3/4 → 7/8 | s:hh cutoff:1968.6986012384295 ]", - "[ 3/4 → 1/1 | s:bd cutoff:1968.6986012384295 ]", - "[ 7/8 → 1/1 | s:hh cutoff:3482.2331061586738 ]", - "[ 1/1 → 9/8 | s:hh cutoff:4396.566238254309 ]", - "[ 1/1 → 5/4 | s:bd cutoff:4396.566238254309 ]", - "[ 9/8 → 5/4 | s:hh cutoff:5543.671359308064 ]", - "[ 5/4 → 11/8 | s:hh cutoff:5965.461523272097 ]", - "[ 5/4 → 3/2 | s:bd cutoff:5965.461523272097 ]", - "[ 11/8 → 3/2 | s:hh cutoff:1871.028139255941 ]", - "[ 3/2 → 13/8 | s:hh cutoff:5063.060561195016 ]", - "[ 3/2 → 7/4 | s:bd cutoff:5063.060561195016 ]", - "[ 13/8 → 7/4 | s:hh cutoff:4225.660336203873 ]", - "[ 7/4 → 15/8 | s:hh cutoff:2035.5342207476497 ]", - "[ 7/4 → 2/1 | s:bd cutoff:2035.5342207476497 ]", - "[ 15/8 → 2/1 | s:hh cutoff:4959.178843535483 ]", - "[ 2/1 → 17/8 | s:hh cutoff:7696.453399956226 ]", - "[ 2/1 → 9/4 | s:bd cutoff:7696.453399956226 ]", - "[ 17/8 → 9/4 | s:hh cutoff:7275.427204556763 ]", - "[ 9/4 → 19/8 | s:hh cutoff:3091.1188358440995 ]", - "[ 9/4 → 5/2 | s:bd cutoff:3091.1188358440995 ]", - "[ 19/8 → 5/2 | s:hh cutoff:6773.7998040392995 ]", - "[ 5/2 → 21/8 | s:hh cutoff:3939.620556309819 ]", - "[ 5/2 → 11/4 | s:bd cutoff:3939.620556309819 ]", - "[ 21/8 → 11/4 | s:hh cutoff:1701.4511320739985 ]", - "[ 11/4 → 23/8 | s:hh cutoff:5249.245778657496 ]", - "[ 11/4 → 3/1 | s:bd cutoff:5249.245778657496 ]", - "[ 23/8 → 3/1 | s:hh cutoff:621.9062879681587 ]", - "[ 3/1 → 25/8 | s:hh cutoff:2129.6683298423886 ]", - "[ 3/1 → 13/4 | s:bd cutoff:2129.6683298423886 ]", - "[ 25/8 → 13/4 | s:hh cutoff:3074.329087510705 ]", - "[ 13/4 → 27/8 | s:hh cutoff:7942.738036625087 ]", - "[ 13/4 → 7/2 | s:bd cutoff:7942.738036625087 ]", - "[ 27/8 → 7/2 | s:hh cutoff:3565.1885084807873 ]", - "[ 7/2 → 29/8 | s:hh cutoff:3574.6161099523306 ]", - "[ 7/2 → 15/4 | s:bd cutoff:3574.6161099523306 ]", - "[ 29/8 → 15/4 | s:hh cutoff:7543.614340946078 ]", - "[ 15/4 → 31/8 | s:hh cutoff:6591.254916973412 ]", - "[ 15/4 → 4/1 | s:bd cutoff:6591.254916973412 ]", - "[ 31/8 → 4/1 | s:hh cutoff:6021.249040029943 ]", + "[ 0/1 → 1/8 | s:hh cutoff:3801.944299018942 ]", + "[ 0/1 → 1/4 | s:bd cutoff:3801.944299018942 ]", + "[ 1/8 → 1/4 | s:hh cutoff:6647.100417292677 ]", + "[ 1/4 → 3/8 | s:hh cutoff:4935.184325557202 ]", + "[ 1/4 → 1/2 | s:bd cutoff:4935.184325557202 ]", + "[ 3/8 → 1/2 | s:hh cutoff:4274.936107802205 ]", + "[ 1/2 → 5/8 | s:hh cutoff:3599.519268143922 ]", + "[ 1/2 → 3/4 | s:bd cutoff:3599.519268143922 ]", + "[ 5/8 → 3/4 | s:hh cutoff:7203.329019364901 ]", + "[ 3/4 → 7/8 | s:hh cutoff:5311.3214410841465 ]", + "[ 3/4 → 1/1 | s:bd cutoff:5311.3214410841465 ]", + "[ 7/8 → 1/1 | s:hh cutoff:7230.677842278965 ]", + "[ 1/1 → 9/8 | s:hh cutoff:701.8214535200968 ]", + "[ 1/1 → 5/4 | s:bd cutoff:701.8214535200968 ]", + "[ 9/8 → 5/4 | s:hh cutoff:6626.493136398494 ]", + "[ 5/4 → 11/8 | s:hh cutoff:5536.982340388931 ]", + "[ 5/4 → 3/2 | s:bd cutoff:5536.982340388931 ]", + "[ 11/8 → 3/2 | s:hh cutoff:6926.114265923388 ]", + "[ 3/2 → 13/8 | s:hh cutoff:2300.4843831295148 ]", + "[ 3/2 → 7/4 | s:bd cutoff:2300.4843831295148 ]", + "[ 13/8 → 7/4 | s:hh cutoff:2510.1786771556363 ]", + "[ 7/4 → 15/8 | s:hh cutoff:5990.686780540273 ]", + "[ 7/4 → 2/1 | s:bd cutoff:5990.686780540273 ]", + "[ 15/8 → 2/1 | s:hh cutoff:6187.015319708735 ]", + "[ 2/1 → 17/8 | s:hh cutoff:4260.78863570001 ]", + "[ 2/1 → 9/4 | s:bd cutoff:4260.78863570001 ]", + "[ 17/8 → 9/4 | s:hh cutoff:6301.981445983984 ]", + "[ 9/4 → 19/8 | s:hh cutoff:5212.422806769609 ]", + "[ 9/4 → 5/2 | s:bd cutoff:5212.422806769609 ]", + "[ 19/8 → 5/2 | s:hh cutoff:5561.523957410827 ]", + "[ 5/2 → 21/8 | s:hh cutoff:3020.9835229907185 ]", + "[ 5/2 → 11/4 | s:bd cutoff:3020.9835229907185 ]", + "[ 21/8 → 11/4 | s:hh cutoff:576.5502714784816 ]", + "[ 11/4 → 23/8 | s:hh cutoff:5743.939216597937 ]", + "[ 11/4 → 3/1 | s:bd cutoff:5743.939216597937 ]", + "[ 23/8 → 3/1 | s:hh cutoff:7271.8438868178055 ]", + "[ 3/1 → 25/8 | s:hh cutoff:3647.474233410321 ]", + "[ 3/1 → 13/4 | s:bd cutoff:3647.474233410321 ]", + "[ 25/8 → 13/4 | s:hh cutoff:5633.619675179943 ]", + "[ 13/4 → 27/8 | s:hh cutoff:2873.2354695675895 ]", + "[ 13/4 → 7/2 | s:bd cutoff:2873.2354695675895 ]", + "[ 27/8 → 7/2 | s:hh cutoff:5596.839588950388 ]", + "[ 7/2 → 29/8 | s:hh cutoff:2628.3173956908286 ]", + "[ 7/2 → 15/4 | s:bd cutoff:2628.3173956908286 ]", + "[ 29/8 → 15/4 | s:hh cutoff:7124.103914946318 ]", + "[ 15/4 → 31/8 | s:hh cutoff:814.1072567086667 ]", + "[ 15/4 → 4/1 | s:bd cutoff:814.1072567086667 ]", + "[ 31/8 → 4/1 | s:hh cutoff:518.1868247454986 ]", ] `; @@ -7808,21 +7833,21 @@ exports[`runs examples > example "rangex" example index 0 1`] = ` exports[`runs examples > example "rarely" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh speed:0.5 ]", + "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", - "[ 5/8 → 3/4 | s:hh speed:0.5 ]", - "[ 3/4 → 7/8 | s:hh speed:0.5 ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh ]", + "[ 1/1 → 9/8 | s:hh speed:0.5 ]", "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh ]", - "[ 7/4 → 15/8 | s:hh speed:0.5 ]", + "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", @@ -7831,15 +7856,15 @@ exports[`runs examples > example "rarely" example index 0 1`] = ` "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh speed:0.5 ]", - "[ 3/1 → 25/8 | s:hh speed:0.5 ]", + "[ 23/8 → 3/1 | s:hh ]", + "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", + "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -7883,22 +7908,22 @@ exports[`runs examples > example "release" example index 0 1`] = ` exports[`runs examples > example "repeatCycles" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:34 s:gm_acoustic_guitar_nylon ]", - "[ 1/4 → 1/2 | note:38 s:gm_acoustic_guitar_nylon ]", - "[ 1/2 → 3/4 | note:37 s:gm_acoustic_guitar_nylon ]", - "[ 3/4 → 1/1 | note:36 s:gm_acoustic_guitar_nylon ]", - "[ 1/1 → 5/4 | note:34 s:gm_acoustic_guitar_nylon ]", - "[ 5/4 → 3/2 | note:38 s:gm_acoustic_guitar_nylon ]", - "[ 3/2 → 7/4 | note:37 s:gm_acoustic_guitar_nylon ]", - "[ 7/4 → 2/1 | note:36 s:gm_acoustic_guitar_nylon ]", - "[ 2/1 → 9/4 | note:40 s:gm_acoustic_guitar_nylon ]", + "[ 0/1 → 1/4 | note:39 s:gm_acoustic_guitar_nylon ]", + "[ 1/4 → 1/2 | note:41 s:gm_acoustic_guitar_nylon ]", + "[ 1/2 → 3/4 | note:38 s:gm_acoustic_guitar_nylon ]", + "[ 3/4 → 1/1 | note:41 s:gm_acoustic_guitar_nylon ]", + "[ 1/1 → 5/4 | note:39 s:gm_acoustic_guitar_nylon ]", + "[ 5/4 → 3/2 | note:41 s:gm_acoustic_guitar_nylon ]", + "[ 3/2 → 7/4 | note:38 s:gm_acoustic_guitar_nylon ]", + "[ 7/4 → 2/1 | note:41 s:gm_acoustic_guitar_nylon ]", + "[ 2/1 → 9/4 | note:34 s:gm_acoustic_guitar_nylon ]", "[ 9/4 → 5/2 | note:42 s:gm_acoustic_guitar_nylon ]", - "[ 5/2 → 11/4 | note:41 s:gm_acoustic_guitar_nylon ]", - "[ 11/4 → 3/1 | note:36 s:gm_acoustic_guitar_nylon ]", - "[ 3/1 → 13/4 | note:40 s:gm_acoustic_guitar_nylon ]", + "[ 5/2 → 11/4 | note:36 s:gm_acoustic_guitar_nylon ]", + "[ 11/4 → 3/1 | note:42 s:gm_acoustic_guitar_nylon ]", + "[ 3/1 → 13/4 | note:34 s:gm_acoustic_guitar_nylon ]", "[ 13/4 → 7/2 | note:42 s:gm_acoustic_guitar_nylon ]", - "[ 7/2 → 15/4 | note:41 s:gm_acoustic_guitar_nylon ]", - "[ 15/4 → 4/1 | note:36 s:gm_acoustic_guitar_nylon ]", + "[ 7/2 → 15/4 | note:36 s:gm_acoustic_guitar_nylon ]", + "[ 15/4 → 4/1 | note:42 s:gm_acoustic_guitar_nylon ]", ] `; @@ -8036,67 +8061,43 @@ exports[`runs examples > example "ribbon" example index 0 1`] = ` exports[`runs examples > example "ribbon" example index 1 1`] = ` [ - "[ 0/1 → 1/4 | note:A3 ]", - "[ 1/4 → 1/2 | note:C3 ]", - "[ 1/2 → 3/4 | note:D3 ]", - "[ 3/4 → 1/1 | note:G3 ]", - "[ 1/1 → 5/4 | note:E3 ]", - "[ 5/4 → 3/2 | note:C4 ]", + "[ 0/1 → 1/4 | note:E4 ]", + "[ 1/4 → 1/2 | note:G3 ]", + "[ 1/2 → 3/4 | note:C3 ]", + "[ 3/4 → 1/1 | note:E4 ]", + "[ 1/1 → 5/4 | note:A3 ]", + "[ 5/4 → 3/2 | note:D3 ]", "[ 3/2 → 7/4 | note:A3 ]", - "[ 7/4 → 2/1 | note:E4 ]", - "[ 2/1 → 9/4 | note:A3 ]", - "[ 9/4 → 5/2 | note:C3 ]", - "[ 5/2 → 11/4 | note:D3 ]", - "[ 11/4 → 3/1 | note:G3 ]", - "[ 3/1 → 13/4 | note:E3 ]", - "[ 13/4 → 7/2 | note:C4 ]", + "[ 7/4 → 2/1 | note:G3 ]", + "[ 2/1 → 9/4 | note:E4 ]", + "[ 9/4 → 5/2 | note:G3 ]", + "[ 5/2 → 11/4 | note:C3 ]", + "[ 11/4 → 3/1 | note:E4 ]", + "[ 3/1 → 13/4 | note:A3 ]", + "[ 13/4 → 7/2 | note:D3 ]", "[ 7/2 → 15/4 | note:A3 ]", - "[ 15/4 → 4/1 | note:E4 ]", + "[ 15/4 → 4/1 | note:G3 ]", ] `; exports[`runs examples > example "ribbon" example index 2 1`] = ` [ - "[ 1/16 → 1/8 | s:bd ]", "[ 1/8 → 3/16 | s:bd ]", - "[ 3/16 → 1/4 | s:bd ]", - "[ 1/4 → 5/16 | s:bd ]", - "[ 3/8 → 7/16 | s:bd ]", - "[ 9/16 → 5/8 | s:bd ]", + "[ 7/16 → 1/2 | s:bd ]", "[ 5/8 → 11/16 | s:bd ]", - "[ 11/16 → 3/4 | s:bd ]", - "[ 3/4 → 13/16 | s:bd ]", - "[ 7/8 → 15/16 | s:bd ]", - "[ 17/16 → 9/8 | s:bd ]", + "[ 15/16 → 1/1 | s:bd ]", "[ 9/8 → 19/16 | s:bd ]", - "[ 19/16 → 5/4 | s:bd ]", - "[ 5/4 → 21/16 | s:bd ]", - "[ 11/8 → 23/16 | s:bd ]", - "[ 25/16 → 13/8 | s:bd ]", + "[ 23/16 → 3/2 | s:bd ]", "[ 13/8 → 27/16 | s:bd ]", - "[ 27/16 → 7/4 | s:bd ]", - "[ 7/4 → 29/16 | s:bd ]", - "[ 15/8 → 31/16 | s:bd ]", - "[ 33/16 → 17/8 | s:bd ]", + "[ 31/16 → 2/1 | s:bd ]", "[ 17/8 → 35/16 | s:bd ]", - "[ 35/16 → 9/4 | s:bd ]", - "[ 9/4 → 37/16 | s:bd ]", - "[ 19/8 → 39/16 | s:bd ]", - "[ 41/16 → 21/8 | s:bd ]", + "[ 39/16 → 5/2 | s:bd ]", "[ 21/8 → 43/16 | s:bd ]", - "[ 43/16 → 11/4 | s:bd ]", - "[ 11/4 → 45/16 | s:bd ]", - "[ 23/8 → 47/16 | s:bd ]", - "[ 49/16 → 25/8 | s:bd ]", + "[ 47/16 → 3/1 | s:bd ]", "[ 25/8 → 51/16 | s:bd ]", - "[ 51/16 → 13/4 | s:bd ]", - "[ 13/4 → 53/16 | s:bd ]", - "[ 27/8 → 55/16 | s:bd ]", - "[ 57/16 → 29/8 | s:bd ]", + "[ 55/16 → 7/2 | s:bd ]", "[ 29/8 → 59/16 | s:bd ]", - "[ 59/16 → 15/4 | s:bd ]", - "[ 15/4 → 61/16 | s:bd ]", - "[ 31/8 → 63/16 | s:bd ]", + "[ 63/16 → 4/1 | s:bd ]", ] `; @@ -8627,38 +8628,38 @@ exports[`runs examples > example "scale" example index 1 1`] = ` exports[`runs examples > example "scale" example index 2 1`] = ` [ - "[ 0/1 → 1/8 | note:C3 s:piano ]", - "[ 1/8 → 1/4 | note:A4 s:piano ]", - "[ 1/4 → 3/8 | note:C4 s:piano ]", - "[ 3/8 → 1/2 | note:C4 s:piano ]", - "[ 1/2 → 5/8 | note:A3 s:piano ]", - "[ 5/8 → 3/4 | note:F3 s:piano ]", - "[ 3/4 → 7/8 | note:G3 s:piano ]", - "[ 7/8 → 1/1 | note:C4 s:piano ]", - "[ 1/1 → 9/8 | note:F4 s:piano ]", - "[ 9/8 → 5/4 | note:A4 s:piano ]", + "[ 0/1 → 1/8 | note:D4 s:piano ]", + "[ 1/8 → 1/4 | note:C5 s:piano ]", + "[ 1/4 → 3/8 | note:G4 s:piano ]", + "[ 3/8 → 1/2 | note:F4 s:piano ]", + "[ 1/2 → 5/8 | note:C4 s:piano ]", + "[ 5/8 → 3/4 | note:D5 s:piano ]", + "[ 3/4 → 7/8 | note:G4 s:piano ]", + "[ 7/8 → 1/1 | note:D5 s:piano ]", + "[ 1/1 → 9/8 | note:D3 s:piano ]", + "[ 9/8 → 5/4 | note:C5 s:piano ]", "[ 5/4 → 11/8 | note:A4 s:piano ]", - "[ 11/8 → 3/2 | note:G3 s:piano ]", - "[ 3/2 → 13/8 | note:G4 s:piano ]", - "[ 13/8 → 7/4 | note:D4 s:piano ]", - "[ 7/4 → 15/8 | note:G3 s:piano ]", - "[ 15/8 → 2/1 | note:G4 s:piano ]", - "[ 2/1 → 17/8 | note:F5 s:piano ]", - "[ 17/8 → 9/4 | note:D5 s:piano ]", - "[ 9/4 → 19/8 | note:C4 s:piano ]", - "[ 19/8 → 5/2 | note:D5 s:piano ]", - "[ 5/2 → 21/8 | note:D4 s:piano ]", - "[ 21/8 → 11/4 | note:F3 s:piano ]", - "[ 11/4 → 23/8 | note:G4 s:piano ]", - "[ 23/8 → 3/1 | note:D3 s:piano ]", - "[ 3/1 → 25/8 | note:G3 s:piano ]", - "[ 25/8 → 13/4 | note:C4 s:piano ]", - "[ 13/4 → 27/8 | note:F5 s:piano ]", - "[ 27/8 → 7/2 | note:C4 s:piano ]", - "[ 7/2 → 29/8 | note:C4 s:piano ]", - "[ 29/8 → 15/4 | note:F5 s:piano ]", - "[ 15/4 → 31/8 | note:C5 s:piano ]", - "[ 31/8 → 4/1 | note:A4 s:piano ]", + "[ 11/8 → 3/2 | note:D5 s:piano ]", + "[ 3/2 → 13/8 | note:G3 s:piano ]", + "[ 13/8 → 7/4 | note:A3 s:piano ]", + "[ 7/4 → 15/8 | note:A4 s:piano ]", + "[ 15/8 → 2/1 | note:C5 s:piano ]", + "[ 2/1 → 17/8 | note:F4 s:piano ]", + "[ 17/8 → 9/4 | note:C5 s:piano ]", + "[ 9/4 → 19/8 | note:G4 s:piano ]", + "[ 19/8 → 5/2 | note:A4 s:piano ]", + "[ 5/2 → 21/8 | note:C4 s:piano ]", + "[ 21/8 → 11/4 | note:D3 s:piano ]", + "[ 11/4 → 23/8 | note:A4 s:piano ]", + "[ 23/8 → 3/1 | note:D5 s:piano ]", + "[ 3/1 → 25/8 | note:D4 s:piano ]", + "[ 25/8 → 13/4 | note:A4 s:piano ]", + "[ 13/4 → 27/8 | note:A3 s:piano ]", + "[ 27/8 → 7/2 | note:A4 s:piano ]", + "[ 7/2 → 29/8 | note:A3 s:piano ]", + "[ 29/8 → 15/4 | note:D5 s:piano ]", + "[ 15/4 → 31/8 | note:D3 s:piano ]", + "[ 31/8 → 4/1 | note:D3 s:piano ]", ] `; @@ -8694,46 +8695,46 @@ exports[`runs examples > example "scope" example index 0 1`] = ` exports[`runs examples > example "scramble" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:c s:piano ]", - "[ 1/4 → 1/2 | note:d s:piano ]", + "[ 0/1 → 1/4 | note:d s:piano ]", + "[ 1/4 → 1/2 | note:e s:piano ]", "[ 1/2 → 3/4 | note:d s:piano ]", - "[ 3/4 → 1/1 | note:c s:piano ]", - "[ 1/1 → 5/4 | note:e s:piano ]", + "[ 3/4 → 1/1 | note:e s:piano ]", + "[ 1/1 → 5/4 | note:c s:piano ]", "[ 5/4 → 3/2 | note:e s:piano ]", - "[ 3/2 → 7/4 | note:e s:piano ]", - "[ 7/4 → 2/1 | note:c s:piano ]", - "[ 2/1 → 9/4 | note:f s:piano ]", - "[ 9/4 → 5/2 | note:d s:piano ]", + "[ 3/2 → 7/4 | note:c s:piano ]", + "[ 7/4 → 2/1 | note:e s:piano ]", + "[ 2/1 → 9/4 | note:e s:piano ]", + "[ 9/4 → 5/2 | note:e s:piano ]", "[ 5/2 → 11/4 | note:d s:piano ]", "[ 11/4 → 3/1 | note:e s:piano ]", - "[ 3/1 → 13/4 | note:c s:piano ]", - "[ 13/4 → 7/2 | note:f s:piano ]", + "[ 3/1 → 13/4 | note:d s:piano ]", + "[ 13/4 → 7/2 | note:d s:piano ]", "[ 7/2 → 15/4 | note:d s:piano ]", - "[ 15/4 → 4/1 | note:f s:piano ]", + "[ 15/4 → 4/1 | note:c s:piano ]", ] `; exports[`runs examples > example "scramble" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | note:c s:piano ]", - "[ 1/8 → 1/4 | note:d s:piano ]", + "[ 0/1 → 1/8 | note:d s:piano ]", + "[ 1/8 → 1/4 | note:e s:piano ]", "[ 1/4 → 3/8 | note:d s:piano ]", - "[ 3/8 → 1/2 | note:c s:piano ]", + "[ 3/8 → 1/2 | note:e s:piano ]", "[ 1/2 → 1/1 | note:g s:piano ]", - "[ 1/1 → 9/8 | note:e s:piano ]", + "[ 1/1 → 9/8 | note:c s:piano ]", "[ 9/8 → 5/4 | note:e s:piano ]", - "[ 5/4 → 11/8 | note:e s:piano ]", - "[ 11/8 → 3/2 | note:c s:piano ]", + "[ 5/4 → 11/8 | note:c s:piano ]", + "[ 11/8 → 3/2 | note:e s:piano ]", "[ 3/2 → 2/1 | note:g s:piano ]", - "[ 2/1 → 17/8 | note:f s:piano ]", - "[ 17/8 → 9/4 | note:d s:piano ]", + "[ 2/1 → 17/8 | note:e s:piano ]", + "[ 17/8 → 9/4 | note:e s:piano ]", "[ 9/4 → 19/8 | note:d s:piano ]", "[ 19/8 → 5/2 | note:e s:piano ]", "[ 5/2 → 3/1 | note:g s:piano ]", - "[ 3/1 → 25/8 | note:c s:piano ]", - "[ 25/8 → 13/4 | note:f s:piano ]", + "[ 3/1 → 25/8 | note:d s:piano ]", + "[ 25/8 → 13/4 | note:d s:piano ]", "[ 13/4 → 27/8 | note:d s:piano ]", - "[ 27/8 → 7/2 | note:f s:piano ]", + "[ 27/8 → 7/2 | note:c s:piano ]", "[ 7/2 → 4/1 | note:g s:piano ]", ] `; @@ -8967,6 +8968,64 @@ exports[`runs examples > example "seqPLoop" example index 0 1`] = ` ] `; +exports[`runs examples > example "setGainCurve" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:bd gain:0.5 ]", + "[ 1/4 → 1/2 | s:bd gain:0.5 ]", + "[ 1/2 → 3/4 | s:bd gain:0.5 ]", + "[ 3/4 → 1/1 | s:bd gain:0.5 ]", + "[ 1/1 → 5/4 | s:bd gain:0.5 ]", + "[ 5/4 → 3/2 | s:bd gain:0.5 ]", + "[ 3/2 → 7/4 | s:bd gain:0.5 ]", + "[ 7/4 → 2/1 | s:bd gain:0.5 ]", + "[ 2/1 → 9/4 | s:bd gain:0.5 ]", + "[ 9/4 → 5/2 | s:bd gain:0.5 ]", + "[ 5/2 → 11/4 | s:bd gain:0.5 ]", + "[ 11/4 → 3/1 | s:bd gain:0.5 ]", + "[ 3/1 → 13/4 | s:bd gain:0.5 ]", + "[ 13/4 → 7/2 | s:bd gain:0.5 ]", + "[ 7/2 → 15/4 | s:bd gain:0.5 ]", + "[ 15/4 → 4/1 | s:bd gain:0.5 ]", +] +`; + +exports[`runs examples > example "setMaxPolyphony" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | note:F#4 room:1 release:4 gain:0.5 ]", + "[ 1/8 → 1/4 | note:A5 room:1 release:4 gain:0.5 ]", + "[ 1/4 → 3/8 | note:C#5 room:1 release:4 gain:0.5 ]", + "[ 3/8 → 1/2 | note:A4 room:1 release:4 gain:0.5 ]", + "[ 1/2 → 5/8 | note:E4 room:1 release:4 gain:0.5 ]", + "[ 5/8 → 3/4 | note:C#6 room:1 release:4 gain:0.5 ]", + "[ 3/4 → 7/8 | note:D#5 room:1 release:4 gain:0.5 ]", + "[ 7/8 → 1/1 | note:C#6 room:1 release:4 gain:0.5 ]", + "[ 1/1 → 9/8 | note:C#3 room:1 release:4 gain:0.5 ]", + "[ 9/8 → 5/4 | note:A5 room:1 release:4 gain:0.5 ]", + "[ 5/4 → 11/8 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 11/8 → 3/2 | note:B5 room:1 release:4 gain:0.5 ]", + "[ 3/2 → 13/8 | note:A3 room:1 release:4 gain:0.5 ]", + "[ 13/8 → 7/4 | note:B3 room:1 release:4 gain:0.5 ]", + "[ 7/4 → 15/8 | note:F#5 room:1 release:4 gain:0.5 ]", + "[ 15/8 → 2/1 | note:G#5 room:1 release:4 gain:0.5 ]", + "[ 2/1 → 17/8 | note:A4 room:1 release:4 gain:0.5 ]", + "[ 17/8 → 9/4 | note:G#5 room:1 release:4 gain:0.5 ]", + "[ 9/4 → 19/8 | note:D#5 room:1 release:4 gain:0.5 ]", + "[ 19/8 → 5/2 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 5/2 → 21/8 | note:D#4 room:1 release:4 gain:0.5 ]", + "[ 21/8 → 11/4 | note:C#3 room:1 release:4 gain:0.5 ]", + "[ 11/4 → 23/8 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 23/8 → 3/1 | note:C#6 room:1 release:4 gain:0.5 ]", + "[ 3/1 → 25/8 | note:F#4 room:1 release:4 gain:0.5 ]", + "[ 25/8 → 13/4 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 13/4 → 27/8 | note:C#4 room:1 release:4 gain:0.5 ]", + "[ 27/8 → 7/2 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 7/2 → 29/8 | note:B3 room:1 release:4 gain:0.5 ]", + "[ 29/8 → 15/4 | note:C#6 room:1 release:4 gain:0.5 ]", + "[ 15/4 → 31/8 | note:D#3 room:1 release:4 gain:0.5 ]", + "[ 31/8 → 4/1 | note:C#3 room:1 release:4 gain:0.5 ]", +] +`; + exports[`runs examples > example "setcpm" example index 0 1`] = ` [ "[ 0/1 → 1/4 | s:bd bank:tr707 ]", @@ -9200,45 +9259,45 @@ exports[`runs examples > example "shrink" example index 3 1`] = ` exports[`runs examples > example "shuffle" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:e s:piano ]", - "[ 1/4 → 1/2 | note:d s:piano ]", + "[ 1/4 → 1/2 | note:c 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 ]", + "[ 3/4 → 1/1 | note:d s:piano ]", + "[ 1/1 → 5/4 | note:f s:piano ]", "[ 5/4 → 3/2 | note:c s:piano ]", - "[ 3/2 → 7/4 | note:f s:piano ]", + "[ 3/2 → 7/4 | note:e 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 ]", + "[ 2/1 → 9/4 | note:c s:piano ]", + "[ 9/4 → 5/2 | note:f s:piano ]", + "[ 5/2 → 11/4 | note:d s:piano ]", + "[ 11/4 → 3/1 | note:e s:piano ]", "[ 3/1 → 13/4 | note:c s:piano ]", - "[ 13/4 → 7/2 | note:e s:piano ]", + "[ 13/4 → 7/2 | note:d s:piano ]", "[ 7/2 → 15/4 | note:f s:piano ]", - "[ 15/4 → 4/1 | note:d s:piano ]", + "[ 15/4 → 4/1 | note:e s:piano ]", ] `; exports[`runs examples > example "shuffle" example index 1 1`] = ` [ "[ 0/1 → 1/8 | note:e s:piano ]", - "[ 1/8 → 1/4 | note:d s:piano ]", + "[ 1/8 → 1/4 | note:c s:piano ]", "[ 1/4 → 3/8 | note:f s:piano ]", - "[ 3/8 → 1/2 | note:c s:piano ]", + "[ 3/8 → 1/2 | note:d s:piano ]", "[ 1/2 → 1/1 | note:g s:piano ]", - "[ 1/1 → 9/8 | note:e s:piano ]", + "[ 1/1 → 9/8 | note:f s:piano ]", "[ 9/8 → 5/4 | note:c s:piano ]", - "[ 5/4 → 11/8 | note:f s:piano ]", + "[ 5/4 → 11/8 | note:e s:piano ]", "[ 11/8 → 3/2 | note:d s:piano ]", "[ 3/2 → 2/1 | note:g 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 ]", + "[ 2/1 → 17/8 | note:c s:piano ]", + "[ 17/8 → 9/4 | note:f s:piano ]", + "[ 9/4 → 19/8 | note:d s:piano ]", + "[ 19/8 → 5/2 | note:e s:piano ]", "[ 5/2 → 3/1 | note:g s:piano ]", "[ 3/1 → 25/8 | note:c s:piano ]", - "[ 25/8 → 13/4 | note:e s:piano ]", + "[ 25/8 → 13/4 | note:d s:piano ]", "[ 13/4 → 27/8 | note:f s:piano ]", - "[ 27/8 → 7/2 | note:d s:piano ]", + "[ 27/8 → 7/2 | note:e s:piano ]", "[ 7/2 → 4/1 | note:g s:piano ]", ] `; @@ -9425,15 +9484,15 @@ exports[`runs examples > example "someCycles" example index 0 1`] = ` "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", "[ 7/8 → 1/1 | s:hh speed:0.5 ]", - "[ 1/1 → 9/8 | s:hh ]", - "[ 1/1 → 2/1 | s:bd ]", - "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", - "[ 3/2 → 13/8 | s:hh ]", - "[ 13/8 → 7/4 | s:hh ]", - "[ 7/4 → 15/8 | s:hh ]", - "[ 15/8 → 2/1 | s:hh ]", + "[ 1/1 → 9/8 | s:hh speed:0.5 ]", + "[ 1/1 → 2/1 | s:bd speed:0.5 ]", + "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 5/4 → 11/8 | s:hh speed:0.5 ]", + "[ 11/8 → 3/2 | s:hh speed:0.5 ]", + "[ 3/2 → 13/8 | s:hh speed:0.5 ]", + "[ 13/8 → 7/4 | s:hh speed:0.5 ]", + "[ 7/4 → 15/8 | s:hh speed:0.5 ]", + "[ 15/8 → 2/1 | s:hh speed:0.5 ]", "[ 2/1 → 17/8 | s:hh ]", "[ 2/1 → 3/1 | s:bd ]", "[ 17/8 → 9/4 | s:hh ]", @@ -9457,24 +9516,24 @@ exports[`runs examples > example "someCycles" example index 0 1`] = ` exports[`runs examples > example "someCyclesBy" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh speed:0.5 ]", - "[ 0/1 → 1/1 | s:bd speed:0.5 ]", - "[ 1/8 → 1/4 | s:hh speed:0.5 ]", - "[ 1/4 → 3/8 | s:hh speed:0.5 ]", - "[ 3/8 → 1/2 | s:hh speed:0.5 ]", - "[ 1/2 → 5/8 | s:hh speed:0.5 ]", - "[ 5/8 → 3/4 | s:hh speed:0.5 ]", - "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh speed:0.5 ]", - "[ 1/1 → 9/8 | s:hh ]", - "[ 1/1 → 2/1 | s:bd ]", - "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", - "[ 3/2 → 13/8 | s:hh ]", - "[ 13/8 → 7/4 | s:hh ]", - "[ 7/4 → 15/8 | s:hh ]", - "[ 15/8 → 2/1 | s:hh ]", + "[ 0/1 → 1/8 | s:hh ]", + "[ 0/1 → 1/1 | s:bd ]", + "[ 1/8 → 1/4 | s:hh ]", + "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", + "[ 1/2 → 5/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", + "[ 1/1 → 9/8 | s:hh speed:0.5 ]", + "[ 1/1 → 2/1 | s:bd speed:0.5 ]", + "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 5/4 → 11/8 | s:hh speed:0.5 ]", + "[ 11/8 → 3/2 | s:hh speed:0.5 ]", + "[ 3/2 → 13/8 | s:hh speed:0.5 ]", + "[ 13/8 → 7/4 | s:hh speed:0.5 ]", + "[ 7/4 → 15/8 | s:hh speed:0.5 ]", + "[ 15/8 → 2/1 | s:hh speed:0.5 ]", "[ 2/1 → 17/8 | s:hh ]", "[ 2/1 → 3/1 | s:bd ]", "[ 17/8 → 9/4 | s:hh ]", @@ -9484,15 +9543,15 @@ exports[`runs examples > example "someCyclesBy" example index 0 1`] = ` "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh speed:0.5 ]", - "[ 3/1 → 4/1 | s:bd speed:0.5 ]", - "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh speed:0.5 ]", - "[ 27/8 → 7/2 | s:hh speed:0.5 ]", - "[ 7/2 → 29/8 | s:hh speed:0.5 ]", - "[ 29/8 → 15/4 | s:hh speed:0.5 ]", - "[ 15/4 → 31/8 | s:hh speed:0.5 ]", - "[ 31/8 → 4/1 | s:hh speed:0.5 ]", + "[ 3/1 → 25/8 | s:hh ]", + "[ 3/1 → 4/1 | s:bd ]", + "[ 25/8 → 13/4 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh ]", + "[ 7/2 → 29/8 | s:hh ]", + "[ 29/8 → 15/4 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -9500,73 +9559,73 @@ exports[`runs examples > example "sometimes" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh speed:0.5 ]", "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh speed:0.5 ]", - "[ 3/8 → 1/2 | s:hh speed:0.5 ]", + "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh speed:0.5 ]", - "[ 5/8 → 3/4 | s:hh speed:0.5 ]", - "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh speed:0.5 ]", - "[ 1/1 → 9/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", + "[ 1/1 → 9/8 | s:hh speed:0.5 ]", "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh speed:0.5 ]", - "[ 7/4 → 15/8 | s:hh speed:0.5 ]", + "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh speed:0.5 ]", + "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh speed:0.5 ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh speed:0.5 ]", - "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh speed:0.5 ]", + "[ 25/8 → 13/4 | s:hh ]", + "[ 13/4 → 27/8 | s:hh speed:0.5 ]", + "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", + "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; exports[`runs examples > example "sometimesBy" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh speed:0.5 ]", + "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh speed:0.5 ]", + "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", - "[ 1/2 → 5/8 | s:hh speed:0.5 ]", - "[ 5/8 → 3/4 | s:hh speed:0.5 ]", - "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh speed:0.5 ]", - "[ 1/1 → 9/8 | s:hh ]", + "[ 1/2 → 5/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", + "[ 1/1 → 9/8 | s:hh speed:0.5 ]", "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh ]", - "[ 13/8 → 7/4 | s:hh ]", - "[ 7/4 → 15/8 | s:hh speed:0.5 ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:hh speed:0.5 ]", + "[ 13/8 → 7/4 | s:hh speed:0.5 ]", + "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh speed:0.5 ]", + "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 5/2 → 21/8 | s:hh ]", + "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh speed:0.5 ]", - "[ 3/1 → 25/8 | s:hh speed:0.5 ]", - "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh ]", + "[ 3/1 → 25/8 | s:hh ]", + "[ 25/8 → 13/4 | s:hh ]", + "[ 13/4 → 27/8 | s:hh speed:0.5 ]", "[ 27/8 → 7/2 | s:hh ]", - "[ 7/2 → 29/8 | s:hh ]", + "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", + "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -10950,23 +11009,17 @@ exports[`runs examples > example "tri" example index 0 1`] = ` exports[`runs examples > example "undegrade" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", - "[ 7/8 → 1/1 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", - "[ 7/4 → 15/8 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", - "[ 25/8 → 13/4 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -10974,82 +11027,81 @@ exports[`runs examples > example "undegrade" example index 1 1`] = ` [ "[ 0/1 → 1/10 | s:hh pan:1 ]", "[ 1/10 → 1/5 | s:hh pan:1 ]", - "[ 1/5 → 3/10 | s:hh pan:0 ]", + "[ 1/5 → 3/10 | s:hh pan:1 ]", "[ 3/10 → 2/5 | s:hh pan:0 ]", - "[ 2/5 → 1/2 | s:hh pan:0 ]", + "[ 2/5 → 1/2 | s:hh pan:1 ]", "[ 1/2 → 3/5 | s:hh pan:1 ]", "[ 3/5 → 7/10 | s:hh pan:0 ]", "[ 7/10 → 4/5 | s:hh pan:0 ]", - "[ 4/5 → 9/10 | s:hh pan:1 ]", - "[ 9/10 → 1/1 | s:hh pan:0 ]", - "[ 1/1 → 11/10 | s:hh pan:0 ]", + "[ 4/5 → 9/10 | s:hh pan:0 ]", + "[ 9/10 → 1/1 | s:hh pan:1 ]", + "[ 1/1 → 11/10 | s:hh pan:1 ]", "[ 11/10 → 6/5 | s:hh pan:0 ]", - "[ 6/5 → 13/10 | s:hh pan:1 ]", + "[ 6/5 → 13/10 | s:hh pan:0 ]", "[ 13/10 → 7/5 | s:hh pan:1 ]", "[ 7/5 → 3/2 | s:hh pan:1 ]", - "[ 3/2 → 8/5 | s:hh pan:0 ]", - "[ 8/5 → 17/10 | s:hh pan:1 ]", - "[ 17/10 → 9/5 | s:hh pan:1 ]", + "[ 3/2 → 8/5 | s:hh pan:1 ]", + "[ 8/5 → 17/10 | s:hh pan:0 ]", + "[ 17/10 → 9/5 | s:hh pan:0 ]", "[ 9/5 → 19/10 | s:hh pan:1 ]", "[ 19/10 → 2/1 | s:hh pan:1 ]", "[ 2/1 → 21/10 | s:hh pan:0 ]", "[ 21/10 → 11/5 | s:hh pan:1 ]", "[ 11/5 → 23/10 | s:hh pan:0 ]", - "[ 23/10 → 12/5 | s:hh pan:0 ]", - "[ 12/5 → 5/2 | s:hh pan:0 ]", + "[ 23/10 → 12/5 | s:hh pan:1 ]", + "[ 12/5 → 5/2 | s:hh pan:1 ]", "[ 5/2 → 13/5 | s:hh pan:1 ]", - "[ 13/5 → 27/10 | s:hh pan:1 ]", + "[ 13/5 → 27/10 | s:hh pan:0 ]", "[ 27/10 → 14/5 | s:hh pan:1 ]", - "[ 14/5 → 29/10 | s:hh pan:0 ]", + "[ 14/5 → 29/10 | s:hh pan:1 ]", "[ 29/10 → 3/1 | s:hh pan:1 ]", "[ 3/1 → 31/10 | s:hh pan:1 ]", - "[ 31/10 → 16/5 | s:hh pan:1 ]", + "[ 31/10 → 16/5 | s:hh pan:0 ]", "[ 16/5 → 33/10 | s:hh pan:1 ]", "[ 33/10 → 17/5 | s:hh pan:0 ]", "[ 17/5 → 7/2 | s:hh pan:0 ]", "[ 7/2 → 18/5 | s:hh pan:1 ]", "[ 18/5 → 37/10 | s:hh pan:0 ]", - "[ 37/10 → 19/5 | s:hh pan:0 ]", - "[ 19/5 → 39/10 | s:hh pan:1 ]", - "[ 39/10 → 4/1 | s:hh pan:1 ]", + "[ 37/10 → 19/5 | s:hh pan:1 ]", + "[ 19/5 → 39/10 | s:hh pan:0 ]", + "[ 39/10 → 4/1 | s:hh pan:0 ]", ] `; exports[`runs examples > example "undegradeBy" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", - "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", - "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", - "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", + "[ 2/1 → 17/8 | s:hh ]", + "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh ]", + "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh ]", ] `; exports[`runs examples > example "undegradeBy" example index 1 1`] = ` [ - "[ 0/1 → 1/10 | s:hh pan:1 ]", - "[ 1/10 → 1/5 | s:hh pan:1 ]", + "[ 0/1 → 1/10 | s:hh pan:0 ]", + "[ 1/10 → 1/5 | s:hh pan:0 ]", "[ 1/5 → 3/10 | s:hh pan:0 ]", "[ 3/10 → 2/5 | s:hh pan:0 ]", "[ 2/5 → 1/2 | s:hh pan:0 ]", @@ -11058,35 +11110,35 @@ exports[`runs examples > example "undegradeBy" example index 1 1`] = ` "[ 7/10 → 4/5 | s:hh pan:0 ]", "[ 4/5 → 9/10 | s:hh pan:0 ]", "[ 9/10 → 1/1 | s:hh pan:0 ]", - "[ 1/1 → 11/10 | s:hh pan:0 ]", + "[ 1/1 → 11/10 | s:hh pan:1 ]", "[ 11/10 → 6/5 | s:hh pan:0 ]", "[ 6/5 → 13/10 | s:hh pan:0 ]", - "[ 13/10 → 7/5 | s:hh pan:0 ]", - "[ 7/5 → 3/2 | s:hh pan:0 ]", + "[ 13/10 → 7/5 | s:hh pan:1 ]", + "[ 7/5 → 3/2 | s:hh pan:1 ]", "[ 3/2 → 8/5 | s:hh pan:0 ]", "[ 8/5 → 17/10 | s:hh pan:0 ]", "[ 17/10 → 9/5 | s:hh pan:0 ]", "[ 9/5 → 19/10 | s:hh pan:0 ]", "[ 19/10 → 2/1 | s:hh pan:1 ]", "[ 2/1 → 21/10 | s:hh pan:0 ]", - "[ 21/10 → 11/5 | s:hh pan:0 ]", + "[ 21/10 → 11/5 | s:hh pan:1 ]", "[ 11/5 → 23/10 | s:hh pan:0 ]", - "[ 23/10 → 12/5 | s:hh pan:0 ]", + "[ 23/10 → 12/5 | s:hh pan:1 ]", "[ 12/5 → 5/2 | s:hh pan:0 ]", "[ 5/2 → 13/5 | s:hh pan:0 ]", "[ 13/5 → 27/10 | s:hh pan:0 ]", - "[ 27/10 → 14/5 | s:hh pan:0 ]", - "[ 14/5 → 29/10 | s:hh pan:0 ]", + "[ 27/10 → 14/5 | s:hh pan:1 ]", + "[ 14/5 → 29/10 | s:hh pan:1 ]", "[ 29/10 → 3/1 | s:hh pan:0 ]", "[ 3/1 → 31/10 | s:hh pan:0 ]", - "[ 31/10 → 16/5 | s:hh pan:1 ]", + "[ 31/10 → 16/5 | s:hh pan:0 ]", "[ 16/5 → 33/10 | s:hh pan:1 ]", "[ 33/10 → 17/5 | s:hh pan:0 ]", "[ 17/5 → 7/2 | s:hh pan:0 ]", "[ 7/2 → 18/5 | s:hh pan:0 ]", "[ 18/5 → 37/10 | s:hh pan:0 ]", - "[ 37/10 → 19/5 | s:hh pan:0 ]", - "[ 19/5 → 39/10 | s:hh pan:1 ]", + "[ 37/10 → 19/5 | s:hh pan:1 ]", + "[ 19/5 → 39/10 | s:hh pan:0 ]", "[ 39/10 → 4/1 | s:hh pan:0 ]", ] `; @@ -11165,6 +11217,75 @@ exports[`runs examples > example "unit" example index 0 1`] = ` ] `; +exports[`runs examples > example "useOldRandom" example index 0 1`] = ` +[ + "[ 0/1 → 1/16 | note:D8 ]", + "[ 1/16 → 1/8 | note:Bb7 ]", + "[ 1/8 → 3/16 | note:Ab6 ]", + "[ 3/16 → 1/4 | note:D5 ]", + "[ 1/4 → 5/16 | note:Ab9 ]", + "[ 5/16 → 3/8 | note:D3 ]", + "[ 3/8 → 7/16 | note:G5 ]", + "[ 7/16 → 1/2 | note:G3 ]", + "[ 1/2 → 9/16 | note:Ab3 ]", + "[ 9/16 → 5/8 | note:Eb6 ]", + "[ 5/8 → 11/16 | note:Eb6 ]", + "[ 11/16 → 3/4 | note:Eb5 ]", + "[ 3/4 → 13/16 | note:G7 ]", + "[ 13/16 → 7/8 | note:Bb5 ]", + "[ 7/8 → 15/16 | note:D3 ]", + "[ 15/16 → 1/1 | note:Eb7 ]", + "[ 1/1 → 17/16 | note:Eb9 ]", + "[ 17/16 → 9/8 | note:G8 ]", + "[ 9/8 → 19/16 | note:Ab3 ]", + "[ 19/16 → 5/4 | note:Ab5 ]", + "[ 5/4 → 21/16 | note:C10 ]", + "[ 21/16 → 11/8 | note:C7 ]", + "[ 11/8 → 23/16 | note:G5 ]", + "[ 23/16 → 3/2 | note:Ab7 ]", + "[ 3/2 → 25/16 | note:G6 ]", + "[ 25/16 → 13/8 | note:Bb6 ]", + "[ 13/8 → 27/16 | note:Eb9 ]", + "[ 27/16 → 7/4 | note:G9 ]", + "[ 7/4 → 29/16 | note:G7 ]", + "[ 29/16 → 15/8 | note:C10 ]", + "[ 15/8 → 31/16 | note:Eb3 ]", + "[ 31/16 → 2/1 | note:Ab7 ]", + "[ 2/1 → 33/16 | note:F6 ]", + "[ 33/16 → 17/8 | note:C5 ]", + "[ 17/8 → 35/16 | note:Ab4 ]", + "[ 35/16 → 9/4 | note:G5 ]", + "[ 9/4 → 37/16 | note:C9 ]", + "[ 37/16 → 19/8 | note:Eb6 ]", + "[ 19/8 → 39/16 | note:C9 ]", + "[ 39/16 → 5/2 | note:Eb9 ]", + "[ 5/2 → 41/16 | note:D5 ]", + "[ 41/16 → 21/8 | note:F5 ]", + "[ 21/8 → 43/16 | note:F9 ]", + "[ 43/16 → 11/4 | note:Bb7 ]", + "[ 11/4 → 45/16 | note:Ab6 ]", + "[ 45/16 → 23/8 | note:Bb9 ]", + "[ 23/8 → 47/16 | note:C8 ]", + "[ 47/16 → 3/1 | note:Eb5 ]", + "[ 3/1 → 49/16 | note:F3 ]", + "[ 49/16 → 25/8 | note:G4 ]", + "[ 25/8 → 51/16 | note:D7 ]", + "[ 51/16 → 13/4 | note:D4 ]", + "[ 13/4 → 53/16 | note:F8 ]", + "[ 53/16 → 27/8 | note:C7 ]", + "[ 27/8 → 55/16 | note:Ab5 ]", + "[ 55/16 → 7/2 | note:Ab3 ]", + "[ 7/2 → 57/16 | note:F9 ]", + "[ 57/16 → 29/8 | note:D8 ]", + "[ 29/8 → 59/16 | note:F5 ]", + "[ 59/16 → 15/4 | note:Eb9 ]", + "[ 15/4 → 61/16 | note:Bb4 ]", + "[ 61/16 → 31/8 | note:C6 ]", + "[ 31/8 → 63/16 | note:C4 ]", + "[ 63/16 → 4/1 | note:G8 ]", +] +`; + exports[`runs examples > example "velocity" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh gain:0.4 velocity:0.4 ]", @@ -11323,38 +11444,38 @@ exports[`runs examples > example "vowel" example index 0 1`] = ` exports[`runs examples > example "vowel" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | s:bd vowel:a ]", - "[ 1/8 → 1/4 | s:sd vowel:a ]", - "[ 1/4 → 3/8 | s:mt vowel:a ]", - "[ 3/8 → 1/2 | s:ht vowel:a ]", - "[ 1/2 → 5/8 | s:bd vowel:a ]", - "[ 11/16 → 3/4 | s:cp vowel:a ]", - "[ 3/4 → 7/8 | s:ht vowel:a ]", - "[ 7/8 → 1/1 | s:lt vowel:a ]", - "[ 1/1 → 9/8 | s:bd vowel:i ]", - "[ 9/8 → 5/4 | s:sd vowel:i ]", - "[ 5/4 → 11/8 | s:mt vowel:i ]", - "[ 11/8 → 3/2 | s:ht vowel:i ]", - "[ 3/2 → 13/8 | s:bd vowel:i ]", - "[ 27/16 → 7/4 | s:cp vowel:i ]", - "[ 7/4 → 15/8 | s:ht vowel:i ]", - "[ 15/8 → 2/1 | s:lt vowel:i ]", - "[ 2/1 → 17/8 | s:bd vowel:u ]", - "[ 17/8 → 9/4 | s:sd vowel:u ]", - "[ 9/4 → 19/8 | s:mt vowel:u ]", - "[ 19/8 → 5/2 | s:ht vowel:u ]", - "[ 5/2 → 21/8 | s:bd vowel:u ]", - "[ 43/16 → 11/4 | s:cp vowel:u ]", - "[ 11/4 → 23/8 | s:ht vowel:u ]", - "[ 23/8 → 3/1 | s:lt vowel:u ]", - "[ 3/1 → 25/8 | s:bd vowel:e ]", - "[ 25/8 → 13/4 | s:sd vowel:e ]", - "[ 13/4 → 27/8 | s:mt vowel:e ]", - "[ 27/8 → 7/2 | s:ht vowel:e ]", - "[ 7/2 → 29/8 | s:bd vowel:e ]", - "[ 59/16 → 15/4 | s:cp vowel:e ]", - "[ 15/4 → 31/8 | s:ht vowel:e ]", - "[ 31/8 → 4/1 | s:lt vowel:e ]", + "[ 0/1 → 1/8 | s:bd vowel:i ]", + "[ 1/8 → 1/4 | s:sd vowel:i ]", + "[ 1/4 → 3/8 | s:mt vowel:i ]", + "[ 3/8 → 1/2 | s:ht vowel:i ]", + "[ 1/2 → 5/8 | s:bd vowel:i ]", + "[ 11/16 → 3/4 | s:cp vowel:i ]", + "[ 3/4 → 7/8 | s:ht vowel:i ]", + "[ 7/8 → 1/1 | s:lt vowel:i ]", + "[ 1/1 → 9/8 | s:bd vowel:a ]", + "[ 9/8 → 5/4 | s:sd vowel:a ]", + "[ 5/4 → 11/8 | s:mt vowel:a ]", + "[ 11/8 → 3/2 | s:ht vowel:a ]", + "[ 3/2 → 13/8 | s:bd vowel:a ]", + "[ 27/16 → 7/4 | s:cp vowel:a ]", + "[ 7/4 → 15/8 | s:ht vowel:a ]", + "[ 15/8 → 2/1 | s:lt vowel:a ]", + "[ 2/1 → 17/8 | s:bd vowel:i ]", + "[ 17/8 → 9/4 | s:sd vowel:i ]", + "[ 9/4 → 19/8 | s:mt vowel:i ]", + "[ 19/8 → 5/2 | s:ht vowel:i ]", + "[ 5/2 → 21/8 | s:bd vowel:i ]", + "[ 43/16 → 11/4 | s:cp vowel:i ]", + "[ 11/4 → 23/8 | s:ht vowel:i ]", + "[ 23/8 → 3/1 | s:lt vowel:i ]", + "[ 3/1 → 25/8 | s:bd vowel:i ]", + "[ 25/8 → 13/4 | s:sd vowel:i ]", + "[ 13/4 → 27/8 | s:mt vowel:i ]", + "[ 27/8 → 7/2 | s:ht vowel:i ]", + "[ 7/2 → 29/8 | s:bd vowel:i ]", + "[ 59/16 → 15/4 | s:cp vowel:i ]", + "[ 15/4 → 31/8 | s:ht vowel:i ]", + "[ 31/8 → 4/1 | s:lt vowel:i ]", ] `; @@ -11363,21 +11484,21 @@ exports[`runs examples > example "wchoose" example index 0 1`] = ` "[ 0/1 → 1/5 | note:c2 s:sine ]", "[ 1/5 → 2/5 | note:g2 s:sine ]", "[ 2/5 → 3/5 | note:g2 s:sine ]", - "[ 3/5 → 4/5 | note:d2 s:sine ]", - "[ 4/5 → 1/1 | note:f1 s:sine ]", + "[ 3/5 → 4/5 | note:d2 s:bd n:6 ]", + "[ 4/5 → 1/1 | note:f1 s:bd n:6 ]", "[ 1/1 → 6/5 | note:c2 s:sine ]", "[ 6/5 → 7/5 | note:g2 s:sine ]", "[ 7/5 → 8/5 | note:g2 s:sine ]", "[ 8/5 → 9/5 | note:d2 s:sine ]", "[ 9/5 → 2/1 | note:f1 s:sine ]", - "[ 2/1 → 11/5 | note:c2 s:bd n:6 ]", - "[ 11/5 → 12/5 | note:g2 s:sine ]", - "[ 12/5 → 13/5 | note:g2 s:bd n:6 ]", + "[ 2/1 → 11/5 | note:c2 s:sine ]", + "[ 11/5 → 12/5 | note:g2 s:triangle ]", + "[ 12/5 → 13/5 | note:g2 s:sine ]", "[ 13/5 → 14/5 | note:d2 s:sine ]", "[ 14/5 → 3/1 | note:f1 s:sine ]", "[ 3/1 → 16/5 | note:c2 s:sine ]", "[ 16/5 → 17/5 | note:g2 s:sine ]", - "[ 17/5 → 18/5 | note:g2 s:sine ]", + "[ 17/5 → 18/5 | note:g2 s:triangle ]", "[ 18/5 → 19/5 | note:d2 s:sine ]", "[ 19/5 → 4/1 | note:f1 s:sine ]", ] @@ -11387,29 +11508,29 @@ exports[`runs examples > example "wchooseCycles" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:bd ]", "[ 1/8 → 1/4 | s:bd ]", - "[ 1/4 → 3/8 | s:sd ]", + "[ 1/4 → 3/8 | s:bd ]", "[ 3/8 → 1/2 | s:bd ]", "[ 1/2 → 5/8 | s:bd ]", "[ 5/8 → 3/4 | s:bd ]", - "[ 3/4 → 7/8 | s:bd ]", + "[ 3/4 → 7/8 | s:sd ]", "[ 7/8 → 1/1 | s:bd ]", - "[ 1/1 → 9/8 | s:hh ]", - "[ 9/8 → 5/4 | s:bd ]", + "[ 1/1 → 9/8 | s:bd ]", + "[ 9/8 → 5/4 | s:sd ]", "[ 5/4 → 11/8 | s:bd ]", "[ 11/8 → 3/2 | s:bd ]", "[ 3/2 → 13/8 | s:bd ]", - "[ 13/8 → 7/4 | s:sd ]", - "[ 7/4 → 15/8 | s:bd ]", + "[ 13/8 → 7/4 | s:bd ]", + "[ 7/4 → 15/8 | s:sd ]", "[ 15/8 → 2/1 | s:bd ]", "[ 2/1 → 17/8 | s:bd ]", - "[ 17/8 → 9/4 | s:bd ]", + "[ 17/8 → 9/4 | s:sd ]", "[ 9/4 → 19/8 | s:bd ]", "[ 19/8 → 5/2 | s:bd ]", "[ 5/2 → 21/8 | s:bd ]", "[ 21/8 → 11/4 | s:bd ]", - "[ 11/4 → 23/8 | s:sd ]", + "[ 11/4 → 23/8 | s:bd ]", "[ 23/8 → 3/1 | s:bd ]", - "[ 3/1 → 25/8 | s:bd ]", + "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:bd ]", "[ 13/4 → 27/8 | s:bd ]", "[ 27/8 → 7/2 | s:bd ]", @@ -11428,9 +11549,9 @@ exports[`runs examples > example "wchooseCycles" example index 1 1`] = ` "[ 1/4 → 1/3 | s:bd ]", "[ 1/3 → 5/12 | s:bd ]", "[ 5/12 → 1/2 | s:bd ]", - "[ 1/2 → 7/12 | s:sd ]", - "[ 7/12 → 2/3 | s:sd ]", - "[ 2/3 → 3/4 | s:sd ]", + "[ 1/2 → 7/12 | s:bd ]", + "[ 7/12 → 2/3 | s:bd ]", + "[ 2/3 → 3/4 | s:bd ]", "[ 3/4 → 5/6 | s:bd ]", "[ 5/6 → 11/12 | s:bd ]", "[ 11/12 → 1/1 | s:bd ]", @@ -11440,36 +11561,36 @@ exports[`runs examples > example "wchooseCycles" example index 1 1`] = ` "[ 5/4 → 4/3 | s:bd ]", "[ 4/3 → 17/12 | s:bd ]", "[ 17/12 → 3/2 | s:bd ]", - "[ 3/2 → 19/12 | s:hh ]", - "[ 19/12 → 5/3 | s:hh ]", - "[ 5/3 → 7/4 | s:hh ]", + "[ 3/2 → 19/12 | s:sd ]", + "[ 19/12 → 5/3 | s:sd ]", + "[ 5/3 → 7/4 | s:sd ]", "[ 7/4 → 11/6 | s:bd ]", "[ 11/6 → 23/12 | s:bd ]", "[ 23/12 → 2/1 | s:bd ]", "[ 2/1 → 25/12 | s:hh ]", "[ 25/12 → 13/6 | s:hh ]", "[ 13/6 → 9/4 | s:hh ]", - "[ 9/4 → 7/3 | s:hh ]", - "[ 7/3 → 29/12 | s:hh ]", - "[ 29/12 → 5/2 | s:hh ]", - "[ 5/2 → 31/12 | s:bd ]", - "[ 31/12 → 8/3 | s:bd ]", - "[ 8/3 → 11/4 | s:bd ]", + "[ 9/4 → 7/3 | s:sd ]", + "[ 7/3 → 29/12 | s:sd ]", + "[ 29/12 → 5/2 | s:sd ]", + "[ 5/2 → 31/12 | s:hh ]", + "[ 31/12 → 8/3 | s:hh ]", + "[ 8/3 → 11/4 | s:hh ]", "[ 11/4 → 17/6 | s:bd ]", "[ 17/6 → 35/12 | s:bd ]", "[ 35/12 → 3/1 | s:bd ]", "[ 3/1 → 37/12 | s:bd ]", "[ 37/12 → 19/6 | s:bd ]", "[ 19/6 → 13/4 | s:bd ]", - "[ 13/4 → 10/3 | s:sd ]", - "[ 10/3 → 41/12 | s:sd ]", - "[ 41/12 → 7/2 | s:sd ]", - "[ 7/2 → 43/12 | s:hh ]", - "[ 43/12 → 11/3 | s:hh ]", - "[ 11/3 → 15/4 | s:hh ]", - "[ 15/4 → 23/6 | s:bd ]", - "[ 23/6 → 47/12 | s:bd ]", - "[ 47/12 → 4/1 | s:bd ]", + "[ 13/4 → 10/3 | s:bd ]", + "[ 10/3 → 41/12 | s:bd ]", + "[ 41/12 → 7/2 | s:bd ]", + "[ 7/2 → 43/12 | s:sd ]", + "[ 43/12 → 11/3 | s:sd ]", + "[ 11/3 → 15/4 | s:sd ]", + "[ 15/4 → 23/6 | s:hh ]", + "[ 23/6 → 47/12 | s:hh ]", + "[ 47/12 → 4/1 | s:hh ]", ] `; @@ -11481,9 +11602,9 @@ exports[`runs examples > example "wchooseCycles" example index 2 1`] = ` "[ 1/4 → 1/3 | s:hh ]", "[ 1/3 → 5/12 | s:hh ]", "[ 5/12 → 1/2 | s:hh ]", - "[ 1/2 → 7/12 | s:hh ]", - "[ 7/12 → 2/3 | s:hh ]", - "[ 2/3 → 3/4 | s:hh ]", + "[ 1/2 → 17/32 | s:bd ]", + "[ 19/32 → 5/8 | s:bd ]", + "[ 11/16 → 23/32 | s:bd ]", "[ 3/4 → 5/6 | s:hh ]", "[ 5/6 → 11/12 | s:hh ]", "[ 11/12 → 1/1 | s:hh ]", @@ -11493,9 +11614,9 @@ exports[`runs examples > example "wchooseCycles" example index 2 1`] = ` "[ 5/4 → 4/3 | s:hh ]", "[ 4/3 → 17/12 | s:hh ]", "[ 17/12 → 3/2 | s:hh ]", - "[ 3/2 → 49/32 | s:bd ]", - "[ 51/32 → 13/8 | s:bd ]", - "[ 27/16 → 55/32 | s:bd ]", + "[ 3/2 → 19/12 | s:hh ]", + "[ 19/12 → 5/3 | s:hh ]", + "[ 5/3 → 7/4 | s:hh ]", "[ 7/4 → 11/6 | s:hh ]", "[ 11/6 → 23/12 | s:hh ]", "[ 23/12 → 2/1 | s:hh ]", @@ -11505,9 +11626,9 @@ exports[`runs examples > example "wchooseCycles" example index 2 1`] = ` "[ 9/4 → 7/3 | s:hh ]", "[ 7/3 → 29/12 | s:hh ]", "[ 29/12 → 5/2 | s:hh ]", - "[ 5/2 → 81/32 | s:bd ]", - "[ 83/32 → 21/8 | s:bd ]", - "[ 43/16 → 87/32 | s:bd ]", + "[ 5/2 → 31/12 | s:hh ]", + "[ 31/12 → 8/3 | s:hh ]", + "[ 8/3 → 11/4 | s:hh ]", "[ 11/4 → 17/6 | s:hh ]", "[ 17/6 → 35/12 | s:hh ]", "[ 35/12 → 3/1 | s:hh ]", From b3e433291cb911542f5e3e3b48fb4d42222d5b7d Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 24 Aug 2025 21:15:47 -0500 Subject: [PATCH 07/66] Turn back on silent --- vitest.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vitest.config.mjs b/vitest.config.mjs index 392b17310..47f624771 100644 --- a/vitest.config.mjs +++ b/vitest.config.mjs @@ -7,7 +7,7 @@ export default defineConfig({ test: { reporters: 'verbose', isolate: false, - silent: false, + silent: true, exclude: [ '**/node_modules/**', '**/dist/**', From 0fbde61b2dd4bb2f2c3bdf2b451d05bfa73264e4 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 19 Oct 2025 14:35:23 +0300 Subject: [PATCH 08/66] WIP non-realtime exporting --- packages/codemirror/codemirror.mjs | 10 +- packages/core/cyclist.mjs | 13 ++ packages/core/repl.mjs | 31 ++-- packages/superdough/audioContext.mjs | 5 + packages/superdough/feedbackdelay.mjs | 2 +- packages/superdough/reverb.mjs | 4 +- packages/superdough/superdough.mjs | 12 +- packages/superdough/vowel.mjs | 2 +- packages/webaudio/webaudio.mjs | 151 +++++++++++++++++- website/src/repl/components/Header.jsx | 12 +- .../src/repl/components/panel/SettingsTab.jsx | 2 +- website/src/repl/useReplContext.jsx | 4 + 12 files changed, 217 insertions(+), 31 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 4dc23996f..645a8a190 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -42,9 +42,9 @@ const extensions = { isMultiCursorEnabled: (on) => on ? [ - EditorState.allowMultipleSelections.of(true), - EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), - ] + EditorState.allowMultipleSelections.of(true), + EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), + ] : [], }; const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); @@ -268,6 +268,10 @@ export class StrudelMirror { this.flash(); await this.repl.evaluate(this.code); } + async exportAudio(begin, end) { + // await this.repl.evaluate(this.code, false) + this.repl.exportAudio(begin, end); + } async stop() { this.repl.scheduler.stop(); } diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index 59e410c53..b7ab7dde4 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -6,6 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import createClock from './zyklus.mjs'; import { errorLogger, logger } from './logger.mjs'; +import { loadBuffer, renderPatternAudio, setAudioContext, superdough } from '@strudel/webaudio'; export class Cyclist { constructor({ @@ -98,6 +99,7 @@ export class Cyclist { this.started = v; this.onToggle?.(v); } + async start() { await this.beforeStart?.(); this.num_ticks_since_cps_change = 0; @@ -109,6 +111,17 @@ export class Cyclist { this.clock.start(); this.setStarted(true); } + + async exportAudio(begin, end) { + if (!this.pattern) { + throw new Error('Scheduler: no pattern set! call .setPattern first.'); + } + logger('[cyclist] exporting'); + // this.clock.start(); + // this.setStarted(true); + await renderPatternAudio(this.pattern, this.cps, begin, end) + } + pause() { logger('[cyclist] pause'); this.clock.pause(); diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 171697eb9..d0cb1e19f 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -91,6 +91,7 @@ export function repl({ const stop = () => scheduler.stop(); const start = () => scheduler.start(); + const exportAudio = (begin, end) => scheduler.exportAudio(begin, end); const pause = () => scheduler.pause(); const toggle = () => scheduler.toggle(); const setCps = (cps) => { @@ -257,23 +258,23 @@ export function repl({ } }; const setCode = (code) => updateState({ code }); - return { scheduler, evaluate, start, stop, pause, setCps, setPattern, setCode, toggle, state }; + return { scheduler, evaluate, start, exportAudio, stop, pause, setCps, setPattern, setCode, toggle, state }; } export const getTrigger = ({ getTime, defaultOutput }) => - async (hap, deadline, duration, cps, t) => { - // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) - // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 - try { - if (!hap.context.onTrigger || !hap.context.dominantTrigger) { - await defaultOutput(hap, deadline, duration, cps, t); + async (hap, deadline, duration, cps, t) => { + // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) + // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 + try { + if (!hap.context.onTrigger || !hap.context.dominantTrigger) { + await defaultOutput(hap, deadline, duration, cps, t); + } + if (hap.context.onTrigger) { + // call signature of output / onTrigger is different... + await hap.context.onTrigger(hap, getTime(), cps, t); + } + } catch (err) { + errorLogger(err, 'getTrigger'); } - if (hap.context.onTrigger) { - // call signature of output / onTrigger is different... - await hap.context.onTrigger(hap, getTime(), cps, t); - } - } catch (err) { - errorLogger(err, 'getTrigger'); - } - }; + }; diff --git a/packages/superdough/audioContext.mjs b/packages/superdough/audioContext.mjs index 71e01d57d..30fbd9fd0 100644 --- a/packages/superdough/audioContext.mjs +++ b/packages/superdough/audioContext.mjs @@ -5,6 +5,11 @@ export const setDefaultAudioContext = () => { return audioContext; }; +export const setAudioContext = (context) => { + audioContext = context + return audioContext; +}; + export const getAudioContext = () => { if (!audioContext) { return setDefaultAudioContext(); diff --git a/packages/superdough/feedbackdelay.mjs b/packages/superdough/feedbackdelay.mjs index c182d6558..b8269bc02 100644 --- a/packages/superdough/feedbackdelay.mjs +++ b/packages/superdough/feedbackdelay.mjs @@ -25,7 +25,7 @@ if (typeof DelayNode !== 'undefined') { } } - AudioContext.prototype.createFeedbackDelay = function (wet, time, feedback) { + BaseAudioContext.prototype.createFeedbackDelay = function (wet, time, feedback) { return new FeedbackDelayNode(this, wet, time, feedback); }; } diff --git a/packages/superdough/reverb.mjs b/packages/superdough/reverb.mjs index 2960b597c..c8b6eb3e5 100644 --- a/packages/superdough/reverb.mjs +++ b/packages/superdough/reverb.mjs @@ -2,7 +2,7 @@ import reverbGen from './reverbGen.mjs'; import { clamp } from './util.mjs'; if (typeof AudioContext !== 'undefined') { - AudioContext.prototype.adjustLength = function (duration, buffer, speed = 1, offsetAmount = 0) { + BaseAudioContext.prototype.adjustLength = function (duration, buffer, speed = 1, offsetAmount = 0) { const sampleOffset = Math.floor(clamp(offsetAmount, 0, 1) * buffer.length); const newLength = buffer.sampleRate * duration; const newBuffer = this.createBuffer(buffer.numberOfChannels, buffer.length, buffer.sampleRate); @@ -23,7 +23,7 @@ if (typeof AudioContext !== 'undefined') { return newBuffer; }; - AudioContext.prototype.createReverb = function (duration, fade, lp, dim, ir, irspeed, irbegin) { + BaseAudioContext.prototype.createReverb = function (duration, fade, lp, dim, ir, irspeed, irbegin) { const convolver = this.createConvolver(); convolver.generate = (d = 2, fade = 0.1, lp = 15000, dim = 1000, ir, irspeed, irbegin) => { convolver.duration = d; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index a37504b1d..80205a298 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -13,7 +13,7 @@ import { createFilter, gainNode, getCompressor, getDistortion, getLfo, getWorkle import { map } from 'nanostores'; import { logger } from './logger.mjs'; import { loadBuffer } from './sampler.mjs'; -import { getAudioContext } from './audioContext.mjs'; +import { getAudioContext, setAudioContext } from './audioContext.mjs'; import { SuperdoughAudioController } from './superdoughoutput.mjs'; export const DEFAULT_MAX_POLYPHONY = 128; @@ -367,6 +367,7 @@ function mapChannelNumbers(channels) { } export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) => { + controller = null; // new: t is always expected to be the absolute target onset time const ac = getAudioContext(); const audioController = getSuperdoughAudioController(); @@ -387,14 +388,13 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // duration is passed as value too.. value.duration = hapDuration; // calculate absolute time - - if (t < ac.currentTime) { + if (t < ac.currentTime && !(ac instanceof OfflineAudioContext)) { console.warn( `[superdough]: cannot schedule sounds in the past (target: ${t.toFixed(2)}, now: ${ac.currentTime.toFixed(2)})`, ); return; - } - // destructure + } // FIXME: fix + // destructure let { tremolo, tremolosync, @@ -736,4 +736,4 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) export const superdoughTrigger = (t, hap, ct, cps) => { superdough(hap, t - ct, hap.duration / cps, cps); -}; +}; \ No newline at end of file diff --git a/packages/superdough/vowel.mjs b/packages/superdough/vowel.mjs index 3f30aef1e..025677fc1 100644 --- a/packages/superdough/vowel.mjs +++ b/packages/superdough/vowel.mjs @@ -63,7 +63,7 @@ if (typeof GainNode !== 'undefined') { } } - AudioContext.prototype.createVowelFilter = function (letter) { + BaseAudioContext.prototype.createVowelFilter = function (letter) { return new VowelNode(this, letter); }; } diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 383e87f87..46bef88d6 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel/core'; -import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet } from 'superdough'; +import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet, setAudioContext, getSampleBufferSource, loadBuffer, getSampleInfo, getSound } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -26,6 +26,60 @@ export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => { return superdough(hap2value(hap), t, hapDuration, cps, hap.whole?.begin.valueOf()); }; +export async function renderPatternAudio(pattern, cps, begin, end) { + let audioContext = new OfflineAudioContext(2, (end - begin) / cps * 48000, 48000); + setAudioContext(audioContext) + logger('[webaudio] start rendering'); + console.log(audioContext) + + let haps = pattern.queryArc(begin, end, { _cps: cps }) + Promise.all(haps.map(async h => { + let s; + if (h.value.s) { + if (h.value.bank) { + s = `${h.value.bank}_${h.value.s}`; + } + else { + s = h.value.s + } + } + let bank = getSound(s).data.samples + if (bank) { + let { url: sampleUrl, label } = getSampleInfo(h.value, bank); + await loadBuffer(sampleUrl, audioContext, label) + } + })) + haps.forEach(async (hap) => { + if (hap.hasOnset()) { + hap.ensureObjectValue(); + await superdough(hap.value, hap.whole.begin.valueOf() / cps, hap.duration, cps, hap.whole?.begin.valueOf()); + } + }) + + let context = getAudioContext() + context.startRendering().then((renderedBuffer) => { + // console.log(renderedBuffer) + const wavBuffer = audioBufferToWav(renderedBuffer); + const blob = new Blob([wavBuffer], { type: 'audio/wav' }); + let downloadName = '' + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + // remove leading dash if they want an empty download name + if (downloadName == '') { + downloadName = `${new Date().toISOString()}.wav`; + } else { + downloadName = downloadName + `-${new Date().toISOString()}.wav`; + } + a.download = `${downloadName}`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + setAudioContext(null) + }); +} + export function webaudioRepl(options = {}) { options = { getTime: () => getAudioContext().currentTime, @@ -38,3 +92,98 @@ export function webaudioRepl(options = {}) { Pattern.prototype.dough = function () { return this.onTrigger(doughTrigger, 1); }; + + +function audioBufferToWav(buffer, opt) { + opt = opt || {} + + var numChannels = buffer.numberOfChannels + var sampleRate = buffer.sampleRate + var format = opt.float32 ? 3 : 1 + var bitDepth = format === 3 ? 32 : 16 + + var result + if (numChannels === 2) { + result = interleave(buffer.getChannelData(0), buffer.getChannelData(1)) + } else { + result = buffer.getChannelData(0) + } + + return encodeWAV(result, format, sampleRate, numChannels, bitDepth) +} + +function encodeWAV(samples, format, sampleRate, numChannels, bitDepth) { + var bytesPerSample = bitDepth / 8 + var blockAlign = numChannels * bytesPerSample + + var buffer = new ArrayBuffer(44 + samples.length * bytesPerSample) + var view = new DataView(buffer) + + /* RIFF identifier */ + writeString(view, 0, 'RIFF') + /* RIFF chunk length */ + view.setUint32(4, 36 + samples.length * bytesPerSample, true) + /* RIFF type */ + writeString(view, 8, 'WAVE') + /* format chunk identifier */ + writeString(view, 12, 'fmt ') + /* format chunk length */ + view.setUint32(16, 16, true) + /* sample format (raw) */ + view.setUint16(20, format, true) + /* channel count */ + view.setUint16(22, numChannels, true) + /* sample rate */ + view.setUint32(24, sampleRate, true) + /* byte rate (sample rate * block align) */ + view.setUint32(28, sampleRate * blockAlign, true) + /* block align (channel count * bytes per sample) */ + view.setUint16(32, blockAlign, true) + /* bits per sample */ + view.setUint16(34, bitDepth, true) + /* data chunk identifier */ + writeString(view, 36, 'data') + /* data chunk length */ + view.setUint32(40, samples.length * bytesPerSample, true) + if (format === 1) { // Raw PCM + floatTo16BitPCM(view, 44, samples) + } else { + writeFloat32(view, 44, samples) + } + + return buffer +} + +function interleave(inputL, inputR) { + var length = inputL.length + inputR.length + var result = new Float32Array(length) + + var index = 0 + var inputIndex = 0 + + while (index < length) { + result[index++] = inputL[inputIndex] + result[index++] = inputR[inputIndex] + inputIndex++ + } + return result +} + +function writeFloat32(output, offset, input) { + for (var i = 0; i < input.length; i++, offset += 4) { + output.setFloat32(offset, input[i], true) + } +} + +function floatTo16BitPCM(output, offset, input) { + for (var i = 0; i < input.length; i++, offset += 2) { + var s = Math.max(-1, Math.min(1, input[i])) + output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true) + } +} + +function writeString(view, offset, string) { + for (var i = 0; i < string.length; i++) { + view.setUint8(offset + i, string.charCodeAt(i)) + } +} \ No newline at end of file diff --git a/website/src/repl/components/Header.jsx b/website/src/repl/components/Header.jsx index ca4e1ecf9..656aa7861 100644 --- a/website/src/repl/components/Header.jsx +++ b/website/src/repl/components/Header.jsx @@ -8,7 +8,7 @@ const { BASE_URL } = import.meta.env; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; export function Header({ context, embedded = false }) { - const { started, pending, isDirty, activeCode, handleTogglePlay, handleEvaluate, handleShuffle, handleShare } = + const { started, pending, isDirty, activeCode, handleTogglePlay, handleEvaluate, handleShuffle, handleShare, handleExport } = context; const isEmbedded = typeof window !== 'undefined' && (embedded || window.location !== window.parent.location); const { isZen, isButtonRowHidden, isCSSAnimationDisabled, fontFamily } = useSettings(); @@ -93,6 +93,16 @@ export function Header({ context, embedded = false }) { > {!isEmbedded && update} + {/* !isEmbedded && ( + + +
+

Start cycle

+ { + let v = parseInt(e.target.value); + console.log(v) + v = isNaN(v) ? 0 : Math.max(1, v); + setStartCycle(v); + }} + onChange={v => { + v = parseInt(v) + setStartCycle(v); + }} + type="number" + placeholder="" + value={startCycle ?? ''} + /> +
+
+

End cycle

+ { + let v = parseInt(e.target.value); + v = isNaN(v) ? Math.max(startCycle + 1, parseInt(v)) : v; + setEndCycle(v); + }} + onChange={(v) => { + v = parseInt(v) + setEndCycle(v); + }} + type="number" + placeholder="" + value={endCycle ?? ''} + /> +
+
+

Maximum polyphony

+ { + let v = parseInt(e.target.value); + v = isNaN(v) ? Math.max(1, parseInt(v)) : v; + setMaxPolyphony(v); + }} + onChange={(v) => { + v = Math.max(1, parseInt(v)); + setMaxPolyphony(v); + }} + type="number" + placeholder="" + value={maxPolyphony ?? ''} + /> +
+
+ { + const val = cbEvent.target.checked; + setMultiChannelOrbits(val) + }} + value={multiChannelOrbits} + /> +
+ +
+ + ); +} diff --git a/website/src/repl/components/Header.jsx b/website/src/repl/components/Header.jsx index 91e942d39..d5d8b5f75 100644 --- a/website/src/repl/components/Header.jsx +++ b/website/src/repl/components/Header.jsx @@ -3,6 +3,7 @@ import StopCircleIcon from '@heroicons/react/20/solid/StopCircleIcon'; import cx from '@src/cx.mjs'; import { useSettings, setIsZen } from '../../settings.mjs'; import '../Repl.css'; +import ExportModal from './ExportModal'; const { BASE_URL } = import.meta.env; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; @@ -93,18 +94,7 @@ export function Header({ context, embedded = false }) { > {!isEmbedded && update} - + {/* !isEmbedded && ( - - -
-

Start cycle

- { - let v = parseInt(e.target.value); - console.log(v) - v = isNaN(v) ? 0 : Math.max(0, v); - setStartCycle(v); - }} - onChange={v => { - v = parseInt(v) - setStartCycle(v); - }} - type="number" - placeholder="" - value={startCycle ?? ''} - /> -
-
-

End cycle

- { - let v = parseInt(e.target.value); - v = isNaN(v) ? Math.max(startCycle + 1, parseInt(v)) : v; - setEndCycle(v); - }} - onChange={(v) => { - v = parseInt(v) - setEndCycle(v); - }} - type="number" - placeholder="" - value={endCycle ?? ''} - /> -
-
-

Maximum polyphony

- { - let v = parseInt(e.target.value); - v = isNaN(v) ? Math.max(1, parseInt(v)) : v; - setMaxPolyphony(v); - }} - onChange={(v) => { - v = Math.max(1, parseInt(v)); - setMaxPolyphony(v); - }} - type="number" - placeholder="" - value={maxPolyphony ?? ''} - /> -
-
- { - const val = cbEvent.target.checked; - setMultiChannelOrbits(val) - }} - value={multiChannelOrbits} - /> -
- + }} + className={cx( + 'absolute text-foreground max-h-8 min-h-8 max-w-8 min-w-8 items-center p-1.5 right-2 top-2 z-50', + exporting && "opacity-50" + )} + aria-label="Close Modal" + > + + +
+ + { + setDownloadName(e.target.value) + }} + onChange={v => { + setDownloadName(v) + }} + disabled={exporting} + placeholder="Leave empty to use current date" + className={cx("placeholder:opacity-50", exporting && "opacity-50 border-opacity-50")} + value={downloadName ?? ''} + /> + +
+ + { + let v = parseInt(e.target.value); + v = isNaN(v) ? 0 : Math.max(0, v); + setStartCycle(v); + }} + onChange={v => { + v = parseInt(v) + setStartCycle(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && "opacity-50 border-opacity-50")} + value={startCycle ?? ''} + /> + + + { + let v = parseInt(e.target.value); + v = isNaN(v) ? Math.max(startCycle + 1, parseInt(v)) : v; + setEndCycle(v); + }} + onChange={(v) => { + v = parseInt(v) + setEndCycle(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && "opacity-50 border-opacity-50")} + value={endCycle ?? ''} + /> + +
+
+ + { + let v = parseInt(e.target.value); + v = isNaN(v) ? 1 : Math.max(1, v); + setSampleRate(v); + }} + onChange={v => { + v = parseInt(v) + setSampleRate(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && "opacity-50 border-opacity-50")} + value={sampleRate ?? ''} + /> + + + { + let v = parseInt(e.target.value); + v = isNaN(v) ? Math.max(1, parseInt(v)) : v; + setMaxPolyphony(v); + }} + onChange={(v) => { + v = Math.max(1, parseInt(v)); + setMaxPolyphony(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && "opacity-50 border-opacity-50")} + value={maxPolyphony ?? ''} + /> + +
+
+ { + const val = cbEvent.target.checked; + setMultiChannelOrbits(val) + }} + disabled={exporting} + value={multiChannelOrbits} + /> +
+ +
); diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index b9f1c8c8b..0e89fb68b 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -203,8 +203,8 @@ export function useReplContext() { const handleEvaluate = () => { editorRef.current.evaluate(); }; - const handleExport = async (begin, end) => { - await editorRef.current.exportAudio(begin, end); + const handleExport = async (begin, end, sampleRate, downloadName = undefined) => { + await editorRef.current.exportAudio(begin, end, sampleRate, downloadName); }; const handleShuffle = async () => { const patternData = await getRandomTune(); From 428a4b3dd742087b5fa50cc0c15ebd380c5d573b Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:21:23 +0300 Subject: [PATCH 15/66] Revert workletsUrl to use ?audioworklet --- packages/superdough/superdough.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index ed5cd9649..2f9eca3ee 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -8,7 +8,7 @@ import './feedbackdelay.mjs'; import './reverb.mjs'; import './vowel.mjs'; import { nanFallback, _mod, cycleToSeconds } from './util.mjs'; -import workletsUrl from './worklets.mjs?url'; +import workletsUrl from './worklets.mjs?audioworklet'; import { createFilter, gainNode, getCompressor, getDistortion, getLfo, getWorklet, effectSend } from './helpers.mjs'; import { map } from 'nanostores'; import { logger } from './logger.mjs'; From 4bdaf577c08cab55afdc4440ab737054578f8aa7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:22:16 +0300 Subject: [PATCH 16/66] Format --- packages/codemirror/codemirror.mjs | 9 +- packages/core/cyclist.mjs | 2 +- packages/core/repl.mjs | 31 +- packages/superdough/audioContext.mjs | 6 +- packages/superdough/helpers.mjs | 2 +- packages/superdough/superdough.mjs | 12 +- packages/webaudio/webaudio.mjs | 198 +++++----- website/src/repl/components/ExportModal.jsx | 405 ++++++++++---------- website/src/repl/components/Header.jsx | 13 +- 9 files changed, 360 insertions(+), 318 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 7cbb925d8..84cbfa96a 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -42,9 +42,9 @@ const extensions = { isMultiCursorEnabled: (on) => on ? [ - EditorState.allowMultipleSelections.of(true), - EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), - ] + EditorState.allowMultipleSelections.of(true), + EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), + ] : [], }; const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); @@ -269,10 +269,9 @@ export class StrudelMirror { await this.repl.evaluate(this.code); } async exportAudio(begin, end, sampleRate, downloadName = undefined) { - await this.repl.evaluate(this.code, false) + await this.repl.evaluate(this.code, false); await this.repl.exportAudio(begin, end, sampleRate, downloadName); this.repl.scheduler.stop(); - } async stop() { this.repl.scheduler.stop(); diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index 167f18828..185d5588b 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -117,7 +117,7 @@ export class Cyclist { throw new Error('Scheduler: no pattern set! call .setPattern first.'); } logger('[cyclist] exporting'); - await renderPatternAudio(this.pattern, this.cps, begin, end, sampleRate, downloadName) + await renderPatternAudio(this.pattern, this.cps, begin, end, sampleRate, downloadName); } pause() { diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 970c15a67..4a35b932e 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -91,7 +91,8 @@ export function repl({ const stop = () => scheduler.stop(); const start = () => scheduler.start(); - const exportAudio = async (begin, end, sampleRate, downloadName = undefined) => await scheduler.exportAudio(begin, end, sampleRate, downloadName); + const exportAudio = async (begin, end, sampleRate, downloadName = undefined) => + await scheduler.exportAudio(begin, end, sampleRate, downloadName); const pause = () => scheduler.pause(); const toggle = () => scheduler.toggle(); const setCps = (cps) => { @@ -263,18 +264,18 @@ export function repl({ export const getTrigger = ({ getTime, defaultOutput }) => - async (hap, deadline, duration, cps, t) => { - // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) - // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 - try { - if (!hap.context.onTrigger || !hap.context.dominantTrigger) { - await defaultOutput(hap, deadline, duration, cps, t); - } - if (hap.context.onTrigger) { - // call signature of output / onTrigger is different... - await hap.context.onTrigger(hap, getTime(), cps, t); - } - } catch (err) { - errorLogger(err, 'getTrigger'); + async (hap, deadline, duration, cps, t) => { + // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) + // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 + try { + if (!hap.context.onTrigger || !hap.context.dominantTrigger) { + await defaultOutput(hap, deadline, duration, cps, t); } - }; + if (hap.context.onTrigger) { + // call signature of output / onTrigger is different... + await hap.context.onTrigger(hap, getTime(), cps, t); + } + } catch (err) { + errorLogger(err, 'getTrigger'); + } + }; diff --git a/packages/superdough/audioContext.mjs b/packages/superdough/audioContext.mjs index ea60722b1..9a5913d80 100644 --- a/packages/superdough/audioContext.mjs +++ b/packages/superdough/audioContext.mjs @@ -1,15 +1,15 @@ -import { analysers, resetGlobalEffects } from "./superdough.mjs"; +import { analysers, resetGlobalEffects } from './superdough.mjs'; let audioContext; export const setDefaultAudioContext = () => { audioContext = new AudioContext(); - resetGlobalEffects() + resetGlobalEffects(); return audioContext; }; export const setAudioContext = (context) => { - audioContext = context + audioContext = context; return audioContext; }; diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index cf65c390f..a471da9dd 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -348,7 +348,7 @@ export function applyFM(param, value, begin) { duration, } = value; let modulator; - let stop = () => { }; + let stop = () => {}; if (fmModulationIndex) { const ac = getAudioContext(); diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 2f9eca3ee..118a152b1 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -212,7 +212,9 @@ export function loadWorklets() { if (!workletsLoading) { const audioCtx = getAudioContext(); const allWorkletURLs = externalWorklets.concat([workletsUrl]); - workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL))).then(() => workletsLoading = undefined); + workletsLoading = Promise.all(allWorkletURLs.map((workletURL) => audioCtx.audioWorklet.addModule(workletURL))).then( + () => (workletsLoading = undefined), + ); } return workletsLoading; @@ -250,7 +252,7 @@ export async function initAudio(options = {}) { logger('[superdough] failed to set audio interface', 'warning'); } } - if (!audioCtx instanceof OfflineAudioContext) { + if ((!audioCtx) instanceof OfflineAudioContext) { await audioCtx.resume(); } if (disableWorklets) { @@ -288,7 +290,7 @@ function getSuperdoughAudioController() { } export function setSuperdoughAudioController(newController) { - controller = newController + controller = newController; return controller; } @@ -401,7 +403,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) ); return; } // FIXME: fix - // destructure + // destructure let { tremolo, tremolosync, @@ -743,4 +745,4 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) export const superdoughTrigger = (t, hap, ct, cps) => { superdough(hap, t - ct, hap.duration / cps, cps); -}; \ No newline at end of file +}; diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 27718bd7d..43c011460 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -5,7 +5,23 @@ This program is free software: you can redistribute it and/or modify it under th */ import * as strudel from '@strudel/core'; -import { superdough, getAudioContext, setLogger, doughTrigger, registerWorklet, setAudioContext, getSampleBufferSource, loadBuffer, getSampleInfo, getSound, initAudio, setSuperdoughAudioController, loadWorklets, setMaxPolyphony, setMultiChannelOrbits } from 'superdough'; +import { + superdough, + getAudioContext, + setLogger, + doughTrigger, + registerWorklet, + setAudioContext, + getSampleBufferSource, + loadBuffer, + getSampleInfo, + getSound, + initAudio, + setSuperdoughAudioController, + loadWorklets, + setMaxPolyphony, + setMultiChannelOrbits, +} from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; import { SuperdoughAudioController } from 'superdough/superdoughoutput.mjs'; @@ -28,59 +44,63 @@ export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => { }; export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, downloadName = undefined) { - const oldAudioCtx = getAudioContext() - await oldAudioCtx.close() - let audioContext = new OfflineAudioContext(2, (end - begin) / cps * sampleRate, sampleRate); - setAudioContext(audioContext) - let context = getAudioContext() - setSuperdoughAudioController(new SuperdoughAudioController(context)) - setMaxPolyphony(1024) - setMultiChannelOrbits(true) - await loadWorklets() + const oldAudioCtx = getAudioContext(); + await oldAudioCtx.close(); + let audioContext = new OfflineAudioContext(2, ((end - begin) / cps) * sampleRate, sampleRate); + setAudioContext(audioContext); + let context = getAudioContext(); + setSuperdoughAudioController(new SuperdoughAudioController(context)); + setMaxPolyphony(1024); + setMultiChannelOrbits(true); + await loadWorklets(); logger('[webaudio] start rendering'); - let haps = pattern.queryArc(begin, end, { _cps: cps }) - Promise.all(haps.map(async h => { - let s; - if (h.value.s) { - if (h.value.bank) { - s = `${h.value.bank}_${h.value.s}`; + let haps = pattern.queryArc(begin, end, { _cps: cps }); + Promise.all( + haps.map(async (h) => { + let s; + if (h.value.s) { + if (h.value.bank) { + s = `${h.value.bank}_${h.value.s}`; + } else { + s = h.value.s; + } + let bank = getSound(s).data.samples; + if (bank) { + let { url: sampleUrl, label } = getSampleInfo(h.value, bank); + await loadBuffer(sampleUrl, context, label); + } } - else { - s = h.value.s - } - let bank = getSound(s).data.samples - if (bank) { - let { url: sampleUrl, label } = getSampleInfo(h.value, bank); - await loadBuffer(sampleUrl, context, label) - } - } - })) + }), + ); haps.forEach(async (hap) => { if (hap.hasOnset()) { hap.ensureObjectValue(); await superdough(hap.value, hap.whole.begin.valueOf() / cps, hap.duration, cps, hap.whole?.begin.valueOf()); } - }) - - return context.startRendering().then((renderedBuffer) => { - console.log(renderedBuffer) - const wavBuffer = audioBufferToWav(renderedBuffer); - const blob = new Blob([wavBuffer], { type: 'audio/wav' }); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - downloadName = downloadName ? `${downloadName}.wav` : `${new Date().toISOString()}.wav`; - a.download = `${downloadName}`; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - URL.revokeObjectURL(url); - }).finally(async () => { - setAudioContext(null) - setSuperdoughAudioController(null) - await initAudio() }); + + return context + .startRendering() + .then((renderedBuffer) => { + console.log(renderedBuffer); + const wavBuffer = audioBufferToWav(renderedBuffer); + const blob = new Blob([wavBuffer], { type: 'audio/wav' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + downloadName = downloadName ? `${downloadName}.wav` : `${new Date().toISOString()}.wav`; + a.download = `${downloadName}`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + }) + .finally(async () => { + setAudioContext(null); + setSuperdoughAudioController(null); + await initAudio(); + }); } export function webaudioRepl(options = {}) { @@ -96,97 +116,97 @@ Pattern.prototype.dough = function () { return this.onTrigger(doughTrigger, 1); }; - function audioBufferToWav(buffer, opt) { - opt = opt || {} + opt = opt || {}; - var numChannels = buffer.numberOfChannels - var sampleRate = buffer.sampleRate - var format = opt.float32 ? 3 : 1 - var bitDepth = format === 3 ? 32 : 16 + var numChannels = buffer.numberOfChannels; + var sampleRate = buffer.sampleRate; + var format = opt.float32 ? 3 : 1; + var bitDepth = format === 3 ? 32 : 16; - var result + var result; if (numChannels === 2) { - result = interleave(buffer.getChannelData(0), buffer.getChannelData(1)) + result = interleave(buffer.getChannelData(0), buffer.getChannelData(1)); } else { - result = buffer.getChannelData(0) + result = buffer.getChannelData(0); } - return encodeWAV(result, format, sampleRate, numChannels, bitDepth) + return encodeWAV(result, format, sampleRate, numChannels, bitDepth); } function encodeWAV(samples, format, sampleRate, numChannels, bitDepth) { - var bytesPerSample = bitDepth / 8 - var blockAlign = numChannels * bytesPerSample + var bytesPerSample = bitDepth / 8; + var blockAlign = numChannels * bytesPerSample; - var buffer = new ArrayBuffer(44 + samples.length * bytesPerSample) - var view = new DataView(buffer) + var buffer = new ArrayBuffer(44 + samples.length * bytesPerSample); + var view = new DataView(buffer); /* RIFF identifier */ - writeString(view, 0, 'RIFF') + writeString(view, 0, 'RIFF'); /* RIFF chunk length */ - view.setUint32(4, 36 + samples.length * bytesPerSample, true) + view.setUint32(4, 36 + samples.length * bytesPerSample, true); /* RIFF type */ - writeString(view, 8, 'WAVE') + writeString(view, 8, 'WAVE'); /* format chunk identifier */ - writeString(view, 12, 'fmt ') + writeString(view, 12, 'fmt '); /* format chunk length */ - view.setUint32(16, 16, true) + view.setUint32(16, 16, true); /* sample format (raw) */ - view.setUint16(20, format, true) + view.setUint16(20, format, true); /* channel count */ - view.setUint16(22, numChannels, true) + view.setUint16(22, numChannels, true); /* sample rate */ - view.setUint32(24, sampleRate, true) + view.setUint32(24, sampleRate, true); /* byte rate (sample rate * block align) */ - view.setUint32(28, sampleRate * blockAlign, true) + view.setUint32(28, sampleRate * blockAlign, true); /* block align (channel count * bytes per sample) */ - view.setUint16(32, blockAlign, true) + view.setUint16(32, blockAlign, true); /* bits per sample */ - view.setUint16(34, bitDepth, true) + view.setUint16(34, bitDepth, true); /* data chunk identifier */ - writeString(view, 36, 'data') + writeString(view, 36, 'data'); /* data chunk length */ - view.setUint32(40, samples.length * bytesPerSample, true) - if (format === 1) { // Raw PCM - floatTo16BitPCM(view, 44, samples) + view.setUint32(40, samples.length * bytesPerSample, true); + if (format === 1) { + // Raw PCM + floatTo16BitPCM(view, 44, samples); } else { - writeFloat32(view, 44, samples) + writeFloat32(view, 44, samples); } - return buffer + return buffer; } function interleave(inputL, inputR) { - var length = inputL.length + inputR.length - var result = new Float32Array(length) + var length = inputL.length + inputR.length; + var result = new Float32Array(length); - var index = 0 - var inputIndex = 0 + var index = 0; + var inputIndex = 0; while (index < length) { - result[index++] = inputL[inputIndex] - result[index++] = inputR[inputIndex] - inputIndex++ + result[index++] = inputL[inputIndex]; + result[index++] = inputR[inputIndex]; + inputIndex++; } - return result + return result; } function writeFloat32(output, offset, input) { for (var i = 0; i < input.length; i++, offset += 4) { - output.setFloat32(offset, input[i], true) + output.setFloat32(offset, input[i], true); } } function floatTo16BitPCM(output, offset, input) { for (var i = 0; i < input.length; i++, offset += 2) { - var s = Math.max(-1, Math.min(1, input[i])) - output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true) + var s = Math.max(-1, Math.min(1, input[i])); + output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true); } } function writeString(view, offset, string) { for (var i = 0; i < string.length; i++) { - view.setUint8(offset + i, string.charCodeAt(i)) + view.setUint8(offset + i, string.charCodeAt(i)); } -} \ No newline at end of file +} diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index 4f474f381..036f6f36a 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -3,215 +3,226 @@ import cx from '@src/cx.mjs'; import NumberInput from './NumberInput'; import { useEffect, useState } from 'react'; import { Textbox } from './textbox/Textbox'; -import { setMultiChannelOrbits as setStrudelMultiChannelOrbits, setMaxPolyphony as setStrudelMaxPolyphony, getAudioContext } from '@strudel/webaudio'; +import { + setMultiChannelOrbits as setStrudelMultiChannelOrbits, + setMaxPolyphony as setStrudelMaxPolyphony, + getAudioContext, +} from '@strudel/webaudio'; import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; function Checkbox({ label, value, onChange, disabled = false }) { - return ( - - ); + return ( + + ); } function FormItem({ label, children, disabled }) { - return ( -
- - {children} -
- ); + return ( +
+ + {children} +
+ ); } export default function ExportModal(Props) { - const { started, isEmbedded, handleExport } = Props; + const { started, isEmbedded, handleExport } = Props; - const [downloadName, setDownloadName] = useState("") // TODO: make a form? - const [startCycle, setStartCycle] = useState(0) - const [endCycle, setEndCycle] = useState(1) - const [sampleRate, setSampleRate] = useState(48000) - const [multiChannelOrbits, setMultiChannelOrbits] = useState(true) - const [maxPolyphony, setMaxPolyphony] = useState(1024) - const [exporting, setExporting] = useState(false) - const [progress, setProgress] = useState(0) - const [length, setLength] = useState(1) + const [downloadName, setDownloadName] = useState(''); // TODO: make a form? + const [startCycle, setStartCycle] = useState(0); + const [endCycle, setEndCycle] = useState(1); + const [sampleRate, setSampleRate] = useState(48000); + const [multiChannelOrbits, setMultiChannelOrbits] = useState(true); + const [maxPolyphony, setMaxPolyphony] = useState(1024); + const [exporting, setExporting] = useState(false); + const [progress, setProgress] = useState(0); + const [length, setLength] = useState(1); - const refreshProgress = () => { - const audioContext = getAudioContext() - if (audioContext instanceof OfflineAudioContext) { - setProgress(audioContext.currentTime) - setLength(audioContext.length / sampleRate) - setTimeout(refreshProgress, 100); - } + const refreshProgress = () => { + const audioContext = getAudioContext(); + if (audioContext instanceof OfflineAudioContext) { + setProgress(audioContext.currentTime); + setLength(audioContext.length / sampleRate); + setTimeout(refreshProgress, 100); } + }; - return ( - <> - + + +
+ + { + setDownloadName(e.target.value); + }} + onChange={(v) => { + setDownloadName(v); + }} + disabled={exporting} + placeholder="Leave empty to use current date" + className={cx('placeholder:opacity-50', exporting && 'opacity-50 border-opacity-50')} + value={downloadName ?? ''} + /> + +
+ + { + let v = parseInt(e.target.value); + v = isNaN(v) ? 0 : Math.max(0, v); + setStartCycle(v); }} - title="export" - className={cx( - 'flex items-center space-x-1', - !isEmbedded ? 'p-2' : 'px-2', - started ? 'opacity-50' : 'hover:opacity-50', - )} - > - {!isEmbedded && export} - - - -
- - { - setDownloadName(e.target.value) - }} - onChange={v => { - setDownloadName(v) - }} - disabled={exporting} - placeholder="Leave empty to use current date" - className={cx("placeholder:opacity-50", exporting && "opacity-50 border-opacity-50")} - value={downloadName ?? ''} - /> - -
- - { - let v = parseInt(e.target.value); - v = isNaN(v) ? 0 : Math.max(0, v); - setStartCycle(v); - }} - onChange={v => { - v = parseInt(v) - setStartCycle(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && "opacity-50 border-opacity-50")} - value={startCycle ?? ''} - /> - - - { - let v = parseInt(e.target.value); - v = isNaN(v) ? Math.max(startCycle + 1, parseInt(v)) : v; - setEndCycle(v); - }} - onChange={(v) => { - v = parseInt(v) - setEndCycle(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && "opacity-50 border-opacity-50")} - value={endCycle ?? ''} - /> - -
-
- - { - let v = parseInt(e.target.value); - v = isNaN(v) ? 1 : Math.max(1, v); - setSampleRate(v); - }} - onChange={v => { - v = parseInt(v) - setSampleRate(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && "opacity-50 border-opacity-50")} - value={sampleRate ?? ''} - /> - - - { - let v = parseInt(e.target.value); - v = isNaN(v) ? Math.max(1, parseInt(v)) : v; - setMaxPolyphony(v); - }} - onChange={(v) => { - v = Math.max(1, parseInt(v)); - setMaxPolyphony(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && "opacity-50 border-opacity-50")} - value={maxPolyphony ?? ''} - /> - -
-
- { - const val = cbEvent.target.checked; - setMultiChannelOrbits(val) - }} - disabled={exporting} - value={multiChannelOrbits} - /> -
- -
-
- - ); + onChange={(v) => { + v = parseInt(v); + setStartCycle(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && 'opacity-50 border-opacity-50')} + value={startCycle ?? ''} + /> +
+ + { + let v = parseInt(e.target.value); + v = isNaN(v) ? Math.max(startCycle + 1, parseInt(v)) : v; + setEndCycle(v); + }} + onChange={(v) => { + v = parseInt(v); + setEndCycle(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && 'opacity-50 border-opacity-50')} + value={endCycle ?? ''} + /> + +
+
+ + { + let v = parseInt(e.target.value); + v = isNaN(v) ? 1 : Math.max(1, v); + setSampleRate(v); + }} + onChange={(v) => { + v = parseInt(v); + setSampleRate(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && 'opacity-50 border-opacity-50')} + value={sampleRate ?? ''} + /> + + + { + let v = parseInt(e.target.value); + v = isNaN(v) ? Math.max(1, parseInt(v)) : v; + setMaxPolyphony(v); + }} + onChange={(v) => { + v = Math.max(1, parseInt(v)); + setMaxPolyphony(v); + }} + type="number" + placeholder="" + disabled={exporting} + className={cx(exporting && 'opacity-50 border-opacity-50')} + value={maxPolyphony ?? ''} + /> + +
+
+ { + const val = cbEvent.target.checked; + setMultiChannelOrbits(val); + }} + disabled={exporting} + value={multiChannelOrbits} + /> +
+ +
+
+ + ); } diff --git a/website/src/repl/components/Header.jsx b/website/src/repl/components/Header.jsx index d5d8b5f75..dd9f684c1 100644 --- a/website/src/repl/components/Header.jsx +++ b/website/src/repl/components/Header.jsx @@ -9,8 +9,17 @@ const { BASE_URL } = import.meta.env; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; export function Header({ context, embedded = false }) { - const { started, pending, isDirty, activeCode, handleTogglePlay, handleEvaluate, handleShuffle, handleShare, handleExport } = - context; + const { + started, + pending, + isDirty, + activeCode, + handleTogglePlay, + handleEvaluate, + handleShuffle, + handleShare, + handleExport, + } = context; const isEmbedded = typeof window !== 'undefined' && (embedded || window.location !== window.parent.location); const { isZen, isButtonRowHidden, isCSSAnimationDisabled, fontFamily } = useSettings(); From 120b46c4a516d0a5932b6162f83185761503f8dc Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:24:42 +0300 Subject: [PATCH 17/66] Add webaudio as a cyclist dependency (do we want that?) --- packages/core/cyclist.mjs | 2 +- packages/core/package-lock.json | 331 ++++++++++++++++++++++++++++++++ packages/core/package.json | 1 + 3 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 packages/core/package-lock.json diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index 185d5588b..119f1d511 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -6,7 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import createClock from './zyklus.mjs'; import { errorLogger, logger } from './logger.mjs'; -import { loadBuffer, renderPatternAudio, setAudioContext, superdough } from '@strudel/webaudio'; +import { renderPatternAudio } from '@strudel/webaudio'; export class Cyclist { constructor({ diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json new file mode 100644 index 000000000..dea7b53a7 --- /dev/null +++ b/packages/core/package-lock.json @@ -0,0 +1,331 @@ +{ + "name": "@strudel/core", + "version": "1.2.4", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@strudel/core", + "version": "1.2.4", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@strudel/webaudio": "^1.2.5", + "fraction.js": "^5.2.1" + }, + "devDependencies": { + "vite": "^6.0.11", + "vitest": "^3.0.4" + } + }, + "../../node_modules/.pnpm/fraction.js@5.2.1/node_modules/fraction.js": { + "version": "5.2.1", + "license": "MIT", + "devDependencies": { + "crude-build": "^0.1.2", + "mocha": "*" + }, + "engines": { + "node": ">= 12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "../../node_modules/.pnpm/vite@6.0.11_@types+node@22.10.10_jiti@2.4.2_lightningcss@1.29.1_terser@5.37.0_yaml@2.7.0/node_modules/vite": { + "version": "6.0.11", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "devDependencies": { + "@ampproject/remapping": "^2.3.0", + "@babel/parser": "^7.26.3", + "@jridgewell/trace-mapping": "^0.3.25", + "@polka/compression": "^1.0.0-next.25", + "@rollup/plugin-alias": "^5.1.1", + "@rollup/plugin-commonjs": "^28.0.2", + "@rollup/plugin-dynamic-import-vars": "2.1.4", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "16.0.0", + "@rollup/pluginutils": "^5.1.4", + "@types/escape-html": "^1.0.4", + "@types/pnpapi": "^0.0.5", + "artichokie": "^0.3.1", + "cac": "^6.7.14", + "chokidar": "^3.6.0", + "connect": "^3.7.0", + "convert-source-map": "^2.0.0", + "cors": "^2.8.5", + "cross-spawn": "^7.0.6", + "debug": "^4.4.0", + "dep-types": "link:./src/types", + "dotenv": "^16.4.7", + "dotenv-expand": "^12.0.1", + "es-module-lexer": "^1.6.0", + "escape-html": "^1.0.3", + "estree-walker": "^3.0.3", + "etag": "^1.8.1", + "http-proxy": "^1.18.1", + "launch-editor-middleware": "^2.9.1", + "lightningcss": "^1.28.2", + "magic-string": "^0.30.17", + "mlly": "^1.7.3", + "mrmime": "^2.0.0", + "nanoid": "^5.0.9", + "open": "^10.1.0", + "parse5": "^7.2.1", + "pathe": "^2.0.0", + "periscopic": "^4.0.2", + "picocolors": "^1.1.1", + "picomatch": "^4.0.2", + "postcss-import": "^16.1.0", + "postcss-load-config": "^6.0.1", + "postcss-modules": "^6.0.1", + "resolve.exports": "^2.0.3", + "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-esbuild": "^6.1.1", + "rollup-plugin-license": "^3.5.3", + "sass": "^1.83.1", + "sass-embedded": "^1.83.1", + "sirv": "^3.0.0", + "source-map-support": "^0.5.21", + "strip-literal": "^2.1.1", + "terser": "^5.37.0", + "tinyglobby": "^0.2.10", + "tsconfck": "^3.1.4", + "tslib": "^2.8.1", + "types": "link:./types", + "ufo": "^1.5.4", + "ws": "^8.18.0" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "../../node_modules/.pnpm/vitest@3.0.4_@types+debug@4.1.12_@types+node@22.10.10_@vitest+ui@3.0.4_jiti@2.4.2_light_04b28d5d33383b617211459e5738d579/node_modules/vitest": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.0.4", + "@vitest/mocker": "3.0.4", + "@vitest/pretty-format": "^3.0.4", + "@vitest/runner": "3.0.4", + "@vitest/snapshot": "3.0.4", + "@vitest/spy": "3.0.4", + "@vitest/utils": "3.0.4", + "chai": "^5.1.2", + "debug": "^4.4.0", + "expect-type": "^1.1.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.0.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "devDependencies": { + "@ampproject/remapping": "^2.3.0", + "@antfu/install-pkg": "^1.0.0", + "@edge-runtime/vm": "^5.0.0", + "@sinonjs/fake-timers": "14.0.0", + "@types/debug": "^4.1.12", + "@types/estree": "^1.0.6", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/jsdom": "^21.1.7", + "@types/micromatch": "^4.0.9", + "@types/node": "^22.10.9", + "@types/prompts": "^2.4.9", + "@types/sinonjs__fake-timers": "^8.1.5", + "acorn-walk": "^8.3.4", + "birpc": "0.2.19", + "cac": "^6.7.14", + "chai-subset": "^1.6.0", + "fast-glob": "3.3.3", + "find-up": "^6.3.0", + "flatted": "^3.3.2", + "get-tsconfig": "^4.10.0", + "happy-dom": "^16.7.2", + "jsdom": "^25.0.1", + "local-pkg": "^0.5.1", + "micromatch": "^4.0.8", + "pretty-format": "^29.7.0", + "prompts": "^2.4.2", + "strip-literal": "^2.1.1", + "ws": "^8.18.0" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.0.4", + "@vitest/ui": "3.0.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/@strudel/core": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@strudel/core/-/core-1.2.4.tgz", + "integrity": "sha512-sUm9/zjEEQuWfW3hNOCcfNbn8jq2G+Ye+mvpLUgcGyLfI5XPlPTn/PBIkv2hFjNs/basnMyrOUvg0Z85AA6+OA==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "fraction.js": "^5.2.1" + } + }, + "node_modules/@strudel/draw": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@strudel/draw/-/draw-1.2.4.tgz", + "integrity": "sha512-9ui5+ZQQB+EEgwJQueGVMgpnPSHnFgRgivlAZbdjEoMdSm5vULWvKK3Psml8WKtOBNiuL+5Bci7a0INRTRusOA==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@strudel/core": "1.2.4" + } + }, + "node_modules/@strudel/webaudio": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@strudel/webaudio/-/webaudio-1.2.5.tgz", + "integrity": "sha512-ilcyBsuwkH6Ghz0egaqIJ5DZi0xFBZwVWvZb0vnfU7kVESroD2j6yptyFMysJFZhQ5pfRiZs2ZeF6yTsviUjng==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@strudel/core": "1.2.4", + "@strudel/draw": "1.2.4", + "superdough": "1.2.5" + } + }, + "node_modules/fraction.js": { + "resolved": "../../node_modules/.pnpm/fraction.js@5.2.1/node_modules/fraction.js", + "link": true + }, + "node_modules/nanostores": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-0.11.4.tgz", + "integrity": "sha512-k1oiVNN4hDK8NcNERSZLQiMfRzEGtfnvZvdBvey3SQbgn8Dcrk0h1I6vpxApjb10PFUflZrgJ2WEZyJQ+5v7YQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/superdough": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/superdough/-/superdough-1.2.5.tgz", + "integrity": "sha512-QVkMGGZjWzaRxYKXoZYMfsRHVk5vwNiqAaDOseccSTgqPPwFRTY2fmHAm5OmwwS8XqFOenZjn+XU3LEaCZMdJw==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "nanostores": "^0.11.3" + } + }, + "node_modules/vite": { + "resolved": "../../node_modules/.pnpm/vite@6.0.11_@types+node@22.10.10_jiti@2.4.2_lightningcss@1.29.1_terser@5.37.0_yaml@2.7.0/node_modules/vite", + "link": true + }, + "node_modules/vitest": { + "resolved": "../../node_modules/.pnpm/vitest@3.0.4_@types+debug@4.1.12_@types+node@22.10.10_@vitest+ui@3.0.4_jiti@2.4.2_light_04b28d5d33383b617211459e5738d579/node_modules/vitest", + "link": true + } + } +} diff --git a/packages/core/package.json b/packages/core/package.json index 7cf20cea7..daaa111de 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,6 +31,7 @@ }, "homepage": "https://strudel.cc", "dependencies": { + "@strudel/webaudio": "^1.2.5", "fraction.js": "^5.2.1" }, "gitHead": "0e26d4e741500f5bae35b023608f062a794905c2", From 8b3c0d2a4aa8e9d2c89622e63d2d614ff15f2ef0 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:27:31 +0300 Subject: [PATCH 18/66] Refresh deps --- packages/osc/server.js | 0 pnpm-lock.yaml | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) mode change 100644 => 100755 packages/osc/server.js diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100644 new mode 100755 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c225057f3..40d6eb57b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -225,6 +225,9 @@ importers: packages/core: dependencies: + '@strudel/webaudio': + specifier: ^1.2.5 + version: 1.2.5 fraction.js: specifier: ^5.2.1 version: 5.2.1 @@ -2468,6 +2471,15 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@strudel/core@1.2.4': + resolution: {integrity: sha512-sUm9/zjEEQuWfW3hNOCcfNbn8jq2G+Ye+mvpLUgcGyLfI5XPlPTn/PBIkv2hFjNs/basnMyrOUvg0Z85AA6+OA==} + + '@strudel/draw@1.2.4': + resolution: {integrity: sha512-9ui5+ZQQB+EEgwJQueGVMgpnPSHnFgRgivlAZbdjEoMdSm5vULWvKK3Psml8WKtOBNiuL+5Bci7a0INRTRusOA==} + + '@strudel/webaudio@1.2.5': + resolution: {integrity: sha512-ilcyBsuwkH6Ghz0egaqIJ5DZi0xFBZwVWvZb0vnfU7kVESroD2j6yptyFMysJFZhQ5pfRiZs2ZeF6yTsviUjng==} + '@supabase/auth-js@2.67.3': resolution: {integrity: sha512-NJDaW8yXs49xMvWVOkSIr8j46jf+tYHV0wHhrwOaLLMZSFO4g6kKAf+MfzQ2RaD06OCUkUHIzctLAxjTgEVpzw==} @@ -6989,6 +7001,9 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + superdough@1.2.5: + resolution: {integrity: sha512-QVkMGGZjWzaRxYKXoZYMfsRHVk5vwNiqAaDOseccSTgqPPwFRTY2fmHAm5OmwwS8XqFOenZjn+XU3LEaCZMdJw==} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -9829,6 +9844,20 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@strudel/core@1.2.4': + dependencies: + fraction.js: 5.2.1 + + '@strudel/draw@1.2.4': + dependencies: + '@strudel/core': 1.2.4 + + '@strudel/webaudio@1.2.5': + dependencies: + '@strudel/core': 1.2.4 + '@strudel/draw': 1.2.4 + superdough: 1.2.5 + '@supabase/auth-js@2.67.3': dependencies: '@supabase/node-fetch': 2.6.15 @@ -15431,6 +15460,10 @@ snapshots: pirates: 4.0.6 ts-interface-checker: 0.1.13 + superdough@1.2.5: + dependencies: + nanostores: 0.11.3 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 From 329289fc3589661473447f0f1d7563d858cdd04d Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:33:04 +0300 Subject: [PATCH 19/66] Revert refreshing deps --- packages/core/cyclist.mjs | 2 +- packages/core/package-lock.json | 331 -------------------------------- packages/core/package.json | 1 - packages/osc/server.js | 0 pnpm-lock.yaml | 33 ---- 5 files changed, 1 insertion(+), 366 deletions(-) delete mode 100644 packages/core/package-lock.json mode change 100755 => 100644 packages/osc/server.js diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index 119f1d511..185d5588b 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -6,7 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import createClock from './zyklus.mjs'; import { errorLogger, logger } from './logger.mjs'; -import { renderPatternAudio } from '@strudel/webaudio'; +import { loadBuffer, renderPatternAudio, setAudioContext, superdough } from '@strudel/webaudio'; export class Cyclist { constructor({ diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json deleted file mode 100644 index dea7b53a7..000000000 --- a/packages/core/package-lock.json +++ /dev/null @@ -1,331 +0,0 @@ -{ - "name": "@strudel/core", - "version": "1.2.4", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@strudel/core", - "version": "1.2.4", - "license": "AGPL-3.0-or-later", - "dependencies": { - "@strudel/webaudio": "^1.2.5", - "fraction.js": "^5.2.1" - }, - "devDependencies": { - "vite": "^6.0.11", - "vitest": "^3.0.4" - } - }, - "../../node_modules/.pnpm/fraction.js@5.2.1/node_modules/fraction.js": { - "version": "5.2.1", - "license": "MIT", - "devDependencies": { - "crude-build": "^0.1.2", - "mocha": "*" - }, - "engines": { - "node": ">= 12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/rawify" - } - }, - "../../node_modules/.pnpm/vite@6.0.11_@types+node@22.10.10_jiti@2.4.2_lightningcss@1.29.1_terser@5.37.0_yaml@2.7.0/node_modules/vite": { - "version": "6.0.11", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "rollup": "^4.23.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "devDependencies": { - "@ampproject/remapping": "^2.3.0", - "@babel/parser": "^7.26.3", - "@jridgewell/trace-mapping": "^0.3.25", - "@polka/compression": "^1.0.0-next.25", - "@rollup/plugin-alias": "^5.1.1", - "@rollup/plugin-commonjs": "^28.0.2", - "@rollup/plugin-dynamic-import-vars": "2.1.4", - "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "16.0.0", - "@rollup/pluginutils": "^5.1.4", - "@types/escape-html": "^1.0.4", - "@types/pnpapi": "^0.0.5", - "artichokie": "^0.3.1", - "cac": "^6.7.14", - "chokidar": "^3.6.0", - "connect": "^3.7.0", - "convert-source-map": "^2.0.0", - "cors": "^2.8.5", - "cross-spawn": "^7.0.6", - "debug": "^4.4.0", - "dep-types": "link:./src/types", - "dotenv": "^16.4.7", - "dotenv-expand": "^12.0.1", - "es-module-lexer": "^1.6.0", - "escape-html": "^1.0.3", - "estree-walker": "^3.0.3", - "etag": "^1.8.1", - "http-proxy": "^1.18.1", - "launch-editor-middleware": "^2.9.1", - "lightningcss": "^1.28.2", - "magic-string": "^0.30.17", - "mlly": "^1.7.3", - "mrmime": "^2.0.0", - "nanoid": "^5.0.9", - "open": "^10.1.0", - "parse5": "^7.2.1", - "pathe": "^2.0.0", - "periscopic": "^4.0.2", - "picocolors": "^1.1.1", - "picomatch": "^4.0.2", - "postcss-import": "^16.1.0", - "postcss-load-config": "^6.0.1", - "postcss-modules": "^6.0.1", - "resolve.exports": "^2.0.3", - "rollup-plugin-dts": "^6.1.1", - "rollup-plugin-esbuild": "^6.1.1", - "rollup-plugin-license": "^3.5.3", - "sass": "^1.83.1", - "sass-embedded": "^1.83.1", - "sirv": "^3.0.0", - "source-map-support": "^0.5.21", - "strip-literal": "^2.1.1", - "terser": "^5.37.0", - "tinyglobby": "^0.2.10", - "tsconfck": "^3.1.4", - "tslib": "^2.8.1", - "types": "link:./types", - "ufo": "^1.5.4", - "ws": "^8.18.0" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "../../node_modules/.pnpm/vitest@3.0.4_@types+debug@4.1.12_@types+node@22.10.10_@vitest+ui@3.0.4_jiti@2.4.2_light_04b28d5d33383b617211459e5738d579/node_modules/vitest": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "3.0.4", - "@vitest/mocker": "3.0.4", - "@vitest/pretty-format": "^3.0.4", - "@vitest/runner": "3.0.4", - "@vitest/snapshot": "3.0.4", - "@vitest/spy": "3.0.4", - "@vitest/utils": "3.0.4", - "chai": "^5.1.2", - "debug": "^4.4.0", - "expect-type": "^1.1.0", - "magic-string": "^0.30.17", - "pathe": "^2.0.2", - "std-env": "^3.8.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinypool": "^1.0.2", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.0.4", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "devDependencies": { - "@ampproject/remapping": "^2.3.0", - "@antfu/install-pkg": "^1.0.0", - "@edge-runtime/vm": "^5.0.0", - "@sinonjs/fake-timers": "14.0.0", - "@types/debug": "^4.1.12", - "@types/estree": "^1.0.6", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/jsdom": "^21.1.7", - "@types/micromatch": "^4.0.9", - "@types/node": "^22.10.9", - "@types/prompts": "^2.4.9", - "@types/sinonjs__fake-timers": "^8.1.5", - "acorn-walk": "^8.3.4", - "birpc": "0.2.19", - "cac": "^6.7.14", - "chai-subset": "^1.6.0", - "fast-glob": "3.3.3", - "find-up": "^6.3.0", - "flatted": "^3.3.2", - "get-tsconfig": "^4.10.0", - "happy-dom": "^16.7.2", - "jsdom": "^25.0.1", - "local-pkg": "^0.5.1", - "micromatch": "^4.0.8", - "pretty-format": "^29.7.0", - "prompts": "^2.4.2", - "strip-literal": "^2.1.1", - "ws": "^8.18.0" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.0.4", - "@vitest/ui": "3.0.4", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/debug": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/@strudel/core": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@strudel/core/-/core-1.2.4.tgz", - "integrity": "sha512-sUm9/zjEEQuWfW3hNOCcfNbn8jq2G+Ye+mvpLUgcGyLfI5XPlPTn/PBIkv2hFjNs/basnMyrOUvg0Z85AA6+OA==", - "license": "AGPL-3.0-or-later", - "dependencies": { - "fraction.js": "^5.2.1" - } - }, - "node_modules/@strudel/draw": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@strudel/draw/-/draw-1.2.4.tgz", - "integrity": "sha512-9ui5+ZQQB+EEgwJQueGVMgpnPSHnFgRgivlAZbdjEoMdSm5vULWvKK3Psml8WKtOBNiuL+5Bci7a0INRTRusOA==", - "license": "AGPL-3.0-or-later", - "dependencies": { - "@strudel/core": "1.2.4" - } - }, - "node_modules/@strudel/webaudio": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@strudel/webaudio/-/webaudio-1.2.5.tgz", - "integrity": "sha512-ilcyBsuwkH6Ghz0egaqIJ5DZi0xFBZwVWvZb0vnfU7kVESroD2j6yptyFMysJFZhQ5pfRiZs2ZeF6yTsviUjng==", - "license": "AGPL-3.0-or-later", - "dependencies": { - "@strudel/core": "1.2.4", - "@strudel/draw": "1.2.4", - "superdough": "1.2.5" - } - }, - "node_modules/fraction.js": { - "resolved": "../../node_modules/.pnpm/fraction.js@5.2.1/node_modules/fraction.js", - "link": true - }, - "node_modules/nanostores": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-0.11.4.tgz", - "integrity": "sha512-k1oiVNN4hDK8NcNERSZLQiMfRzEGtfnvZvdBvey3SQbgn8Dcrk0h1I6vpxApjb10PFUflZrgJ2WEZyJQ+5v7YQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/superdough": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/superdough/-/superdough-1.2.5.tgz", - "integrity": "sha512-QVkMGGZjWzaRxYKXoZYMfsRHVk5vwNiqAaDOseccSTgqPPwFRTY2fmHAm5OmwwS8XqFOenZjn+XU3LEaCZMdJw==", - "license": "AGPL-3.0-or-later", - "dependencies": { - "nanostores": "^0.11.3" - } - }, - "node_modules/vite": { - "resolved": "../../node_modules/.pnpm/vite@6.0.11_@types+node@22.10.10_jiti@2.4.2_lightningcss@1.29.1_terser@5.37.0_yaml@2.7.0/node_modules/vite", - "link": true - }, - "node_modules/vitest": { - "resolved": "../../node_modules/.pnpm/vitest@3.0.4_@types+debug@4.1.12_@types+node@22.10.10_@vitest+ui@3.0.4_jiti@2.4.2_light_04b28d5d33383b617211459e5738d579/node_modules/vitest", - "link": true - } - } -} diff --git a/packages/core/package.json b/packages/core/package.json index daaa111de..7cf20cea7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,6 @@ }, "homepage": "https://strudel.cc", "dependencies": { - "@strudel/webaudio": "^1.2.5", "fraction.js": "^5.2.1" }, "gitHead": "0e26d4e741500f5bae35b023608f062a794905c2", diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100755 new mode 100644 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 40d6eb57b..c225057f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -225,9 +225,6 @@ importers: packages/core: dependencies: - '@strudel/webaudio': - specifier: ^1.2.5 - version: 1.2.5 fraction.js: specifier: ^5.2.1 version: 5.2.1 @@ -2471,15 +2468,6 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@strudel/core@1.2.4': - resolution: {integrity: sha512-sUm9/zjEEQuWfW3hNOCcfNbn8jq2G+Ye+mvpLUgcGyLfI5XPlPTn/PBIkv2hFjNs/basnMyrOUvg0Z85AA6+OA==} - - '@strudel/draw@1.2.4': - resolution: {integrity: sha512-9ui5+ZQQB+EEgwJQueGVMgpnPSHnFgRgivlAZbdjEoMdSm5vULWvKK3Psml8WKtOBNiuL+5Bci7a0INRTRusOA==} - - '@strudel/webaudio@1.2.5': - resolution: {integrity: sha512-ilcyBsuwkH6Ghz0egaqIJ5DZi0xFBZwVWvZb0vnfU7kVESroD2j6yptyFMysJFZhQ5pfRiZs2ZeF6yTsviUjng==} - '@supabase/auth-js@2.67.3': resolution: {integrity: sha512-NJDaW8yXs49xMvWVOkSIr8j46jf+tYHV0wHhrwOaLLMZSFO4g6kKAf+MfzQ2RaD06OCUkUHIzctLAxjTgEVpzw==} @@ -7001,9 +6989,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true - superdough@1.2.5: - resolution: {integrity: sha512-QVkMGGZjWzaRxYKXoZYMfsRHVk5vwNiqAaDOseccSTgqPPwFRTY2fmHAm5OmwwS8XqFOenZjn+XU3LEaCZMdJw==} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -9844,20 +9829,6 @@ snapshots: '@sinclair/typebox@0.27.8': {} - '@strudel/core@1.2.4': - dependencies: - fraction.js: 5.2.1 - - '@strudel/draw@1.2.4': - dependencies: - '@strudel/core': 1.2.4 - - '@strudel/webaudio@1.2.5': - dependencies: - '@strudel/core': 1.2.4 - '@strudel/draw': 1.2.4 - superdough: 1.2.5 - '@supabase/auth-js@2.67.3': dependencies: '@supabase/node-fetch': 2.6.15 @@ -15460,10 +15431,6 @@ snapshots: pirates: 4.0.6 ts-interface-checker: 0.1.13 - superdough@1.2.5: - dependencies: - nanostores: 0.11.3 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 From 7774364ac78b6be15d1fab04b95abf3f9be94ef9 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:36:19 +0300 Subject: [PATCH 20/66] Add webaudio as a workspace dependency --- packages/core/package.json | 1 + packages/osc/server.js | 0 pnpm-lock.yaml | 3 +++ 3 files changed, 4 insertions(+) mode change 100644 => 100755 packages/osc/server.js diff --git a/packages/core/package.json b/packages/core/package.json index 7cf20cea7..e771f0a73 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,6 +31,7 @@ }, "homepage": "https://strudel.cc", "dependencies": { + "@strudel/webaudio": "workspace:*", "fraction.js": "^5.2.1" }, "gitHead": "0e26d4e741500f5bae35b023608f062a794905c2", diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100644 new mode 100755 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c225057f3..217a63d8f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -225,6 +225,9 @@ importers: packages/core: dependencies: + '@strudel/webaudio': + specifier: workspace:* + version: link:../webaudio fraction.js: specifier: ^5.2.1 version: 5.2.1 From f5fc0ff9d19dfb0dc89017be4aa8dd66960864d6 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:58:01 +0300 Subject: [PATCH 21/66] Remove resetGlobalEffects from AudioContext --- packages/superdough/audioContext.mjs | 3 --- packages/webaudio/webaudio.mjs | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/superdough/audioContext.mjs b/packages/superdough/audioContext.mjs index 9a5913d80..2c34f9daf 100644 --- a/packages/superdough/audioContext.mjs +++ b/packages/superdough/audioContext.mjs @@ -1,10 +1,7 @@ -import { analysers, resetGlobalEffects } from './superdough.mjs'; - let audioContext; export const setDefaultAudioContext = () => { audioContext = new AudioContext(); - resetGlobalEffects(); return audioContext; }; diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 43c011460..b1247e34b 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -21,6 +21,7 @@ import { loadWorklets, setMaxPolyphony, setMultiChannelOrbits, + resetGlobalEffects, } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -99,6 +100,7 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d .finally(async () => { setAudioContext(null); setSuperdoughAudioController(null); + resetGlobalEffects() await initAudio(); }); } From 2a0635879cf4fdbc21c933fcaaa46ced4acb6a25 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 20:58:27 +0300 Subject: [PATCH 22/66] Format --- packages/webaudio/webaudio.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index b1247e34b..8141b5363 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -100,7 +100,7 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d .finally(async () => { setAudioContext(null); setSuperdoughAudioController(null); - resetGlobalEffects() + resetGlobalEffects(); await initAudio(); }); } From 0f652e8b5bc73609daa1f52a77cea9db6bc5fb47 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 21:24:27 +0300 Subject: [PATCH 23/66] Remove webaudio from core dependencies --- packages/codemirror/codemirror.mjs | 11 +++------- packages/core/cyclist.mjs | 10 --------- packages/core/package.json | 3 +-- packages/core/repl.mjs | 32 ++++++++++++++--------------- website/src/repl/useReplContext.jsx | 6 +++++- 5 files changed, 24 insertions(+), 38 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 84cbfa96a..a5a978bbb 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -42,9 +42,9 @@ const extensions = { isMultiCursorEnabled: (on) => on ? [ - EditorState.allowMultipleSelections.of(true), - EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), - ] + EditorState.allowMultipleSelections.of(true), + EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), + ] : [], }; const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); @@ -268,11 +268,6 @@ export class StrudelMirror { this.flash(); await this.repl.evaluate(this.code); } - async exportAudio(begin, end, sampleRate, downloadName = undefined) { - await this.repl.evaluate(this.code, false); - await this.repl.exportAudio(begin, end, sampleRate, downloadName); - this.repl.scheduler.stop(); - } async stop() { this.repl.scheduler.stop(); } diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index 185d5588b..fdd8cf1c7 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -6,7 +6,6 @@ This program is free software: you can redistribute it and/or modify it under th import createClock from './zyklus.mjs'; import { errorLogger, logger } from './logger.mjs'; -import { loadBuffer, renderPatternAudio, setAudioContext, superdough } from '@strudel/webaudio'; export class Cyclist { constructor({ @@ -111,15 +110,6 @@ export class Cyclist { this.clock.start(); this.setStarted(true); } - - async exportAudio(begin, end, sampleRate, downloadName = undefined) { - if (!this.pattern) { - throw new Error('Scheduler: no pattern set! call .setPattern first.'); - } - logger('[cyclist] exporting'); - await renderPatternAudio(this.pattern, this.cps, begin, end, sampleRate, downloadName); - } - pause() { logger('[cyclist] pause'); this.clock.pause(); diff --git a/packages/core/package.json b/packages/core/package.json index e771f0a73..50e02e4b2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,6 @@ }, "homepage": "https://strudel.cc", "dependencies": { - "@strudel/webaudio": "workspace:*", "fraction.js": "^5.2.1" }, "gitHead": "0e26d4e741500f5bae35b023608f062a794905c2", @@ -39,4 +38,4 @@ "vite": "^6.0.11", "vitest": "^3.0.4" } -} +} \ No newline at end of file diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 4a35b932e..6cbc9e9ce 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -91,8 +91,6 @@ export function repl({ const stop = () => scheduler.stop(); const start = () => scheduler.start(); - const exportAudio = async (begin, end, sampleRate, downloadName = undefined) => - await scheduler.exportAudio(begin, end, sampleRate, downloadName); const pause = () => scheduler.pause(); const toggle = () => scheduler.toggle(); const setCps = (cps) => { @@ -259,23 +257,23 @@ export function repl({ } }; const setCode = (code) => updateState({ code }); - return { scheduler, evaluate, start, exportAudio, stop, pause, setCps, setPattern, setCode, toggle, state }; + return { scheduler, evaluate, start, stop, pause, setCps, setPattern, setCode, toggle, state }; } export const getTrigger = ({ getTime, defaultOutput }) => - async (hap, deadline, duration, cps, t) => { - // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) - // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 - try { - if (!hap.context.onTrigger || !hap.context.dominantTrigger) { - await defaultOutput(hap, deadline, duration, cps, t); + async (hap, deadline, duration, cps, t) => { + // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) + // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 + try { + if (!hap.context.onTrigger || !hap.context.dominantTrigger) { + await defaultOutput(hap, deadline, duration, cps, t); + } + if (hap.context.onTrigger) { + // call signature of output / onTrigger is different... + await hap.context.onTrigger(hap, getTime(), cps, t); + } + } catch (err) { + errorLogger(err, 'getTrigger'); } - if (hap.context.onTrigger) { - // call signature of output / onTrigger is different... - await hap.context.onTrigger(hap, getTime(), cps, t); - } - } catch (err) { - errorLogger(err, 'getTrigger'); - } - }; + }; diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 0e89fb68b..118277083 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -9,6 +9,7 @@ import { getDrawContext } from '@strudel/draw'; import { transpiler } from '@strudel/transpiler'; import { getAudioContextCurrentTime, + renderPatternAudio, webaudioOutput, resetGlobalEffects, resetLoadedSounds, @@ -203,8 +204,11 @@ export function useReplContext() { const handleEvaluate = () => { editorRef.current.evaluate(); }; + const handleExport = async (begin, end, sampleRate, downloadName = undefined) => { - await editorRef.current.exportAudio(begin, end, sampleRate, downloadName); + await editorRef.current.evaluate(); + await renderPatternAudio(editorRef.current.repl.state.pattern, editorRef.current.repl.scheduler.cps, begin, end, sampleRate, downloadName) + editorRef.current.repl.scheduler.stop(); }; const handleShuffle = async () => { const patternData = await getRandomTune(); From a2b76bde142dbca85a993fc9f18e7bf2071d8095 Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 21:24:54 +0300 Subject: [PATCH 24/66] Format --- packages/codemirror/codemirror.mjs | 6 +++--- packages/core/repl.mjs | 28 ++++++++++++++-------------- website/src/repl/useReplContext.jsx | 9 ++++++++- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index a5a978bbb..4dc23996f 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -42,9 +42,9 @@ const extensions = { isMultiCursorEnabled: (on) => on ? [ - EditorState.allowMultipleSelections.of(true), - EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), - ] + EditorState.allowMultipleSelections.of(true), + EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), + ] : [], }; const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 6cbc9e9ce..171697eb9 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -262,18 +262,18 @@ export function repl({ export const getTrigger = ({ getTime, defaultOutput }) => - async (hap, deadline, duration, cps, t) => { - // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) - // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 - try { - if (!hap.context.onTrigger || !hap.context.dominantTrigger) { - await defaultOutput(hap, deadline, duration, cps, t); - } - if (hap.context.onTrigger) { - // call signature of output / onTrigger is different... - await hap.context.onTrigger(hap, getTime(), cps, t); - } - } catch (err) { - errorLogger(err, 'getTrigger'); + async (hap, deadline, duration, cps, t) => { + // ^ this signature is different from hap.context.onTrigger, as set by Pattern.onTrigger(onTrigger) + // TODO: get rid of deadline after https://codeberg.org/uzu/strudel/pulls/1004 + try { + if (!hap.context.onTrigger || !hap.context.dominantTrigger) { + await defaultOutput(hap, deadline, duration, cps, t); } - }; + if (hap.context.onTrigger) { + // call signature of output / onTrigger is different... + await hap.context.onTrigger(hap, getTime(), cps, t); + } + } catch (err) { + errorLogger(err, 'getTrigger'); + } + }; diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 118277083..aacd0872a 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -207,7 +207,14 @@ export function useReplContext() { const handleExport = async (begin, end, sampleRate, downloadName = undefined) => { await editorRef.current.evaluate(); - await renderPatternAudio(editorRef.current.repl.state.pattern, editorRef.current.repl.scheduler.cps, begin, end, sampleRate, downloadName) + await renderPatternAudio( + editorRef.current.repl.state.pattern, + editorRef.current.repl.scheduler.cps, + begin, + end, + sampleRate, + downloadName, + ); editorRef.current.repl.scheduler.stop(); }; const handleShuffle = async () => { From a8ea9a1b6334e0792b404c7bdefa850a8d41329e Mon Sep 17 00:00:00 2001 From: Nikita Date: Mon, 20 Oct 2025 21:26:40 +0300 Subject: [PATCH 25/66] Update lockfile --- pnpm-lock.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 217a63d8f..c225057f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -225,9 +225,6 @@ importers: packages/core: dependencies: - '@strudel/webaudio': - specifier: workspace:* - version: link:../webaudio fraction.js: specifier: ^5.2.1 version: 5.2.1 From bf702c3b2a12a76d1dbac81c2d5eb0d50f72acff Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 21 Oct 2025 16:30:18 +0300 Subject: [PATCH 26/66] Reviewed changes --- packages/core/cyclist.mjs | 1 - packages/superdough/superdough.mjs | 5 ++--- packages/webaudio/webaudio.mjs | 14 ++++++-------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/core/cyclist.mjs b/packages/core/cyclist.mjs index fdd8cf1c7..59e410c53 100644 --- a/packages/core/cyclist.mjs +++ b/packages/core/cyclist.mjs @@ -98,7 +98,6 @@ export class Cyclist { this.started = v; this.onToggle?.(v); } - async start() { await this.beforeStart?.(); this.num_ticks_since_cps_change = 0; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 118a152b1..c2bbba36a 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -282,7 +282,7 @@ export async function initAudioOnFirstClick(options) { } let controller; -function getSuperdoughAudioController() { +export function getSuperdoughAudioController() { if (controller == null) { controller = new SuperdoughAudioController(getAudioContext()); } @@ -376,7 +376,6 @@ function mapChannelNumbers(channels) { } export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) => { - // controller = null; // new: t is always expected to be the absolute target onset time const ac = getAudioContext(); const audioController = getSuperdoughAudioController(); @@ -402,7 +401,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) `[superdough]: cannot schedule sounds in the past (target: ${t.toFixed(2)}, now: ${ac.currentTime.toFixed(2)})`, ); return; - } // FIXME: fix + } // destructure let { tremolo, diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 8141b5363..46b5d8d08 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -45,12 +45,11 @@ export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => { }; export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, downloadName = undefined) { - const oldAudioCtx = getAudioContext(); - await oldAudioCtx.close(); - let audioContext = new OfflineAudioContext(2, ((end - begin) / cps) * sampleRate, sampleRate); + let audioContext = getAudioContext(); + await audioContext.close(); + audioContext = new OfflineAudioContext(2, ((end - begin) / cps) * sampleRate, sampleRate); setAudioContext(audioContext); - let context = getAudioContext(); - setSuperdoughAudioController(new SuperdoughAudioController(context)); + setSuperdoughAudioController(new SuperdoughAudioController(audioContext)); setMaxPolyphony(1024); setMultiChannelOrbits(true); await loadWorklets(); @@ -69,7 +68,7 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d let bank = getSound(s).data.samples; if (bank) { let { url: sampleUrl, label } = getSampleInfo(h.value, bank); - await loadBuffer(sampleUrl, context, label); + await loadBuffer(sampleUrl, audioContext, label); } } }), @@ -81,10 +80,9 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d } }); - return context + return audioContext .startRendering() .then((renderedBuffer) => { - console.log(renderedBuffer); const wavBuffer = audioBufferToWav(renderedBuffer); const blob = new Blob([wavBuffer], { type: 'audio/wav' }); const url = URL.createObjectURL(blob); From 498624f6fe24b57b83d5e1e028b0b23a9ad8d5b7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 21 Oct 2025 16:35:33 +0300 Subject: [PATCH 27/66] Make server.js a normal file --- packages/osc/server.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 packages/osc/server.js diff --git a/packages/osc/server.js b/packages/osc/server.js old mode 100755 new mode 100644 From 98031676d6a13e5ee8ceb76a0e82cb539f92552c Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 21 Oct 2025 16:44:42 +0300 Subject: [PATCH 28/66] Add an EOL character to package.json --- packages/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 50e02e4b2..7cf20cea7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -38,4 +38,4 @@ "vite": "^6.0.11", "vitest": "^3.0.4" } -} \ No newline at end of file +} From 92d3fe496d7d893497724cfb436ca6c7965561a5 Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 21 Oct 2025 21:00:30 +0300 Subject: [PATCH 29/66] Bug fixes --- packages/codemirror/codemirror.mjs | 4 ++-- packages/webaudio/webaudio.mjs | 4 ++-- website/src/repl/useReplContext.jsx | 8 +++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 4dc23996f..a42529cc4 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -264,9 +264,9 @@ export class StrudelMirror { console.warn('first frame could not be painted'); } } - async evaluate() { + async evaluate(autoplay = true) { this.flash(); - await this.repl.evaluate(this.code); + await this.repl.evaluate(this.code, autoplay); } async stop() { this.repl.scheduler.stop(); diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 46b5d8d08..7a5ffac32 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -52,11 +52,11 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d setSuperdoughAudioController(new SuperdoughAudioController(audioContext)); setMaxPolyphony(1024); setMultiChannelOrbits(true); - await loadWorklets(); + await initAudio(); logger('[webaudio] start rendering'); let haps = pattern.queryArc(begin, end, { _cps: cps }); - Promise.all( + await Promise.all( haps.map(async (h) => { let s; if (h.value.s) { diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index aacd0872a..49d493157 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -206,7 +206,8 @@ export function useReplContext() { }; const handleExport = async (begin, end, sampleRate, downloadName = undefined) => { - await editorRef.current.evaluate(); + await editorRef.current.evaluate(true); + editorRef.current.repl.scheduler.stop(); await renderPatternAudio( editorRef.current.repl.state.pattern, editorRef.current.repl.scheduler.cps, @@ -214,8 +215,9 @@ export function useReplContext() { end, sampleRate, downloadName, - ); - editorRef.current.repl.scheduler.stop(); + ).finally(() => { + editorRef.current.repl.scheduler.stop(); + }); }; const handleShuffle = async () => { const patternData = await getRandomTune(); From daea207aff9403ae7db8365136caa7702f08337a Mon Sep 17 00:00:00 2001 From: Nikita Date: Tue, 21 Oct 2025 22:42:01 +0300 Subject: [PATCH 30/66] Better sample loading --- packages/codemirror/codemirror.mjs | 10 ++++----- packages/superdough/sampler.mjs | 2 +- packages/superdough/superdough.mjs | 2 +- packages/webaudio/webaudio.mjs | 32 ++++++++++++++++++++++------- website/src/repl/useReplContext.jsx | 2 +- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index a42529cc4..3411728a0 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -42,9 +42,9 @@ const extensions = { isMultiCursorEnabled: (on) => on ? [ - EditorState.allowMultipleSelections.of(true), - EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), - ] + EditorState.allowMultipleSelections.of(true), + EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), + ] : [], }; const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); @@ -264,9 +264,9 @@ export class StrudelMirror { console.warn('first frame could not be painted'); } } - async evaluate(autoplay = true) { + async evaluate(autostart = true) { this.flash(); - await this.repl.evaluate(this.code, autoplay); + await this.repl.evaluate(this.code, autostart); } async stop() { this.repl.scheduler.stop(); diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 3232fa476..d996f3a26 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -289,7 +289,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { const { bufferSource, sliceDuration, offset } = await getSampleBufferSource(value, bank, resolveUrl); // asny stuff above took too long? - if (ac.currentTime > t) { + if (ac.currentTime > t && !(ac instanceof OfflineAudioContext)) { logger(`[sampler] still loading sound "${s}:${n}"`, 'highlight'); // console.warn('sample still loading:', s, n); return; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index c2bbba36a..e6972ab71 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -562,7 +562,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) return; } - if (ac.currentTime > t) { + if (ac.currentTime > t && !(ac instanceof OfflineAudioContext)) { logger('[webaudio] skip hap: still loading', ac.currentTime - t); return; } diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 7a5ffac32..fae2c46cf 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -22,11 +22,14 @@ import { setMaxPolyphony, setMultiChannelOrbits, resetGlobalEffects, + getDefaultValue, } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; import { SuperdoughAudioController } from 'superdough/superdoughoutput.mjs'; - +import { loadModules } from '@src/repl/util.mjs'; +import { prebake } from '@src/repl/prebake.mjs'; +import { getFontBufferSource, getFontPitch } from 'node_modules/@strudel/soundfonts/fontloader.mjs'; registerWorklet(workletUrl); const { Pattern, logger, repl } = strudel; @@ -56,7 +59,9 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d logger('[webaudio] start rendering'); let haps = pattern.queryArc(begin, end, { _cps: cps }); - await Promise.all( + await Promise.all([ + loadModules(), + prebake(), haps.map(async (h) => { let s; if (h.value.s) { @@ -65,13 +70,26 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d } else { s = h.value.s; } - let bank = getSound(s).data.samples; - if (bank) { - let { url: sampleUrl, label } = getSampleInfo(h.value, bank); - await loadBuffer(sampleUrl, audioContext, label); + // let bank = getSound(s).data.samples; + let sample = getSound(s); + if (sample.data.type == "soundfont") { + sample.data.fonts.forEach(async (font) => { + await getFontBufferSource(font, h.value, audioContext) + }) } + if (sample.data.type == "sample") { + let url; + if (Array.isArray(sample)) { + url = sample.data.samples[i % sample.data.samples.length]; + } else if (typeof sample === 'object') { + console.log(sample.data.samples) + url = Object.values(sample.data.samples).flat()[getDefaultValue("i") % Object.values(sample.data.samples).length]; + } + await loadBuffer(url, audioContext, s, 0); + } // TODO: waveform } - }), + }) + ], ); haps.forEach(async (hap) => { if (hap.hasOnset()) { diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 49d493157..b775df659 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -206,7 +206,7 @@ export function useReplContext() { }; const handleExport = async (begin, end, sampleRate, downloadName = undefined) => { - await editorRef.current.evaluate(true); + await editorRef.current.evaluate(false); editorRef.current.repl.scheduler.stop(); await renderPatternAudio( editorRef.current.repl.state.pattern, From 5e27358fe86706d36775ac6134c3d7025fc780f6 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 22 Oct 2025 16:19:58 +0300 Subject: [PATCH 31/66] Better preloading --- packages/webaudio/webaudio.mjs | 65 ++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index fae2c46cf..2bdb9a98a 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -23,6 +23,7 @@ import { setMultiChannelOrbits, resetGlobalEffects, getDefaultValue, + getSampleBuffer, } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -62,45 +63,47 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d await Promise.all([ loadModules(), prebake(), - haps.map(async (h) => { - let s; - if (h.value.s) { - if (h.value.bank) { - s = `${h.value.bank}_${h.value.s}`; - } else { - s = h.value.s; - } - // let bank = getSound(s).data.samples; - let sample = getSound(s); - if (sample.data.type == "soundfont") { - sample.data.fonts.forEach(async (font) => { - await getFontBufferSource(font, h.value, audioContext) - }) - } - if (sample.data.type == "sample") { - let url; - if (Array.isArray(sample)) { - url = sample.data.samples[i % sample.data.samples.length]; - } else if (typeof sample === 'object') { - console.log(sample.data.samples) - url = Object.values(sample.data.samples).flat()[getDefaultValue("i") % Object.values(sample.data.samples).length]; - } - await loadBuffer(url, audioContext, s, 0); - } // TODO: waveform + ]); + + haps.forEach(async (h) => { + let s; + if (h.value.s) { + if (h.value.bank) { + s = `${h.value.bank}_${h.value.s}`; + } else { + s = h.value.s; } - }) - ], - ); - haps.forEach(async (hap) => { + // let bank = getSound(s).data.samples; + let sample = getSound(s); + if (sample.data.type == "soundfont") { + for (let index = 0; index < sample.data.fonts.length; index++) { + const font = array[index]; + await getFontBufferSource(font, h.value, audioContext) + } + } + if (sample.data.type == "sample") { + for (let index = 0; index < sample.data.samples.length; index++) { + const sample = array[index]; + await getSampleBuffer(h.value, bank, sample) + } + } // TODO: waveform + } + }) + + for (let index = 0; index < haps.length; index++) { + const hap = haps[index]; if (hap.hasOnset()) { - hap.ensureObjectValue(); + await hap.ensureObjectValue(); + console.log("dough") await superdough(hap.value, hap.whole.begin.valueOf() / cps, hap.duration, cps, hap.whole?.begin.valueOf()); } - }); + } + console.log("starting rendering") return audioContext .startRendering() .then((renderedBuffer) => { + console.log('downloading') const wavBuffer = audioBufferToWav(renderedBuffer); const blob = new Blob([wavBuffer], { type: 'audio/wav' }); const url = URL.createObjectURL(blob); From e7578be6c5c11756e20669337ca33f310c24a2ea Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 22 Oct 2025 17:16:05 +0300 Subject: [PATCH 32/66] Remove preloading code and instead await superdough --- packages/webaudio/webaudio.mjs | 42 ++++------------------------------ 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 2bdb9a98a..9764516c7 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -57,48 +57,16 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d setMaxPolyphony(1024); setMultiChannelOrbits(true); await initAudio(); - logger('[webaudio] start rendering'); + logger('[webaudio] preloading'); let haps = pattern.queryArc(begin, end, { _cps: cps }); - await Promise.all([ - loadModules(), - prebake(), - ]); - haps.forEach(async (h) => { - let s; - if (h.value.s) { - if (h.value.bank) { - s = `${h.value.bank}_${h.value.s}`; - } else { - s = h.value.s; - } - // let bank = getSound(s).data.samples; - let sample = getSound(s); - if (sample.data.type == "soundfont") { - for (let index = 0; index < sample.data.fonts.length; index++) { - const font = array[index]; - await getFontBufferSource(font, h.value, audioContext) - } - } - if (sample.data.type == "sample") { - for (let index = 0; index < sample.data.samples.length; index++) { - const sample = array[index]; - await getSampleBuffer(h.value, bank, sample) - } - } // TODO: waveform - } - }) - - for (let index = 0; index < haps.length; index++) { - const hap = haps[index]; + await Promise.all(haps.map(async (hap) => { if (hap.hasOnset()) { - await hap.ensureObjectValue(); - console.log("dough") - await superdough(hap.value, hap.whole.begin.valueOf() / cps, hap.duration, cps, hap.whole?.begin.valueOf()); + await superdough(hap2value(hap), hap.whole.begin.valueOf() / cps, hap.duration, cps, hap.whole?.begin.valueOf()); } - } - console.log("starting rendering") + })); + logger('[webaudio] start rendering'); return audioContext .startRendering() From 95700e11967b9be35c984f67e9a8510573fbe80f Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 22 Oct 2025 20:00:36 +0300 Subject: [PATCH 33/66] Fix wavetables breaking after playback --- packages/codemirror/codemirror.mjs | 6 +++--- packages/superdough/superdough.mjs | 2 ++ packages/superdough/wavetable.mjs | 5 +++++ packages/webaudio/webaudio.mjs | 20 ++++++++++++++------ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index 3411728a0..ab3a3c995 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -42,9 +42,9 @@ const extensions = { isMultiCursorEnabled: (on) => on ? [ - EditorState.allowMultipleSelections.of(true), - EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), - ] + EditorState.allowMultipleSelections.of(true), + EditorView.clickAddsSelectionRange.of((ev) => ev.metaKey || ev.ctrlKey), + ] : [], }; const compartments = Object.fromEntries(Object.keys(extensions).map((key) => [key, new Compartment()])); diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index e6972ab71..7fe60ae49 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -15,6 +15,7 @@ import { logger } from './logger.mjs'; import { loadBuffer } from './sampler.mjs'; import { getAudioContext, setAudioContext } from './audioContext.mjs'; import { SuperdoughAudioController } from './superdoughoutput.mjs'; +import { resetSeenKeys } from './wavetable.mjs'; export const DEFAULT_MAX_POLYPHONY = 128; const DEFAULT_AUDIO_DEVICE_NAME = 'System Standard'; @@ -231,6 +232,7 @@ export async function initAudio(options = {}) { setMaxPolyphony(maxPolyphony); setMultiChannelOrbits(multiChannelOrbits); + resetSeenKeys(); if (typeof window === 'undefined') { return; } diff --git a/packages/superdough/wavetable.mjs b/packages/superdough/wavetable.mjs index 01d4eb838..902fb4edd 100644 --- a/packages/superdough/wavetable.mjs +++ b/packages/superdough/wavetable.mjs @@ -40,6 +40,11 @@ export const Warpmode = Object.freeze({ }); const seenKeys = new Set(); + +export function resetSeenKeys() { + seenKeys.clear(); +} + async function getPayload(url, label, frameLen = 2048) { const key = `${url},${frameLen}`; if (!seenKeys.has(key)) { diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 9764516c7..777a271aa 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -61,17 +61,25 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d let haps = pattern.queryArc(begin, end, { _cps: cps }); - await Promise.all(haps.map(async (hap) => { - if (hap.hasOnset()) { - await superdough(hap2value(hap), hap.whole.begin.valueOf() / cps, hap.duration, cps, hap.whole?.begin.valueOf()); - } - })); + await Promise.all( + haps.map(async (hap) => { + if (hap.hasOnset()) { + await superdough( + hap2value(hap), + hap.whole.begin.valueOf() / cps, + hap.duration, + cps, + hap.whole?.begin.valueOf(), + ); + } + }), + ); logger('[webaudio] start rendering'); return audioContext .startRendering() .then((renderedBuffer) => { - console.log('downloading') + console.log('downloading'); const wavBuffer = audioBufferToWav(renderedBuffer); const blob = new Blob([wavBuffer], { type: 'audio/wav' }); const url = URL.createObjectURL(blob); From 7b74a902a21ffcf3aa171f2b28ebe29d821d25a6 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 22 Oct 2025 20:05:03 +0300 Subject: [PATCH 34/66] Remove unneeded imports --- packages/webaudio/webaudio.mjs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 777a271aa..c87f8ab05 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -12,25 +12,15 @@ import { doughTrigger, registerWorklet, setAudioContext, - getSampleBufferSource, - loadBuffer, - getSampleInfo, - getSound, initAudio, setSuperdoughAudioController, - loadWorklets, setMaxPolyphony, setMultiChannelOrbits, resetGlobalEffects, - getDefaultValue, - getSampleBuffer, } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; import { SuperdoughAudioController } from 'superdough/superdoughoutput.mjs'; -import { loadModules } from '@src/repl/util.mjs'; -import { prebake } from '@src/repl/prebake.mjs'; -import { getFontBufferSource, getFontPitch } from 'node_modules/@strudel/soundfonts/fontloader.mjs'; registerWorklet(workletUrl); const { Pattern, logger, repl } = strudel; @@ -79,7 +69,6 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d return audioContext .startRendering() .then((renderedBuffer) => { - console.log('downloading'); const wavBuffer = audioBufferToWav(renderedBuffer); const blob = new Blob([wavBuffer], { type: 'audio/wav' }); const url = URL.createObjectURL(blob); From 5a70599aac6907fbcb32b4e2a3cb85f55d8410de Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 22 Oct 2025 22:48:04 +0300 Subject: [PATCH 35/66] Ignore superdough errors when exporting, instead skip sound. --- packages/webaudio/webaudio.mjs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index c87f8ab05..816434889 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -54,13 +54,17 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d await Promise.all( haps.map(async (hap) => { if (hap.hasOnset()) { - await superdough( - hap2value(hap), - hap.whole.begin.valueOf() / cps, - hap.duration, - cps, - hap.whole?.begin.valueOf(), - ); + try { + await superdough( + hap2value(hap), + hap.whole.begin.valueOf() / cps, + hap.duration, + cps, + hap.whole?.begin.valueOf(), + ); + } catch (error) { + logger("[webaudio] An error had occured while calling superdough. Skipping hap.") + } } }), ); @@ -81,12 +85,12 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d document.body.removeChild(a); URL.revokeObjectURL(url); }) - .finally(async () => { - setAudioContext(null); - setSuperdoughAudioController(null); - resetGlobalEffects(); - await initAudio(); - }); + // .finally(async () => { + // setAudioContext(null); + // setSuperdoughAudioController(null); + // resetGlobalEffects(); + // await initAudio(); + // }); } export function webaudioRepl(options = {}) { From 16f885c010d9fc27f7afd7a49a3419476b767f86 Mon Sep 17 00:00:00 2001 From: Nikita Date: Wed, 22 Oct 2025 23:09:30 +0300 Subject: [PATCH 36/66] Use errorLogger instead --- packages/webaudio/webaudio.mjs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 816434889..4ad778d17 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -17,6 +17,7 @@ import { setMaxPolyphony, setMultiChannelOrbits, resetGlobalEffects, + errorLogger, } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -62,8 +63,8 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d cps, hap.whole?.begin.valueOf(), ); - } catch (error) { - logger("[webaudio] An error had occured while calling superdough. Skipping hap.") + } catch (err) { + errorLogger(err, 'webaudio') } } }), @@ -85,12 +86,12 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d document.body.removeChild(a); URL.revokeObjectURL(url); }) - // .finally(async () => { - // setAudioContext(null); - // setSuperdoughAudioController(null); - // resetGlobalEffects(); - // await initAudio(); - // }); + .finally(async () => { + setAudioContext(null); + setSuperdoughAudioController(null); + resetGlobalEffects(); + await initAudio(); + }); } export function webaudioRepl(options = {}) { From 6baca67cd3f7ab18970dfff68d8e72dbfccd77f5 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 23 Oct 2025 17:07:53 +0300 Subject: [PATCH 37/66] Fix maxPolyphony and multiChannelOrbits not applying to export --- packages/webaudio/webaudio.mjs | 8 ++++---- website/src/repl/components/ExportModal.jsx | 2 +- website/src/repl/useReplContext.jsx | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 4ad778d17..3fc4df8bd 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -39,15 +39,15 @@ export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => { return superdough(hap2value(hap), t, hapDuration, cps, hap.whole?.begin.valueOf()); }; -export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, downloadName = undefined) { +export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, maxPolyphony, multiChannelOrbits, downloadName = undefined) { let audioContext = getAudioContext(); await audioContext.close(); audioContext = new OfflineAudioContext(2, ((end - begin) / cps) * sampleRate, sampleRate); setAudioContext(audioContext); setSuperdoughAudioController(new SuperdoughAudioController(audioContext)); - setMaxPolyphony(1024); - setMultiChannelOrbits(true); await initAudio(); + setMaxPolyphony(maxPolyphony); + setMultiChannelOrbits(multiChannelOrbits); logger('[webaudio] preloading'); let haps = pattern.queryArc(begin, end, { _cps: cps }); @@ -64,7 +64,7 @@ export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, d hap.whole?.begin.valueOf(), ); } catch (err) { - errorLogger(err, 'webaudio') + errorLogger(err, 'webaudio'); } } }), diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index 036f6f36a..990eb1132 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -204,7 +204,7 @@ export default function ExportModal(Props) { setStrudelMaxPolyphony(maxPolyphony); setStrudelMultiChannelOrbits(multiChannelOrbits); setTimeout(refreshProgress, 1000); - await handleExport(startCycle, endCycle, sampleRate, downloadName).finally(() => { + await handleExport(startCycle, endCycle, sampleRate, maxPolyphony, multiChannelOrbits, downloadName).finally(() => { setExporting(false); const modal = document.getElementById('exportModal'); setProgress(0); diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index b775df659..15b3fab10 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -205,7 +205,7 @@ export function useReplContext() { editorRef.current.evaluate(); }; - const handleExport = async (begin, end, sampleRate, downloadName = undefined) => { + const handleExport = async (begin, end, sampleRate, maxPolyphony, multiChannelOrbits, downloadName = undefined) => { await editorRef.current.evaluate(false); editorRef.current.repl.scheduler.stop(); await renderPatternAudio( @@ -214,6 +214,8 @@ export function useReplContext() { begin, end, sampleRate, + maxPolyphony, + multiChannelOrbits, downloadName, ).finally(() => { editorRef.current.repl.scheduler.stop(); From fe70a2df43c874639ff0fd778fe03e9261212de5 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 23 Oct 2025 17:08:11 +0300 Subject: [PATCH 38/66] Format --- packages/webaudio/webaudio.mjs | 11 ++++++++++- website/src/repl/components/ExportModal.jsx | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 3fc4df8bd..0df487be2 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -39,7 +39,16 @@ export const webaudioOutput = (hap, _deadline, hapDuration, cps, t) => { return superdough(hap2value(hap), t, hapDuration, cps, hap.whole?.begin.valueOf()); }; -export async function renderPatternAudio(pattern, cps, begin, end, sampleRate, maxPolyphony, multiChannelOrbits, downloadName = undefined) { +export async function renderPatternAudio( + pattern, + cps, + begin, + end, + sampleRate, + maxPolyphony, + multiChannelOrbits, + downloadName = undefined, +) { let audioContext = getAudioContext(); await audioContext.close(); audioContext = new OfflineAudioContext(2, ((end - begin) / cps) * sampleRate, sampleRate); diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index 990eb1132..ad4ddad5d 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -204,7 +204,14 @@ export default function ExportModal(Props) { setStrudelMaxPolyphony(maxPolyphony); setStrudelMultiChannelOrbits(multiChannelOrbits); setTimeout(refreshProgress, 1000); - await handleExport(startCycle, endCycle, sampleRate, maxPolyphony, multiChannelOrbits, downloadName).finally(() => { + await handleExport( + startCycle, + endCycle, + sampleRate, + maxPolyphony, + multiChannelOrbits, + downloadName, + ).finally(() => { setExporting(false); const modal = document.getElementById('exportModal'); setProgress(0); From ca936aada775ec734c25769fa10af2a35f4da402 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 23 Oct 2025 21:46:13 +0300 Subject: [PATCH 39/66] Fix incorrect duration calculation --- packages/webaudio/webaudio.mjs | 2 +- website/src/repl/components/ExportModal.jsx | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 0df487be2..99e5be5ed 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -68,7 +68,7 @@ export async function renderPatternAudio( await superdough( hap2value(hap), hap.whole.begin.valueOf() / cps, - hap.duration, + hap.duration / cps, cps, hap.whole?.begin.valueOf(), ); diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index ad4ddad5d..9f32d6930 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -211,12 +211,13 @@ export default function ExportModal(Props) { maxPolyphony, multiChannelOrbits, downloadName, - ).finally(() => { - setExporting(false); + ).then(() => { const modal = document.getElementById('exportModal'); + modal.close(); + }).finally(() => { + setExporting(false); setProgress(0); setLength(1); - modal.close(); }); }} > From 9cbeaef88defc63150db0eb094ca3e7e2ad21275 Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 23 Oct 2025 22:21:40 +0300 Subject: [PATCH 40/66] Format --- website/src/repl/components/ExportModal.jsx | 25 +++++++++------------ 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index 9f32d6930..93624fa07 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -204,21 +204,16 @@ export default function ExportModal(Props) { setStrudelMaxPolyphony(maxPolyphony); setStrudelMultiChannelOrbits(multiChannelOrbits); setTimeout(refreshProgress, 1000); - await handleExport( - startCycle, - endCycle, - sampleRate, - maxPolyphony, - multiChannelOrbits, - downloadName, - ).then(() => { - const modal = document.getElementById('exportModal'); - modal.close(); - }).finally(() => { - setExporting(false); - setProgress(0); - setLength(1); - }); + await handleExport(startCycle, endCycle, sampleRate, maxPolyphony, multiChannelOrbits, downloadName) + .then(() => { + const modal = document.getElementById('exportModal'); + modal.close(); + }) + .finally(() => { + setExporting(false); + setProgress(0); + setLength(1); + }); }} > {exporting ? 'Exporting...' : 'Export to WAV'} From ff370cf86f5d5a2b7bc21b59f74fb1839cd3c755 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 24 Oct 2025 14:07:57 +0300 Subject: [PATCH 41/66] Reapply realtimeOptions after export --- packages/superdough/sampler.mjs | 2 +- packages/superdough/superdough.mjs | 8 ++++---- packages/webaudio/webaudio.mjs | 15 +++++++++++---- website/src/repl/components/ExportModal.jsx | 4 ---- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/superdough/sampler.mjs b/packages/superdough/sampler.mjs index 742be592f..84bac3582 100644 --- a/packages/superdough/sampler.mjs +++ b/packages/superdough/sampler.mjs @@ -287,7 +287,7 @@ export async function onTriggerSample(t, value, onended, bank, resolveUrl) { const { bufferSource, sliceDuration, offset } = await getSampleBufferSource(value, bank, resolveUrl); // asny stuff above took too long? - if (ac.currentTime > t && !(ac instanceof OfflineAudioContext)) { + if (ac.currentTime > t) { logger(`[sampler] still loading sound "${s}:${n}"`, 'highlight'); // console.warn('sample still loading:', s, n); return; diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index ae722b7ce..e7d62a8eb 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -20,13 +20,13 @@ import { resetSeenKeys } from './wavetable.mjs'; export const DEFAULT_MAX_POLYPHONY = 128; const DEFAULT_AUDIO_DEVICE_NAME = 'System Standard'; -let maxPolyphony = DEFAULT_MAX_POLYPHONY; +export let maxPolyphony = DEFAULT_MAX_POLYPHONY; export function setMaxPolyphony(polyphony) { maxPolyphony = parseInt(polyphony) ?? DEFAULT_MAX_POLYPHONY; } -let multiChannelOrbits = false; +export let multiChannelOrbits = false; export function setMultiChannelOrbits(bool) { multiChannelOrbits = bool == true; } @@ -398,7 +398,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) // duration is passed as value too.. value.duration = hapDuration; // calculate absolute time - if (t < ac.currentTime && !(ac instanceof OfflineAudioContext)) { + if (t < ac.currentTime) { console.warn( `[superdough]: cannot schedule sounds in the past (target: ${t.toFixed(2)}, now: ${ac.currentTime.toFixed(2)})`, ); @@ -564,7 +564,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5) return; } - if (ac.currentTime > t && !(ac instanceof OfflineAudioContext)) { + if (ac.currentTime > t) { logger('[webaudio] skip hap: still loading', ac.currentTime - t); return; } diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 99e5be5ed..c9b5cbda3 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -18,6 +18,8 @@ import { setMultiChannelOrbits, resetGlobalEffects, errorLogger, + maxPolyphony as superdoughMaxPolyphony, + multiChannelOrbits as superdoughMultiChannelOrbits } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -49,14 +51,19 @@ export async function renderPatternAudio( multiChannelOrbits, downloadName = undefined, ) { + let realtimeOptions = { + maxPolyphony: superdoughMaxPolyphony, + multiChannelOrbits: superdoughMultiChannelOrbits + } let audioContext = getAudioContext(); await audioContext.close(); audioContext = new OfflineAudioContext(2, ((end - begin) / cps) * sampleRate, sampleRate); setAudioContext(audioContext); setSuperdoughAudioController(new SuperdoughAudioController(audioContext)); - await initAudio(); - setMaxPolyphony(maxPolyphony); - setMultiChannelOrbits(multiChannelOrbits); + await initAudio({ + maxPolyphony, + multiChannelOrbits + }); logger('[webaudio] preloading'); let haps = pattern.queryArc(begin, end, { _cps: cps }); @@ -99,7 +106,7 @@ export async function renderPatternAudio( setAudioContext(null); setSuperdoughAudioController(null); resetGlobalEffects(); - await initAudio(); + await initAudio(realtimeOptions); }); } diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index 93624fa07..4bc8990ea 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -4,8 +4,6 @@ import NumberInput from './NumberInput'; import { useEffect, useState } from 'react'; import { Textbox } from './textbox/Textbox'; import { - setMultiChannelOrbits as setStrudelMultiChannelOrbits, - setMaxPolyphony as setStrudelMaxPolyphony, getAudioContext, } from '@strudel/webaudio'; import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; @@ -201,8 +199,6 @@ export default function ExportModal(Props) { disabled={exporting} onClick={async () => { setExporting(true); - setStrudelMaxPolyphony(maxPolyphony); - setStrudelMultiChannelOrbits(multiChannelOrbits); setTimeout(refreshProgress, 1000); await handleExport(startCycle, endCycle, sampleRate, maxPolyphony, multiChannelOrbits, downloadName) .then(() => { From fb7f686519130ed07fe66f561e6ab46cbc609a27 Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 16 Nov 2025 15:22:34 -0600 Subject: [PATCH 42/66] Add seeding --- packages/core/signal.mjs | 111 +- test/__snapshots__/examples.test.mjs.snap | 1627 +++++++++++---------- 2 files changed, 893 insertions(+), 845 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 492f6a7f0..9f3a264f4 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -16,7 +16,7 @@ export function steady(value) { } export const signal = (func) => { - const query = (state) => [new Hap(undefined, state.span, func(state.span.begin))]; + const query = (state) => [new Hap(undefined, state.span, func(state.span.begin, state.controls))]; return new Pattern(query); }; @@ -191,7 +191,7 @@ export const mouseX = signal(() => _mouseX); // Produce "Avalanche effect" where flipping a single bit of x // results in all output bits flipping with probability 0.5 // See e.g. https://github.com/aappleby/smhasher/blob/0ff96f7835817a27d0487325b6c16033e2992eb5/src/MurmurHash3.cpp#L68-L77 -function _murmurHashFinalizer(x) { +const _murmurHashFinalizer = (x) => { x |= 0; x ^= x >>> 16; x = Math.imul(x, 0x85ebca6b); @@ -199,36 +199,37 @@ function _murmurHashFinalizer(x) { x = Math.imul(x, 0xc2b2ae35); x ^= x >>> 16; return x >>> 0; // unsigned -} +}; // Convert t to a 32 bit integer, preserving temporal resolution down to 1/2^29 -function _tToT(t) { +const _tToT = (t) => { return Math.floor(t * 536870912); -} +}; -// Used to decorrelate nearby T and i prior to hashing -function _decorrelate(T, i = 0) { +// Used to decorrelate nearby T, i, and seed prior to hashing +const _decorrelate = (T, i = 0, seed = 0) => { const lowBits = (T >>> 0) >>> 0; const highBits = Math.floor(T / 4294967296) >>> 0; // 2^32 let key = lowBits ^ Math.imul(highBits ^ 0x85ebca6b, 0xc2b2ae35); key ^= Math.imul(i ^ 0x7f4a7c15, 0x9e3779b9); + key ^= Math.imul(seed ^ 0x165667b1, 0x27d4eb2d); return key >>> 0; -} +}; -function randAt(T, i = 0) { - return _murmurHashFinalizer(_decorrelate(T, i)) / 4294967296; // 2^32 -} +const randAt = (T, i = 0, seed = 0) => { + return _murmurHashFinalizer(_decorrelate(T, i, seed)) / 4294967296; // 2^32 +}; // n samples at time t -function timeToRands(t, n) { +const timeToRands = (t, n, seed = 0) => { const T = _tToT(t); if (n === 1) { - return randAt(T, 0); + return randAt(T, 0, seed); } const out = new Array(n); - for (let i = 0; i < n; i++) out[i] = randAt(T, i); + for (let i = 0; i < n; i++) out[i] = randAt(T, i, seed); return out; -} +}; // Deprecated: Old random signals. Configuration `useOldRandom` may be used for legacy songs @@ -257,8 +258,8 @@ const __timeToRands = (t, n) => __timeToRandsPrime(__timeToIntSeed(t), n); // End old random let useOldRandomBool = false; -const getRandsAtTime = (t, n = 1) => { - return useOldRandomBool ? __timeToRands(t, n) : timeToRands(t, n); +export const getRandsAtTime = (t, n = 1, seed = 0) => { + return useOldRandomBool ? __timeToRands(t + seed, n) : timeToRands(t, n, seed); }; /** @@ -314,9 +315,9 @@ export const binaryN = (n, nBits = 16) => { }; export const randrun = (n) => { - return signal((t) => { + return signal((t, controls) => { // Without adding 0.5, the first cycle is always 0,1,2,3,... - const rands = getRandsAtTime(t.floor().add(0.5), n); + const rands = getRandsAtTime(t.floor().add(0.5), n, controls.randSeed); const nums = rands .map((n, i) => [n, i]) .sort((a, b) => (a[0] > b[0]) - (a[0] < b[0])) @@ -357,6 +358,50 @@ export const scramble = register('scramble', (n, pat) => { return _rearrangeWith(_irand(n)._segment(n), n, pat); }); +/** + * Modify a pattern by applying a function to the `randomSeed` control if present + * + * @param {Function} func Function from seed (or undefined) to seed (or undefined) + * @param {Pattern} pat Pattern to update + * @returns Pattern + */ +function withSeed(func, pat) { + return new Pattern((state) => { + let { randSeed, ...controls } = state.controls; + randSeed = func(randSeed); + return pat.query(state.setControls({ ...controls, randSeed })); + }, pat._steps); +} + +/** + * Change the seed for random signals. Normally, random signals depend on time, + * so two patterns at the same time will have the same random values. Specifying + * a new seed changes the signal output by `rand`. This also affects other functions + * that use randomness, like `shuffle` and `sometimes`. + * + * @name seed + * @param {number} n A new seed. Can be any number. + * @example + * $: s("hh*4").degrade(); + * $: s("bd*4").degrade().seed(1); // Will degrade different events from the hi-hat + */ +export const seed = register('seed', (n, pat) => { + return withSeed((prev) => (prev !== undefined ? randAt(prev, n) * Number.MAX_SAFE_INTEGER : n), pat); +}); + +/** + * Set the seed for random signals. Differs from `seed` in that `seed` can be used + * multiple times with the final signal depending on all seeds. `setSeed` on the + * other hand overwrites the previous calls to `seed`. + * + * @name setSeed + * @param {number} n An arbitrary number to be used as the new seed. 0 is the same + * as the default random behavior. + */ +export const setSeed = register('setSeed', (n, pat) => { + return withSeed(() => n, pat); +}); + /** * A continuous pattern of random numbers, between 0 and 1. * @@ -366,7 +411,7 @@ export const scramble = register('scramble', (n, pat) => { * s("bd*4,hh*8").cutoff(rand.range(500,8000)) * */ -export const rand = signal(getRandsAtTime); +export const rand = signal((t, controls) => getRandsAtTime(t, 1, controls.randSeed)); /** * A continuous pattern of random numbers, between -1 and 1 */ @@ -543,36 +588,32 @@ export const wchooseCycles = (...pairs) => _wchooseWith(rand.segment(1), ...pair export const wrandcat = wchooseCycles; -function _perlin(t) { +function _perlin(t, seed = 0) { let ta = Math.floor(t); let tb = ta + 1; const smootherStep = (x) => 6.0 * x ** 5 - 15.0 * x ** 4 + 10.0 * x ** 3; const interp = (x) => (a) => (b) => a + smootherStep(x) * (b - a); - const v = interp(t - ta)(getRandsAtTime(ta))(getRandsAtTime(tb)); + const ra = getRandsAtTime(ta, 1, seed); + const rb = getRandsAtTime(tb, 1, seed); + const v = interp(t - ta)(ra)(rb); return v; } -export const perlinWith = (tpat) => { - return tpat.fmap(_perlin); -}; -function _berlin(t) { +function _berlin(t, seed = 0) { const prevRidgeStartIndex = Math.floor(t); const nextRidgeStartIndex = prevRidgeStartIndex + 1; - const prevRidgeBottomPoint = getRandsAtTime(prevRidgeStartIndex); - const nextRidgeTopPoint = getRandsAtTime(nextRidgeStartIndex) + prevRidgeBottomPoint; + const prevRidgeBottomPoint = getRandsAtTime(prevRidgeStartIndex, 1, seed); + const height = getRandsAtTime(nextRidgeStartIndex, 1, seed); + const nextRidgeTopPoint = prevRidgeBottomPoint + height; const currentPercent = (t - prevRidgeStartIndex) / (nextRidgeStartIndex - prevRidgeStartIndex); const interp = (a, b, t) => { - return a + (b - a) * t; + return a + t * (b - a); }; return interp(prevRidgeBottomPoint, nextRidgeTopPoint, currentPercent) / 2; } -export const berlinWith = (tpat) => { - return tpat.fmap(_berlin); -}; - /** * Generates a continuous pattern of [perlin noise](https://en.wikipedia.org/wiki/Perlin_noise), in the range 0..1. * @@ -582,7 +623,7 @@ export const berlinWith = (tpat) => { * s("bd*4,hh*8").cutoff(perlin.range(500,8000)) * */ -export const perlin = perlinWith(time.fmap((v) => Number(v))); +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, @@ -594,7 +635,7 @@ export const perlin = perlinWith(time.fmap((v) => Number(v))); * n("0!16".add(berlin.fast(4).mul(14))).scale("d:minor") * */ -export const berlin = berlinWith(time.fmap((v) => Number(v))); +export const berlin = signal((t, controls) => _berlin(t, controls.randSeed)); export const degradeByWith = register( 'degradeByWith', diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index c045133ff..b26823a9b 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -677,10 +677,10 @@ exports[`runs examples > example "almostAlways" example index 0 1`] = ` "[ 1/2 → 5/8 | s:hh speed:0.5 ]", "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh speed:0.5 ]", + "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", "[ 9/8 → 5/4 | s:hh speed:0.5 ]", - "[ 5/4 → 11/8 | s:hh speed:0.5 ]", + "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh speed:0.5 ]", @@ -693,10 +693,10 @@ exports[`runs examples > example "almostAlways" example index 0 1`] = ` "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh speed:0.5 ]", - "[ 23/8 → 3/1 | s:hh ]", + "[ 23/8 → 3/1 | s:hh speed:0.5 ]", "[ 3/1 → 25/8 | s:hh speed:0.5 ]", "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh speed:0.5 ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh speed:0.5 ]", @@ -715,10 +715,10 @@ exports[`runs examples > example "almostNever" example index 0 1`] = ` "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh speed:0.5 ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", @@ -728,17 +728,17 @@ exports[`runs examples > example "almostNever" example index 0 1`] = ` "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", - "[ 21/8 → 11/4 | s:hh speed:0.5 ]", + "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", + "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh speed:0.5 ]", - "[ 31/8 → 4/1 | s:hh speed:0.5 ]", + "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -1078,70 +1078,70 @@ exports[`runs examples > example "begin" example index 0 1`] = ` exports[`runs examples > example "berlin" example index 0 1`] = ` [ - "[ 0/1 → 1/16 | note:A3 ]", - "[ 1/16 → 1/8 | note:A3 ]", + "[ 0/1 → 1/16 | note:G3 ]", + "[ 1/16 → 1/8 | note:G3 ]", "[ 1/8 → 3/16 | note:A3 ]", "[ 3/16 → 1/4 | note:A3 ]", "[ 1/4 → 5/16 | note:E3 ]", "[ 5/16 → 3/8 | note:F3 ]", - "[ 3/8 → 7/16 | note:F3 ]", - "[ 7/16 → 1/2 | note:G3 ]", - "[ 1/2 → 9/16 | note:A3 ]", - "[ 9/16 → 5/8 | note:Bb3 ]", - "[ 5/8 → 11/16 | note:Bb3 ]", - "[ 11/16 → 3/4 | note:C4 ]", - "[ 3/4 → 13/16 | note:G3 ]", - "[ 13/16 → 7/8 | note:A3 ]", - "[ 7/8 → 15/16 | note:A3 ]", - "[ 15/16 → 1/1 | note:Bb3 ]", - "[ 1/1 → 17/16 | note:F3 ]", + "[ 3/8 → 7/16 | note:G3 ]", + "[ 7/16 → 1/2 | note:A3 ]", + "[ 1/2 → 9/16 | note:Bb3 ]", + "[ 9/16 → 5/8 | note:C4 ]", + "[ 5/8 → 11/16 | note:D4 ]", + "[ 11/16 → 3/4 | note:E4 ]", + "[ 3/4 → 13/16 | note:Bb3 ]", + "[ 13/16 → 7/8 | note:Bb3 ]", + "[ 7/8 → 15/16 | note:Bb3 ]", + "[ 15/16 → 1/1 | note:C4 ]", + "[ 1/1 → 17/16 | note:E3 ]", "[ 17/16 → 9/8 | note:G3 ]", - "[ 9/8 → 19/16 | note:G3 ]", - "[ 19/16 → 5/4 | note:A3 ]", - "[ 5/4 → 21/16 | note:G3 ]", - "[ 21/16 → 11/8 | note:Bb3 ]", + "[ 9/8 → 19/16 | note:A3 ]", + "[ 19/16 → 5/4 | note:C4 ]", + "[ 5/4 → 21/16 | note:C4 ]", + "[ 21/16 → 11/8 | note:D4 ]", "[ 11/8 → 23/16 | note:D4 ]", "[ 23/16 → 3/2 | note:E4 ]", - "[ 3/2 → 25/16 | note:D4 ]", - "[ 25/16 → 13/8 | note:E4 ]", - "[ 13/8 → 27/16 | note:E4 ]", - "[ 27/16 → 7/4 | note:E4 ]", - "[ 7/4 → 29/16 | note:F3 ]", - "[ 29/16 → 15/8 | note:A3 ]", - "[ 15/8 → 31/16 | note:Bb3 ]", - "[ 31/16 → 2/1 | note:C4 ]", - "[ 2/1 → 33/16 | note:C4 ]", - "[ 33/16 → 17/8 | note:E4 ]", - "[ 17/8 → 35/16 | note:G4 ]", - "[ 35/16 → 9/4 | note:A4 ]", - "[ 9/4 → 37/16 | note:D4 ]", - "[ 37/16 → 19/8 | note:F4 ]", - "[ 19/8 → 39/16 | note:G4 ]", - "[ 39/16 → 5/2 | note:A4 ]", - "[ 5/2 → 41/16 | note:Bb3 ]", - "[ 41/16 → 21/8 | note:C4 ]", - "[ 21/8 → 43/16 | note:C4 ]", - "[ 43/16 → 11/4 | note:C4 ]", - "[ 11/4 → 45/16 | note:F3 ]", - "[ 45/16 → 23/8 | note:G3 ]", - "[ 23/8 → 47/16 | note:G3 ]", - "[ 47/16 → 3/1 | note:A3 ]", - "[ 3/1 → 49/16 | note:F3 ]", - "[ 49/16 → 25/8 | note:G3 ]", - "[ 25/8 → 51/16 | note:G3 ]", - "[ 51/16 → 13/4 | note:A3 ]", - "[ 13/4 → 53/16 | note:G3 ]", - "[ 53/16 → 27/8 | note:A3 ]", - "[ 27/8 → 55/16 | note:C4 ]", - "[ 55/16 → 7/2 | note:E4 ]", - "[ 7/2 → 57/16 | note:D4 ]", - "[ 57/16 → 29/8 | note:E4 ]", - "[ 29/8 → 59/16 | note:F4 ]", - "[ 59/16 → 15/4 | note:G4 ]", - "[ 15/4 → 61/16 | note:Bb3 ]", - "[ 61/16 → 31/8 | note:C4 ]", - "[ 31/8 → 63/16 | note:D4 ]", - "[ 63/16 → 4/1 | note:E4 ]", + "[ 3/2 → 25/16 | note:F3 ]", + "[ 25/16 → 13/8 | note:A3 ]", + "[ 13/8 → 27/16 | note:Bb3 ]", + "[ 27/16 → 7/4 | note:D4 ]", + "[ 7/4 → 29/16 | note:C4 ]", + "[ 29/16 → 15/8 | note:D4 ]", + "[ 15/8 → 31/16 | note:E4 ]", + "[ 31/16 → 2/1 | note:F4 ]", + "[ 2/1 → 33/16 | note:Bb3 ]", + "[ 33/16 → 17/8 | note:C4 ]", + "[ 17/8 → 35/16 | note:D4 ]", + "[ 35/16 → 9/4 | note:E4 ]", + "[ 9/4 → 37/16 | note:Bb3 ]", + "[ 37/16 → 19/8 | note:C4 ]", + "[ 19/8 → 39/16 | note:D4 ]", + "[ 39/16 → 5/2 | note:F4 ]", + "[ 5/2 → 41/16 | note:C4 ]", + "[ 41/16 → 21/8 | note:D4 ]", + "[ 21/8 → 43/16 | note:F4 ]", + "[ 43/16 → 11/4 | note:A4 ]", + "[ 11/4 → 45/16 | note:D4 ]", + "[ 45/16 → 23/8 | note:F4 ]", + "[ 23/8 → 47/16 | note:G4 ]", + "[ 47/16 → 3/1 | note:A4 ]", + "[ 3/1 → 49/16 | note:C4 ]", + "[ 49/16 → 25/8 | note:C4 ]", + "[ 25/8 → 51/16 | note:C4 ]", + "[ 51/16 → 13/4 | note:D4 ]", + "[ 13/4 → 53/16 | note:F3 ]", + "[ 53/16 → 27/8 | note:F3 ]", + "[ 27/8 → 55/16 | note:F3 ]", + "[ 55/16 → 7/2 | note:F3 ]", + "[ 7/2 → 57/16 | note:E3 ]", + "[ 57/16 → 29/8 | note:E3 ]", + "[ 29/8 → 59/16 | note:F3 ]", + "[ 59/16 → 15/4 | note:F3 ]", + "[ 15/4 → 61/16 | note:F3 ]", + "[ 61/16 → 31/8 | note:F3 ]", + "[ 31/8 → 63/16 | note:F3 ]", + "[ 63/16 → 4/1 | note:G3 ]", ] `; @@ -1524,44 +1524,44 @@ exports[`runs examples > example "brand" example index 0 1`] = ` [ "[ 0/1 → 1/10 | s:hh pan:true ]", "[ 1/10 → 1/5 | s:hh pan:true ]", - "[ 1/5 → 3/10 | s:hh pan:true ]", - "[ 3/10 → 2/5 | s:hh pan:false ]", - "[ 2/5 → 1/2 | s:hh pan:true ]", + "[ 1/5 → 3/10 | s:hh pan:false ]", + "[ 3/10 → 2/5 | s:hh pan:true ]", + "[ 2/5 → 1/2 | s:hh pan:false ]", "[ 1/2 → 3/5 | s:hh pan:true ]", - "[ 3/5 → 7/10 | s:hh pan:false ]", - "[ 7/10 → 4/5 | s:hh pan:false ]", - "[ 4/5 → 9/10 | s:hh pan:false ]", - "[ 9/10 → 1/1 | s:hh pan:true ]", + "[ 3/5 → 7/10 | s:hh pan:true ]", + "[ 7/10 → 4/5 | s:hh pan:true ]", + "[ 4/5 → 9/10 | s:hh pan:true ]", + "[ 9/10 → 1/1 | s:hh pan:false ]", "[ 1/1 → 11/10 | s:hh pan:true ]", - "[ 11/10 → 6/5 | s:hh pan:false ]", + "[ 11/10 → 6/5 | s:hh pan:true ]", "[ 6/5 → 13/10 | s:hh pan:false ]", "[ 13/10 → 7/5 | s:hh pan:true ]", - "[ 7/5 → 3/2 | s:hh pan:true ]", + "[ 7/5 → 3/2 | s:hh pan:false ]", "[ 3/2 → 8/5 | s:hh pan:true ]", "[ 8/5 → 17/10 | s:hh pan:false ]", - "[ 17/10 → 9/5 | s:hh pan:false ]", - "[ 9/5 → 19/10 | s:hh pan:true ]", + "[ 17/10 → 9/5 | s:hh pan:true ]", + "[ 9/5 → 19/10 | s:hh pan:false ]", "[ 19/10 → 2/1 | s:hh pan:true ]", "[ 2/1 → 21/10 | s:hh pan:false ]", "[ 21/10 → 11/5 | s:hh pan:true ]", "[ 11/5 → 23/10 | s:hh pan:false ]", "[ 23/10 → 12/5 | s:hh pan:true ]", - "[ 12/5 → 5/2 | s:hh pan:true ]", - "[ 5/2 → 13/5 | s:hh pan:true ]", + "[ 12/5 → 5/2 | s:hh pan:false ]", + "[ 5/2 → 13/5 | s:hh pan:false ]", "[ 13/5 → 27/10 | s:hh pan:false ]", "[ 27/10 → 14/5 | s:hh pan:true ]", - "[ 14/5 → 29/10 | s:hh pan:true ]", - "[ 29/10 → 3/1 | s:hh pan:true ]", - "[ 3/1 → 31/10 | s:hh pan:true ]", - "[ 31/10 → 16/5 | s:hh pan:false ]", + "[ 14/5 → 29/10 | s:hh pan:false ]", + "[ 29/10 → 3/1 | s:hh pan:false ]", + "[ 3/1 → 31/10 | s:hh pan:false ]", + "[ 31/10 → 16/5 | s:hh pan:true ]", "[ 16/5 → 33/10 | s:hh pan:true ]", "[ 33/10 → 17/5 | s:hh pan:false ]", - "[ 17/5 → 7/2 | s:hh pan:false ]", + "[ 17/5 → 7/2 | s:hh pan:true ]", "[ 7/2 → 18/5 | s:hh pan:true ]", - "[ 18/5 → 37/10 | s:hh pan:false ]", + "[ 18/5 → 37/10 | s:hh pan:true ]", "[ 37/10 → 19/5 | s:hh pan:true ]", "[ 19/5 → 39/10 | s:hh pan:false ]", - "[ 39/10 → 4/1 | s:hh pan:false ]", + "[ 39/10 → 4/1 | s:hh pan:true ]", ] `; @@ -1581,32 +1581,32 @@ exports[`runs examples > example "brandBy" example index 0 1`] = ` "[ 11/10 → 6/5 | s:hh pan:false ]", "[ 6/5 → 13/10 | s:hh pan:false ]", "[ 13/10 → 7/5 | s:hh pan:true ]", - "[ 7/5 → 3/2 | s:hh pan:true ]", - "[ 3/2 → 8/5 | s:hh pan:false ]", + "[ 7/5 → 3/2 | s:hh pan:false ]", + "[ 3/2 → 8/5 | s:hh pan:true ]", "[ 8/5 → 17/10 | s:hh pan:false ]", "[ 17/10 → 9/5 | s:hh pan:false ]", "[ 9/5 → 19/10 | s:hh pan:false ]", - "[ 19/10 → 2/1 | s:hh pan:true ]", + "[ 19/10 → 2/1 | s:hh pan:false ]", "[ 2/1 → 21/10 | s:hh pan:false ]", "[ 21/10 → 11/5 | s:hh pan:true ]", "[ 11/5 → 23/10 | s:hh pan:false ]", - "[ 23/10 → 12/5 | s:hh pan:true ]", + "[ 23/10 → 12/5 | s:hh pan:false ]", "[ 12/5 → 5/2 | s:hh pan:false ]", "[ 5/2 → 13/5 | s:hh pan:false ]", "[ 13/5 → 27/10 | s:hh pan:false ]", - "[ 27/10 → 14/5 | s:hh pan:true ]", - "[ 14/5 → 29/10 | s:hh pan:true ]", + "[ 27/10 → 14/5 | s:hh pan:false ]", + "[ 14/5 → 29/10 | s:hh pan:false ]", "[ 29/10 → 3/1 | s:hh pan:false ]", "[ 3/1 → 31/10 | s:hh pan:false ]", - "[ 31/10 → 16/5 | s:hh pan:false ]", - "[ 16/5 → 33/10 | s:hh pan:true ]", + "[ 31/10 → 16/5 | s:hh pan:true ]", + "[ 16/5 → 33/10 | s:hh pan:false ]", "[ 33/10 → 17/5 | s:hh pan:false ]", "[ 17/5 → 7/2 | s:hh pan:false ]", "[ 7/2 → 18/5 | s:hh pan:false ]", "[ 18/5 → 37/10 | s:hh pan:false ]", - "[ 37/10 → 19/5 | s:hh pan:true ]", + "[ 37/10 → 19/5 | s:hh pan:false ]", "[ 19/5 → 39/10 | s:hh pan:false ]", - "[ 39/10 → 4/1 | s:hh pan:false ]", + "[ 39/10 → 4/1 | s:hh pan:true ]", ] `; @@ -1738,23 +1738,23 @@ exports[`runs examples > example "channels" example index 0 1`] = ` exports[`runs examples > example "choose" example index 0 1`] = ` [ "[ 0/1 → 1/5 | note:c2 s:triangle ]", - "[ 1/5 → 2/5 | note:g2 s:sine ]", + "[ 1/5 → 2/5 | note:g2 s:triangle ]", "[ 2/5 → 3/5 | note:g2 s:triangle ]", - "[ 3/5 → 4/5 | note:d2 s:bd n:6 ]", - "[ 4/5 → 1/1 | note:f1 s:bd n:6 ]", + "[ 3/5 → 4/5 | note:d2 s:sine ]", + "[ 4/5 → 1/1 | note:f1 s:triangle ]", "[ 1/1 → 6/5 | note:c2 s:sine ]", - "[ 6/5 → 7/5 | note:g2 s:bd n:6 ]", - "[ 7/5 → 8/5 | note:g2 s:sine ]", - "[ 8/5 → 9/5 | note:d2 s:bd n:6 ]", - "[ 9/5 → 2/1 | note:f1 s:sine ]", + "[ 6/5 → 7/5 | note:g2 s:triangle ]", + "[ 7/5 → 8/5 | note:g2 s:bd n:6 ]", + "[ 8/5 → 9/5 | note:d2 s:triangle ]", + "[ 9/5 → 2/1 | note:f1 s:triangle ]", "[ 2/1 → 11/5 | note:c2 s:triangle ]", "[ 11/5 → 12/5 | note:g2 s:bd n:6 ]", - "[ 12/5 → 13/5 | note:g2 s:sine ]", + "[ 12/5 → 13/5 | note:g2 s:bd n:6 ]", "[ 13/5 → 14/5 | note:d2 s:bd n:6 ]", - "[ 14/5 → 3/1 | note:f1 s:sine ]", + "[ 14/5 → 3/1 | note:f1 s:bd n:6 ]", "[ 3/1 → 16/5 | note:c2 s:triangle ]", - "[ 16/5 → 17/5 | note:g2 s:sine ]", - "[ 17/5 → 18/5 | note:g2 s:bd n:6 ]", + "[ 16/5 → 17/5 | note:g2 s:triangle ]", + "[ 17/5 → 18/5 | note:g2 s:sine ]", "[ 18/5 → 19/5 | note:d2 s:triangle ]", "[ 19/5 → 4/1 | note:f1 s:bd n:6 ]", ] @@ -1767,33 +1767,33 @@ exports[`runs examples > example "chooseCycles" example index 0 1`] = ` "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:sd ]", - "[ 7/8 → 1/1 | s:bd ]", - "[ 1/1 → 9/8 | s:sd ]", - "[ 9/8 → 5/4 | s:sd ]", - "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:bd ]", - "[ 3/2 → 13/8 | s:bd ]", + "[ 5/8 → 3/4 | s:sd ]", + "[ 3/4 → 7/8 | s:bd ]", + "[ 7/8 → 1/1 | s:sd ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", + "[ 5/4 → 11/8 | s:sd ]", + "[ 11/8 → 3/2 | s:sd ]", + "[ 3/2 → 13/8 | s:sd ]", "[ 13/8 → 7/4 | s:bd ]", - "[ 7/4 → 15/8 | s:sd ]", - "[ 15/8 → 2/1 | s:hh ]", - "[ 2/1 → 17/8 | s:sd ]", + "[ 7/4 → 15/8 | s:bd ]", + "[ 15/8 → 2/1 | s:bd ]", + "[ 2/1 → 17/8 | s:bd ]", "[ 17/8 → 9/4 | s:sd ]", - "[ 9/4 → 19/8 | s:bd ]", - "[ 19/8 → 5/2 | s:hh ]", + "[ 9/4 → 19/8 | s:sd ]", + "[ 19/8 → 5/2 | s:sd ]", "[ 5/2 → 21/8 | s:bd ]", - "[ 21/8 → 11/4 | s:sd ]", - "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:bd ]", - "[ 3/1 → 25/8 | s:sd ]", + "[ 21/8 → 11/4 | s:hh ]", + "[ 11/4 → 23/8 | s:sd ]", + "[ 23/8 → 3/1 | s:sd ]", + "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:sd ]", - "[ 13/4 → 27/8 | s:sd ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:bd ]", "[ 7/2 → 29/8 | s:sd ]", - "[ 29/8 → 15/4 | s:bd ]", + "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:bd ]", - "[ 31/8 → 4/1 | s:bd ]", + "[ 31/8 → 4/1 | s:sd ]", ] `; @@ -1804,33 +1804,33 @@ exports[`runs examples > example "chooseCycles" example index 1 1`] = ` "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:sd ]", - "[ 7/8 → 1/1 | s:bd ]", - "[ 1/1 → 9/8 | s:sd ]", - "[ 9/8 → 5/4 | s:sd ]", - "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:bd ]", - "[ 3/2 → 13/8 | s:bd ]", + "[ 5/8 → 3/4 | s:sd ]", + "[ 3/4 → 7/8 | s:bd ]", + "[ 7/8 → 1/1 | s:sd ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", + "[ 5/4 → 11/8 | s:sd ]", + "[ 11/8 → 3/2 | s:sd ]", + "[ 3/2 → 13/8 | s:sd ]", "[ 13/8 → 7/4 | s:bd ]", - "[ 7/4 → 15/8 | s:sd ]", - "[ 15/8 → 2/1 | s:hh ]", - "[ 2/1 → 17/8 | s:sd ]", + "[ 7/4 → 15/8 | s:bd ]", + "[ 15/8 → 2/1 | s:bd ]", + "[ 2/1 → 17/8 | s:bd ]", "[ 17/8 → 9/4 | s:sd ]", - "[ 9/4 → 19/8 | s:bd ]", - "[ 19/8 → 5/2 | s:hh ]", + "[ 9/4 → 19/8 | s:sd ]", + "[ 19/8 → 5/2 | s:sd ]", "[ 5/2 → 21/8 | s:bd ]", - "[ 21/8 → 11/4 | s:sd ]", - "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:bd ]", - "[ 3/1 → 25/8 | s:sd ]", + "[ 21/8 → 11/4 | s:hh ]", + "[ 11/4 → 23/8 | s:sd ]", + "[ 23/8 → 3/1 | s:sd ]", + "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:sd ]", - "[ 13/4 → 27/8 | s:sd ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:bd ]", "[ 7/2 → 29/8 | s:sd ]", - "[ 29/8 → 15/4 | s:bd ]", + "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:bd ]", - "[ 31/8 → 4/1 | s:bd ]", + "[ 31/8 → 4/1 | s:sd ]", ] `; @@ -2494,45 +2494,44 @@ exports[`runs examples > example "decay" example index 0 1`] = ` exports[`runs examples > example "degrade" example index 0 1`] = ` [ "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", - "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", - "[ 7/4 → 15/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", - "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 11/4 → 23/8 | s:hh ]", + "[ 5/2 → 21/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", + "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", ] `; exports[`runs examples > example "degrade" example index 1 1`] = ` [ "[ 1/4 → 3/8 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 7/4 → 15/8 | s:hh ]", - "[ 15/8 → 2/1 | s:hh ]", - "[ 2/1 → 17/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", + "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 21/8 → 11/4 | s:hh ]", + "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -2540,16 +2539,12 @@ exports[`runs examples > example "degradeBy" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", - "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", - "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", @@ -2558,14 +2553,15 @@ exports[`runs examples > example "degradeBy" example index 0 1`] = ` "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", + "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", ] `; @@ -2574,7 +2570,6 @@ exports[`runs examples > example "degradeBy" example index 1 1`] = ` "[ 0/1 → 1/8 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", - "[ 1/2 → 5/8 | s:hh ]", "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", @@ -2583,66 +2578,56 @@ exports[`runs examples > example "degradeBy" example index 1 1`] = ` "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh ]", - "[ 13/8 → 7/4 | s:hh ]", - "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", - "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", + "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", + "[ 29/8 → 15/4 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; exports[`runs examples > example "degradeBy" example index 2 1`] = ` [ - "[ 0/1 → 1/16 | s:bd ]", "[ 1/16 → 1/8 | s:bd ]", "[ 1/8 → 3/16 | s:bd ]", + "[ 3/16 → 1/4 | s:bd ]", + "[ 5/16 → 3/8 | s:bd ]", "[ 3/8 → 7/16 | s:bd ]", "[ 1/2 → 9/16 | s:bd ]", - "[ 9/16 → 5/8 | s:bd ]", - "[ 5/8 → 11/16 | s:bd ]", - "[ 11/16 → 3/4 | s:bd ]", - "[ 3/4 → 13/16 | s:bd ]", - "[ 15/16 → 1/1 | s:bd ]", - "[ 1/1 → 17/16 | s:bd ]", + "[ 13/16 → 7/8 | s:bd ]", + "[ 7/8 → 15/16 | s:bd ]", "[ 17/16 → 9/8 | s:bd ]", "[ 9/8 → 19/16 | s:bd ]", + "[ 19/16 → 5/4 | s:bd ]", + "[ 21/16 → 11/8 | s:bd ]", "[ 11/8 → 23/16 | s:bd ]", "[ 3/2 → 25/16 | s:bd ]", - "[ 25/16 → 13/8 | s:bd ]", - "[ 13/8 → 27/16 | s:bd ]", - "[ 27/16 → 7/4 | s:bd ]", - "[ 7/4 → 29/16 | s:bd ]", - "[ 31/16 → 2/1 | s:bd ]", - "[ 2/1 → 33/16 | s:bd ]", + "[ 29/16 → 15/8 | s:bd ]", + "[ 15/8 → 31/16 | s:bd ]", "[ 33/16 → 17/8 | s:bd ]", "[ 17/8 → 35/16 | s:bd ]", + "[ 35/16 → 9/4 | s:bd ]", + "[ 37/16 → 19/8 | s:bd ]", "[ 19/8 → 39/16 | s:bd ]", "[ 5/2 → 41/16 | s:bd ]", - "[ 41/16 → 21/8 | s:bd ]", - "[ 21/8 → 43/16 | s:bd ]", - "[ 43/16 → 11/4 | s:bd ]", - "[ 11/4 → 45/16 | s:bd ]", - "[ 47/16 → 3/1 | s:bd ]", - "[ 3/1 → 49/16 | s:bd ]", + "[ 45/16 → 23/8 | s:bd ]", + "[ 23/8 → 47/16 | s:bd ]", "[ 49/16 → 25/8 | s:bd ]", "[ 25/8 → 51/16 | s:bd ]", + "[ 51/16 → 13/4 | s:bd ]", + "[ 53/16 → 27/8 | s:bd ]", "[ 27/8 → 55/16 | s:bd ]", "[ 7/2 → 57/16 | s:bd ]", - "[ 57/16 → 29/8 | s:bd ]", - "[ 29/8 → 59/16 | s:bd ]", - "[ 59/16 → 15/4 | s:bd ]", - "[ 15/4 → 61/16 | s:bd ]", - "[ 63/16 → 4/1 | s:bd ]", + "[ 61/16 → 31/8 | s:bd ]", + "[ 31/8 → 63/16 | s:bd ]", ] `; @@ -2965,14 +2950,14 @@ exports[`runs examples > example "distorttype" example index 0 1`] = ` exports[`runs examples > example "distorttype" example index 1 1`] = ` [ - "[ (0/1 → 1/2) ⇝ 1/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1 distorttype:fold ]", - "[ 0/1 ⇜ (1/2 → 1/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1 distorttype:fold ]", - "[ (1/1 → 3/2) ⇝ 2/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:4.6367951557040215 distorttype:chebyshev ]", - "[ 1/1 ⇜ (3/2 → 2/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:4.6367951557040215 distorttype:chebyshev ]", - "[ (2/1 → 5/2) ⇝ 3/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:7.716689839959145 distorttype:scurve ]", - "[ 2/1 ⇜ (5/2 → 3/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:7.716689839959145 distorttype:scurve ]", - "[ (3/1 → 7/2) ⇝ 4/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:2.5210237745195627 distorttype:diode ]", - "[ 3/1 ⇜ (7/2 → 4/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:2.5210237745195627 distorttype:diode ]", + "[ (0/1 → 1/2) ⇝ 1/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:3.71662513515912 distorttype:fold ]", + "[ 0/1 ⇜ (1/2 → 1/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:3.71662513515912 distorttype:fold ]", + "[ (1/1 → 3/2) ⇝ 2/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1.8276505067478865 distorttype:chebyshev ]", + "[ 1/1 ⇜ (3/2 → 2/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1.8276505067478865 distorttype:chebyshev ]", + "[ (2/1 → 5/2) ⇝ 3/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.068953953683376 distorttype:scurve ]", + "[ 2/1 ⇜ (5/2 → 3/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.068953953683376 distorttype:scurve ]", + "[ (3/1 → 7/2) ⇝ 4/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.303743980126455 distorttype:diode ]", + "[ 3/1 ⇜ (7/2 → 4/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.303743980126455 distorttype:diode ]", ] `; @@ -2999,38 +2984,38 @@ exports[`runs examples > example "distortvol" example index 0 1`] = ` exports[`runs examples > example "djf" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | note:D3 s:supersaw djf:0.5 ]", + "[ 0/1 → 1/8 | note:C4 s:supersaw djf:0.5 ]", "[ 1/8 → 1/4 | note:G4 s:supersaw djf:0.5 ]", - "[ 1/4 → 3/8 | note:Bb3 s:supersaw djf:0.5 ]", - "[ 3/8 → 1/2 | note:C4 s:supersaw djf:0.5 ]", - "[ 1/2 → 5/8 | note:A3 s:supersaw djf:0.5 ]", - "[ 5/8 → 3/4 | note:F3 s:supersaw djf:0.5 ]", - "[ 3/4 → 7/8 | note:G3 s:supersaw djf:0.5 ]", - "[ 7/8 → 1/1 | note:C4 s:supersaw djf:0.5 ]", - "[ 1/1 → 9/8 | note:Eb4 s:supersaw djf:0.3 ]", - "[ 9/8 → 5/4 | note:G4 s:supersaw djf:0.3 ]", - "[ 5/4 → 11/8 | note:A4 s:supersaw djf:0.3 ]", - "[ 11/8 → 3/2 | note:F3 s:supersaw djf:0.3 ]", - "[ 3/2 → 13/8 | note:F4 s:supersaw djf:0.3 ]", - "[ 13/8 → 7/4 | note:D4 s:supersaw djf:0.3 ]", - "[ 7/4 → 15/8 | note:G3 s:supersaw djf:0.3 ]", - "[ 15/8 → 2/1 | note:F4 s:supersaw djf:0.3 ]", - "[ 2/1 → 17/8 | note:Eb5 s:supersaw djf:0.2 ]", - "[ 17/8 → 9/4 | note:D5 s:supersaw djf:0.2 ]", - "[ 9/4 → 19/8 | note:Bb3 s:supersaw djf:0.2 ]", + "[ 1/4 → 3/8 | note:F3 s:supersaw djf:0.5 ]", + "[ 3/8 → 1/2 | note:C5 s:supersaw djf:0.5 ]", + "[ 1/2 → 5/8 | note:Bb3 s:supersaw djf:0.5 ]", + "[ 5/8 → 3/4 | note:A4 s:supersaw djf:0.5 ]", + "[ 3/4 → 7/8 | note:A3 s:supersaw djf:0.5 ]", + "[ 7/8 → 1/1 | note:D5 s:supersaw djf:0.5 ]", + "[ 1/1 → 9/8 | note:Eb3 s:supersaw djf:0.3 ]", + "[ 9/8 → 5/4 | note:D3 s:supersaw djf:0.3 ]", + "[ 5/4 → 11/8 | note:Eb5 s:supersaw djf:0.3 ]", + "[ 11/8 → 3/2 | note:D3 s:supersaw djf:0.3 ]", + "[ 3/2 → 13/8 | note:F3 s:supersaw djf:0.3 ]", + "[ 13/8 → 7/4 | note:G4 s:supersaw djf:0.3 ]", + "[ 7/4 → 15/8 | note:Bb3 s:supersaw djf:0.3 ]", + "[ 15/8 → 2/1 | note:G4 s:supersaw djf:0.3 ]", + "[ 2/1 → 17/8 | note:F4 s:supersaw djf:0.2 ]", + "[ 17/8 → 9/4 | note:D4 s:supersaw djf:0.2 ]", + "[ 9/4 → 19/8 | note:G3 s:supersaw djf:0.2 ]", "[ 19/8 → 5/2 | note:C5 s:supersaw djf:0.2 ]", - "[ 5/2 → 21/8 | note:D4 s:supersaw djf:0.2 ]", - "[ 21/8 → 11/4 | note:F3 s:supersaw djf:0.2 ]", - "[ 11/4 → 23/8 | note:G4 s:supersaw djf:0.2 ]", - "[ 23/8 → 3/1 | note:D3 s:supersaw djf:0.2 ]", - "[ 3/1 → 25/8 | note:G3 s:supersaw djf:0.75 ]", - "[ 25/8 → 13/4 | note:Bb3 s:supersaw djf:0.75 ]", - "[ 13/4 → 27/8 | note:Eb5 s:supersaw djf:0.75 ]", - "[ 27/8 → 7/2 | note:C4 s:supersaw djf:0.75 ]", - "[ 7/2 → 29/8 | note:C4 s:supersaw djf:0.75 ]", - "[ 29/8 → 15/4 | note:Eb5 s:supersaw djf:0.75 ]", - "[ 15/4 → 31/8 | note:Bb4 s:supersaw djf:0.75 ]", - "[ 31/8 → 4/1 | note:A4 s:supersaw djf:0.75 ]", + "[ 5/2 → 21/8 | note:A4 s:supersaw djf:0.2 ]", + "[ 21/8 → 11/4 | note:Bb3 s:supersaw djf:0.2 ]", + "[ 11/4 → 23/8 | note:Bb3 s:supersaw djf:0.2 ]", + "[ 23/8 → 3/1 | note:C5 s:supersaw djf:0.2 ]", + "[ 3/1 → 25/8 | note:F4 s:supersaw djf:0.75 ]", + "[ 25/8 → 13/4 | note:F4 s:supersaw djf:0.75 ]", + "[ 13/4 → 27/8 | note:D5 s:supersaw djf:0.75 ]", + "[ 27/8 → 7/2 | note:D3 s:supersaw djf:0.75 ]", + "[ 7/2 → 29/8 | note:G3 s:supersaw djf:0.75 ]", + "[ 29/8 → 15/4 | note:F4 s:supersaw djf:0.75 ]", + "[ 15/4 → 31/8 | note:F4 s:supersaw djf:0.75 ]", + "[ 31/8 → 4/1 | note:F3 s:supersaw djf:0.75 ]", ] `; @@ -5189,31 +5174,31 @@ exports[`runs examples > example "invert" example index 0 1`] = ` exports[`runs examples > example "irand" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:F3 ]", - "[ 1/4 → 3/8 | note:G3 ]", - "[ 3/8 → 1/2 | note:G3 ]", - "[ 1/2 → 3/4 | note:F3 ]", - "[ 3/4 → 5/6 | note:Ab3 ]", - "[ 5/6 → 11/12 | note:Bb3 ]", - "[ 11/12 → 1/1 | note:C4 ]", + "[ 1/4 → 3/8 | note:D3 ]", + "[ 3/8 → 1/2 | note:Bb3 ]", + "[ 1/2 → 3/4 | note:Eb3 ]", + "[ 3/4 → 5/6 | note:Eb3 ]", + "[ 5/6 → 11/12 | note:Ab3 ]", + "[ 11/12 → 1/1 | note:D3 ]", "[ 1/1 → 5/4 | note:C3 ]", - "[ 5/4 → 11/8 | note:Ab3 ]", - "[ 11/8 → 3/2 | note:Bb3 ]", + "[ 5/4 → 11/8 | note:C4 ]", + "[ 11/8 → 3/2 | note:C3 ]", "[ 3/2 → 7/4 | note:D3 ]", - "[ 7/4 → 11/6 | note:Ab3 ]", - "[ 11/6 → 23/12 | note:Bb3 ]", - "[ 23/12 → 2/1 | note:C3 ]", + "[ 7/4 → 11/6 | note:Eb3 ]", + "[ 11/6 → 23/12 | note:C3 ]", + "[ 23/12 → 2/1 | note:Ab3 ]", "[ 2/1 → 9/4 | note:G3 ]", - "[ 9/4 → 19/8 | note:Ab3 ]", - "[ 19/8 → 5/2 | note:Ab3 ]", - "[ 5/2 → 11/4 | note:Eb3 ]", - "[ 11/4 → 17/6 | note:Ab3 ]", - "[ 17/6 → 35/12 | note:Bb3 ]", - "[ 35/12 → 3/1 | note:Ab3 ]", - "[ 3/1 → 13/4 | note:F3 ]", - "[ 13/4 → 27/8 | note:Eb3 ]", - "[ 27/8 → 7/2 | note:Ab3 ]", - "[ 7/2 → 15/4 | note:Eb3 ]", - "[ 15/4 → 23/6 | note:C3 ]", + "[ 9/4 → 19/8 | note:D3 ]", + "[ 19/8 → 5/2 | note:Bb3 ]", + "[ 5/2 → 11/4 | note:Ab3 ]", + "[ 11/4 → 17/6 | note:Eb3 ]", + "[ 17/6 → 35/12 | note:Ab3 ]", + "[ 35/12 → 3/1 | note:D3 ]", + "[ 3/1 → 13/4 | note:G3 ]", + "[ 13/4 → 27/8 | note:C4 ]", + "[ 27/8 → 7/2 | note:C3 ]", + "[ 7/2 → 15/4 | note:D3 ]", + "[ 15/4 → 23/6 | note:G3 ]", "[ 23/6 → 47/12 | note:Ab3 ]", "[ 47/12 → 4/1 | note:Ab3 ]", ] @@ -5221,38 +5206,38 @@ exports[`runs examples > example "irand" example index 0 1`] = ` exports[`runs examples > example "irbegin" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", "[ 1/8 → 1/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.5 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.0625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", "[ 19/8 → 5/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.75 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", ] `; @@ -5279,38 +5264,38 @@ exports[`runs examples > example "iresponse" example index 0 1`] = ` exports[`runs examples > example "irspeed" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", "[ 1/8 → 1/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.5 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.0625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", "[ 19/8 → 5/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.75 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", ] `; @@ -6998,35 +6983,35 @@ exports[`runs examples > example "offset" example index 0 1`] = ` exports[`runs examples > example "often" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh speed:0.5 ]", - "[ 1/8 → 1/4 | s:hh ]", + "[ 1/8 → 1/4 | s:hh speed:0.5 ]", "[ 1/4 → 3/8 | s:hh speed:0.5 ]", - "[ 3/8 → 1/2 | s:hh speed:0.5 ]", + "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh speed:0.5 ]", - "[ 5/8 → 3/4 | s:hh ]", + "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:hh speed:0.5 ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 5/4 → 11/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh speed:0.5 ]", "[ 7/4 → 15/8 | s:hh speed:0.5 ]", - "[ 15/8 → 2/1 | s:hh ]", + "[ 15/8 → 2/1 | s:hh speed:0.5 ]", "[ 2/1 → 17/8 | s:hh speed:0.5 ]", - "[ 17/8 → 9/4 | s:hh ]", + "[ 17/8 → 9/4 | s:hh speed:0.5 ]", "[ 9/4 → 19/8 | s:hh speed:0.5 ]", - "[ 19/8 → 5/2 | s:hh speed:0.5 ]", + "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh speed:0.5 ]", "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh speed:0.5 ]", "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh speed:0.5 ]", + "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", - "[ 29/8 → 15/4 | s:hh ]", + "[ 29/8 → 15/4 | s:hh speed:0.5 ]", "[ 15/4 → 31/8 | s:hh speed:0.5 ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] @@ -7298,54 +7283,54 @@ exports[`runs examples > example "penv" example index 0 1`] = ` exports[`runs examples > example "perlin" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh cutoff:3801.944299018942 ]", - "[ 0/1 → 1/4 | s:bd cutoff:3801.944299018942 ]", - "[ 1/8 → 1/4 | s:hh cutoff:3752.180364182138 ]", - "[ 1/4 → 3/8 | s:hh cutoff:3481.0331450903504 ]", - "[ 1/4 → 1/2 | s:bd cutoff:3481.0331450903504 ]", - "[ 3/8 → 1/2 | s:hh cutoff:2948.767180467044 ]", - "[ 1/2 → 5/8 | s:hh cutoff:2251.8828762695193 ]", - "[ 1/2 → 3/4 | s:bd cutoff:2251.8828762695193 ]", - "[ 5/8 → 3/4 | s:hh cutoff:1554.9985720719947 ]", - "[ 3/4 → 7/8 | s:hh cutoff:1022.7326074486882 ]", - "[ 3/4 → 1/1 | s:bd cutoff:1022.7326074486882 ]", - "[ 7/8 → 1/1 | s:hh cutoff:751.5853883569008 ]", - "[ 1/1 → 9/8 | s:hh cutoff:701.8214535200968 ]", - "[ 1/1 → 5/4 | s:bd cutoff:701.8214535200968 ]", - "[ 9/8 → 5/4 | s:hh cutoff:758.9508705680288 ]", - "[ 5/4 → 11/8 | s:hh cutoff:1070.2301657379394 ]", - "[ 5/4 → 3/2 | s:bd cutoff:1070.2301657379394 ]", - "[ 11/8 → 3/2 | s:hh cutoff:1681.2759838209531 ]", - "[ 3/2 → 13/8 | s:hh cutoff:2481.3050446100533 ]", - "[ 3/2 → 7/4 | s:bd cutoff:2481.3050446100533 ]", - "[ 13/8 → 7/4 | s:hh cutoff:3281.3341053991535 ]", - "[ 7/4 → 15/8 | s:hh cutoff:3892.379923482167 ]", - "[ 7/4 → 2/1 | s:bd cutoff:3892.379923482167 ]", - "[ 15/8 → 2/1 | s:hh cutoff:4203.6592186520775 ]", - "[ 2/1 → 17/8 | s:hh cutoff:4260.78863570001 ]", - "[ 2/1 → 9/4 | s:bd cutoff:4260.78863570001 ]", - "[ 17/8 → 9/4 | s:hh cutoff:4250.943561981614 ]", - "[ 9/4 → 19/8 | s:hh cutoff:4197.301012025491 ]", - "[ 9/4 → 5/2 | s:bd cutoff:4197.301012025491 ]", - "[ 19/8 → 5/2 | s:hh cutoff:4091.9999003530734 ]", - "[ 5/2 → 21/8 | s:hh cutoff:3954.1314345551655 ]", - "[ 5/2 → 11/4 | s:bd cutoff:3954.1314345551655 ]", - "[ 21/8 → 11/4 | s:hh cutoff:3816.2629687572576 ]", - "[ 11/4 → 23/8 | s:hh cutoff:3710.9618570848397 ]", - "[ 11/4 → 3/1 | s:bd cutoff:3710.9618570848397 ]", - "[ 23/8 → 3/1 | s:hh cutoff:3657.3193071287164 ]", - "[ 3/1 → 25/8 | s:hh cutoff:3647.474233410321 ]", - "[ 3/1 → 13/4 | s:bd cutoff:3647.474233410321 ]", - "[ 25/8 → 13/4 | s:hh cutoff:3623.927675406968 ]", - "[ 13/4 → 27/8 | s:hh cutoff:3495.6302700122706 ]", - "[ 13/4 → 7/2 | s:bd cutoff:3495.6302700122706 ]", - "[ 27/8 → 7/2 | s:hh cutoff:3243.7805830790653 ]", - "[ 7/2 → 29/8 | s:hh cutoff:2914.039240393322 ]", - "[ 7/2 → 15/4 | s:bd cutoff:2914.039240393322 ]", - "[ 29/8 → 15/4 | s:hh cutoff:2584.2978977075786 ]", - "[ 15/4 → 31/8 | s:hh cutoff:2332.4482107743734 ]", - "[ 15/4 → 4/1 | s:bd cutoff:2332.4482107743734 ]", - "[ 31/8 → 4/1 | s:hh cutoff:2204.150805379676 ]", + "[ 0/1 → 1/8 | s:hh cutoff:3410.6697876704857 ]", + "[ 0/1 → 1/4 | s:bd cutoff:3410.6697876704857 ]", + "[ 1/8 → 1/4 | s:hh cutoff:3378.181624527514 ]", + "[ 1/4 → 3/8 | s:hh cutoff:3201.164370596416 ]", + "[ 1/4 → 1/2 | s:bd cutoff:3201.164370596416 ]", + "[ 3/8 → 1/2 | s:hh cutoff:2853.676907017785 ]", + "[ 1/2 → 5/8 | s:hh cutoff:2398.7190938787535 ]", + "[ 1/2 → 3/4 | s:bd cutoff:2398.7190938787535 ]", + "[ 5/8 → 3/4 | s:hh cutoff:1943.7612807397215 ]", + "[ 3/4 → 7/8 | s:hh cutoff:1596.2738171610908 ]", + "[ 3/4 → 1/1 | s:bd cutoff:1596.2738171610908 ]", + "[ 7/8 → 1/1 | s:hh cutoff:1419.2565632299932 ]", + "[ 1/1 → 9/8 | s:hh cutoff:1386.7684000870213 ]", + "[ 1/1 → 5/4 | s:bd cutoff:1386.7684000870213 ]", + "[ 9/8 → 5/4 | s:hh cutoff:1442.5150435813734 ]", + "[ 5/4 → 11/8 | s:hh cutoff:1746.2600630772158 ]", + "[ 5/4 → 3/2 | s:bd cutoff:1746.2600630772158 ]", + "[ 11/8 → 3/2 | s:hh cutoff:2342.5159876004573 ]", + "[ 3/2 → 13/8 | s:hh cutoff:3123.1809609453194 ]", + "[ 3/2 → 7/4 | s:bd cutoff:3123.1809609453194 ]", + "[ 13/8 → 7/4 | s:hh cutoff:3903.8459342901815 ]", + "[ 7/4 → 15/8 | s:hh cutoff:4500.101858813423 ]", + "[ 7/4 → 2/1 | s:bd cutoff:4500.101858813423 ]", + "[ 15/8 → 2/1 | s:hh cutoff:4803.846878309266 ]", + "[ 2/1 → 17/8 | s:hh cutoff:4859.5935218036175 ]", + "[ 2/1 → 9/4 | s:bd cutoff:4859.5935218036175 ]", + "[ 17/8 → 9/4 | s:hh cutoff:4863.631636751641 ]", + "[ 9/4 → 19/8 | s:hh cutoff:4885.633989301141 ]", + "[ 9/4 → 5/2 | s:bd cutoff:4885.633989301141 ]", + "[ 19/8 → 5/2 | s:hh cutoff:4928.824929790842 ]", + "[ 5/2 → 21/8 | s:hh cutoff:4985.37389311241 ]", + "[ 5/2 → 11/4 | s:bd cutoff:4985.37389311241 ]", + "[ 21/8 → 11/4 | s:hh cutoff:5041.922856433977 ]", + "[ 11/4 → 23/8 | s:hh cutoff:5085.113796923679 ]", + "[ 11/4 → 3/1 | s:bd cutoff:5085.113796923679 ]", + "[ 23/8 → 3/1 | s:hh cutoff:5107.116149473179 ]", + "[ 3/1 → 25/8 | s:hh cutoff:5111.154264421202 ]", + "[ 3/1 → 13/4 | s:bd cutoff:5111.154264421202 ]", + "[ 25/8 → 13/4 | s:hh cutoff:5054.286698772394 ]", + "[ 13/4 → 27/8 | s:hh cutoff:4744.434145256264 ]", + "[ 13/4 → 7/2 | s:bd cutoff:4744.434145256264 ]", + "[ 27/8 → 7/2 | s:hh cutoff:4136.189041947908 ]", + "[ 7/2 → 29/8 | s:hh cutoff:3339.826896379236 ]", + "[ 7/2 → 15/4 | s:bd cutoff:3339.826896379236 ]", + "[ 29/8 → 15/4 | s:hh cutoff:2543.464750810564 ]", + "[ 15/4 → 31/8 | s:hh cutoff:1935.2196475022083 ]", + "[ 15/4 → 4/1 | s:bd cutoff:1935.2196475022083 ]", + "[ 31/8 → 4/1 | s:hh cutoff:1625.3670939860783 ]", ] `; @@ -8167,54 +8152,54 @@ exports[`runs examples > example "queryArc" example index 0 1`] = `[]`; exports[`runs examples > example "rand" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh cutoff:3801.944299018942 ]", - "[ 0/1 → 1/4 | s:bd cutoff:3801.944299018942 ]", - "[ 1/8 → 1/4 | s:hh cutoff:6647.100417292677 ]", - "[ 1/4 → 3/8 | s:hh cutoff:4935.184325557202 ]", - "[ 1/4 → 1/2 | s:bd cutoff:4935.184325557202 ]", - "[ 3/8 → 1/2 | s:hh cutoff:4274.936107802205 ]", - "[ 1/2 → 5/8 | s:hh cutoff:3599.519268143922 ]", - "[ 1/2 → 3/4 | s:bd cutoff:3599.519268143922 ]", - "[ 5/8 → 3/4 | s:hh cutoff:7203.329019364901 ]", - "[ 3/4 → 7/8 | s:hh cutoff:5311.3214410841465 ]", - "[ 3/4 → 1/1 | s:bd cutoff:5311.3214410841465 ]", - "[ 7/8 → 1/1 | s:hh cutoff:7230.677842278965 ]", - "[ 1/1 → 9/8 | s:hh cutoff:701.8214535200968 ]", - "[ 1/1 → 5/4 | s:bd cutoff:701.8214535200968 ]", - "[ 9/8 → 5/4 | s:hh cutoff:6626.493136398494 ]", - "[ 5/4 → 11/8 | s:hh cutoff:5536.982340388931 ]", - "[ 5/4 → 3/2 | s:bd cutoff:5536.982340388931 ]", - "[ 11/8 → 3/2 | s:hh cutoff:6926.114265923388 ]", - "[ 3/2 → 13/8 | s:hh cutoff:2300.4843831295148 ]", - "[ 3/2 → 7/4 | s:bd cutoff:2300.4843831295148 ]", - "[ 13/8 → 7/4 | s:hh cutoff:2510.1786771556363 ]", - "[ 7/4 → 15/8 | s:hh cutoff:5990.686780540273 ]", - "[ 7/4 → 2/1 | s:bd cutoff:5990.686780540273 ]", - "[ 15/8 → 2/1 | s:hh cutoff:6187.015319708735 ]", - "[ 2/1 → 17/8 | s:hh cutoff:4260.78863570001 ]", - "[ 2/1 → 9/4 | s:bd cutoff:4260.78863570001 ]", - "[ 17/8 → 9/4 | s:hh cutoff:6301.981445983984 ]", - "[ 9/4 → 19/8 | s:hh cutoff:5212.422806769609 ]", - "[ 9/4 → 5/2 | s:bd cutoff:5212.422806769609 ]", - "[ 19/8 → 5/2 | s:hh cutoff:5561.523957410827 ]", - "[ 5/2 → 21/8 | s:hh cutoff:3020.9835229907185 ]", - "[ 5/2 → 11/4 | s:bd cutoff:3020.9835229907185 ]", - "[ 21/8 → 11/4 | s:hh cutoff:576.5502714784816 ]", - "[ 11/4 → 23/8 | s:hh cutoff:5743.939216597937 ]", - "[ 11/4 → 3/1 | s:bd cutoff:5743.939216597937 ]", - "[ 23/8 → 3/1 | s:hh cutoff:7271.8438868178055 ]", - "[ 3/1 → 25/8 | s:hh cutoff:3647.474233410321 ]", - "[ 3/1 → 13/4 | s:bd cutoff:3647.474233410321 ]", - "[ 25/8 → 13/4 | s:hh cutoff:5633.619675179943 ]", - "[ 13/4 → 27/8 | s:hh cutoff:2873.2354695675895 ]", - "[ 13/4 → 7/2 | s:bd cutoff:2873.2354695675895 ]", - "[ 27/8 → 7/2 | s:hh cutoff:5596.839588950388 ]", - "[ 7/2 → 29/8 | s:hh cutoff:2628.3173956908286 ]", - "[ 7/2 → 15/4 | s:bd cutoff:2628.3173956908286 ]", - "[ 29/8 → 15/4 | s:hh cutoff:7124.103914946318 ]", - "[ 15/4 → 31/8 | s:hh cutoff:814.1072567086667 ]", - "[ 15/4 → 4/1 | s:bd cutoff:814.1072567086667 ]", - "[ 31/8 → 4/1 | s:hh cutoff:518.1868247454986 ]", + "[ 0/1 → 1/8 | s:hh cutoff:3410.6697876704857 ]", + "[ 0/1 → 1/4 | s:bd cutoff:3410.6697876704857 ]", + "[ 1/8 → 1/4 | s:hh cutoff:5409.978067153133 ]", + "[ 1/4 → 3/8 | s:hh cutoff:1470.4432229045779 ]", + "[ 1/4 → 1/2 | s:bd cutoff:1470.4432229045779 ]", + "[ 3/8 → 1/2 | s:hh cutoff:6906.840303097852 ]", + "[ 1/2 → 5/8 | s:hh cutoff:2951.713348273188 ]", + "[ 1/2 → 3/4 | s:bd cutoff:2951.713348273188 ]", + "[ 5/8 → 3/4 | s:hh cutoff:5732.849565800279 ]", + "[ 3/4 → 7/8 | s:hh cutoff:2621.97931134142 ]", + "[ 3/4 → 1/1 | s:bd cutoff:2621.97931134142 ]", + "[ 7/8 → 1/1 | s:hh cutoff:7323.85477644857 ]", + "[ 1/1 → 9/8 | s:hh cutoff:1386.7684000870213 ]", + "[ 1/1 → 5/4 | s:bd cutoff:1386.7684000870213 ]", + "[ 9/8 → 5/4 | s:hh cutoff:968.4956459095702 ]", + "[ 5/4 → 11/8 | s:hh cutoff:7674.6532345423475 ]", + "[ 5/4 → 3/2 | s:bd cutoff:7674.6532345423475 ]", + "[ 11/8 → 3/2 | s:hh cutoff:863.651579245925 ]", + "[ 3/2 → 13/8 | s:hh cutoff:1476.3008129084483 ]", + "[ 3/2 → 7/4 | s:bd cutoff:1476.3008129084483 ]", + "[ 13/8 → 7/4 | s:hh cutoff:5232.728436938487 ]", + "[ 7/4 → 15/8 | s:hh cutoff:3057.402160600759 ]", + "[ 7/4 → 2/1 | s:bd cutoff:3057.402160600759 ]", + "[ 15/8 → 2/1 | s:hh cutoff:5307.644687825814 ]", + "[ 2/1 → 17/8 | s:hh cutoff:4859.5935218036175 ]", + "[ 2/1 → 9/4 | s:bd cutoff:4859.5935218036175 ]", + "[ 17/8 → 9/4 | s:hh cutoff:3798.551473999396 ]", + "[ 9/4 → 19/8 | s:hh cutoff:2020.6333762034774 ]", + "[ 9/4 → 5/2 | s:bd cutoff:2020.6333762034774 ]", + "[ 19/8 → 5/2 | s:hh cutoff:6903.368854080327 ]", + "[ 5/2 → 21/8 | s:hh cutoff:5992.341757635586 ]", + "[ 5/2 → 11/4 | s:bd cutoff:5992.341757635586 ]", + "[ 21/8 → 11/4 | s:hh cutoff:3192.4760919064283 ]", + "[ 11/4 → 23/8 | s:hh cutoff:3188.529685838148 ]", + "[ 11/4 → 3/1 | s:bd cutoff:3188.529685838148 ]", + "[ 23/8 → 3/1 | s:hh cutoff:6837.369324173778 ]", + "[ 3/1 → 25/8 | s:hh cutoff:5111.154264421202 ]", + "[ 3/1 → 13/4 | s:bd cutoff:5111.154264421202 ]", + "[ 25/8 → 13/4 | s:hh cutoff:4812.422384973615 ]", + "[ 13/4 → 27/8 | s:hh cutoff:7517.148802988231 ]", + "[ 13/4 → 7/2 | s:bd cutoff:7517.148802988231 ]", + "[ 27/8 → 7/2 | s:hh cutoff:821.3959728600457 ]", + "[ 7/2 → 29/8 | s:hh cutoff:2354.0139601100236 ]", + "[ 7/2 → 15/4 | s:bd cutoff:2354.0139601100236 ]", + "[ 29/8 → 15/4 | s:hh cutoff:4901.923676487058 ]", + "[ 15/4 → 31/8 | s:hh cutoff:4723.308931104839 ]", + "[ 15/4 → 4/1 | s:bd cutoff:4723.308931104839 ]", + "[ 31/8 → 4/1 | s:hh cutoff:1649.9183619162068 ]", ] `; @@ -8381,35 +8366,35 @@ exports[`runs examples > example "rarely" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", + "[ 1/4 → 3/8 | s:hh speed:0.5 ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh ]", + "[ 9/8 → 5/4 | s:hh speed:0.5 ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", + "[ 9/4 → 19/8 | s:hh speed:0.5 ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", - "[ 21/8 → 11/4 | s:hh speed:0.5 ]", + "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", - "[ 7/2 → 29/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh speed:0.5 ]", + "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -8454,22 +8439,22 @@ exports[`runs examples > example "release" example index 0 1`] = ` exports[`runs examples > example "repeatCycles" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:39 s:gm_acoustic_guitar_nylon ]", - "[ 1/4 → 1/2 | note:41 s:gm_acoustic_guitar_nylon ]", - "[ 1/2 → 3/4 | note:38 s:gm_acoustic_guitar_nylon ]", - "[ 3/4 → 1/1 | note:41 s:gm_acoustic_guitar_nylon ]", - "[ 1/1 → 5/4 | note:39 s:gm_acoustic_guitar_nylon ]", - "[ 5/4 → 3/2 | note:41 s:gm_acoustic_guitar_nylon ]", - "[ 3/2 → 7/4 | note:38 s:gm_acoustic_guitar_nylon ]", - "[ 7/4 → 2/1 | note:41 s:gm_acoustic_guitar_nylon ]", - "[ 2/1 → 9/4 | note:34 s:gm_acoustic_guitar_nylon ]", - "[ 9/4 → 5/2 | note:42 s:gm_acoustic_guitar_nylon ]", - "[ 5/2 → 11/4 | note:36 s:gm_acoustic_guitar_nylon ]", - "[ 11/4 → 3/1 | note:42 s:gm_acoustic_guitar_nylon ]", - "[ 3/1 → 13/4 | note:34 s:gm_acoustic_guitar_nylon ]", - "[ 13/4 → 7/2 | note:42 s:gm_acoustic_guitar_nylon ]", - "[ 7/2 → 15/4 | note:36 s:gm_acoustic_guitar_nylon ]", - "[ 15/4 → 4/1 | note:42 s:gm_acoustic_guitar_nylon ]", + "[ 0/1 → 1/4 | note:38 s:gm_acoustic_guitar_nylon ]", + "[ 1/4 → 1/2 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 1/2 → 3/4 | note:37 s:gm_acoustic_guitar_nylon ]", + "[ 3/4 → 1/1 | note:37 s:gm_acoustic_guitar_nylon ]", + "[ 1/1 → 5/4 | note:38 s:gm_acoustic_guitar_nylon ]", + "[ 5/4 → 3/2 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 3/2 → 7/4 | note:37 s:gm_acoustic_guitar_nylon ]", + "[ 7/4 → 2/1 | note:37 s:gm_acoustic_guitar_nylon ]", + "[ 2/1 → 9/4 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 9/4 → 5/2 | note:45 s:gm_acoustic_guitar_nylon ]", + "[ 5/2 → 11/4 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 11/4 → 3/1 | note:38 s:gm_acoustic_guitar_nylon ]", + "[ 3/1 → 13/4 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 13/4 → 7/2 | note:45 s:gm_acoustic_guitar_nylon ]", + "[ 7/2 → 15/4 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 15/4 → 4/1 | note:38 s:gm_acoustic_guitar_nylon ]", ] `; @@ -8634,43 +8619,43 @@ exports[`runs examples > example "ribbon" example index 0 1`] = ` exports[`runs examples > example "ribbon" example index 1 1`] = ` [ - "[ 0/1 → 1/4 | note:E4 ]", - "[ 1/4 → 1/2 | note:G3 ]", - "[ 1/2 → 3/4 | note:C3 ]", - "[ 3/4 → 1/1 | note:E4 ]", - "[ 1/1 → 5/4 | note:A3 ]", + "[ 0/1 → 1/4 | note:D3 ]", + "[ 1/4 → 1/2 | note:A3 ]", + "[ 1/2 → 3/4 | note:D3 ]", + "[ 3/4 → 1/1 | note:E3 ]", + "[ 1/1 → 5/4 | note:C3 ]", "[ 5/4 → 3/2 | note:D3 ]", - "[ 3/2 → 7/4 | note:A3 ]", - "[ 7/4 → 2/1 | note:G3 ]", - "[ 2/1 → 9/4 | note:E4 ]", - "[ 9/4 → 5/2 | note:G3 ]", - "[ 5/2 → 11/4 | note:C3 ]", - "[ 11/4 → 3/1 | note:E4 ]", - "[ 3/1 → 13/4 | note:A3 ]", + "[ 3/2 → 7/4 | note:D3 ]", + "[ 7/4 → 2/1 | note:C4 ]", + "[ 2/1 → 9/4 | note:D3 ]", + "[ 9/4 → 5/2 | note:A3 ]", + "[ 5/2 → 11/4 | note:D3 ]", + "[ 11/4 → 3/1 | note:E3 ]", + "[ 3/1 → 13/4 | note:C3 ]", "[ 13/4 → 7/2 | note:D3 ]", - "[ 7/2 → 15/4 | note:A3 ]", - "[ 15/4 → 4/1 | note:G3 ]", + "[ 7/2 → 15/4 | note:D3 ]", + "[ 15/4 → 4/1 | note:C4 ]", ] `; exports[`runs examples > example "ribbon" example index 2 1`] = ` [ - "[ 1/8 → 3/16 | s:bd ]", - "[ 7/16 → 1/2 | s:bd ]", - "[ 5/8 → 11/16 | s:bd ]", - "[ 15/16 → 1/1 | s:bd ]", - "[ 9/8 → 19/16 | s:bd ]", - "[ 23/16 → 3/2 | s:bd ]", - "[ 13/8 → 27/16 | s:bd ]", - "[ 31/16 → 2/1 | s:bd ]", - "[ 17/8 → 35/16 | s:bd ]", - "[ 39/16 → 5/2 | s:bd ]", - "[ 21/8 → 43/16 | s:bd ]", - "[ 47/16 → 3/1 | s:bd ]", - "[ 25/8 → 51/16 | s:bd ]", - "[ 55/16 → 7/2 | s:bd ]", - "[ 29/8 → 59/16 | s:bd ]", - "[ 63/16 → 4/1 | s:bd ]", + "[ 1/16 → 1/8 | s:bd ]", + "[ 3/16 → 1/4 | s:bd ]", + "[ 9/16 → 5/8 | s:bd ]", + "[ 11/16 → 3/4 | s:bd ]", + "[ 17/16 → 9/8 | s:bd ]", + "[ 19/16 → 5/4 | s:bd ]", + "[ 25/16 → 13/8 | s:bd ]", + "[ 27/16 → 7/4 | s:bd ]", + "[ 33/16 → 17/8 | s:bd ]", + "[ 35/16 → 9/4 | s:bd ]", + "[ 41/16 → 21/8 | s:bd ]", + "[ 43/16 → 11/4 | s:bd ]", + "[ 49/16 → 25/8 | s:bd ]", + "[ 51/16 → 13/4 | s:bd ]", + "[ 57/16 → 29/8 | s:bd ]", + "[ 59/16 → 15/4 | s:bd ]", ] `; @@ -9201,38 +9186,38 @@ exports[`runs examples > example "scale" example index 1 1`] = ` exports[`runs examples > example "scale" example index 2 1`] = ` [ - "[ 0/1 → 1/8 | note:D4 s:piano ]", - "[ 1/8 → 1/4 | note:C5 s:piano ]", - "[ 1/4 → 3/8 | note:G4 s:piano ]", - "[ 3/8 → 1/2 | note:F4 s:piano ]", - "[ 1/2 → 5/8 | note:C4 s:piano ]", - "[ 5/8 → 3/4 | note:D5 s:piano ]", - "[ 3/4 → 7/8 | note:G4 s:piano ]", + "[ 0/1 → 1/8 | note:C4 s:piano ]", + "[ 1/8 → 1/4 | note:G4 s:piano ]", + "[ 1/4 → 3/8 | note:F3 s:piano ]", + "[ 3/8 → 1/2 | note:D5 s:piano ]", + "[ 1/2 → 5/8 | note:A3 s:piano ]", + "[ 5/8 → 3/4 | note:A4 s:piano ]", + "[ 3/4 → 7/8 | note:A3 s:piano ]", "[ 7/8 → 1/1 | note:D5 s:piano ]", - "[ 1/1 → 9/8 | note:D3 s:piano ]", - "[ 9/8 → 5/4 | note:C5 s:piano ]", - "[ 5/4 → 11/8 | note:A4 s:piano ]", - "[ 11/8 → 3/2 | note:D5 s:piano ]", - "[ 3/2 → 13/8 | note:G3 s:piano ]", - "[ 13/8 → 7/4 | note:A3 s:piano ]", - "[ 7/4 → 15/8 | note:A4 s:piano ]", - "[ 15/8 → 2/1 | note:C5 s:piano ]", + "[ 1/1 → 9/8 | note:F3 s:piano ]", + "[ 9/8 → 5/4 | note:D3 s:piano ]", + "[ 5/4 → 11/8 | note:F5 s:piano ]", + "[ 11/8 → 3/2 | note:D3 s:piano ]", + "[ 3/2 → 13/8 | note:F3 s:piano ]", + "[ 13/8 → 7/4 | note:G4 s:piano ]", + "[ 7/4 → 15/8 | note:C4 s:piano ]", + "[ 15/8 → 2/1 | note:G4 s:piano ]", "[ 2/1 → 17/8 | note:F4 s:piano ]", - "[ 17/8 → 9/4 | note:C5 s:piano ]", - "[ 9/4 → 19/8 | note:G4 s:piano ]", - "[ 19/8 → 5/2 | note:A4 s:piano ]", - "[ 5/2 → 21/8 | note:C4 s:piano ]", - "[ 21/8 → 11/4 | note:D3 s:piano ]", - "[ 11/4 → 23/8 | note:A4 s:piano ]", + "[ 17/8 → 9/4 | note:D4 s:piano ]", + "[ 9/4 → 19/8 | note:G3 s:piano ]", + "[ 19/8 → 5/2 | note:D5 s:piano ]", + "[ 5/2 → 21/8 | note:A4 s:piano ]", + "[ 21/8 → 11/4 | note:C4 s:piano ]", + "[ 11/4 → 23/8 | note:C4 s:piano ]", "[ 23/8 → 3/1 | note:D5 s:piano ]", - "[ 3/1 → 25/8 | note:D4 s:piano ]", - "[ 25/8 → 13/4 | note:A4 s:piano ]", - "[ 13/4 → 27/8 | note:A3 s:piano ]", - "[ 27/8 → 7/2 | note:A4 s:piano ]", - "[ 7/2 → 29/8 | note:A3 s:piano ]", - "[ 29/8 → 15/4 | note:D5 s:piano ]", - "[ 15/4 → 31/8 | note:D3 s:piano ]", - "[ 31/8 → 4/1 | note:D3 s:piano ]", + "[ 3/1 → 25/8 | note:G4 s:piano ]", + "[ 25/8 → 13/4 | note:F4 s:piano ]", + "[ 13/4 → 27/8 | note:F5 s:piano ]", + "[ 27/8 → 7/2 | note:D3 s:piano ]", + "[ 7/2 → 29/8 | note:G3 s:piano ]", + "[ 29/8 → 15/4 | note:G4 s:piano ]", + "[ 15/4 → 31/8 | note:F4 s:piano ]", + "[ 31/8 → 4/1 | note:F3 s:piano ]", ] `; @@ -9271,70 +9256,70 @@ exports[`runs examples > example "scale" example index 3 1`] = ` exports[`runs examples > example "scale" example index 4 1`] = ` [ - "[ 0/1 → 1/16 | note:Gb1 ]", - "[ 1/16 → 1/8 | note:Gb1 ]", - "[ 1/8 → 3/16 | note:Gb1 ]", - "[ 3/16 → 1/4 | note:Gb1 ]", - "[ 1/4 → 5/16 | note:Gb1 ]", - "[ 5/16 → 3/8 | note:Gb1 ]", - "[ 3/8 → 7/16 | note:Gb1 ]", - "[ 7/16 → 1/2 | note:Gb1 ]", - "[ 1/2 → 9/16 | note:Gb1 ]", - "[ 9/16 → 5/8 | note:Gb1 ]", - "[ 5/8 → 11/16 | note:Gb1 ]", - "[ 11/16 → 3/4 | note:Gb1 ]", - "[ 3/4 → 13/16 | note:Gb1 ]", - "[ 13/16 → 7/8 | note:Gb1 ]", - "[ 7/8 → 15/16 | note:Gb1 ]", - "[ 15/16 → 1/1 | note:Gb1 ]", - "[ 1/1 → 17/16 | note:Cb3 ]", - "[ 17/16 → 9/8 | note:Cb3 ]", - "[ 9/8 → 19/16 | note:Cb3 ]", - "[ 19/16 → 5/4 | note:Cb3 ]", - "[ 5/4 → 21/16 | note:Cb3 ]", - "[ 21/16 → 11/8 | note:Cb3 ]", - "[ 11/8 → 23/16 | note:Cb3 ]", - "[ 23/16 → 3/2 | note:Cb3 ]", - "[ 3/2 → 25/16 | note:Cb3 ]", - "[ 25/16 → 13/8 | note:Cb3 ]", - "[ 13/8 → 27/16 | note:Cb3 ]", - "[ 27/16 → 7/4 | note:Cb3 ]", - "[ 7/4 → 29/16 | note:Cb3 ]", - "[ 29/16 → 15/8 | note:Cb3 ]", - "[ 15/8 → 31/16 | note:Cb3 ]", - "[ 31/16 → 2/1 | note:Cb3 ]", - "[ 2/1 → 33/16 | note:Eb4 ]", - "[ 33/16 → 17/8 | note:Eb4 ]", - "[ 17/8 → 35/16 | note:Eb4 ]", - "[ 35/16 → 9/4 | note:Eb4 ]", - "[ 9/4 → 37/16 | note:Eb4 ]", - "[ 37/16 → 19/8 | note:Eb4 ]", - "[ 19/8 → 39/16 | note:Eb4 ]", - "[ 39/16 → 5/2 | note:Eb4 ]", - "[ 5/2 → 41/16 | note:Eb4 ]", - "[ 41/16 → 21/8 | note:Eb4 ]", - "[ 21/8 → 43/16 | note:Eb4 ]", - "[ 43/16 → 11/4 | note:Eb4 ]", - "[ 11/4 → 45/16 | note:Eb4 ]", - "[ 45/16 → 23/8 | note:Eb4 ]", - "[ 23/8 → 47/16 | note:Eb4 ]", - "[ 47/16 → 3/1 | note:Eb4 ]", - "[ 3/1 → 49/16 | note:Db2 ]", - "[ 49/16 → 25/8 | note:Db2 ]", - "[ 25/8 → 51/16 | note:Db2 ]", - "[ 51/16 → 13/4 | note:Db2 ]", - "[ 13/4 → 53/16 | note:Db2 ]", - "[ 53/16 → 27/8 | note:Db2 ]", - "[ 27/8 → 55/16 | note:Db2 ]", - "[ 55/16 → 7/2 | note:Db2 ]", - "[ 7/2 → 57/16 | note:Db2 ]", - "[ 57/16 → 29/8 | note:Db2 ]", - "[ 29/8 → 59/16 | note:Db2 ]", - "[ 59/16 → 15/4 | note:Db2 ]", - "[ 15/4 → 61/16 | note:Db2 ]", - "[ 61/16 → 31/8 | note:Db2 ]", - "[ 31/8 → 63/16 | note:Db2 ]", - "[ 63/16 → 4/1 | note:Db2 ]", + "[ 0/1 → 1/16 | note:Gb2 ]", + "[ 1/16 → 1/8 | note:Gb2 ]", + "[ 1/8 → 3/16 | note:Gb2 ]", + "[ 3/16 → 1/4 | note:Gb2 ]", + "[ 1/4 → 5/16 | note:Gb2 ]", + "[ 5/16 → 3/8 | note:Gb2 ]", + "[ 3/8 → 7/16 | note:Gb2 ]", + "[ 7/16 → 1/2 | note:Gb2 ]", + "[ 1/2 → 9/16 | note:Gb2 ]", + "[ 9/16 → 5/8 | note:Gb2 ]", + "[ 5/8 → 11/16 | note:Gb2 ]", + "[ 11/16 → 3/4 | note:Gb2 ]", + "[ 3/4 → 13/16 | note:Gb2 ]", + "[ 13/16 → 7/8 | note:Gb2 ]", + "[ 7/8 → 15/16 | note:Gb2 ]", + "[ 15/16 → 1/1 | note:Gb2 ]", + "[ 1/1 → 17/16 | note:Bb1 ]", + "[ 17/16 → 9/8 | note:Bb1 ]", + "[ 9/8 → 19/16 | note:Bb1 ]", + "[ 19/16 → 5/4 | note:Bb1 ]", + "[ 5/4 → 21/16 | note:Bb1 ]", + "[ 21/16 → 11/8 | note:Bb1 ]", + "[ 11/8 → 23/16 | note:Bb1 ]", + "[ 23/16 → 3/2 | note:Bb1 ]", + "[ 3/2 → 25/16 | note:Bb1 ]", + "[ 25/16 → 13/8 | note:Bb1 ]", + "[ 13/8 → 27/16 | note:Bb1 ]", + "[ 27/16 → 7/4 | note:Bb1 ]", + "[ 7/4 → 29/16 | note:Bb1 ]", + "[ 29/16 → 15/8 | note:Bb1 ]", + "[ 15/8 → 31/16 | note:Bb1 ]", + "[ 31/16 → 2/1 | note:Bb1 ]", + "[ 2/1 → 33/16 | note:Db3 ]", + "[ 33/16 → 17/8 | note:Db3 ]", + "[ 17/8 → 35/16 | note:Db3 ]", + "[ 35/16 → 9/4 | note:Db3 ]", + "[ 9/4 → 37/16 | note:Db3 ]", + "[ 37/16 → 19/8 | note:Db3 ]", + "[ 19/8 → 39/16 | note:Db3 ]", + "[ 39/16 → 5/2 | note:Db3 ]", + "[ 5/2 → 41/16 | note:Db3 ]", + "[ 41/16 → 21/8 | note:Db3 ]", + "[ 21/8 → 43/16 | note:Db3 ]", + "[ 43/16 → 11/4 | note:Db3 ]", + "[ 11/4 → 45/16 | note:Db3 ]", + "[ 45/16 → 23/8 | note:Db3 ]", + "[ 23/8 → 47/16 | note:Db3 ]", + "[ 47/16 → 3/1 | note:Db3 ]", + "[ 3/1 → 49/16 | note:Eb3 ]", + "[ 49/16 → 25/8 | note:Eb3 ]", + "[ 25/8 → 51/16 | note:Eb3 ]", + "[ 51/16 → 13/4 | note:Eb3 ]", + "[ 13/4 → 53/16 | note:Eb3 ]", + "[ 53/16 → 27/8 | note:Eb3 ]", + "[ 27/8 → 55/16 | note:Eb3 ]", + "[ 55/16 → 7/2 | note:Eb3 ]", + "[ 7/2 → 57/16 | note:Eb3 ]", + "[ 57/16 → 29/8 | note:Eb3 ]", + "[ 29/8 → 59/16 | note:Eb3 ]", + "[ 59/16 → 15/4 | note:Eb3 ]", + "[ 15/4 → 61/16 | note:Eb3 ]", + "[ 61/16 → 31/8 | note:Eb3 ]", + "[ 31/8 → 63/16 | note:Eb3 ]", + "[ 63/16 → 4/1 | note:Eb3 ]", ] `; @@ -9408,45 +9393,45 @@ exports[`runs examples > example "scope" example index 0 1`] = ` exports[`runs examples > example "scramble" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:d s:piano ]", - "[ 1/4 → 1/2 | note:e s:piano ]", + "[ 1/4 → 1/2 | note:c s:piano ]", "[ 1/2 → 3/4 | note:d s:piano ]", - "[ 3/4 → 1/1 | note:e s:piano ]", + "[ 3/4 → 1/1 | note:d s:piano ]", "[ 1/1 → 5/4 | note:c s:piano ]", - "[ 5/4 → 3/2 | note:e s:piano ]", + "[ 5/4 → 3/2 | note:f s:piano ]", "[ 3/2 → 7/4 | note:c s:piano ]", - "[ 7/4 → 2/1 | note:e s:piano ]", + "[ 7/4 → 2/1 | note:d s:piano ]", "[ 2/1 → 9/4 | note:e s:piano ]", - "[ 9/4 → 5/2 | note:e s:piano ]", - "[ 5/2 → 11/4 | note:d s:piano ]", - "[ 11/4 → 3/1 | note:e s:piano ]", - "[ 3/1 → 13/4 | note:d s:piano ]", - "[ 13/4 → 7/2 | note:d s:piano ]", - "[ 7/2 → 15/4 | note:d s:piano ]", - "[ 15/4 → 4/1 | note:c s:piano ]", + "[ 9/4 → 5/2 | note:c s:piano ]", + "[ 5/2 → 11/4 | note:e s:piano ]", + "[ 11/4 → 3/1 | note:d s:piano ]", + "[ 3/1 → 13/4 | note:e s:piano ]", + "[ 13/4 → 7/2 | note:f s:piano ]", + "[ 7/2 → 15/4 | note:c s:piano ]", + "[ 15/4 → 4/1 | note:e s:piano ]", ] `; exports[`runs examples > example "scramble" example index 1 1`] = ` [ "[ 0/1 → 1/8 | note:d s:piano ]", - "[ 1/8 → 1/4 | note:e s:piano ]", + "[ 1/8 → 1/4 | note:c s:piano ]", "[ 1/4 → 3/8 | note:d s:piano ]", - "[ 3/8 → 1/2 | note:e s:piano ]", + "[ 3/8 → 1/2 | note:d s:piano ]", "[ 1/2 → 1/1 | note:g s:piano ]", "[ 1/1 → 9/8 | note:c s:piano ]", - "[ 9/8 → 5/4 | note:e s:piano ]", + "[ 9/8 → 5/4 | note:f s:piano ]", "[ 5/4 → 11/8 | note:c s:piano ]", - "[ 11/8 → 3/2 | note:e s:piano ]", + "[ 11/8 → 3/2 | note:d s:piano ]", "[ 3/2 → 2/1 | note:g s:piano ]", "[ 2/1 → 17/8 | note:e s:piano ]", - "[ 17/8 → 9/4 | note:e s:piano ]", - "[ 9/4 → 19/8 | note:d s:piano ]", - "[ 19/8 → 5/2 | note:e s:piano ]", + "[ 17/8 → 9/4 | note:c s:piano ]", + "[ 9/4 → 19/8 | note:e s:piano ]", + "[ 19/8 → 5/2 | note:d s:piano ]", "[ 5/2 → 3/1 | note:g s:piano ]", - "[ 3/1 → 25/8 | note:d s:piano ]", - "[ 25/8 → 13/4 | note:d s:piano ]", - "[ 13/4 → 27/8 | note:d s:piano ]", - "[ 27/8 → 7/2 | note:c s:piano ]", + "[ 3/1 → 25/8 | note:e s:piano ]", + "[ 25/8 → 13/4 | note:f s:piano ]", + "[ 13/4 → 27/8 | note:c s:piano ]", + "[ 27/8 → 7/2 | note:e s:piano ]", "[ 7/2 → 4/1 | note:g s:piano ]", ] `; @@ -9497,6 +9482,23 @@ exports[`runs examples > example "scrub" example index 1 1`] = ` ] `; +exports[`runs examples > example "seed" example index 0 1`] = ` +[ + "[ 1/4 → 1/2 | s:bd ]", + "[ 1/2 → 3/4 | s:bd ]", + "[ 3/4 → 1/1 | s:bd ]", + "[ 1/1 → 5/4 | s:bd ]", + "[ 5/4 → 3/2 | s:bd ]", + "[ 3/2 → 7/4 | s:bd ]", + "[ 7/4 → 2/1 | s:bd ]", + "[ 2/1 → 9/4 | s:bd ]", + "[ 11/4 → 3/1 | s:bd ]", + "[ 3/1 → 13/4 | s:bd ]", + "[ 13/4 → 7/2 | s:bd ]", + "[ 7/2 → 15/4 | s:bd ]", +] +`; + exports[`runs examples > example "segment" example index 0 1`] = ` [ "[ 0/1 → 1/24 | note:40 ]", @@ -9703,38 +9705,38 @@ exports[`runs examples > example "setGainCurve" example index 0 1`] = ` exports[`runs examples > example "setMaxPolyphony" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | note:F#4 room:1 release:4 gain:0.5 ]", - "[ 1/8 → 1/4 | note:A5 room:1 release:4 gain:0.5 ]", - "[ 1/4 → 3/8 | note:C#5 room:1 release:4 gain:0.5 ]", - "[ 3/8 → 1/2 | note:A4 room:1 release:4 gain:0.5 ]", - "[ 1/2 → 5/8 | note:E4 room:1 release:4 gain:0.5 ]", - "[ 5/8 → 3/4 | note:C#6 room:1 release:4 gain:0.5 ]", - "[ 3/4 → 7/8 | note:D#5 room:1 release:4 gain:0.5 ]", + "[ 0/1 → 1/8 | note:E4 room:1 release:4 gain:0.5 ]", + "[ 1/8 → 1/4 | note:D#5 room:1 release:4 gain:0.5 ]", + "[ 1/4 → 3/8 | note:F#3 room:1 release:4 gain:0.5 ]", + "[ 3/8 → 1/2 | note:B5 room:1 release:4 gain:0.5 ]", + "[ 1/2 → 5/8 | note:C#4 room:1 release:4 gain:0.5 ]", + "[ 5/8 → 3/4 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 3/4 → 7/8 | note:B3 room:1 release:4 gain:0.5 ]", "[ 7/8 → 1/1 | note:C#6 room:1 release:4 gain:0.5 ]", - "[ 1/1 → 9/8 | note:C#3 room:1 release:4 gain:0.5 ]", - "[ 9/8 → 5/4 | note:A5 room:1 release:4 gain:0.5 ]", - "[ 5/4 → 11/8 | note:E5 room:1 release:4 gain:0.5 ]", - "[ 11/8 → 3/2 | note:B5 room:1 release:4 gain:0.5 ]", - "[ 3/2 → 13/8 | note:A3 room:1 release:4 gain:0.5 ]", - "[ 13/8 → 7/4 | note:B3 room:1 release:4 gain:0.5 ]", - "[ 7/4 → 15/8 | note:F#5 room:1 release:4 gain:0.5 ]", - "[ 15/8 → 2/1 | note:G#5 room:1 release:4 gain:0.5 ]", - "[ 2/1 → 17/8 | note:A4 room:1 release:4 gain:0.5 ]", - "[ 17/8 → 9/4 | note:G#5 room:1 release:4 gain:0.5 ]", - "[ 9/4 → 19/8 | note:D#5 room:1 release:4 gain:0.5 ]", - "[ 19/8 → 5/2 | note:E5 room:1 release:4 gain:0.5 ]", - "[ 5/2 → 21/8 | note:D#4 room:1 release:4 gain:0.5 ]", - "[ 21/8 → 11/4 | note:C#3 room:1 release:4 gain:0.5 ]", - "[ 11/4 → 23/8 | note:E5 room:1 release:4 gain:0.5 ]", - "[ 23/8 → 3/1 | note:C#6 room:1 release:4 gain:0.5 ]", - "[ 3/1 → 25/8 | note:F#4 room:1 release:4 gain:0.5 ]", - "[ 25/8 → 13/4 | note:E5 room:1 release:4 gain:0.5 ]", - "[ 13/4 → 27/8 | note:C#4 room:1 release:4 gain:0.5 ]", - "[ 27/8 → 7/2 | note:E5 room:1 release:4 gain:0.5 ]", - "[ 7/2 → 29/8 | note:B3 room:1 release:4 gain:0.5 ]", - "[ 29/8 → 15/4 | note:C#6 room:1 release:4 gain:0.5 ]", - "[ 15/4 → 31/8 | note:D#3 room:1 release:4 gain:0.5 ]", - "[ 31/8 → 4/1 | note:C#3 room:1 release:4 gain:0.5 ]", + "[ 1/1 → 9/8 | note:E3 room:1 release:4 gain:0.5 ]", + "[ 9/8 → 5/4 | note:D#3 room:1 release:4 gain:0.5 ]", + "[ 5/4 → 11/8 | note:D#6 room:1 release:4 gain:0.5 ]", + "[ 11/8 → 3/2 | note:D#3 room:1 release:4 gain:0.5 ]", + "[ 3/2 → 13/8 | note:F#3 room:1 release:4 gain:0.5 ]", + "[ 13/8 → 7/4 | note:D#5 room:1 release:4 gain:0.5 ]", + "[ 7/4 → 15/8 | note:D#4 room:1 release:4 gain:0.5 ]", + "[ 15/8 → 2/1 | note:D#5 room:1 release:4 gain:0.5 ]", + "[ 2/1 → 17/8 | note:B4 room:1 release:4 gain:0.5 ]", + "[ 17/8 → 9/4 | note:F#4 room:1 release:4 gain:0.5 ]", + "[ 9/4 → 19/8 | note:G#3 room:1 release:4 gain:0.5 ]", + "[ 19/8 → 5/2 | note:B5 room:1 release:4 gain:0.5 ]", + "[ 5/2 → 21/8 | note:F#5 room:1 release:4 gain:0.5 ]", + "[ 21/8 → 11/4 | note:D#4 room:1 release:4 gain:0.5 ]", + "[ 11/4 → 23/8 | note:D#4 room:1 release:4 gain:0.5 ]", + "[ 23/8 → 3/1 | note:B5 room:1 release:4 gain:0.5 ]", + "[ 3/1 → 25/8 | note:C#5 room:1 release:4 gain:0.5 ]", + "[ 25/8 → 13/4 | note:B4 room:1 release:4 gain:0.5 ]", + "[ 13/4 → 27/8 | note:D#6 room:1 release:4 gain:0.5 ]", + "[ 27/8 → 7/2 | note:D#3 room:1 release:4 gain:0.5 ]", + "[ 7/2 → 29/8 | note:A3 room:1 release:4 gain:0.5 ]", + "[ 29/8 → 15/4 | note:C#5 room:1 release:4 gain:0.5 ]", + "[ 15/4 → 31/8 | note:B4 room:1 release:4 gain:0.5 ]", + "[ 31/8 → 4/1 | note:F#3 room:1 release:4 gain:0.5 ]", ] `; @@ -9970,46 +9972,46 @@ exports[`runs examples > example "shrink" example index 3 1`] = ` exports[`runs examples > example "shuffle" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:e s:piano ]", - "[ 1/4 → 1/2 | note:c s:piano ]", - "[ 1/2 → 3/4 | note:f s:piano ]", - "[ 3/4 → 1/1 | note:d s:piano ]", - "[ 1/1 → 5/4 | note:f s:piano ]", - "[ 5/4 → 3/2 | note:c s:piano ]", - "[ 3/2 → 7/4 | note:e s:piano ]", - "[ 7/4 → 2/1 | note:d s:piano ]", - "[ 2/1 → 9/4 | note:c s:piano ]", - "[ 9/4 → 5/2 | note:f s:piano ]", - "[ 5/2 → 11/4 | note:d s:piano ]", - "[ 11/4 → 3/1 | note:e s:piano ]", - "[ 3/1 → 13/4 | note:c s:piano ]", - "[ 13/4 → 7/2 | note:d s:piano ]", - "[ 7/2 → 15/4 | note:f s:piano ]", - "[ 15/4 → 4/1 | note:e s:piano ]", + "[ 0/1 → 1/4 | note:f s:piano ]", + "[ 1/4 → 1/2 | note:d s:piano ]", + "[ 1/2 → 3/4 | note:c s:piano ]", + "[ 3/4 → 1/1 | note:e s:piano ]", + "[ 1/1 → 5/4 | note:c s:piano ]", + "[ 5/4 → 3/2 | note:f s:piano ]", + "[ 3/2 → 7/4 | note:d s:piano ]", + "[ 7/4 → 2/1 | note:e s:piano ]", + "[ 2/1 → 9/4 | note:e s:piano ]", + "[ 9/4 → 5/2 | note:d s:piano ]", + "[ 5/2 → 11/4 | note:f s:piano ]", + "[ 11/4 → 3/1 | note:c s:piano ]", + "[ 3/1 → 13/4 | note:f s:piano ]", + "[ 13/4 → 7/2 | note:c s:piano ]", + "[ 7/2 → 15/4 | note:e s:piano ]", + "[ 15/4 → 4/1 | note:d s:piano ]", ] `; exports[`runs examples > example "shuffle" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | note:e s:piano ]", - "[ 1/8 → 1/4 | note:c s:piano ]", - "[ 1/4 → 3/8 | note:f s:piano ]", - "[ 3/8 → 1/2 | note:d s:piano ]", + "[ 0/1 → 1/8 | note:f s:piano ]", + "[ 1/8 → 1/4 | note:d s:piano ]", + "[ 1/4 → 3/8 | note:c s:piano ]", + "[ 3/8 → 1/2 | note:e s:piano ]", "[ 1/2 → 1/1 | note:g s:piano ]", - "[ 1/1 → 9/8 | note:f s:piano ]", - "[ 9/8 → 5/4 | note:c s:piano ]", - "[ 5/4 → 11/8 | note:e s:piano ]", - "[ 11/8 → 3/2 | note:d s:piano ]", + "[ 1/1 → 9/8 | note:c s:piano ]", + "[ 9/8 → 5/4 | note:f s:piano ]", + "[ 5/4 → 11/8 | note:d s:piano ]", + "[ 11/8 → 3/2 | note:e s:piano ]", "[ 3/2 → 2/1 | note:g s:piano ]", - "[ 2/1 → 17/8 | note:c s:piano ]", - "[ 17/8 → 9/4 | note:f s:piano ]", - "[ 9/4 → 19/8 | note:d s:piano ]", - "[ 19/8 → 5/2 | note:e s:piano ]", + "[ 2/1 → 17/8 | note:e s:piano ]", + "[ 17/8 → 9/4 | note:d s:piano ]", + "[ 9/4 → 19/8 | note:f s:piano ]", + "[ 19/8 → 5/2 | note:c 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:f s:piano ]", - "[ 27/8 → 7/2 | note:e s:piano ]", + "[ 3/1 → 25/8 | note:f s:piano ]", + "[ 25/8 → 13/4 | note:c s:piano ]", + "[ 13/4 → 27/8 | note:e s:piano ]", + "[ 27/8 → 7/2 | note:d s:piano ]", "[ 7/2 → 4/1 | note:g s:piano ]", ] `; @@ -10214,15 +10216,15 @@ exports[`runs examples > example "someCycles" example index 0 1`] = ` "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh speed:0.5 ]", - "[ 3/1 → 4/1 | s:bd speed:0.5 ]", - "[ 25/8 → 13/4 | s:hh speed:0.5 ]", - "[ 13/4 → 27/8 | s:hh speed:0.5 ]", - "[ 27/8 → 7/2 | s:hh speed:0.5 ]", - "[ 7/2 → 29/8 | s:hh speed:0.5 ]", - "[ 29/8 → 15/4 | s:hh speed:0.5 ]", - "[ 15/4 → 31/8 | s:hh speed:0.5 ]", - "[ 31/8 → 4/1 | s:hh speed:0.5 ]", + "[ 3/1 → 25/8 | s:hh ]", + "[ 3/1 → 4/1 | s:bd ]", + "[ 25/8 → 13/4 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh ]", + "[ 7/2 → 29/8 | s:hh ]", + "[ 29/8 → 15/4 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -10271,72 +10273,72 @@ exports[`runs examples > example "sometimes" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh speed:0.5 ]", "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", + "[ 1/4 → 3/8 | s:hh speed:0.5 ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh speed:0.5 ]", "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", + "[ 3/4 → 7/8 | s:hh speed:0.5 ]", "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh ]", + "[ 9/8 → 5/4 | s:hh speed:0.5 ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", - "[ 13/8 → 7/4 | s:hh speed:0.5 ]", - "[ 7/4 → 15/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", + "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", - "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", + "[ 17/8 → 9/4 | s:hh speed:0.5 ]", + "[ 9/4 → 19/8 | s:hh speed:0.5 ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 5/2 → 21/8 | s:hh speed:0.5 ]", + "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", - "[ 11/4 → 23/8 | s:hh ]", + "[ 11/4 → 23/8 | s:hh speed:0.5 ]", "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh speed:0.5 ]", + "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh speed:0.5 ]", - "[ 27/8 → 7/2 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; exports[`runs examples > example "sometimesBy" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh ]", + "[ 0/1 → 1/8 | s:hh speed:0.5 ]", "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", + "[ 1/4 → 3/8 | s:hh speed:0.5 ]", "[ 3/8 → 1/2 | s:hh ]", - "[ 1/2 → 5/8 | s:hh ]", + "[ 1/2 → 5/8 | s:hh speed:0.5 ]", "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", + "[ 3/4 → 7/8 | s:hh speed:0.5 ]", "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh ]", + "[ 9/8 → 5/4 | s:hh speed:0.5 ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", + "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", - "[ 13/8 → 7/4 | s:hh speed:0.5 ]", - "[ 7/4 → 15/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", + "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", + "[ 9/4 → 19/8 | s:hh speed:0.5 ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 5/2 → 21/8 | s:hh speed:0.5 ]", + "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", - "[ 11/4 → 23/8 | s:hh ]", + "[ 11/4 → 23/8 | s:hh speed:0.5 ]", "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh speed:0.5 ]", - "[ 27/8 → 7/2 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -11721,16 +11723,20 @@ exports[`runs examples > example "tri" example index 0 1`] = ` exports[`runs examples > example "undegrade" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", + "[ 1/4 → 3/8 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh ]", - "[ 13/8 → 7/4 | s:hh ]", - "[ 5/2 → 21/8 | s:hh ]", + "[ 7/4 → 15/8 | s:hh ]", + "[ 17/8 → 9/4 | s:hh ]", + "[ 9/4 → 19/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 11/4 → 23/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -11739,56 +11745,58 @@ exports[`runs examples > example "undegrade" example index 1 1`] = ` [ "[ 0/1 → 1/10 | s:hh pan:1 ]", "[ 1/10 → 1/5 | s:hh pan:1 ]", - "[ 1/5 → 3/10 | s:hh pan:1 ]", - "[ 3/10 → 2/5 | s:hh pan:0 ]", - "[ 2/5 → 1/2 | s:hh pan:1 ]", + "[ 1/5 → 3/10 | s:hh pan:0 ]", + "[ 3/10 → 2/5 | s:hh pan:1 ]", + "[ 2/5 → 1/2 | s:hh pan:0 ]", "[ 1/2 → 3/5 | s:hh pan:1 ]", - "[ 3/5 → 7/10 | s:hh pan:0 ]", - "[ 7/10 → 4/5 | s:hh pan:0 ]", - "[ 4/5 → 9/10 | s:hh pan:0 ]", - "[ 9/10 → 1/1 | s:hh pan:1 ]", + "[ 3/5 → 7/10 | s:hh pan:1 ]", + "[ 7/10 → 4/5 | s:hh pan:1 ]", + "[ 4/5 → 9/10 | s:hh pan:1 ]", + "[ 9/10 → 1/1 | s:hh pan:0 ]", "[ 1/1 → 11/10 | s:hh pan:1 ]", - "[ 11/10 → 6/5 | s:hh pan:0 ]", + "[ 11/10 → 6/5 | s:hh pan:1 ]", "[ 6/5 → 13/10 | s:hh pan:0 ]", "[ 13/10 → 7/5 | s:hh pan:1 ]", - "[ 7/5 → 3/2 | s:hh pan:1 ]", + "[ 7/5 → 3/2 | s:hh pan:0 ]", "[ 3/2 → 8/5 | s:hh pan:1 ]", "[ 8/5 → 17/10 | s:hh pan:0 ]", - "[ 17/10 → 9/5 | s:hh pan:0 ]", - "[ 9/5 → 19/10 | s:hh pan:1 ]", + "[ 17/10 → 9/5 | s:hh pan:1 ]", + "[ 9/5 → 19/10 | s:hh pan:0 ]", "[ 19/10 → 2/1 | s:hh pan:1 ]", "[ 2/1 → 21/10 | s:hh pan:0 ]", "[ 21/10 → 11/5 | s:hh pan:1 ]", "[ 11/5 → 23/10 | s:hh pan:0 ]", "[ 23/10 → 12/5 | s:hh pan:1 ]", - "[ 12/5 → 5/2 | s:hh pan:1 ]", - "[ 5/2 → 13/5 | s:hh pan:1 ]", + "[ 12/5 → 5/2 | s:hh pan:0 ]", + "[ 5/2 → 13/5 | s:hh pan:0 ]", "[ 13/5 → 27/10 | s:hh pan:0 ]", "[ 27/10 → 14/5 | s:hh pan:1 ]", - "[ 14/5 → 29/10 | s:hh pan:1 ]", - "[ 29/10 → 3/1 | s:hh pan:1 ]", - "[ 3/1 → 31/10 | s:hh pan:1 ]", - "[ 31/10 → 16/5 | s:hh pan:0 ]", + "[ 14/5 → 29/10 | s:hh pan:0 ]", + "[ 29/10 → 3/1 | s:hh pan:0 ]", + "[ 3/1 → 31/10 | s:hh pan:0 ]", + "[ 31/10 → 16/5 | s:hh pan:1 ]", "[ 16/5 → 33/10 | s:hh pan:1 ]", "[ 33/10 → 17/5 | s:hh pan:0 ]", - "[ 17/5 → 7/2 | s:hh pan:0 ]", + "[ 17/5 → 7/2 | s:hh pan:1 ]", "[ 7/2 → 18/5 | s:hh pan:1 ]", - "[ 18/5 → 37/10 | s:hh pan:0 ]", + "[ 18/5 → 37/10 | s:hh pan:1 ]", "[ 37/10 → 19/5 | s:hh pan:1 ]", "[ 19/5 → 39/10 | s:hh pan:0 ]", - "[ 39/10 → 4/1 | s:hh pan:0 ]", + "[ 39/10 → 4/1 | s:hh pan:1 ]", ] `; exports[`runs examples > example "undegradeBy" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", + "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", - "[ 5/4 → 11/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", @@ -11796,15 +11804,14 @@ exports[`runs examples > example "undegradeBy" example index 0 1`] = ` "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh ]", - "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", + "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh ]", ] @@ -11826,32 +11833,32 @@ exports[`runs examples > example "undegradeBy" example index 1 1`] = ` "[ 11/10 → 6/5 | s:hh pan:0 ]", "[ 6/5 → 13/10 | s:hh pan:0 ]", "[ 13/10 → 7/5 | s:hh pan:1 ]", - "[ 7/5 → 3/2 | s:hh pan:1 ]", - "[ 3/2 → 8/5 | s:hh pan:0 ]", + "[ 7/5 → 3/2 | s:hh pan:0 ]", + "[ 3/2 → 8/5 | s:hh pan:1 ]", "[ 8/5 → 17/10 | s:hh pan:0 ]", "[ 17/10 → 9/5 | s:hh pan:0 ]", "[ 9/5 → 19/10 | s:hh pan:0 ]", - "[ 19/10 → 2/1 | s:hh pan:1 ]", + "[ 19/10 → 2/1 | s:hh pan:0 ]", "[ 2/1 → 21/10 | s:hh pan:0 ]", "[ 21/10 → 11/5 | s:hh pan:1 ]", "[ 11/5 → 23/10 | s:hh pan:0 ]", - "[ 23/10 → 12/5 | s:hh pan:1 ]", + "[ 23/10 → 12/5 | s:hh pan:0 ]", "[ 12/5 → 5/2 | s:hh pan:0 ]", "[ 5/2 → 13/5 | s:hh pan:0 ]", "[ 13/5 → 27/10 | s:hh pan:0 ]", - "[ 27/10 → 14/5 | s:hh pan:1 ]", - "[ 14/5 → 29/10 | s:hh pan:1 ]", + "[ 27/10 → 14/5 | s:hh pan:0 ]", + "[ 14/5 → 29/10 | s:hh pan:0 ]", "[ 29/10 → 3/1 | s:hh pan:0 ]", "[ 3/1 → 31/10 | s:hh pan:0 ]", - "[ 31/10 → 16/5 | s:hh pan:0 ]", - "[ 16/5 → 33/10 | s:hh pan:1 ]", + "[ 31/10 → 16/5 | s:hh pan:1 ]", + "[ 16/5 → 33/10 | s:hh pan:0 ]", "[ 33/10 → 17/5 | s:hh pan:0 ]", "[ 17/5 → 7/2 | s:hh pan:0 ]", "[ 7/2 → 18/5 | s:hh pan:0 ]", "[ 18/5 → 37/10 | s:hh pan:0 ]", - "[ 37/10 → 19/5 | s:hh pan:1 ]", + "[ 37/10 → 19/5 | s:hh pan:0 ]", "[ 19/5 → 39/10 | s:hh pan:0 ]", - "[ 39/10 → 4/1 | s:hh pan:0 ]", + "[ 39/10 → 4/1 | s:hh pan:1 ]", ] `; @@ -12156,14 +12163,14 @@ exports[`runs examples > example "vowel" example index 0 1`] = ` exports[`runs examples > example "vowel" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | s:bd vowel:i ]", - "[ 1/8 → 1/4 | s:sd vowel:i ]", - "[ 1/4 → 3/8 | s:mt vowel:i ]", - "[ 3/8 → 1/2 | s:ht vowel:i ]", - "[ 1/2 → 5/8 | s:bd vowel:i ]", - "[ 11/16 → 3/4 | s:cp vowel:i ]", - "[ 3/4 → 7/8 | s:ht vowel:i ]", - "[ 7/8 → 1/1 | s:lt vowel:i ]", + "[ 0/1 → 1/8 | s:bd vowel:e ]", + "[ 1/8 → 1/4 | s:sd vowel:e ]", + "[ 1/4 → 3/8 | s:mt vowel:e ]", + "[ 3/8 → 1/2 | s:ht vowel:e ]", + "[ 1/2 → 5/8 | s:bd vowel:e ]", + "[ 11/16 → 3/4 | s:cp vowel:e ]", + "[ 3/4 → 7/8 | s:ht vowel:e ]", + "[ 7/8 → 1/1 | s:lt vowel:e ]", "[ 1/1 → 9/8 | s:bd vowel:a ]", "[ 9/8 → 5/4 | s:sd vowel:a ]", "[ 5/4 → 11/8 | s:mt vowel:a ]", @@ -12180,14 +12187,14 @@ exports[`runs examples > example "vowel" example index 1 1`] = ` "[ 43/16 → 11/4 | s:cp vowel:i ]", "[ 11/4 → 23/8 | s:ht vowel:i ]", "[ 23/8 → 3/1 | s:lt vowel:i ]", - "[ 3/1 → 25/8 | s:bd vowel:i ]", - "[ 25/8 → 13/4 | s:sd vowel:i ]", - "[ 13/4 → 27/8 | s:mt vowel:i ]", - "[ 27/8 → 7/2 | s:ht vowel:i ]", - "[ 7/2 → 29/8 | s:bd vowel:i ]", - "[ 59/16 → 15/4 | s:cp vowel:i ]", - "[ 15/4 → 31/8 | s:ht vowel:i ]", - "[ 31/8 → 4/1 | s:lt vowel:i ]", + "[ 3/1 → 25/8 | s:bd vowel:o ]", + "[ 25/8 → 13/4 | s:sd vowel:o ]", + "[ 13/4 → 27/8 | s:mt vowel:o ]", + "[ 27/8 → 7/2 | s:ht vowel:o ]", + "[ 7/2 → 29/8 | s:bd vowel:o ]", + "[ 59/16 → 15/4 | s:cp vowel:o ]", + "[ 15/4 → 31/8 | s:ht vowel:o ]", + "[ 31/8 → 4/1 | s:lt vowel:o ]", ] `; @@ -12302,23 +12309,23 @@ exports[`runs examples > example "wchoose" example index 0 1`] = ` "[ 0/1 → 1/5 | note:c2 s:sine ]", "[ 1/5 → 2/5 | note:g2 s:sine ]", "[ 2/5 → 3/5 | note:g2 s:sine ]", - "[ 3/5 → 4/5 | note:d2 s:bd n:6 ]", - "[ 4/5 → 1/1 | note:f1 s:bd n:6 ]", + "[ 3/5 → 4/5 | note:d2 s:sine ]", + "[ 4/5 → 1/1 | note:f1 s:sine ]", "[ 1/1 → 6/5 | note:c2 s:sine ]", "[ 6/5 → 7/5 | note:g2 s:sine ]", "[ 7/5 → 8/5 | note:g2 s:sine ]", "[ 8/5 → 9/5 | note:d2 s:sine ]", "[ 9/5 → 2/1 | note:f1 s:sine ]", "[ 2/1 → 11/5 | note:c2 s:sine ]", - "[ 11/5 → 12/5 | note:g2 s:triangle ]", + "[ 11/5 → 12/5 | note:g2 s:bd n:6 ]", "[ 12/5 → 13/5 | note:g2 s:sine ]", "[ 13/5 → 14/5 | note:d2 s:sine ]", "[ 14/5 → 3/1 | note:f1 s:sine ]", "[ 3/1 → 16/5 | note:c2 s:sine ]", "[ 16/5 → 17/5 | note:g2 s:sine ]", - "[ 17/5 → 18/5 | note:g2 s:triangle ]", + "[ 17/5 → 18/5 | note:g2 s:sine ]", "[ 18/5 → 19/5 | note:d2 s:sine ]", - "[ 19/5 → 4/1 | note:f1 s:sine ]", + "[ 19/5 → 4/1 | note:f1 s:bd n:6 ]", ] `; @@ -12329,30 +12336,30 @@ exports[`runs examples > example "wchooseCycles" example index 0 1`] = ` "[ 1/4 → 3/8 | s:bd ]", "[ 3/8 → 1/2 | s:bd ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:bd ]", - "[ 3/4 → 7/8 | s:sd ]", + "[ 5/8 → 3/4 | s:hh ]", + "[ 3/4 → 7/8 | s:bd ]", "[ 7/8 → 1/1 | s:bd ]", "[ 1/1 → 9/8 | s:bd ]", - "[ 9/8 → 5/4 | s:sd ]", + "[ 9/8 → 5/4 | s:bd ]", "[ 5/4 → 11/8 | s:bd ]", - "[ 11/8 → 3/2 | s:bd ]", + "[ 11/8 → 3/2 | s:sd ]", "[ 3/2 → 13/8 | s:bd ]", "[ 13/8 → 7/4 | s:bd ]", - "[ 7/4 → 15/8 | s:sd ]", + "[ 7/4 → 15/8 | s:bd ]", "[ 15/8 → 2/1 | s:bd ]", "[ 2/1 → 17/8 | s:bd ]", - "[ 17/8 → 9/4 | s:sd ]", - "[ 9/4 → 19/8 | s:bd ]", - "[ 19/8 → 5/2 | s:bd ]", + "[ 17/8 → 9/4 | s:hh ]", + "[ 9/4 → 19/8 | s:hh ]", + "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:bd ]", "[ 21/8 → 11/4 | s:bd ]", - "[ 11/4 → 23/8 | s:bd ]", - "[ 23/8 → 3/1 | s:bd ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 25/8 → 13/4 | s:bd ]", + "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:sd ]", + "[ 3/1 → 25/8 | s:bd ]", + "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:bd ]", "[ 27/8 → 7/2 | s:bd ]", - "[ 7/2 → 29/8 | s:bd ]", + "[ 7/2 → 29/8 | s:sd ]", "[ 29/8 → 15/4 | s:bd ]", "[ 15/4 → 31/8 | s:bd ]", "[ 31/8 → 4/1 | s:bd ]", @@ -12367,48 +12374,48 @@ exports[`runs examples > example "wchooseCycles" example index 1 1`] = ` "[ 1/4 → 1/3 | s:bd ]", "[ 1/3 → 5/12 | s:bd ]", "[ 5/12 → 1/2 | s:bd ]", - "[ 1/2 → 7/12 | s:bd ]", - "[ 7/12 → 2/3 | s:bd ]", - "[ 2/3 → 3/4 | s:bd ]", - "[ 3/4 → 5/6 | s:bd ]", - "[ 5/6 → 11/12 | s:bd ]", - "[ 11/12 → 1/1 | s:bd ]", + "[ 1/2 → 7/12 | s:hh ]", + "[ 7/12 → 2/3 | s:hh ]", + "[ 2/3 → 3/4 | s:hh ]", + "[ 3/4 → 5/6 | s:hh ]", + "[ 5/6 → 11/12 | s:hh ]", + "[ 11/12 → 1/1 | s:hh ]", "[ 1/1 → 13/12 | s:bd ]", "[ 13/12 → 7/6 | s:bd ]", "[ 7/6 → 5/4 | s:bd ]", - "[ 5/4 → 4/3 | s:bd ]", - "[ 4/3 → 17/12 | s:bd ]", - "[ 17/12 → 3/2 | s:bd ]", - "[ 3/2 → 19/12 | s:sd ]", - "[ 19/12 → 5/3 | s:sd ]", - "[ 5/3 → 7/4 | s:sd ]", - "[ 7/4 → 11/6 | s:bd ]", - "[ 11/6 → 23/12 | s:bd ]", - "[ 23/12 → 2/1 | s:bd ]", + "[ 5/4 → 4/3 | s:hh ]", + "[ 4/3 → 17/12 | s:hh ]", + "[ 17/12 → 3/2 | s:hh ]", + "[ 3/2 → 19/12 | s:bd ]", + "[ 19/12 → 5/3 | s:bd ]", + "[ 5/3 → 7/4 | s:bd ]", + "[ 7/4 → 11/6 | s:hh ]", + "[ 11/6 → 23/12 | s:hh ]", + "[ 23/12 → 2/1 | s:hh ]", "[ 2/1 → 25/12 | s:hh ]", "[ 25/12 → 13/6 | s:hh ]", "[ 13/6 → 9/4 | s:hh ]", - "[ 9/4 → 7/3 | s:sd ]", - "[ 7/3 → 29/12 | s:sd ]", - "[ 29/12 → 5/2 | s:sd ]", + "[ 9/4 → 7/3 | s:hh ]", + "[ 7/3 → 29/12 | s:hh ]", + "[ 29/12 → 5/2 | s:hh ]", "[ 5/2 → 31/12 | s:hh ]", "[ 31/12 → 8/3 | s:hh ]", "[ 8/3 → 11/4 | s:hh ]", - "[ 11/4 → 17/6 | s:bd ]", - "[ 17/6 → 35/12 | s:bd ]", - "[ 35/12 → 3/1 | s:bd ]", - "[ 3/1 → 37/12 | s:bd ]", - "[ 37/12 → 19/6 | s:bd ]", - "[ 19/6 → 13/4 | s:bd ]", + "[ 11/4 → 17/6 | s:sd ]", + "[ 17/6 → 35/12 | s:sd ]", + "[ 35/12 → 3/1 | s:sd ]", + "[ 3/1 → 37/12 | s:hh ]", + "[ 37/12 → 19/6 | s:hh ]", + "[ 19/6 → 13/4 | s:hh ]", "[ 13/4 → 10/3 | s:bd ]", "[ 10/3 → 41/12 | s:bd ]", "[ 41/12 → 7/2 | s:bd ]", - "[ 7/2 → 43/12 | s:sd ]", - "[ 43/12 → 11/3 | s:sd ]", - "[ 11/3 → 15/4 | s:sd ]", - "[ 15/4 → 23/6 | s:hh ]", - "[ 23/6 → 47/12 | s:hh ]", - "[ 47/12 → 4/1 | s:hh ]", + "[ 7/2 → 43/12 | s:bd ]", + "[ 43/12 → 11/3 | s:bd ]", + "[ 11/3 → 15/4 | s:bd ]", + "[ 15/4 → 23/6 | s:bd ]", + "[ 23/6 → 47/12 | s:bd ]", + "[ 47/12 → 4/1 | s:bd ]", ] `; @@ -12432,15 +12439,15 @@ exports[`runs examples > example "wchooseCycles" example index 2 1`] = ` "[ 5/4 → 4/3 | s:hh ]", "[ 4/3 → 17/12 | s:hh ]", "[ 17/12 → 3/2 | s:hh ]", - "[ 3/2 → 19/12 | s:hh ]", - "[ 19/12 → 5/3 | s:hh ]", - "[ 5/3 → 7/4 | s:hh ]", + "[ 3/2 → 49/32 | s:bd ]", + "[ 51/32 → 13/8 | s:bd ]", + "[ 27/16 → 55/32 | s:bd ]", "[ 7/4 → 11/6 | s:hh ]", "[ 11/6 → 23/12 | s:hh ]", "[ 23/12 → 2/1 | s:hh ]", - "[ 2/1 → 25/12 | s:hh ]", - "[ 25/12 → 13/6 | s:hh ]", - "[ 13/6 → 9/4 | s:hh ]", + "[ 2/1 → 65/32 | s:bd ]", + "[ 67/32 → 17/8 | s:bd ]", + "[ 35/16 → 71/32 | s:bd ]", "[ 9/4 → 7/3 | s:hh ]", "[ 7/3 → 29/12 | s:hh ]", "[ 29/12 → 5/2 | s:hh ]", @@ -12450,15 +12457,15 @@ exports[`runs examples > example "wchooseCycles" example index 2 1`] = ` "[ 11/4 → 17/6 | s:hh ]", "[ 17/6 → 35/12 | s:hh ]", "[ 35/12 → 3/1 | s:hh ]", - "[ 3/1 → 97/32 | s:bd ]", - "[ 99/32 → 25/8 | s:bd ]", - "[ 51/16 → 103/32 | s:bd ]", + "[ 3/1 → 37/12 | s:hh ]", + "[ 37/12 → 19/6 | s:hh ]", + "[ 19/6 → 13/4 | s:hh ]", "[ 13/4 → 10/3 | s:hh ]", "[ 10/3 → 41/12 | s:hh ]", "[ 41/12 → 7/2 | s:hh ]", - "[ 7/2 → 43/12 | s:hh ]", - "[ 43/12 → 11/3 | s:hh ]", - "[ 11/3 → 15/4 | s:hh ]", + "[ 7/2 → 113/32 | s:bd ]", + "[ 115/32 → 29/8 | s:bd ]", + "[ 59/16 → 119/32 | s:bd ]", "[ 15/4 → 23/6 | s:hh ]", "[ 23/6 → 47/12 | s:hh ]", "[ 47/12 → 4/1 | s:hh ]", From e90aa5202d5f4f0ee5ad8c161cd02907512f2bfa Mon Sep 17 00:00:00 2001 From: Aria Date: Sun, 16 Nov 2025 15:28:10 -0600 Subject: [PATCH 43/66] Export withseed --- packages/core/signal.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 9f3a264f4..e50ba22db 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -365,13 +365,13 @@ export const scramble = register('scramble', (n, pat) => { * @param {Pattern} pat Pattern to update * @returns Pattern */ -function withSeed(func, pat) { +export const withSeed = (func, pat) => { return new Pattern((state) => { let { randSeed, ...controls } = state.controls; randSeed = func(randSeed); return pat.query(state.setControls({ ...controls, randSeed })); }, pat._steps); -} +}; /** * Change the seed for random signals. Normally, random signals depend on time, From fc74dcdb1a56e7f2122e87210be53e6a60d1ea74 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 24 Oct 2025 19:21:34 +0300 Subject: [PATCH 44/66] More bug fixes --- packages/webaudio/webaudio.mjs | 43 +++++++++++------------------ website/src/repl/useReplContext.jsx | 10 ++++++- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index c9b5cbda3..7c8ff648e 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -14,12 +14,8 @@ import { setAudioContext, initAudio, setSuperdoughAudioController, - setMaxPolyphony, - setMultiChannelOrbits, resetGlobalEffects, - errorLogger, - maxPolyphony as superdoughMaxPolyphony, - multiChannelOrbits as superdoughMultiChannelOrbits + errorLogger } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -51,10 +47,6 @@ export async function renderPatternAudio( multiChannelOrbits, downloadName = undefined, ) { - let realtimeOptions = { - maxPolyphony: superdoughMaxPolyphony, - multiChannelOrbits: superdoughMultiChannelOrbits - } let audioContext = getAudioContext(); await audioContext.close(); audioContext = new OfflineAudioContext(2, ((end - begin) / cps) * sampleRate, sampleRate); @@ -63,28 +55,26 @@ export async function renderPatternAudio( await initAudio({ maxPolyphony, multiChannelOrbits - }); + }) logger('[webaudio] preloading'); let haps = pattern.queryArc(begin, end, { _cps: cps }); - await Promise.all( - haps.map(async (hap) => { - if (hap.hasOnset()) { - try { - await superdough( - hap2value(hap), - hap.whole.begin.valueOf() / cps, - hap.duration / cps, - cps, - hap.whole?.begin.valueOf(), - ); - } catch (err) { - errorLogger(err, 'webaudio'); - } + for (const hap of haps) { + if (hap.hasOnset()) { + try { + await superdough( + hap2value(hap), + (hap.whole.begin.valueOf() - begin) / cps, + hap.duration / cps, + cps, + (hap.whole?.begin.valueOf() - begin) / cps, + ); + } catch (err) { + errorLogger(err, 'webaudio'); } - }), - ); + } + } logger('[webaudio] start rendering'); return audioContext @@ -106,7 +96,6 @@ export async function renderPatternAudio( setAudioContext(null); setSuperdoughAudioController(null); resetGlobalEffects(); - await initAudio(realtimeOptions); }); } diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 15b3fab10..361abc1d3 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -15,6 +15,7 @@ import { resetLoadedSounds, initAudioOnFirstClick, resetDefaults, + initAudio, } from '@strudel/webaudio'; import { setVersionDefaultsFrom } from './util.mjs'; import { StrudelMirror, defaultSettings } from '@strudel/codemirror'; @@ -217,7 +218,14 @@ export function useReplContext() { maxPolyphony, multiChannelOrbits, downloadName, - ).finally(() => { + ).finally(async () => { + const { latestCode, maxPolyphony, audioDeviceName, multiChannelOrbits } = settingsMap.get() + await initAudio({ + latestCode, + maxPolyphony, + audioDeviceName, + multiChannelOrbits + }) editorRef.current.repl.scheduler.stop(); }); }; From 91ebdd5ea62ddeb8d9a346f73d5c3dd2a06aa98b Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 24 Oct 2025 20:55:39 +0300 Subject: [PATCH 45/66] Better progress bar UI --- website/src/repl/components/ExportModal.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index 4bc8990ea..ad1fc5827 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -199,7 +199,7 @@ export default function ExportModal(Props) { disabled={exporting} onClick={async () => { setExporting(true); - setTimeout(refreshProgress, 1000); + setTimeout(refreshProgress, 2000); await handleExport(startCycle, endCycle, sampleRate, maxPolyphony, multiChannelOrbits, downloadName) .then(() => { const modal = document.getElementById('exportModal'); @@ -212,13 +212,13 @@ export default function ExportModal(Props) { }); }} > - {exporting ? 'Exporting...' : 'Export to WAV'}
+ {exporting ? 'Exporting...' : 'Export to WAV'}
From 8f9967c76dae6d053f8157f2e091d697c385a19c Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 24 Oct 2025 20:55:56 +0300 Subject: [PATCH 46/66] Format --- packages/webaudio/webaudio.mjs | 6 +++--- website/src/repl/components/ExportModal.jsx | 6 ++---- website/src/repl/useReplContext.jsx | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 7c8ff648e..9da5a411d 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -15,7 +15,7 @@ import { initAudio, setSuperdoughAudioController, resetGlobalEffects, - errorLogger + errorLogger, } from 'superdough'; import './supradough.mjs'; import { workletUrl } from 'supradough'; @@ -54,8 +54,8 @@ export async function renderPatternAudio( setSuperdoughAudioController(new SuperdoughAudioController(audioContext)); await initAudio({ maxPolyphony, - multiChannelOrbits - }) + multiChannelOrbits, + }); logger('[webaudio] preloading'); let haps = pattern.queryArc(begin, end, { _cps: cps }); diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx index ad1fc5827..bac8c6b14 100644 --- a/website/src/repl/components/ExportModal.jsx +++ b/website/src/repl/components/ExportModal.jsx @@ -3,9 +3,7 @@ import cx from '@src/cx.mjs'; import NumberInput from './NumberInput'; import { useEffect, useState } from 'react'; import { Textbox } from './textbox/Textbox'; -import { - getAudioContext, -} from '@strudel/webaudio'; +import { getAudioContext } from '@strudel/webaudio'; import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; function Checkbox({ label, value, onChange, disabled = false }) { @@ -215,7 +213,7 @@ export default function ExportModal(Props) {
{exporting ? 'Exporting...' : 'Export to WAV'} diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 361abc1d3..59d86a4d6 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -219,13 +219,13 @@ export function useReplContext() { multiChannelOrbits, downloadName, ).finally(async () => { - const { latestCode, maxPolyphony, audioDeviceName, multiChannelOrbits } = settingsMap.get() + const { latestCode, maxPolyphony, audioDeviceName, multiChannelOrbits } = settingsMap.get(); await initAudio({ latestCode, maxPolyphony, audioDeviceName, - multiChannelOrbits - }) + multiChannelOrbits, + }); editorRef.current.repl.scheduler.stop(); }); }; From 7d890156f4c2a4a584c975e57fc8fa3e44d897df Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 25 Oct 2025 18:53:24 +0300 Subject: [PATCH 47/66] Fix haps not being sorted by time --- packages/webaudio/webaudio.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 9da5a411d..8f18d80dc 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -58,7 +58,9 @@ export async function renderPatternAudio( }); logger('[webaudio] preloading'); - let haps = pattern.queryArc(begin, end, { _cps: cps }); + let haps = pattern + .queryArc(begin, end, { _cps: cps }) + .sort((a, b) => a.whole.begin.valueOf() - b.whole.begin.valueOf()); for (const hap of haps) { if (hap.hasOnset()) { From c5250d7794a2600d0aeca36885adf0e93e1d7be7 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 25 Oct 2025 18:59:12 +0300 Subject: [PATCH 48/66] Add info comment about ascending time order --- packages/webaudio/webaudio.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 8f18d80dc..36ee9d645 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -58,10 +58,11 @@ export async function renderPatternAudio( }); logger('[webaudio] preloading'); + // Calling superdough(...) in ascending onset time order is important + // for controls that depend on the audio graph state like `cut` let haps = pattern .queryArc(begin, end, { _cps: cps }) .sort((a, b) => a.whole.begin.valueOf() - b.whole.begin.valueOf()); - for (const hap of haps) { if (hap.hasOnset()) { try { From 5bddb6f48d969427d977ad807f3e7c3f0f482703 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 30 Nov 2025 10:09:06 +0300 Subject: [PATCH 49/66] Move export UI to the panel --- website/src/repl/components/ExportModal.jsx | 225 ------------------ website/src/repl/components/Header.jsx | 15 +- .../src/repl/components/panel/ExportTab.jsx | 197 +++++++++++++++ website/src/repl/components/panel/Panel.jsx | 4 + 4 files changed, 203 insertions(+), 238 deletions(-) delete mode 100644 website/src/repl/components/ExportModal.jsx create mode 100644 website/src/repl/components/panel/ExportTab.jsx diff --git a/website/src/repl/components/ExportModal.jsx b/website/src/repl/components/ExportModal.jsx deleted file mode 100644 index bac8c6b14..000000000 --- a/website/src/repl/components/ExportModal.jsx +++ /dev/null @@ -1,225 +0,0 @@ -import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; -import cx from '@src/cx.mjs'; -import NumberInput from './NumberInput'; -import { useEffect, useState } from 'react'; -import { Textbox } from './textbox/Textbox'; -import { getAudioContext } from '@strudel/webaudio'; -import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; - -function Checkbox({ label, value, onChange, disabled = false }) { - return ( - - ); -} - -function FormItem({ label, children, disabled }) { - return ( -
- - {children} -
- ); -} - -export default function ExportModal(Props) { - const { started, isEmbedded, handleExport } = Props; - - const [downloadName, setDownloadName] = useState(''); // TODO: make a form? - const [startCycle, setStartCycle] = useState(0); - const [endCycle, setEndCycle] = useState(1); - const [sampleRate, setSampleRate] = useState(48000); - const [multiChannelOrbits, setMultiChannelOrbits] = useState(true); - const [maxPolyphony, setMaxPolyphony] = useState(1024); - const [exporting, setExporting] = useState(false); - const [progress, setProgress] = useState(0); - const [length, setLength] = useState(1); - - const refreshProgress = () => { - const audioContext = getAudioContext(); - if (audioContext instanceof OfflineAudioContext) { - setProgress(audioContext.currentTime); - setLength(audioContext.length / sampleRate); - setTimeout(refreshProgress, 100); - } - }; - - return ( - <> - - - -
- - { - setDownloadName(e.target.value); - }} - onChange={(v) => { - setDownloadName(v); - }} - disabled={exporting} - placeholder="Leave empty to use current date" - className={cx('placeholder:opacity-50', exporting && 'opacity-50 border-opacity-50')} - value={downloadName ?? ''} - /> - -
- - { - let v = parseInt(e.target.value); - v = isNaN(v) ? 0 : Math.max(0, v); - setStartCycle(v); - }} - onChange={(v) => { - v = parseInt(v); - setStartCycle(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && 'opacity-50 border-opacity-50')} - value={startCycle ?? ''} - /> - - - { - let v = parseInt(e.target.value); - v = isNaN(v) ? Math.max(startCycle + 1, parseInt(v)) : v; - setEndCycle(v); - }} - onChange={(v) => { - v = parseInt(v); - setEndCycle(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && 'opacity-50 border-opacity-50')} - value={endCycle ?? ''} - /> - -
-
- - { - let v = parseInt(e.target.value); - v = isNaN(v) ? 1 : Math.max(1, v); - setSampleRate(v); - }} - onChange={(v) => { - v = parseInt(v); - setSampleRate(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && 'opacity-50 border-opacity-50')} - value={sampleRate ?? ''} - /> - - - { - let v = parseInt(e.target.value); - v = isNaN(v) ? Math.max(1, parseInt(v)) : v; - setMaxPolyphony(v); - }} - onChange={(v) => { - v = Math.max(1, parseInt(v)); - setMaxPolyphony(v); - }} - type="number" - placeholder="" - disabled={exporting} - className={cx(exporting && 'opacity-50 border-opacity-50')} - value={maxPolyphony ?? ''} - /> - -
-
- { - const val = cbEvent.target.checked; - setMultiChannelOrbits(val); - }} - disabled={exporting} - value={multiChannelOrbits} - /> -
- -
-
- - ); -} diff --git a/website/src/repl/components/Header.jsx b/website/src/repl/components/Header.jsx index dd9f684c1..ca4e1ecf9 100644 --- a/website/src/repl/components/Header.jsx +++ b/website/src/repl/components/Header.jsx @@ -3,23 +3,13 @@ import StopCircleIcon from '@heroicons/react/20/solid/StopCircleIcon'; import cx from '@src/cx.mjs'; import { useSettings, setIsZen } from '../../settings.mjs'; import '../Repl.css'; -import ExportModal from './ExportModal'; const { BASE_URL } = import.meta.env; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; export function Header({ context, embedded = false }) { - const { - started, - pending, - isDirty, - activeCode, - handleTogglePlay, - handleEvaluate, - handleShuffle, - handleShare, - handleExport, - } = context; + const { started, pending, isDirty, activeCode, handleTogglePlay, handleEvaluate, handleShuffle, handleShare } = + context; const isEmbedded = typeof window !== 'undefined' && (embedded || window.location !== window.parent.location); const { isZen, isButtonRowHidden, isCSSAnimationDisabled, fontFamily } = useSettings(); @@ -103,7 +93,6 @@ export function Header({ context, embedded = false }) { > {!isEmbedded && update} - {/* !isEmbedded && ( +
+ + + ); +} diff --git a/website/src/repl/components/panel/Panel.jsx b/website/src/repl/components/panel/Panel.jsx index b26c2edef..cfe90ae30 100644 --- a/website/src/repl/components/panel/Panel.jsx +++ b/website/src/repl/components/panel/Panel.jsx @@ -9,6 +9,7 @@ import { useLogger } from '../useLogger'; import { WelcomeTab } from './WelcomeTab'; import { PatternsTab } from './PatternsTab'; import { ChevronLeftIcon, XMarkIcon } from '@heroicons/react/16/solid'; +import ExportTab from './ExportTab'; const TAURI = typeof window !== 'undefined' && window.__TAURI__; @@ -80,6 +81,7 @@ const tabNames = { patterns: 'patterns', sounds: 'sounds', reference: 'reference', + export: 'export', console: 'console', settings: 'settings', }; @@ -126,6 +128,8 @@ function PanelContent({ context, tab }) { return ; case tabNames.reference: return ; + case tabNames.export: + return ; case tabNames.settings: return ; case tabNames.files: From 24b69ad1bcc6861268f34f4cf01685e8f11bfeca Mon Sep 17 00:00:00 2001 From: jeromew Date: Sun, 30 Nov 2025 14:09:03 +0000 Subject: [PATCH 50/66] [perf] Add audiograph `await debugAudiograph();` tool --- website/src/repl/audiograph.mjs | 618 ++++++++++++++++++++++++++++ website/src/repl/useReplContext.jsx | 2 + 2 files changed, 620 insertions(+) create mode 100644 website/src/repl/audiograph.mjs diff --git a/website/src/repl/audiograph.mjs b/website/src/repl/audiograph.mjs new file mode 100644 index 000000000..d203496ae --- /dev/null +++ b/website/src/repl/audiograph.mjs @@ -0,0 +1,618 @@ +/* +audiograph.mjs - show a svg view of the web audio API graph built during a playback +Copyright (C) 2025 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 . +*/ + +// main entry point is `debugAudiograph` + +import { logger } from '@strudel/core'; +import { getAudioContext, getSuperdoughAudioController, webaudioOutput } from '@strudel/webaudio'; + +let mermaid = null; +let svgPanZoom = null; + +let running = false; +let hap_count = 0; + +let cache = new Map(); +const initCache = JSON.stringify({ + connect: [], + where: [], + disconnectAll: 0, + disconnectOne: 0, + stopCount: 0, + ac: null, + creation: null, +}); + +let toggleOrig; + +function stackTrace() { + var err = new Error(); + const stacktrace = err.stack; + const lines = stacktrace.split('\n'); + let lineIndex = lines.findIndex((line) => line !== 'Error' && !line.includes('audiograph.mjs')); + if (lines[lineIndex].includes('gainNode')) lineIndex++; + if (lines[lineIndex].includes('getWorklet')) lineIndex++; + const line = lines[lineIndex].replace(/\s*at\s/, '').replace('http', '@'); + let match; + match = line.match(/([^@]*)@.*packages(\/[^:]+:\d+:\d+)/); + if (match) { + return match[1].replace(/[^.:/a-zA-Z0-9]/g, '') + '@' + match[2].replace(/[^.:/a-zA-Z0-9]/g, ''); + } + return '@'; +} + +// This captures all AudioNodes lazily +// when an `.audioid` property is called +// no solution was found to hook +// AudioNode's constructor directly +let audioid = 0; +const lazyRegister = (o) => { + Object.defineProperty(o.prototype, 'audioid', { + get: function () { + if (!this._audioid) { + this._audioid = ++audioid; + const s = JSON.parse(initCache); + s.type = this.constructor.name === 'AudiographNode' ? this.constructor._parentClassName : this.constructor.name; + s.ac = this.context?.constructor.name || 'AudioParam'; + s.creation = s.creation || stackTrace(); + cache.set(this._audioid, s); + } + return this._audioid; + }, + enumerable: false, + configurable: true, + }); +}; + +// extend a specific AudioNode's constructor +// necessary when creation is done direclty by +// calling the constructor +// eg: new GainNode(...) +const audioNodeHook = (node) => { + const name = node.prototype.constructor.name; + const PatchedNode = class AudiographNode extends node { + constructor(...args) { + super(...args); + // trigger the lazy register + this._audioid = this.audioid; + } + }; + PatchedNode._parentClassName = name; + window[name] = PatchedNode; +}; + +const drawMessage = async function (message) { + const element = document.querySelector('.strudel-mermaid'); + let gd = ''; + gd += '---\n'; + gd += 'config:\n'; + gd += ' flowchart:\n'; + gd += ' wrappingWidth: 600\n'; + gd += '---\n'; + gd += 'flowchart LR\n'; + gd += 'id[' + message.replaceAll(' ', ' ') + ']\n'; + + let { svg } = await mermaid.render('strudelSvgId', gd); + svg = svg.replace(/max-width:\s[0-9.]*px;/i, 'height: 100%'); + svg = svg.replaceAll('&nbsp;', ' '); + element.innerHTML = svg; +}; + +const drawDiagram = async function () { + const element = document.querySelector('.strudel-mermaid'); + + let code = window.strudelMirror.code; + code = code.replace(/^await debugAudiograph.*\n?/gm, ''); + code = '// date: ' + new Date().toISOString() + '\n\n' + code; + code = '// host: ' + document.location.hostname + '\n' + code; + const codeLines = code.split(/(?:\n|\r\n?)/); + const maxLineLength = codeLines.reduce((memo, line) => Math.max(memo, line.length), 0); + + // https://mermaid.js.org/syntax/flowchart.html + let gd = ''; + gd += '---\n'; + gd += 'config:\n'; + gd += ' flowchart:\n'; + gd += ' wrappingWidth: ' + 14 * maxLineLength + '\n'; + gd += '---\n'; + gd += 'flowchart TB\n'; + gd += '\tsubgraph AG[STRUDEL AUDIOGRAPH]\n'; + + // seed graph builder with all + // unconnected nodes + let lookup = []; + cache.forEach((v, k) => { + if (v.connect.length === 0) lookup.push(k); + }); + const relations = []; + let curRelations; + const zombieCount = 0; + const sourceLoc = (stack) => { + if (stack === '@') return stack; + return stack.replace('@', '\n').replace('/superdough/', '/'); + }; + const label = (s) => { + const source = s.creation ? '\n' + sourceLoc(s.creation) : ''; + let lb = '[' + '**' + s.type + '**' + source + ']'; + if (s.ac === 'OfflineAudioContext') lb = '[' + lb + ']'; + return lb; + }; + const isLeak = (s) => { + return ( + ['AudioDestinationNode', 'AudioParam'].indexOf(s.type) === -1 && + s.disconnectAll === 0 && + s.connect.length > s.disconnectOne + ); + }; + do { + curRelations = relations.length; + lookup.slice().forEach((n) => { + cache.forEach((v, k) => { + if (v.connect.indexOf(n) !== -1) { + if (lookup.indexOf(k) === -1) lookup.push(k); + gd += v.connect + .map((i) => { + if (lookup.indexOf(i) === -1) lookup.push(i); + if (relations.indexOf(k + '-' + i) === -1) { + relations.push(k + '-' + i); + return ( + '\t\tnode' + + k + + label(v) + + ' -- ' + + sourceLoc(v.where[0]) + + ' --> node' + + i + + label(cache.get(i)) + + '\n' + ); + } + }) + .join(''); + } + if (k === n) { + gd += v.connect + .map((i) => { + if (lookup.indexOf(i) === -1) lookup.push(i); + if (relations.indexOf(k + '-' + i) === -1) { + relations.push(k + '-' + i); + return ( + '\t\tnode' + + k + + label(v) + + ' -- ' + + sourceLoc(v.where[0]) + + ' --> node' + + i + + label(cache.get(i)) + + '\n' + ); + } + }) + .join(''); + } + }); + }); + } while (relations.length > curRelations /*&& lookup.length < 100*/); + + const codePlaceholder = 'm'.repeat(maxLineLength); + gd += '\tsubgraph LEGEND\n'; + gd += '\t\tlegend1[in AudioContext]\n'; + gd += '\t\tlegend2[[in OfflineAudioContext]]\n'; + gd += '\t\tlegend3[not disconnected]\n'; + gd += '\t\tlegend4[AudioParam]\n'; + gd += '\t\tlegend5[AudioDestinationNode]\n'; + gd += '\tend\n'; + gd += '\tsubgraph CODE[Strudel Code]\n'; + // we use a codePlaceholder to + // - avoid problems with special chars + // - stop mermaid to split lines on space with multiple tspans + // - force mermaid to prepare a sufficiently sized zone + gd += '\ncode[' + (codePlaceholder + '
').repeat(codeLines.length) + ']\n'; + gd += '\tend\n'; + gd += '\tend\n'; + gd += '\tclassDef audioparam fill:#6f6;\n'; + gd += '\tclassDef destination fill:#99f;\n'; + gd += '\tclassDef suspect fill:#f96,stroke:#f00,stroke-width:2px;\n'; + gd += '\tclass legend3 suspect;\n'; + gd += '\tclass legend4 audioparam;\n'; + gd += '\tclass legend5 destination;\n'; + cache.forEach((v, k) => { + if (isLeak(v)) { + gd += '\tclass node' + k + ' suspect;\n'; + } + if (v.type === 'AudioParam') { + gd += '\tclass node' + k + ' audioparam;\n'; + } + if (v.type === 'AudioDestinationNode') { + gd += '\tclass node' + k + ' destination;\n'; + } + }); + let { svg } = await mermaid.render('strudelSvgId', gd); + + // put real code in code zone + let idx = 0; + const escapeHtml = (unsafe) => { + return unsafe + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + }; + svg = svg.replaceAll(codePlaceholder, () => escapeHtml(codeLines[idx++])); + + // improve sizing on web page + svg = svg.replace(/max-width:\s[0-9.]*px;/i, 'height: 100%'); + element.innerHTML = svg; + + // align the code lines + let svgText = document.querySelector('[id^=flowchart-code] text'); + svgText.setAttributeNS(null, 'style', 'text-anchor: start;'); + const svgElement = document.querySelector('svg'); + const svgLabel = document.querySelector('svg [id^=flowchart-code] .label'); + const transformList = svgLabel.transform.baseVal; + const svgTransform = svgElement.createSVGTransform(); + const tspans = Array.from(document.querySelectorAll('[id^=flowchart-code] tspan.text-inner-tspan')); + let tspansMaxLength = tspans.reduce((memo, tspan) => Math.max(memo, tspan.getComputedTextLength()), 0); + svgTransform.setTranslate(-tspansMaxLength / 2, 0); + transformList.appendItem(svgTransform); + + let doPan = false; + let eventsHandler; + let panZoom; + let mousepos; + + eventsHandler = { + haltEventListeners: ['mousedown', 'mousemove', 'mouseup'], + mouseDownHandler: function (ev) { + if (event.target.className == '[object SVGAnimatedString]') { + doPan = true; + mousepos = { + x: ev.clientX, + y: ev.clientY, + }; + } + }, + mouseMoveHandler: function (ev) { + if (doPan) { + panZoom.panBy({ + x: ev.clientX - mousepos.x, + y: ev.clientY - mousepos.y, + }); + mousepos = { + x: ev.clientX, + y: ev.clientY, + }; + window.getSelection().removeAllRanges(); + } + }, + mouseUpHandler: function (ev) { + doPan = false; + }, + init: function (options) { + options.svgElement.addEventListener('mousedown', this.mouseDownHandler, false); + options.svgElement.addEventListener('mousemove', this.mouseMoveHandler, false); + options.svgElement.addEventListener('mouseup', this.mouseUpHandler, false); + }, + destroy: function (options) { + options.svgElement.removeEventListener('mousedown', this.mouseDownHandler, false); + options.svgElement.removeEventListener('mousemove', this.mouseMoveHandler, false); + options.svgElement.removeEventListener('mouseup', this.mouseUpHandler, false); + }, + }; + panZoom = svgPanZoom('#strudelSvgId', { + zoomEnabled: true, + controlIconsEnabled: true, + fit: 1, + center: 1, + zoomScaleSensitivity: 0.4, + customEventsHandler: eventsHandler, + }); +}; + +const svgExport = async () => { + const a = document.createElement('a'); + document.body.appendChild(a); + a.style = 'display: none'; + + const selector = '.strudel-mermaid'; + const bbox = document.querySelector('svg g').getBBox(); + let transform, style; + // clean pan-zoom viewport + const pzViewport = document.querySelector('.svg-pan-zoom_viewport'); + if (pzViewport) { + transform = pzViewport.transform; + style = pzViewport.style; + pzViewport.setAttribute('transform', ''); + pzViewport.style = ''; + } + + const spzMin = await fetch('https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.2/dist/svg-pan-zoom.min.js').then((res) => + res.text(), + ); + + const scriptContent = ''; + // prepare svg + const content = document + .querySelector(selector) + .innerHTML.replaceAll('
', '
') + // remove useless tags + .replace(/ { + if (k <= audioid) cache.delete(k); + }); +}; + +const postProcessing = async function () { + hap_count = 0; + await drawDiagram(); + + resetAudioOutput(audioid); +}; + +const defaultOptions = { + StopAfterHapCount: 10, + hapsBatch: 0, + maxEdges: 10000, + maxTextSize: 200000, + audioAPIBreathingRoomSec: 5, +}; + +// `StopAfterHapCount` : +// The player will auto-stop after hap count have +// been played. when StopAfterHapCount = 0, it will +// continue playing until 'stop' is clicked +// `audioAPIBreathingRoomSec` : +// how much time should we wait after 'stop' to let +// the audioAPI finish its tail of ondended calls +// `hapsBatch` : +// the AudioGraph will be displayed every hapsBatch haps +// when hapsBatch = 0, AudioGraph will only be displayed +// after and auto-stop or after 'stop' is clicked +// In hapsBatch mode you will probably see a trailing of +// non disconnected notes on the graph because the audio +// API may have some lag disconnecting them +// cf also audioAPIBreathingRoomSec +// `maxEdges` +// This is a mermaid.js config that forces a hard limit +// on the maximum number of Edges of a graph +// needs a reload to be taken into account +// `maxTextSize` +// This is a mermaid.js config that forces a hard limit +// on the maximum text size of a graph definition +// needs a reload to be taken into account + +export const debugAudiograph = async (argOptions = {}) => { + const options = Object.assign({}, defaultOptions, argOptions); + const { StopAfterHapCount, hapsBatch, maxEdges, maxTextSize, audioAPIBreathingRoomSec } = options; + const sm = window.strudelMirror; + const code = sm.code; + if (!code.match(/await\s+debugAudiograph/)) { + throw new Error('you need to call `await debugAudiograph()` for audiograph to work'); + } + const emptyOptions = /await\s+debugAudiograph\(\)/.exec(code); + if (emptyOptions) { + const cutCode = emptyOptions.index + emptyOptions[0].length - 1; + const codeOptions = JSON.stringify({ StopAfterHapCount: StopAfterHapCount }).replaceAll('"', ''); + sm.setCode(code.slice(0, cutCode) + codeOptions + code.slice(cutCode)); + } + + if (window.audiograph === undefined) { + const ag = (window.audiograph = {}); + + toggleOrig = sm.toggle; + + //////////////////////////////////////// + // step 1: web audio api instrumentation + //////////////////////////////////////// + + // path AudioNode & AudioParam + // to give them lazy ids + // this captures both `ac.createGain` + // and `new GainNode(..)` patterns + lazyRegister(AudioNode); + lazyRegister(AudioParam); + + const audioNodes = [ + AudioBufferSourceNode, + AudioWorkletNode, + AnalyserNode, + BiquadFilterNode, + ChannelMergerNode, + ChannelSplitterNode, + ConstantSourceNode, + ConvolverNode, + DelayNode, + DynamicsCompressorNode, + GainNode, + IIRFilterNode, + OscillatorNode, + PannerNode, + StereoPannerNode, + WaveShaperNode, + ]; + audioNodes.map((n) => audioNodeHook(n)); + + // patch BaseAudioContext factory methods + // to capture the source reference + Object.getOwnPropertyNames(BaseAudioContext.prototype) + .filter((n) => n.startsWith('create') && ['createBuffer'].indexOf(n) === -1) + .map((name) => { + const orig = BaseAudioContext.prototype[name]; + BaseAudioContext.prototype[name] = function (...args) { + const result = orig.call(this, ...args); + const s = cache.get(result.audioid); + s.creation = stackTrace(); + return result; + }; + }); + + const connectOrig = AudioNode.prototype.connect; + AudioNode.prototype.connect = function (destination, ...args) { + const result = connectOrig.call(this, destination, ...args); + const s = cache.get(this.audioid); + s.connect.push(destination.audioid); + s.where.push(stackTrace()); + return result; + }; + + const disconnectOrig = AudioNode.prototype.disconnect; + AudioNode.prototype.disconnect = function (destination, ...args) { + const result = disconnectOrig.call(this, destination, ...args); + const s = cache.get(this.audioid); + if (s.connect.length) { + if (destination) { + s.disconnectOne++; + } else { + s.disconnectAll++; + } + } else { + logger('WEIRD: node ' + this.audioid + 'called disconnect before any call to connect !'); + logger(new Error().stack); + console.log(cache); + } + return result; + }; + + // call reset 2 times to handle reload + 'play' + // the first reset's disconnect adds audioid tags on previous outputs + // that were not tagged (wrong cutoff) + resetAudioOutput(audioid); + // the second reset has the correct audioid cutoff + resetAudioOutput(audioid); + + //////////////////////////////////////// + // step 2: Load external modules + //////////////////////////////////////// + + const { default: mermaidModule } = await import( + 'https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.mjs' + ); + mermaid = mermaidModule; + + mermaid.initialize({ + startOnLoad: false, + themeCSS: '.flowchart { height: 100%; }', + maxEdges: maxEdges, + maxTextSize: maxTextSize, + htmlLabels: false, + flowchart: { + htmlLabels: false, + }, + }); + + const { default: svgPanZoomModule } = await import('https://esm.sh/svg-pan-zoom'); + svgPanZoom = svgPanZoomModule; + + ////////////////////////////////////////// + // step 3: UI modifications + ////////////////////////////////////////// + + // add audiograph panel + if (!document.querySelector('.strudel-mermaid')) { + const mermaidDiv = document.createElement('div'); + mermaidDiv.className = 'strudel-mermaid'; + mermaidDiv.style = 'min-height: 600px; width: 60%'; + const referenceNode = document.querySelector('#code'); + referenceNode.parentNode.insertBefore(mermaidDiv, referenceNode.nextSibling); + } + + // add svg export button + if (!document.querySelector('button[title=svg]')) { + const exportButton = document.createElement('button'); + exportButton.innerHTML = 'ExportDiagram'; + exportButton.title = 'svg'; + exportButton.onclick = svgExport; + const updateButton = document.querySelector('button[title=update]'); + updateButton.parentNode.insertBefore(exportButton, updateButton); + } + } + + if (!running) { + running = true; + } + + if (hapsBatch === 0 || hap_count < hapsBatch) { + let msg = ''; + msg += 'Recording activity...'; + msg += '\npress stop to build diagram'; + if (StopAfterHapCount) { + msg += '\nwill stop automatically in ' + Math.max(StopAfterHapCount - hap_count, 0) + ' haps'; + } + await drawMessage(msg); + } + + sm.toggle = async () => { + running = false; + sm.toggle = toggleOrig; + // schedule `toggle` on the js main loop + // to avoid interfering with any on-flight onTick + // not doing this can lead to a phase > 0 which will + // break the next start + setTimeout(sm.toggle.bind(sm), 0); + await drawMessage('please wait ' + audioAPIBreathingRoomSec + ' seconds\n' + 'the audio API is finishing its work'); + setTimeout(postProcessing, audioAPIBreathingRoomSec * 1000); + }; + + /*global all*/ + all((pat) => + pat.onTrigger(async (hap, duration, cps, t) => { + hap_count++; + const key = Object.entries(hap.value) + .map((param) => param.join('/')) + .join('/'); + + // if we reached StopAfterHapCount, click 'stop' + if (StopAfterHapCount && hap_count > StopAfterHapCount) { + if (running) { + await sm.toggle(); + } + // stop sending haps to superdough(...) + return; + } + + await webaudioOutput(hap, t, hap.duration / cps, cps, t); + + if (hapsBatch && hap_count % hapsBatch === 0) drawDiagram(); + }), + ); +}; diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index 8dcb6b754..7ef86c08e 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -36,6 +36,7 @@ import { getRandomTune, initCode, loadModules, shareCode } from './util.mjs'; import './Repl.css'; import { setInterval, clearInterval } from 'worker-timers'; import { getMetadata } from '../metadata_parser'; +import { debugAudiograph } from './audiograph'; const { latestCode, maxPolyphony, audioDeviceName, multiChannelOrbits } = settingsMap.get(); let modulesLoading, presets, drawContext, clearCanvas, audioReady; @@ -129,6 +130,7 @@ export function useReplContext() { bgFill: false, }); window.strudelMirror = editor; + window.debugAudiograph = debugAudiograph; // init settings initCode().then(async (decoded) => { From 05ed16e15860c5ac704a9c14b88048998942c3e9 Mon Sep 17 00:00:00 2001 From: jeromew Date: Sun, 30 Nov 2025 17:50:56 +0000 Subject: [PATCH 51/66] Add `stop-leak` detection. Stoppable nodes that are not stopped --- website/src/repl/audiograph.mjs | 42 +++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/website/src/repl/audiograph.mjs b/website/src/repl/audiograph.mjs index d203496ae..52ac311a3 100644 --- a/website/src/repl/audiograph.mjs +++ b/website/src/repl/audiograph.mjs @@ -21,6 +21,7 @@ const initCache = JSON.stringify({ where: [], disconnectAll: 0, disconnectOne: 0, + hasStop: false, stopCount: 0, ac: null, creation: null, @@ -56,6 +57,7 @@ const lazyRegister = (o) => { this._audioid = ++audioid; const s = JSON.parse(initCache); s.type = this.constructor.name === 'AudiographNode' ? this.constructor._parentClassName : this.constructor.name; + s.hasStop = window[s.type].prototype instanceof AudioScheduledSourceNode; s.ac = this.context?.constructor.name || 'AudioParam'; s.creation = s.creation || stackTrace(); cache.set(this._audioid, s); @@ -103,7 +105,6 @@ const drawMessage = async function (message) { const drawDiagram = async function () { const element = document.querySelector('.strudel-mermaid'); - let code = window.strudelMirror.code; code = code.replace(/^await debugAudiograph.*\n?/gm, ''); code = '// date: ' + new Date().toISOString() + '\n\n' + code; @@ -140,13 +141,16 @@ const drawDiagram = async function () { if (s.ac === 'OfflineAudioContext') lb = '[' + lb + ']'; return lb; }; - const isLeak = (s) => { + const isConnectLeak = (s) => { return ( ['AudioDestinationNode', 'AudioParam'].indexOf(s.type) === -1 && s.disconnectAll === 0 && s.connect.length > s.disconnectOne ); }; + const isStopLeak = (s) => { + return s.hasStop && s.stopCount === 0; + }; do { curRelations = relations.length; lookup.slice().forEach((n) => { @@ -197,6 +201,13 @@ const drawDiagram = async function () { }); }); } while (relations.length > curRelations /*&& lookup.length < 100*/); + // add orphan nodes + const inRelation = '-' + relations.join('-') + '-'; + cache.forEach((v, k) => { + if (!inRelation.includes('-' + k + '-')) { + gd += '\t\tnode' + k + label(v) + '\n'; + } + }); const codePlaceholder = 'm'.repeat(maxLineLength); gd += '\tsubgraph LEGEND\n'; @@ -205,6 +216,7 @@ const drawDiagram = async function () { gd += '\t\tlegend3[not disconnected]\n'; gd += '\t\tlegend4[AudioParam]\n'; gd += '\t\tlegend5[AudioDestinationNode]\n'; + gd += '\t\tlegend6[not stopped]\n'; gd += '\tend\n'; gd += '\tsubgraph CODE[Strudel Code]\n'; // we use a codePlaceholder to @@ -216,13 +228,17 @@ const drawDiagram = async function () { gd += '\tend\n'; gd += '\tclassDef audioparam fill:#6f6;\n'; gd += '\tclassDef destination fill:#99f;\n'; - gd += '\tclassDef suspect fill:#f96,stroke:#f00,stroke-width:2px;\n'; - gd += '\tclass legend3 suspect;\n'; + gd += '\tclassDef connectleak fill:#f96,stroke:#f00,stroke-width:2px;\n'; + gd += '\tclassDef stopleak fill:#f55,stroke:#f00,stroke-width:2px;\n'; + gd += '\tclass legend3 connectleak;\n'; gd += '\tclass legend4 audioparam;\n'; gd += '\tclass legend5 destination;\n'; + gd += '\tclass legend6 stopleak;\n'; cache.forEach((v, k) => { - if (isLeak(v)) { - gd += '\tclass node' + k + ' suspect;\n'; + if (isConnectLeak(v)) { + gd += '\tclass node' + k + ' connectleak;\n'; + } else if (isStopLeak(v)) { + gd += '\tclass node' + k + ' stopleak;\n'; } if (v.type === 'AudioParam') { gd += '\tclass node' + k + ' audioparam;\n'; @@ -470,7 +486,19 @@ export const debugAudiograph = async (argOptions = {}) => { StereoPannerNode, WaveShaperNode, ]; - audioNodes.map((n) => audioNodeHook(n)); + audioNodes.map((n) => { + if (n.prototype instanceof AudioScheduledSourceNode) { + const stopOrig = n.prototype.stop; + n.prototype.stop = function (...args) { + // stop called + const result = stopOrig.call(this, ...args); + const s = cache.get(this.audioid); + s.stopCount++; + return result; + }; + } + audioNodeHook(n); + }); // patch BaseAudioContext factory methods // to capture the source reference From 71d1fe99e499d07f5d6a4d84bea5ea2e69b25908 Mon Sep 17 00:00:00 2001 From: jeromew Date: Tue, 2 Dec 2025 13:51:16 +0000 Subject: [PATCH 52/66] Fix special case for FeedbackDelayNode --- website/src/repl/audiograph.mjs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/website/src/repl/audiograph.mjs b/website/src/repl/audiograph.mjs index 52ac311a3..bdd379711 100644 --- a/website/src/repl/audiograph.mjs +++ b/website/src/repl/audiograph.mjs @@ -5,7 +5,6 @@ This program is free software: you can redistribute it and/or modify it under th */ // main entry point is `debugAudiograph` - import { logger } from '@strudel/core'; import { getAudioContext, getSuperdoughAudioController, webaudioOutput } from '@strudel/webaudio'; @@ -57,7 +56,12 @@ const lazyRegister = (o) => { this._audioid = ++audioid; const s = JSON.parse(initCache); s.type = this.constructor.name === 'AudiographNode' ? this.constructor._parentClassName : this.constructor.name; - s.hasStop = window[s.type].prototype instanceof AudioScheduledSourceNode; + // special case for FeedbackDelayNode + // it is a subclass of DelayNode created in superdough/feedbackdelay.mjs + // it is not an AudioScheduledSourceNode anyway + if (s.type !== 'FeedbackDelayNode') { + s.hasStop = window[s.type].prototype instanceof AudioScheduledSourceNode; + } s.ac = this.context?.constructor.name || 'AudioParam'; s.creation = s.creation || stackTrace(); cache.set(this._audioid, s); From 2db30a710b9d35047c48991cdc25d36f9a70ffd9 Mon Sep 17 00:00:00 2001 From: jeromew Date: Tue, 2 Dec 2025 13:54:27 +0000 Subject: [PATCH 53/66] Fix codeformat --- website/src/repl/audiograph.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/src/repl/audiograph.mjs b/website/src/repl/audiograph.mjs index bdd379711..2ec75befe 100644 --- a/website/src/repl/audiograph.mjs +++ b/website/src/repl/audiograph.mjs @@ -56,10 +56,10 @@ const lazyRegister = (o) => { this._audioid = ++audioid; const s = JSON.parse(initCache); s.type = this.constructor.name === 'AudiographNode' ? this.constructor._parentClassName : this.constructor.name; - // special case for FeedbackDelayNode - // it is a subclass of DelayNode created in superdough/feedbackdelay.mjs - // it is not an AudioScheduledSourceNode anyway - if (s.type !== 'FeedbackDelayNode') { + // special case for FeedbackDelayNode + // it is a subclass of DelayNode created in superdough/feedbackdelay.mjs + // it is not an AudioScheduledSourceNode anyway + if (s.type !== 'FeedbackDelayNode') { s.hasStop = window[s.type].prototype instanceof AudioScheduledSourceNode; } s.ac = this.context?.constructor.name || 'AudioParam'; From 25c20296a1a8fba2824d8df01bcc121a25205127 Mon Sep 17 00:00:00 2001 From: jeromew Date: Tue, 2 Dec 2025 13:58:09 +0000 Subject: [PATCH 54/66] Tone down log message when a pure orphan node is found --- website/src/repl/audiograph.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/audiograph.mjs b/website/src/repl/audiograph.mjs index 2ec75befe..fd599db79 100644 --- a/website/src/repl/audiograph.mjs +++ b/website/src/repl/audiograph.mjs @@ -539,7 +539,7 @@ export const debugAudiograph = async (argOptions = {}) => { } } else { logger('WEIRD: node ' + this.audioid + 'called disconnect before any call to connect !'); - logger(new Error().stack); + //logger(new Error().stack); console.log(cache); } return result; From d7e240e2dcce012256fc9c8bad509818a3d80828 Mon Sep 17 00:00:00 2001 From: jeromew Date: Thu, 4 Dec 2025 12:56:54 +0000 Subject: [PATCH 55/66] Add PeriodicWave & VowelNode support --- website/src/repl/audiograph.mjs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/website/src/repl/audiograph.mjs b/website/src/repl/audiograph.mjs index fd599db79..2876388a8 100644 --- a/website/src/repl/audiograph.mjs +++ b/website/src/repl/audiograph.mjs @@ -56,10 +56,10 @@ const lazyRegister = (o) => { this._audioid = ++audioid; const s = JSON.parse(initCache); s.type = this.constructor.name === 'AudiographNode' ? this.constructor._parentClassName : this.constructor.name; - // special case for FeedbackDelayNode - // it is a subclass of DelayNode created in superdough/feedbackdelay.mjs - // it is not an AudioScheduledSourceNode anyway - if (s.type !== 'FeedbackDelayNode') { + // special case for subclassed AudioNodes + // they are implemented in superdough but hard to get a reference on here + // they are not AudioScheduledSourceNodes anyway + if (['FeedbackDelayNode', 'VowelNode'].indexOf(s.type) === -1) { s.hasStop = window[s.type].prototype instanceof AudioScheduledSourceNode; } s.ac = this.context?.constructor.name || 'AudioParam'; @@ -471,6 +471,7 @@ export const debugAudiograph = async (argOptions = {}) => { // and `new GainNode(..)` patterns lazyRegister(AudioNode); lazyRegister(AudioParam); + lazyRegister(PeriodicWave); const audioNodes = [ AudioBufferSourceNode, From 173e359a653895d3728aac34fa839f6d89a16dbb Mon Sep 17 00:00:00 2001 From: miranda Date: Sat, 6 Dec 2025 17:46:16 +0200 Subject: [PATCH 56/66] simplify envValAtTime and remove asymmetric behavior (fix #1653) --- packages/superdough/helpers.mjs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 0b696df9b..0f29e1d62 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -42,6 +42,7 @@ export const getParamADSR = ( decay, sustain, release, + // min = value at start of attack, max = value at end of attack; it is possible that max < min min, max, begin, @@ -59,17 +60,15 @@ export const getParamADSR = ( max = max === 0 ? 0.001 : max; } const range = max - min; - const peak = max; const sustainVal = min + sustain * range; const duration = end - begin; const envValAtTime = (time) => { let val; if (attack > time) { - let slope = getSlope(min, peak, 0, attack); - val = time * slope + (min > peak ? min : 0); + val = time * getSlope(min, max, 0, attack) + min; } else { - val = (time - attack) * getSlope(peak, sustainVal, 0, decay) + peak; + val = (time - attack) * getSlope(max, sustainVal, 0, decay) + max; } if (curve === 'exponential') { val = val || 0.001; From 53c101005c9f4bee299842a819d7ae27a7ddc58a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sun, 7 Dec 2025 00:12:40 +0100 Subject: [PATCH 57/66] Document "-" in mini-notation --- website/src/pages/learn/mini-notation.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/src/pages/learn/mini-notation.mdx b/website/src/pages/learn/mini-notation.mdx index 02ead7434..8b09f12f4 100644 --- a/website/src/pages/learn/mini-notation.mdx +++ b/website/src/pages/learn/mini-notation.mdx @@ -142,6 +142,8 @@ The "~" represents a rest, and will create silence between other events: +Alternatively, "-" can be used instead of "~". It means the same thing. + ## Parallel / polyphony Using commas, we can play chords. From 8e1fba04363cdcf39c946c8fb10a21554ef42cb7 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 12 Dec 2025 15:45:36 +0000 Subject: [PATCH 58/66] rename delta to loose, add inverse tight, and exponential tightx --- packages/core/signal.mjs | 41 ++++++++++++++++++++++++++--- packages/core/test/pattern.test.mjs | 14 ---------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 9ac768951..ff94c3b8b 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -884,10 +884,45 @@ export const keyDown = register('keyDown', function (pat) { }); /** - * A pattern that gives the duration of events that are combined with it. + * A pattern giving the 'looseness' of events, or in other words, the duration of pattern events, + * in cycles per event. `loose` doesn't have structure itself, but takes structure, and therefore + * event durations, from the pattern that it is combined with. + * For example `loose.struct("1 1 [1 1] 1")` would give the same as `"0.25 0.25 [0.125 0.125] 0.25"`. + * See also its inverse, `tight`. * @example - * sound("bd sd [bd bd] sd*4 [- sd] [bd [bd bd]]").note(delta.withValue(x => 1/x + 20)) + * // Shorter events are lower in pitch + * sound("saw saw [saw saw] saw") + * .note(loose.range(50, 100)) + * @example + * sound("bd sd [bd bd] sd*4 [- sd] [bd [bd bd]]") + * .note(tight.add(20)) */ -export const delta = new Pattern(function (state) { +export const loose = new Pattern(function (state) { return [new Hap(undefined, state.span, state.span.duration)]; }); + +/** + * A pattern giving the 'tightness' of events, or in other words, the duration of pattern events, + * in events per cycle. `tight` doesn't have structure itself, but takes structure, and therefore + * event durations, from the pattern that it is combined with. + * For example `tight.struct("1 1 [1 1] 1")` would give the same as `"4 4 [8 8] 4"`. + * See also its inverse, `loose`. + * @example + * // Shorter events are more distorted + * n("0 0*2 0 0*2 0 [0 0 0]@2").sound("bd") + * .distort(tight.div(2)) + */ +export const tight = new Pattern(function (state) { + return [new Hap(undefined, state.span, Fraction(1).div(state.span.duration))]; +}); + +/** + * Like `tight` but gives the tightness of events according to an exponential curve. In + * particular, where the event tightness doubles (i.e. where an event duration halves), the + * returned value increases by one. `tightx.struct("1 1 1 [1 [1 1]]")` would therefore be + * the same as `"3 3 3 [4 [5 5]]"`. + */ +export const tightx = new Pattern(function (state) { + const n = Fraction(1).div(state.span.duration); + return [new Hap(undefined, state.span, Math.log(n) / Math.log(2) + 1)]; +}); diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 408ff274b..aaa14bd27 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -740,20 +740,6 @@ describe('Pattern', () => { ); }); }); - describe('signal()', () => { - it('Can make saw/saw2', () => { - expect(saw.struct(true, true, true, true).firstCycle()).toStrictEqual( - sequence(0, 1 / 4, 1 / 2, 3 / 4).firstCycle(), - ); - - expect(saw2.struct(true, true, true, true).firstCycle()).toStrictEqual(sequence(-1, -0.5, 0, 0.5).firstCycle()); - }); - it('Can make isaw/isaw2', () => { - expect(isaw.struct(true, true, true, true).firstCycle()).toStrictEqual(sequence(1, 0.75, 0.5, 0.25).firstCycle()); - - expect(isaw2.struct(true, true, true, true).firstCycle()).toStrictEqual(sequence(1, 0.5, 0, -0.5).firstCycle()); - }); - }); describe('_setContext()', () => { it('Can set the hap context', () => { expect( From cd071cb7c062909a850b2e60041f6c8057f47d5a Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 12 Dec 2025 15:46:04 +0000 Subject: [PATCH 59/66] separate out signal tests, add tests for tight, tightx, loose --- packages/core/test/signal.test.mjs | 61 ++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 packages/core/test/signal.test.mjs diff --git a/packages/core/test/signal.test.mjs b/packages/core/test/signal.test.mjs new file mode 100644 index 000000000..ee0ec9c7c --- /dev/null +++ b/packages/core/test/signal.test.mjs @@ -0,0 +1,61 @@ +/* +signal.test.mjs - +Copyright (C) 2022 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 . +*/ + +import Fraction from 'fraction.js'; + +import { describe, it, expect, vi } from 'vitest'; + +import { saw, saw2, isaw, isaw2, tight, tightx, loose } from '../signal.mjs'; +import { fastcat, sequence } from '../pattern.mjs'; + +const st = (begin, end) => new State(ts(begin, end)); +const ts = (begin, end) => new TimeSpan(Fraction(begin), Fraction(end)); +const hap = (whole, part, value, context = {}) => new Hap(whole, part, value, context); + +const third = Fraction(1, 3); +const twothirds = Fraction(2, 3); + +const sameFirst = (a, b) => { + return expect(a.sortHapsByPart().firstCycle()).toStrictEqual(b.sortHapsByPart().firstCycle()); +}; + +describe('signal()', () => { + it('Can make saw/saw2', () => { + expect(saw.struct(true, true, true, true).firstCycle()).toStrictEqual( + sequence(0, 1 / 4, 1 / 2, 3 / 4).firstCycle(), + ); + + expect(saw2.struct(true, true, true, true).firstCycle()).toStrictEqual(sequence(-1, -0.5, 0, 0.5).firstCycle()); + }); + it('Can make isaw/isaw2', () => { + expect(isaw.struct(true, true, true, true).firstCycle()).toStrictEqual(sequence(1, 0.75, 0.5, 0.25).firstCycle()); + + expect(isaw2.struct(true, true, true, true).firstCycle()).toStrictEqual(sequence(1, 0.5, 0, -0.5).firstCycle()); + }); +}); + +describe('loose', () => { + it('gives cycles per hap', () => { + sameFirst( + loose.struct(true, true, true, fastcat(true, true)), + sequence(0.25, 0.25, 0.25, fastcat(0.125, 0.125)).fmap(Fraction), + ); + }); +}); +describe('tight', () => { + it('gives haps per cycle', () => { + sameFirst(tight.struct(true, true, true, fastcat(true, true)), sequence(4, 4, 4, fastcat(8, 8)).fmap(Fraction)); + }); +}); + +describe('tightx', () => { + it('gives exponential haps per cycle', () => { + sameFirst( + tightx.struct(true, true, true, fastcat(true, fastcat(true, true))), + sequence(3, 3, 3, fastcat(4, fastcat(5, 5))), + ); + }); +}); From 99e4999e6a7cd98979aa9bb93864c21b06a84cce Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 12 Dec 2025 15:46:19 +0000 Subject: [PATCH 60/66] snapshot --- test/__snapshots__/examples.test.mjs.snap | 176 +++++++++++++++------- 1 file changed, 123 insertions(+), 53 deletions(-) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 17dcb08ba..29237fdcf 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -2784,59 +2784,6 @@ exports[`runs examples > example "delaysync" example index 0 1`] = ` ] `; -exports[`runs examples > example "delta" example index 0 1`] = ` -[ - "[ 0/1 → 1/6 | s:bd note:26 ]", - "[ 1/6 → 1/3 | s:sd note:26 ]", - "[ 1/3 → 5/12 | s:bd note:32 ]", - "[ 5/12 → 1/2 | s:bd note:32 ]", - "[ 1/2 → 13/24 | s:sd note:44 ]", - "[ 13/24 → 7/12 | s:sd note:44 ]", - "[ 7/12 → 5/8 | s:sd note:44 ]", - "[ 5/8 → 2/3 | s:sd note:44 ]", - "[ 3/4 → 5/6 | s:sd note:32 ]", - "[ 5/6 → 11/12 | s:bd note:32 ]", - "[ 11/12 → 23/24 | s:bd note:44 ]", - "[ 23/24 → 1/1 | s:bd note:44 ]", - "[ 1/1 → 7/6 | s:bd note:26 ]", - "[ 7/6 → 4/3 | s:sd note:26 ]", - "[ 4/3 → 17/12 | s:bd note:32 ]", - "[ 17/12 → 3/2 | s:bd note:32 ]", - "[ 3/2 → 37/24 | s:sd note:44 ]", - "[ 37/24 → 19/12 | s:sd note:44 ]", - "[ 19/12 → 13/8 | s:sd note:44 ]", - "[ 13/8 → 5/3 | s:sd note:44 ]", - "[ 7/4 → 11/6 | s:sd note:32 ]", - "[ 11/6 → 23/12 | s:bd note:32 ]", - "[ 23/12 → 47/24 | s:bd note:44 ]", - "[ 47/24 → 2/1 | s:bd note:44 ]", - "[ 2/1 → 13/6 | s:bd note:26 ]", - "[ 13/6 → 7/3 | s:sd note:26 ]", - "[ 7/3 → 29/12 | s:bd note:32 ]", - "[ 29/12 → 5/2 | s:bd note:32 ]", - "[ 5/2 → 61/24 | s:sd note:44 ]", - "[ 61/24 → 31/12 | s:sd note:44 ]", - "[ 31/12 → 21/8 | s:sd note:44 ]", - "[ 21/8 → 8/3 | s:sd note:44 ]", - "[ 11/4 → 17/6 | s:sd note:32 ]", - "[ 17/6 → 35/12 | s:bd note:32 ]", - "[ 35/12 → 71/24 | s:bd note:44 ]", - "[ 71/24 → 3/1 | s:bd note:44 ]", - "[ 3/1 → 19/6 | s:bd note:26 ]", - "[ 19/6 → 10/3 | s:sd note:26 ]", - "[ 10/3 → 41/12 | s:bd note:32 ]", - "[ 41/12 → 7/2 | s:bd note:32 ]", - "[ 7/2 → 85/24 | s:sd note:44 ]", - "[ 85/24 → 43/12 | s:sd note:44 ]", - "[ 43/12 → 29/8 | s:sd note:44 ]", - "[ 29/8 → 11/3 | s:sd note:44 ]", - "[ 15/4 → 23/6 | s:sd note:32 ]", - "[ 23/6 → 47/12 | s:bd note:32 ]", - "[ 47/12 → 95/24 | s:bd note:44 ]", - "[ 95/24 → 4/1 | s:bd note:44 ]", -] -`; - exports[`runs examples > example "density" example index 0 1`] = ` [ "[ 0/1 → 1/4 | s:crackle density:0.01 ]", @@ -6219,6 +6166,84 @@ exports[`runs examples > example "loopEnd" example index 0 1`] = ` ] `; +exports[`runs examples > example "loose" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:saw note:62.5 ]", + "[ 1/4 → 1/2 | s:saw note:62.5 ]", + "[ 1/2 → 5/8 | s:saw note:56.25 ]", + "[ 5/8 → 3/4 | s:saw note:56.25 ]", + "[ 3/4 → 1/1 | s:saw note:62.5 ]", + "[ 1/1 → 5/4 | s:saw note:62.5 ]", + "[ 5/4 → 3/2 | s:saw note:62.5 ]", + "[ 3/2 → 13/8 | s:saw note:56.25 ]", + "[ 13/8 → 7/4 | s:saw note:56.25 ]", + "[ 7/4 → 2/1 | s:saw note:62.5 ]", + "[ 2/1 → 9/4 | s:saw note:62.5 ]", + "[ 9/4 → 5/2 | s:saw note:62.5 ]", + "[ 5/2 → 21/8 | s:saw note:56.25 ]", + "[ 21/8 → 11/4 | s:saw note:56.25 ]", + "[ 11/4 → 3/1 | s:saw note:62.5 ]", + "[ 3/1 → 13/4 | s:saw note:62.5 ]", + "[ 13/4 → 7/2 | s:saw note:62.5 ]", + "[ 7/2 → 29/8 | s:saw note:56.25 ]", + "[ 29/8 → 15/4 | s:saw note:56.25 ]", + "[ 15/4 → 4/1 | s:saw note:62.5 ]", +] +`; + +exports[`runs examples > example "loose" example index 1 1`] = ` +[ + "[ 0/1 → 1/6 | s:bd note:26 ]", + "[ 1/6 → 1/3 | s:sd note:26 ]", + "[ 1/3 → 5/12 | s:bd note:32 ]", + "[ 5/12 → 1/2 | s:bd note:32 ]", + "[ 1/2 → 13/24 | s:sd note:44 ]", + "[ 13/24 → 7/12 | s:sd note:44 ]", + "[ 7/12 → 5/8 | s:sd note:44 ]", + "[ 5/8 → 2/3 | s:sd note:44 ]", + "[ 3/4 → 5/6 | s:sd note:32 ]", + "[ 5/6 → 11/12 | s:bd note:32 ]", + "[ 11/12 → 23/24 | s:bd note:44 ]", + "[ 23/24 → 1/1 | s:bd note:44 ]", + "[ 1/1 → 7/6 | s:bd note:26 ]", + "[ 7/6 → 4/3 | s:sd note:26 ]", + "[ 4/3 → 17/12 | s:bd note:32 ]", + "[ 17/12 → 3/2 | s:bd note:32 ]", + "[ 3/2 → 37/24 | s:sd note:44 ]", + "[ 37/24 → 19/12 | s:sd note:44 ]", + "[ 19/12 → 13/8 | s:sd note:44 ]", + "[ 13/8 → 5/3 | s:sd note:44 ]", + "[ 7/4 → 11/6 | s:sd note:32 ]", + "[ 11/6 → 23/12 | s:bd note:32 ]", + "[ 23/12 → 47/24 | s:bd note:44 ]", + "[ 47/24 → 2/1 | s:bd note:44 ]", + "[ 2/1 → 13/6 | s:bd note:26 ]", + "[ 13/6 → 7/3 | s:sd note:26 ]", + "[ 7/3 → 29/12 | s:bd note:32 ]", + "[ 29/12 → 5/2 | s:bd note:32 ]", + "[ 5/2 → 61/24 | s:sd note:44 ]", + "[ 61/24 → 31/12 | s:sd note:44 ]", + "[ 31/12 → 21/8 | s:sd note:44 ]", + "[ 21/8 → 8/3 | s:sd note:44 ]", + "[ 11/4 → 17/6 | s:sd note:32 ]", + "[ 17/6 → 35/12 | s:bd note:32 ]", + "[ 35/12 → 71/24 | s:bd note:44 ]", + "[ 71/24 → 3/1 | s:bd note:44 ]", + "[ 3/1 → 19/6 | s:bd note:26 ]", + "[ 19/6 → 10/3 | s:sd note:26 ]", + "[ 10/3 → 41/12 | s:bd note:32 ]", + "[ 41/12 → 7/2 | s:bd note:32 ]", + "[ 7/2 → 85/24 | s:sd note:44 ]", + "[ 85/24 → 43/12 | s:sd note:44 ]", + "[ 43/12 → 29/8 | s:sd note:44 ]", + "[ 29/8 → 11/3 | s:sd note:44 ]", + "[ 15/4 → 23/6 | s:sd note:32 ]", + "[ 23/6 → 47/12 | s:bd note:32 ]", + "[ 47/12 → 95/24 | s:bd note:44 ]", + "[ 95/24 → 4/1 | s:bd note:44 ]", +] +`; + exports[`runs examples > example "lpattack" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c2 s:sawtooth cutoff:300 lpattack:0.5 lpenv:4 ]", @@ -12041,6 +12066,51 @@ exports[`runs examples > example "take" example index 2 1`] = ` ] `; +exports[`runs examples > example "tight" example index 0 1`] = ` +[ + "[ 0/1 → 1/7 | n:0 s:bd distort:3.5 ]", + "[ 1/7 → 3/14 | n:0 s:bd distort:7 ]", + "[ 3/14 → 2/7 | n:0 s:bd distort:7 ]", + "[ 2/7 → 3/7 | n:0 s:bd distort:3.5 ]", + "[ 3/7 → 1/2 | n:0 s:bd distort:7 ]", + "[ 1/2 → 4/7 | n:0 s:bd distort:7 ]", + "[ 4/7 → 5/7 | n:0 s:bd distort:3.5 ]", + "[ 5/7 → 17/21 | n:0 s:bd distort:5.25 ]", + "[ 17/21 → 19/21 | n:0 s:bd distort:5.25 ]", + "[ 19/21 → 1/1 | n:0 s:bd distort:5.25 ]", + "[ 1/1 → 8/7 | n:0 s:bd distort:3.5 ]", + "[ 8/7 → 17/14 | n:0 s:bd distort:7 ]", + "[ 17/14 → 9/7 | n:0 s:bd distort:7 ]", + "[ 9/7 → 10/7 | n:0 s:bd distort:3.5 ]", + "[ 10/7 → 3/2 | n:0 s:bd distort:7 ]", + "[ 3/2 → 11/7 | n:0 s:bd distort:7 ]", + "[ 11/7 → 12/7 | n:0 s:bd distort:3.5 ]", + "[ 12/7 → 38/21 | n:0 s:bd distort:5.25 ]", + "[ 38/21 → 40/21 | n:0 s:bd distort:5.25 ]", + "[ 40/21 → 2/1 | n:0 s:bd distort:5.25 ]", + "[ 2/1 → 15/7 | n:0 s:bd distort:3.5 ]", + "[ 15/7 → 31/14 | n:0 s:bd distort:7 ]", + "[ 31/14 → 16/7 | n:0 s:bd distort:7 ]", + "[ 16/7 → 17/7 | n:0 s:bd distort:3.5 ]", + "[ 17/7 → 5/2 | n:0 s:bd distort:7 ]", + "[ 5/2 → 18/7 | n:0 s:bd distort:7 ]", + "[ 18/7 → 19/7 | n:0 s:bd distort:3.5 ]", + "[ 19/7 → 59/21 | n:0 s:bd distort:5.25 ]", + "[ 59/21 → 61/21 | n:0 s:bd distort:5.25 ]", + "[ 61/21 → 3/1 | n:0 s:bd distort:5.25 ]", + "[ 3/1 → 22/7 | n:0 s:bd distort:3.5 ]", + "[ 22/7 → 45/14 | n:0 s:bd distort:7 ]", + "[ 45/14 → 23/7 | n:0 s:bd distort:7 ]", + "[ 23/7 → 24/7 | n:0 s:bd distort:3.5 ]", + "[ 24/7 → 7/2 | n:0 s:bd distort:7 ]", + "[ 7/2 → 25/7 | n:0 s:bd distort:7 ]", + "[ 25/7 → 26/7 | n:0 s:bd distort:3.5 ]", + "[ 26/7 → 80/21 | n:0 s:bd distort:5.25 ]", + "[ 80/21 → 82/21 | n:0 s:bd distort:5.25 ]", + "[ 82/21 → 4/1 | n:0 s:bd distort:5.25 ]", +] +`; + exports[`runs examples > example "tour" example index 0 1`] = ` [ "[ 0/1 → 1/8 | note:e s:folkharp ]", From a53385aa116b5fedf03619acc78d43a61b24a483 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 12 Dec 2025 16:50:24 +0000 Subject: [PATCH 61/66] delint --- packages/core/test/signal.test.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/signal.test.mjs b/packages/core/test/signal.test.mjs index ee0ec9c7c..6036b61dc 100644 --- a/packages/core/test/signal.test.mjs +++ b/packages/core/test/signal.test.mjs @@ -9,7 +9,7 @@ import Fraction from 'fraction.js'; import { describe, it, expect, vi } from 'vitest'; import { saw, saw2, isaw, isaw2, tight, tightx, loose } from '../signal.mjs'; -import { fastcat, sequence } from '../pattern.mjs'; +import { fastcat, sequence, State, TimeSpan, Hap } from '../index.mjs'; const st = (begin, end) => new State(ts(begin, end)); const ts = (begin, end) => new TimeSpan(Fraction(begin), Fraction(end)); From 8eeebf1e4f31be65508260d791aed0fbd21ccdd5 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 13 Dec 2025 16:30:51 +0000 Subject: [PATCH 62/66] try renaming to per / perx / cyclesPer --- packages/core/signal.mjs | 39 ++-- packages/core/test/signal.test.mjs | 14 +- test/__snapshots__/examples.test.mjs.snap | 246 +++++++++++----------- 3 files changed, 151 insertions(+), 148 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index ff94c3b8b..fa450c670 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -884,45 +884,48 @@ export const keyDown = register('keyDown', function (pat) { }); /** - * A pattern giving the 'looseness' of events, or in other words, the duration of pattern events, - * in cycles per event. `loose` doesn't have structure itself, but takes structure, and therefore + * A pattern measuring the duration of events, + * in cycles per event. `cyclesPer` doesn't have structure itself, but takes structure, and therefore * event durations, from the pattern that it is combined with. - * For example `loose.struct("1 1 [1 1] 1")` would give the same as `"0.25 0.25 [0.125 0.125] 0.25"`. - * See also its inverse, `tight`. + * 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`. * @example * // Shorter events are lower in pitch * sound("saw saw [saw saw] saw") - * .note(loose.range(50, 100)) + * .note(cyclesPer.range(50, 100)) * @example * sound("bd sd [bd bd] sd*4 [- sd] [bd [bd bd]]") - * .note(tight.add(20)) + * .note(cyclesPer.add(20)) */ -export const loose = new Pattern(function (state) { +export const cyclesPer = new Pattern(function (state) { return [new Hap(undefined, state.span, state.span.duration)]; }); /** - * A pattern giving the 'tightness' of events, or in other words, the duration of pattern events, - * in events per cycle. `tight` doesn't have structure itself, but takes structure, and therefore + * A pattern measuring the 'shortness' of events, or in other words, the duration of pattern events, + * in events per cycle. `per` doesn't have structure itself, but takes structure, and therefore * event durations, from the pattern that it is combined with. - * For example `tight.struct("1 1 [1 1] 1")` would give the same as `"4 4 [8 8] 4"`. - * See also its inverse, `loose`. + * For example `per.struct("1 1 [1 1] 1")` would give the same as `"4 4 [8 8] 4"`. + * See also its reciprocal, `cyclesPer`. + * @synonyms perCycle * @example * // Shorter events are more distorted * n("0 0*2 0 0*2 0 [0 0 0]@2").sound("bd") - * .distort(tight.div(2)) + * .distort(per.div(2)) */ -export const tight = new Pattern(function (state) { +export const per = new Pattern(function (state) { return [new Hap(undefined, state.span, Fraction(1).div(state.span.duration))]; }); +export const perCycle = per; + /** - * Like `tight` but gives the tightness of events according to an exponential curve. In - * particular, where the event tightness doubles (i.e. where an event duration halves), the - * returned value increases by one. `tightx.struct("1 1 1 [1 [1 1]]")` would therefore be - * the same as `"3 3 3 [4 [5 5]]"`. + * Like `per` but measures the shortness of events according to an exponential curve. In + * 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"`. */ -export const tightx = new Pattern(function (state) { +export const perx = new Pattern(function (state) { const n = Fraction(1).div(state.span.duration); return [new Hap(undefined, state.span, Math.log(n) / Math.log(2) + 1)]; }); diff --git a/packages/core/test/signal.test.mjs b/packages/core/test/signal.test.mjs index 6036b61dc..b02f8a08b 100644 --- a/packages/core/test/signal.test.mjs +++ b/packages/core/test/signal.test.mjs @@ -8,7 +8,7 @@ import Fraction from 'fraction.js'; import { describe, it, expect, vi } from 'vitest'; -import { saw, saw2, isaw, isaw2, tight, tightx, loose } from '../signal.mjs'; +import { saw, saw2, isaw, isaw2, per, perx, cyclesPer } from '../signal.mjs'; import { fastcat, sequence, State, TimeSpan, Hap } from '../index.mjs'; const st = (begin, end) => new State(ts(begin, end)); @@ -37,24 +37,24 @@ describe('signal()', () => { }); }); -describe('loose', () => { +describe('cyclesPer', () => { it('gives cycles per hap', () => { sameFirst( - loose.struct(true, true, true, fastcat(true, true)), + cyclesPer.struct(true, true, true, fastcat(true, true)), sequence(0.25, 0.25, 0.25, fastcat(0.125, 0.125)).fmap(Fraction), ); }); }); -describe('tight', () => { +describe('per', () => { it('gives haps per cycle', () => { - sameFirst(tight.struct(true, true, true, fastcat(true, true)), sequence(4, 4, 4, fastcat(8, 8)).fmap(Fraction)); + sameFirst(per.struct(true, true, true, fastcat(true, true)), sequence(4, 4, 4, fastcat(8, 8)).fmap(Fraction)); }); }); -describe('tightx', () => { +describe('perx', () => { it('gives exponential haps per cycle', () => { sameFirst( - tightx.struct(true, true, true, fastcat(true, fastcat(true, true))), + perx.struct(true, true, true, fastcat(true, fastcat(true, true))), sequence(3, 3, 3, fastcat(4, fastcat(5, 5))), ); }); diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 29237fdcf..c4b50d368 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -2539,6 +2539,84 @@ exports[`runs examples > example "cut" example index 0 1`] = ` ] `; +exports[`runs examples > example "cyclesPer" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | s:saw note:62.5 ]", + "[ 1/4 → 1/2 | s:saw note:62.5 ]", + "[ 1/2 → 5/8 | s:saw note:56.25 ]", + "[ 5/8 → 3/4 | s:saw note:56.25 ]", + "[ 3/4 → 1/1 | s:saw note:62.5 ]", + "[ 1/1 → 5/4 | s:saw note:62.5 ]", + "[ 5/4 → 3/2 | s:saw note:62.5 ]", + "[ 3/2 → 13/8 | s:saw note:56.25 ]", + "[ 13/8 → 7/4 | s:saw note:56.25 ]", + "[ 7/4 → 2/1 | s:saw note:62.5 ]", + "[ 2/1 → 9/4 | s:saw note:62.5 ]", + "[ 9/4 → 5/2 | s:saw note:62.5 ]", + "[ 5/2 → 21/8 | s:saw note:56.25 ]", + "[ 21/8 → 11/4 | s:saw note:56.25 ]", + "[ 11/4 → 3/1 | s:saw note:62.5 ]", + "[ 3/1 → 13/4 | s:saw note:62.5 ]", + "[ 13/4 → 7/2 | s:saw note:62.5 ]", + "[ 7/2 → 29/8 | s:saw note:56.25 ]", + "[ 29/8 → 15/4 | s:saw note:56.25 ]", + "[ 15/4 → 4/1 | s:saw note:62.5 ]", +] +`; + +exports[`runs examples > example "cyclesPer" example index 1 1`] = ` +[ + "[ 0/1 → 1/6 | s:bd note:20.166666666666668 ]", + "[ 1/6 → 1/3 | s:sd note:20.166666666666668 ]", + "[ 1/3 → 5/12 | s:bd note:20.083333333333332 ]", + "[ 5/12 → 1/2 | s:bd note:20.083333333333332 ]", + "[ 1/2 → 13/24 | s:sd note:20.041666666666668 ]", + "[ 13/24 → 7/12 | s:sd note:20.041666666666668 ]", + "[ 7/12 → 5/8 | s:sd note:20.041666666666668 ]", + "[ 5/8 → 2/3 | s:sd note:20.041666666666668 ]", + "[ 3/4 → 5/6 | s:sd note:20.083333333333332 ]", + "[ 5/6 → 11/12 | s:bd note:20.083333333333332 ]", + "[ 11/12 → 23/24 | s:bd note:20.041666666666668 ]", + "[ 23/24 → 1/1 | s:bd note:20.041666666666668 ]", + "[ 1/1 → 7/6 | s:bd note:20.166666666666668 ]", + "[ 7/6 → 4/3 | s:sd note:20.166666666666668 ]", + "[ 4/3 → 17/12 | s:bd note:20.083333333333332 ]", + "[ 17/12 → 3/2 | s:bd note:20.083333333333332 ]", + "[ 3/2 → 37/24 | s:sd note:20.041666666666668 ]", + "[ 37/24 → 19/12 | s:sd note:20.041666666666668 ]", + "[ 19/12 → 13/8 | s:sd note:20.041666666666668 ]", + "[ 13/8 → 5/3 | s:sd note:20.041666666666668 ]", + "[ 7/4 → 11/6 | s:sd note:20.083333333333332 ]", + "[ 11/6 → 23/12 | s:bd note:20.083333333333332 ]", + "[ 23/12 → 47/24 | s:bd note:20.041666666666668 ]", + "[ 47/24 → 2/1 | s:bd note:20.041666666666668 ]", + "[ 2/1 → 13/6 | s:bd note:20.166666666666668 ]", + "[ 13/6 → 7/3 | s:sd note:20.166666666666668 ]", + "[ 7/3 → 29/12 | s:bd note:20.083333333333332 ]", + "[ 29/12 → 5/2 | s:bd note:20.083333333333332 ]", + "[ 5/2 → 61/24 | s:sd note:20.041666666666668 ]", + "[ 61/24 → 31/12 | s:sd note:20.041666666666668 ]", + "[ 31/12 → 21/8 | s:sd note:20.041666666666668 ]", + "[ 21/8 → 8/3 | s:sd note:20.041666666666668 ]", + "[ 11/4 → 17/6 | s:sd note:20.083333333333332 ]", + "[ 17/6 → 35/12 | s:bd note:20.083333333333332 ]", + "[ 35/12 → 71/24 | s:bd note:20.041666666666668 ]", + "[ 71/24 → 3/1 | s:bd note:20.041666666666668 ]", + "[ 3/1 → 19/6 | s:bd note:20.166666666666668 ]", + "[ 19/6 → 10/3 | s:sd note:20.166666666666668 ]", + "[ 10/3 → 41/12 | s:bd note:20.083333333333332 ]", + "[ 41/12 → 7/2 | s:bd note:20.083333333333332 ]", + "[ 7/2 → 85/24 | s:sd note:20.041666666666668 ]", + "[ 85/24 → 43/12 | s:sd note:20.041666666666668 ]", + "[ 43/12 → 29/8 | s:sd note:20.041666666666668 ]", + "[ 29/8 → 11/3 | s:sd note:20.041666666666668 ]", + "[ 15/4 → 23/6 | s:sd note:20.083333333333332 ]", + "[ 23/6 → 47/12 | s:bd note:20.083333333333332 ]", + "[ 47/12 → 95/24 | s:bd note:20.041666666666668 ]", + "[ 95/24 → 4/1 | s:bd note:20.041666666666668 ]", +] +`; + exports[`runs examples > example "decay" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c3 decay:0.1 sustain:0 ]", @@ -6166,84 +6244,6 @@ exports[`runs examples > example "loopEnd" example index 0 1`] = ` ] `; -exports[`runs examples > example "loose" example index 0 1`] = ` -[ - "[ 0/1 → 1/4 | s:saw note:62.5 ]", - "[ 1/4 → 1/2 | s:saw note:62.5 ]", - "[ 1/2 → 5/8 | s:saw note:56.25 ]", - "[ 5/8 → 3/4 | s:saw note:56.25 ]", - "[ 3/4 → 1/1 | s:saw note:62.5 ]", - "[ 1/1 → 5/4 | s:saw note:62.5 ]", - "[ 5/4 → 3/2 | s:saw note:62.5 ]", - "[ 3/2 → 13/8 | s:saw note:56.25 ]", - "[ 13/8 → 7/4 | s:saw note:56.25 ]", - "[ 7/4 → 2/1 | s:saw note:62.5 ]", - "[ 2/1 → 9/4 | s:saw note:62.5 ]", - "[ 9/4 → 5/2 | s:saw note:62.5 ]", - "[ 5/2 → 21/8 | s:saw note:56.25 ]", - "[ 21/8 → 11/4 | s:saw note:56.25 ]", - "[ 11/4 → 3/1 | s:saw note:62.5 ]", - "[ 3/1 → 13/4 | s:saw note:62.5 ]", - "[ 13/4 → 7/2 | s:saw note:62.5 ]", - "[ 7/2 → 29/8 | s:saw note:56.25 ]", - "[ 29/8 → 15/4 | s:saw note:56.25 ]", - "[ 15/4 → 4/1 | s:saw note:62.5 ]", -] -`; - -exports[`runs examples > example "loose" example index 1 1`] = ` -[ - "[ 0/1 → 1/6 | s:bd note:26 ]", - "[ 1/6 → 1/3 | s:sd note:26 ]", - "[ 1/3 → 5/12 | s:bd note:32 ]", - "[ 5/12 → 1/2 | s:bd note:32 ]", - "[ 1/2 → 13/24 | s:sd note:44 ]", - "[ 13/24 → 7/12 | s:sd note:44 ]", - "[ 7/12 → 5/8 | s:sd note:44 ]", - "[ 5/8 → 2/3 | s:sd note:44 ]", - "[ 3/4 → 5/6 | s:sd note:32 ]", - "[ 5/6 → 11/12 | s:bd note:32 ]", - "[ 11/12 → 23/24 | s:bd note:44 ]", - "[ 23/24 → 1/1 | s:bd note:44 ]", - "[ 1/1 → 7/6 | s:bd note:26 ]", - "[ 7/6 → 4/3 | s:sd note:26 ]", - "[ 4/3 → 17/12 | s:bd note:32 ]", - "[ 17/12 → 3/2 | s:bd note:32 ]", - "[ 3/2 → 37/24 | s:sd note:44 ]", - "[ 37/24 → 19/12 | s:sd note:44 ]", - "[ 19/12 → 13/8 | s:sd note:44 ]", - "[ 13/8 → 5/3 | s:sd note:44 ]", - "[ 7/4 → 11/6 | s:sd note:32 ]", - "[ 11/6 → 23/12 | s:bd note:32 ]", - "[ 23/12 → 47/24 | s:bd note:44 ]", - "[ 47/24 → 2/1 | s:bd note:44 ]", - "[ 2/1 → 13/6 | s:bd note:26 ]", - "[ 13/6 → 7/3 | s:sd note:26 ]", - "[ 7/3 → 29/12 | s:bd note:32 ]", - "[ 29/12 → 5/2 | s:bd note:32 ]", - "[ 5/2 → 61/24 | s:sd note:44 ]", - "[ 61/24 → 31/12 | s:sd note:44 ]", - "[ 31/12 → 21/8 | s:sd note:44 ]", - "[ 21/8 → 8/3 | s:sd note:44 ]", - "[ 11/4 → 17/6 | s:sd note:32 ]", - "[ 17/6 → 35/12 | s:bd note:32 ]", - "[ 35/12 → 71/24 | s:bd note:44 ]", - "[ 71/24 → 3/1 | s:bd note:44 ]", - "[ 3/1 → 19/6 | s:bd note:26 ]", - "[ 19/6 → 10/3 | s:sd note:26 ]", - "[ 10/3 → 41/12 | s:bd note:32 ]", - "[ 41/12 → 7/2 | s:bd note:32 ]", - "[ 7/2 → 85/24 | s:sd note:44 ]", - "[ 85/24 → 43/12 | s:sd note:44 ]", - "[ 43/12 → 29/8 | s:sd note:44 ]", - "[ 29/8 → 11/3 | s:sd note:44 ]", - "[ 15/4 → 23/6 | s:sd note:32 ]", - "[ 23/6 → 47/12 | s:bd note:32 ]", - "[ 47/12 → 95/24 | s:bd note:44 ]", - "[ 95/24 → 4/1 | s:bd note:44 ]", -] -`; - exports[`runs examples > example "lpattack" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c2 s:sawtooth cutoff:300 lpattack:0.5 lpenv:4 ]", @@ -7991,6 +7991,51 @@ exports[`runs examples > example "penv" example index 0 1`] = ` ] `; +exports[`runs examples > example "per" example index 0 1`] = ` +[ + "[ 0/1 → 1/7 | n:0 s:bd distort:3.5 ]", + "[ 1/7 → 3/14 | n:0 s:bd distort:7 ]", + "[ 3/14 → 2/7 | n:0 s:bd distort:7 ]", + "[ 2/7 → 3/7 | n:0 s:bd distort:3.5 ]", + "[ 3/7 → 1/2 | n:0 s:bd distort:7 ]", + "[ 1/2 → 4/7 | n:0 s:bd distort:7 ]", + "[ 4/7 → 5/7 | n:0 s:bd distort:3.5 ]", + "[ 5/7 → 17/21 | n:0 s:bd distort:5.25 ]", + "[ 17/21 → 19/21 | n:0 s:bd distort:5.25 ]", + "[ 19/21 → 1/1 | n:0 s:bd distort:5.25 ]", + "[ 1/1 → 8/7 | n:0 s:bd distort:3.5 ]", + "[ 8/7 → 17/14 | n:0 s:bd distort:7 ]", + "[ 17/14 → 9/7 | n:0 s:bd distort:7 ]", + "[ 9/7 → 10/7 | n:0 s:bd distort:3.5 ]", + "[ 10/7 → 3/2 | n:0 s:bd distort:7 ]", + "[ 3/2 → 11/7 | n:0 s:bd distort:7 ]", + "[ 11/7 → 12/7 | n:0 s:bd distort:3.5 ]", + "[ 12/7 → 38/21 | n:0 s:bd distort:5.25 ]", + "[ 38/21 → 40/21 | n:0 s:bd distort:5.25 ]", + "[ 40/21 → 2/1 | n:0 s:bd distort:5.25 ]", + "[ 2/1 → 15/7 | n:0 s:bd distort:3.5 ]", + "[ 15/7 → 31/14 | n:0 s:bd distort:7 ]", + "[ 31/14 → 16/7 | n:0 s:bd distort:7 ]", + "[ 16/7 → 17/7 | n:0 s:bd distort:3.5 ]", + "[ 17/7 → 5/2 | n:0 s:bd distort:7 ]", + "[ 5/2 → 18/7 | n:0 s:bd distort:7 ]", + "[ 18/7 → 19/7 | n:0 s:bd distort:3.5 ]", + "[ 19/7 → 59/21 | n:0 s:bd distort:5.25 ]", + "[ 59/21 → 61/21 | n:0 s:bd distort:5.25 ]", + "[ 61/21 → 3/1 | n:0 s:bd distort:5.25 ]", + "[ 3/1 → 22/7 | n:0 s:bd distort:3.5 ]", + "[ 22/7 → 45/14 | n:0 s:bd distort:7 ]", + "[ 45/14 → 23/7 | n:0 s:bd distort:7 ]", + "[ 23/7 → 24/7 | n:0 s:bd distort:3.5 ]", + "[ 24/7 → 7/2 | n:0 s:bd distort:7 ]", + "[ 7/2 → 25/7 | n:0 s:bd distort:7 ]", + "[ 25/7 → 26/7 | n:0 s:bd distort:3.5 ]", + "[ 26/7 → 80/21 | n:0 s:bd distort:5.25 ]", + "[ 80/21 → 82/21 | n:0 s:bd distort:5.25 ]", + "[ 82/21 → 4/1 | n:0 s:bd distort:5.25 ]", +] +`; + exports[`runs examples > example "perlin" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh cutoff:500 ]", @@ -12066,51 +12111,6 @@ exports[`runs examples > example "take" example index 2 1`] = ` ] `; -exports[`runs examples > example "tight" example index 0 1`] = ` -[ - "[ 0/1 → 1/7 | n:0 s:bd distort:3.5 ]", - "[ 1/7 → 3/14 | n:0 s:bd distort:7 ]", - "[ 3/14 → 2/7 | n:0 s:bd distort:7 ]", - "[ 2/7 → 3/7 | n:0 s:bd distort:3.5 ]", - "[ 3/7 → 1/2 | n:0 s:bd distort:7 ]", - "[ 1/2 → 4/7 | n:0 s:bd distort:7 ]", - "[ 4/7 → 5/7 | n:0 s:bd distort:3.5 ]", - "[ 5/7 → 17/21 | n:0 s:bd distort:5.25 ]", - "[ 17/21 → 19/21 | n:0 s:bd distort:5.25 ]", - "[ 19/21 → 1/1 | n:0 s:bd distort:5.25 ]", - "[ 1/1 → 8/7 | n:0 s:bd distort:3.5 ]", - "[ 8/7 → 17/14 | n:0 s:bd distort:7 ]", - "[ 17/14 → 9/7 | n:0 s:bd distort:7 ]", - "[ 9/7 → 10/7 | n:0 s:bd distort:3.5 ]", - "[ 10/7 → 3/2 | n:0 s:bd distort:7 ]", - "[ 3/2 → 11/7 | n:0 s:bd distort:7 ]", - "[ 11/7 → 12/7 | n:0 s:bd distort:3.5 ]", - "[ 12/7 → 38/21 | n:0 s:bd distort:5.25 ]", - "[ 38/21 → 40/21 | n:0 s:bd distort:5.25 ]", - "[ 40/21 → 2/1 | n:0 s:bd distort:5.25 ]", - "[ 2/1 → 15/7 | n:0 s:bd distort:3.5 ]", - "[ 15/7 → 31/14 | n:0 s:bd distort:7 ]", - "[ 31/14 → 16/7 | n:0 s:bd distort:7 ]", - "[ 16/7 → 17/7 | n:0 s:bd distort:3.5 ]", - "[ 17/7 → 5/2 | n:0 s:bd distort:7 ]", - "[ 5/2 → 18/7 | n:0 s:bd distort:7 ]", - "[ 18/7 → 19/7 | n:0 s:bd distort:3.5 ]", - "[ 19/7 → 59/21 | n:0 s:bd distort:5.25 ]", - "[ 59/21 → 61/21 | n:0 s:bd distort:5.25 ]", - "[ 61/21 → 3/1 | n:0 s:bd distort:5.25 ]", - "[ 3/1 → 22/7 | n:0 s:bd distort:3.5 ]", - "[ 22/7 → 45/14 | n:0 s:bd distort:7 ]", - "[ 45/14 → 23/7 | n:0 s:bd distort:7 ]", - "[ 23/7 → 24/7 | n:0 s:bd distort:3.5 ]", - "[ 24/7 → 7/2 | n:0 s:bd distort:7 ]", - "[ 7/2 → 25/7 | n:0 s:bd distort:7 ]", - "[ 25/7 → 26/7 | n:0 s:bd distort:3.5 ]", - "[ 26/7 → 80/21 | n:0 s:bd distort:5.25 ]", - "[ 80/21 → 82/21 | n:0 s:bd distort:5.25 ]", - "[ 82/21 → 4/1 | n:0 s:bd distort:5.25 ]", -] -`; - exports[`runs examples > example "tour" example index 0 1`] = ` [ "[ 0/1 → 1/8 | note:e s:folkharp ]", From 4a7344595d8e72c14acb1ace5c629a1aa81e4a00 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 13 Dec 2025 17:28:42 -0600 Subject: [PATCH 63/66] Make legacy the default --- packages/core/bench/signal.bench.mjs | 10 +- packages/core/signal.mjs | 19 +- test/__snapshots__/examples.test.mjs.snap | 1785 +++++++++++---------- vitest.setup.mjs | 4 +- website/src/repl/tunes.mjs | 20 +- 5 files changed, 926 insertions(+), 912 deletions(-) diff --git a/packages/core/bench/signal.bench.mjs b/packages/core/bench/signal.bench.mjs index d92840ef6..bd651ccd3 100644 --- a/packages/core/bench/signal.bench.mjs +++ b/packages/core/bench/signal.bench.mjs @@ -1,6 +1,6 @@ import { describe, bench } from 'vitest'; -import { calculateSteps, rand, useOldRandom } from '../index.mjs'; +import { calculateSteps, rand, useRNG } from '../index.mjs'; const testingResolution = 128; @@ -11,13 +11,13 @@ describe('old random', () => { bench( '+tactus', () => { - useOldRandom(); + useRNG('legacy'); _generateRandomPattern(); }, { time: 1000, teardown() { - useOldRandom(false); + useRNG('legacy'); }, }, ); @@ -26,13 +26,13 @@ describe('old random', () => { bench( '-tactus', () => { - useOldRandom(); + useRNG('precise'); _generateRandomPattern(); }, { time: 1000, teardown() { - useOldRandom(false); + useRNG('legacy'); }, }, ); diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index e50ba22db..e497fb1b0 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -231,7 +231,8 @@ const timeToRands = (t, n, seed = 0) => { return out; }; -// Deprecated: Old random signals. Configuration `useOldRandom` may be used for legacy songs +// Old random signals. Currently the default, but can also be chosen via +// `useRNG('legacy')` // stretch 300 cycles over the range of [0,2**29 == 536870912) then apply the xorshift algorithm const __xorwise = (x) => { @@ -257,23 +258,25 @@ const __timeToRands = (t, n) => __timeToRandsPrime(__timeToIntSeed(t), n); // End old random -let useOldRandomBool = false; +let RNG_MODE = 'legacy'; export const getRandsAtTime = (t, n = 1, seed = 0) => { - return useOldRandomBool ? __timeToRands(t + seed, n) : timeToRands(t, n, seed); + return RNG_MODE === 'legacy' ? __timeToRands(t + seed, n) : timeToRands(t, n, seed); }; /** - * Whether to use the old random number generator or not. Can be used to support legacy projects + * Sets which random number generator to use. Historically Strudel would + * use `useRNG('legacy')`, which remains the default. To use a new more statistically + * precise RNG, try `useRNG('precise')`. * - * @name useOldRandom - * @param {boolean} b - Whether to use old RNG + * @name useRNG + * @param {string} mod - Mode. One of 'legacy', 'precise' * @example - * useOldRandom(true) + * useRNG('legacy') * // Repeats every 300 cycles * $: n(irand(50)).seg(16).scale("C:minor").ribbon(88, 32) * $: n(irand(50)).seg(16).scale("C:minor").ribbon(388, 32) */ -export const useOldRandom = (b = true) => (useOldRandomBool = b); +export const useRNG = (mode = 'legacy') => (RNG_MODE = mode); /** * A discrete pattern of numbers from 0 to n-1 diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index b26823a9b..481315873 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -677,17 +677,17 @@ exports[`runs examples > example "almostAlways" example index 0 1`] = ` "[ 1/2 → 5/8 | s:hh speed:0.5 ]", "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh ]", + "[ 7/8 → 1/1 | s:hh speed:0.5 ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", "[ 9/8 → 5/4 | s:hh speed:0.5 ]", - "[ 5/4 → 11/8 | s:hh ]", + "[ 5/4 → 11/8 | s:hh speed:0.5 ]", "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh speed:0.5 ]", "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh speed:0.5 ]", - "[ 2/1 → 17/8 | s:hh speed:0.5 ]", - "[ 17/8 → 9/4 | s:hh speed:0.5 ]", + "[ 2/1 → 17/8 | s:hh ]", + "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh speed:0.5 ]", "[ 19/8 → 5/2 | s:hh speed:0.5 ]", "[ 5/2 → 21/8 | s:hh speed:0.5 ]", @@ -699,7 +699,7 @@ exports[`runs examples > example "almostAlways" example index 0 1`] = ` "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", - "[ 29/8 → 15/4 | s:hh speed:0.5 ]", + "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh speed:0.5 ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] @@ -707,7 +707,7 @@ exports[`runs examples > example "almostAlways" example index 0 1`] = ` exports[`runs examples > example "almostNever" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh ]", + "[ 0/1 → 1/8 | s:hh speed:0.5 ]", "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", @@ -716,9 +716,9 @@ exports[`runs examples > example "almostNever" example index 0 1`] = ` "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", - "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh speed:0.5 ]", + "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", @@ -730,11 +730,11 @@ exports[`runs examples > example "almostNever" example index 0 1`] = ` "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", + "[ 23/8 → 3/1 | s:hh speed:0.5 ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh speed:0.5 ]", + "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh ]", @@ -1078,70 +1078,70 @@ exports[`runs examples > example "begin" example index 0 1`] = ` exports[`runs examples > example "berlin" example index 0 1`] = ` [ - "[ 0/1 → 1/16 | note:G3 ]", - "[ 1/16 → 1/8 | note:G3 ]", - "[ 1/8 → 3/16 | note:A3 ]", - "[ 3/16 → 1/4 | note:A3 ]", - "[ 1/4 → 5/16 | note:E3 ]", - "[ 5/16 → 3/8 | note:F3 ]", - "[ 3/8 → 7/16 | note:G3 ]", - "[ 7/16 → 1/2 | note:A3 ]", - "[ 1/2 → 9/16 | note:Bb3 ]", - "[ 9/16 → 5/8 | note:C4 ]", - "[ 5/8 → 11/16 | note:D4 ]", + "[ 0/1 → 1/16 | note:D3 ]", + "[ 1/16 → 1/8 | note:E3 ]", + "[ 1/8 → 3/16 | note:F3 ]", + "[ 3/16 → 1/4 | note:G3 ]", + "[ 1/4 → 5/16 | note:A3 ]", + "[ 5/16 → 3/8 | note:C4 ]", + "[ 3/8 → 7/16 | note:D4 ]", + "[ 7/16 → 1/2 | note:F4 ]", + "[ 1/2 → 9/16 | note:D4 ]", + "[ 9/16 → 5/8 | note:E4 ]", + "[ 5/8 → 11/16 | note:E4 ]", "[ 11/16 → 3/4 | note:E4 ]", - "[ 3/4 → 13/16 | note:Bb3 ]", - "[ 13/16 → 7/8 | note:Bb3 ]", - "[ 7/8 → 15/16 | note:Bb3 ]", - "[ 15/16 → 1/1 | note:C4 ]", + "[ 3/4 → 13/16 | note:F3 ]", + "[ 13/16 → 7/8 | note:F3 ]", + "[ 7/8 → 15/16 | note:F3 ]", + "[ 15/16 → 1/1 | note:F3 ]", "[ 1/1 → 17/16 | note:E3 ]", - "[ 17/16 → 9/8 | note:G3 ]", - "[ 9/8 → 19/16 | note:A3 ]", - "[ 19/16 → 5/4 | note:C4 ]", - "[ 5/4 → 21/16 | note:C4 ]", - "[ 21/16 → 11/8 | note:D4 ]", - "[ 11/8 → 23/16 | note:D4 ]", - "[ 23/16 → 3/2 | note:E4 ]", - "[ 3/2 → 25/16 | note:F3 ]", - "[ 25/16 → 13/8 | note:A3 ]", + "[ 17/16 → 9/8 | note:E3 ]", + "[ 9/8 → 19/16 | note:E3 ]", + "[ 19/16 → 5/4 | note:F3 ]", + "[ 5/4 → 21/16 | note:E3 ]", + "[ 21/16 → 11/8 | note:F3 ]", + "[ 11/8 → 23/16 | note:G3 ]", + "[ 23/16 → 3/2 | note:A3 ]", + "[ 3/2 → 25/16 | note:A3 ]", + "[ 25/16 → 13/8 | note:Bb3 ]", "[ 13/8 → 27/16 | note:Bb3 ]", - "[ 27/16 → 7/4 | note:D4 ]", - "[ 7/4 → 29/16 | note:C4 ]", - "[ 29/16 → 15/8 | note:D4 ]", - "[ 15/8 → 31/16 | note:E4 ]", - "[ 31/16 → 2/1 | note:F4 ]", - "[ 2/1 → 33/16 | note:Bb3 ]", - "[ 33/16 → 17/8 | note:C4 ]", - "[ 17/8 → 35/16 | note:D4 ]", - "[ 35/16 → 9/4 | note:E4 ]", + "[ 27/16 → 7/4 | note:Bb3 ]", + "[ 7/4 → 29/16 | note:F3 ]", + "[ 29/16 → 15/8 | note:G3 ]", + "[ 15/8 → 31/16 | note:Bb3 ]", + "[ 31/16 → 2/1 | note:C4 ]", + "[ 2/1 → 33/16 | note:C4 ]", + "[ 33/16 → 17/8 | note:D4 ]", + "[ 17/8 → 35/16 | note:F4 ]", + "[ 35/16 → 9/4 | note:G4 ]", "[ 9/4 → 37/16 | note:Bb3 ]", - "[ 37/16 → 19/8 | note:C4 ]", - "[ 19/8 → 39/16 | note:D4 ]", - "[ 39/16 → 5/2 | note:F4 ]", - "[ 5/2 → 41/16 | note:C4 ]", - "[ 41/16 → 21/8 | note:D4 ]", - "[ 21/8 → 43/16 | note:F4 ]", - "[ 43/16 → 11/4 | note:A4 ]", - "[ 11/4 → 45/16 | note:D4 ]", - "[ 45/16 → 23/8 | note:F4 ]", - "[ 23/8 → 47/16 | note:G4 ]", - "[ 47/16 → 3/1 | note:A4 ]", - "[ 3/1 → 49/16 | note:C4 ]", - "[ 49/16 → 25/8 | note:C4 ]", - "[ 25/8 → 51/16 | note:C4 ]", - "[ 51/16 → 13/4 | note:D4 ]", - "[ 13/4 → 53/16 | note:F3 ]", - "[ 53/16 → 27/8 | note:F3 ]", - "[ 27/8 → 55/16 | note:F3 ]", - "[ 55/16 → 7/2 | note:F3 ]", - "[ 7/2 → 57/16 | note:E3 ]", - "[ 57/16 → 29/8 | note:E3 ]", - "[ 29/8 → 59/16 | note:F3 ]", - "[ 59/16 → 15/4 | note:F3 ]", + "[ 37/16 → 19/8 | note:Bb3 ]", + "[ 19/8 → 39/16 | note:Bb3 ]", + "[ 39/16 → 5/2 | note:C4 ]", + "[ 5/2 → 41/16 | note:F3 ]", + "[ 41/16 → 21/8 | note:F3 ]", + "[ 21/8 → 43/16 | note:G3 ]", + "[ 43/16 → 11/4 | note:A3 ]", + "[ 11/4 → 45/16 | note:A3 ]", + "[ 45/16 → 23/8 | note:A3 ]", + "[ 23/8 → 47/16 | note:A3 ]", + "[ 47/16 → 3/1 | note:A3 ]", + "[ 3/1 → 49/16 | note:E3 ]", + "[ 49/16 → 25/8 | note:G3 ]", + "[ 25/8 → 51/16 | note:Bb3 ]", + "[ 51/16 → 13/4 | note:C4 ]", + "[ 13/4 → 53/16 | note:D4 ]", + "[ 53/16 → 27/8 | note:E4 ]", + "[ 27/8 → 55/16 | note:G4 ]", + "[ 55/16 → 7/2 | note:A4 ]", + "[ 7/2 → 57/16 | note:Bb3 ]", + "[ 57/16 → 29/8 | note:Bb3 ]", + "[ 29/8 → 59/16 | note:C4 ]", + "[ 59/16 → 15/4 | note:C4 ]", "[ 15/4 → 61/16 | note:F3 ]", - "[ 61/16 → 31/8 | note:F3 ]", - "[ 31/8 → 63/16 | note:F3 ]", - "[ 63/16 → 4/1 | note:G3 ]", + "[ 61/16 → 31/8 | note:G3 ]", + "[ 31/8 → 63/16 | note:G3 ]", + "[ 63/16 → 4/1 | note:A3 ]", ] `; @@ -1525,50 +1525,50 @@ exports[`runs examples > example "brand" example index 0 1`] = ` "[ 0/1 → 1/10 | s:hh pan:true ]", "[ 1/10 → 1/5 | s:hh pan:true ]", "[ 1/5 → 3/10 | s:hh pan:false ]", - "[ 3/10 → 2/5 | s:hh pan:true ]", + "[ 3/10 → 2/5 | s:hh pan:false ]", "[ 2/5 → 1/2 | s:hh pan:false ]", "[ 1/2 → 3/5 | s:hh pan:true ]", - "[ 3/5 → 7/10 | s:hh pan:true ]", - "[ 7/10 → 4/5 | s:hh pan:true ]", + "[ 3/5 → 7/10 | s:hh pan:false ]", + "[ 7/10 → 4/5 | s:hh pan:false ]", "[ 4/5 → 9/10 | s:hh pan:true ]", "[ 9/10 → 1/1 | s:hh pan:false ]", - "[ 1/1 → 11/10 | s:hh pan:true ]", - "[ 11/10 → 6/5 | s:hh pan:true ]", - "[ 6/5 → 13/10 | s:hh pan:false ]", + "[ 1/1 → 11/10 | s:hh pan:false ]", + "[ 11/10 → 6/5 | s:hh pan:false ]", + "[ 6/5 → 13/10 | s:hh pan:true ]", "[ 13/10 → 7/5 | s:hh pan:true ]", - "[ 7/5 → 3/2 | s:hh pan:false ]", - "[ 3/2 → 8/5 | s:hh pan:true ]", - "[ 8/5 → 17/10 | s:hh pan:false ]", + "[ 7/5 → 3/2 | s:hh pan:true ]", + "[ 3/2 → 8/5 | s:hh pan:false ]", + "[ 8/5 → 17/10 | s:hh pan:true ]", "[ 17/10 → 9/5 | s:hh pan:true ]", - "[ 9/5 → 19/10 | s:hh pan:false ]", + "[ 9/5 → 19/10 | s:hh pan:true ]", "[ 19/10 → 2/1 | s:hh pan:true ]", "[ 2/1 → 21/10 | s:hh pan:false ]", "[ 21/10 → 11/5 | s:hh pan:true ]", "[ 11/5 → 23/10 | s:hh pan:false ]", - "[ 23/10 → 12/5 | s:hh pan:true ]", + "[ 23/10 → 12/5 | s:hh pan:false ]", "[ 12/5 → 5/2 | s:hh pan:false ]", - "[ 5/2 → 13/5 | s:hh pan:false ]", - "[ 13/5 → 27/10 | s:hh pan:false ]", + "[ 5/2 → 13/5 | s:hh pan:true ]", + "[ 13/5 → 27/10 | s:hh pan:true ]", "[ 27/10 → 14/5 | s:hh pan:true ]", "[ 14/5 → 29/10 | s:hh pan:false ]", - "[ 29/10 → 3/1 | s:hh pan:false ]", - "[ 3/1 → 31/10 | s:hh pan:false ]", + "[ 29/10 → 3/1 | s:hh pan:true ]", + "[ 3/1 → 31/10 | s:hh pan:true ]", "[ 31/10 → 16/5 | s:hh pan:true ]", "[ 16/5 → 33/10 | s:hh pan:true ]", "[ 33/10 → 17/5 | s:hh pan:false ]", - "[ 17/5 → 7/2 | s:hh pan:true ]", + "[ 17/5 → 7/2 | s:hh pan:false ]", "[ 7/2 → 18/5 | s:hh pan:true ]", - "[ 18/5 → 37/10 | s:hh pan:true ]", - "[ 37/10 → 19/5 | s:hh pan:true ]", - "[ 19/5 → 39/10 | s:hh pan:false ]", + "[ 18/5 → 37/10 | s:hh pan:false ]", + "[ 37/10 → 19/5 | s:hh pan:false ]", + "[ 19/5 → 39/10 | s:hh pan:true ]", "[ 39/10 → 4/1 | s:hh pan:true ]", ] `; exports[`runs examples > example "brandBy" example index 0 1`] = ` [ - "[ 0/1 → 1/10 | s:hh pan:false ]", - "[ 1/10 → 1/5 | s:hh pan:false ]", + "[ 0/1 → 1/10 | s:hh pan:true ]", + "[ 1/10 → 1/5 | s:hh pan:true ]", "[ 1/5 → 3/10 | s:hh pan:false ]", "[ 3/10 → 2/5 | s:hh pan:false ]", "[ 2/5 → 1/2 | s:hh pan:false ]", @@ -1577,18 +1577,18 @@ exports[`runs examples > example "brandBy" example index 0 1`] = ` "[ 7/10 → 4/5 | s:hh pan:false ]", "[ 4/5 → 9/10 | s:hh pan:false ]", "[ 9/10 → 1/1 | s:hh pan:false ]", - "[ 1/1 → 11/10 | s:hh pan:true ]", + "[ 1/1 → 11/10 | s:hh pan:false ]", "[ 11/10 → 6/5 | s:hh pan:false ]", "[ 6/5 → 13/10 | s:hh pan:false ]", - "[ 13/10 → 7/5 | s:hh pan:true ]", + "[ 13/10 → 7/5 | s:hh pan:false ]", "[ 7/5 → 3/2 | s:hh pan:false ]", - "[ 3/2 → 8/5 | s:hh pan:true ]", + "[ 3/2 → 8/5 | s:hh pan:false ]", "[ 8/5 → 17/10 | s:hh pan:false ]", "[ 17/10 → 9/5 | s:hh pan:false ]", "[ 9/5 → 19/10 | s:hh pan:false ]", - "[ 19/10 → 2/1 | s:hh pan:false ]", + "[ 19/10 → 2/1 | s:hh pan:true ]", "[ 2/1 → 21/10 | s:hh pan:false ]", - "[ 21/10 → 11/5 | s:hh pan:true ]", + "[ 21/10 → 11/5 | s:hh pan:false ]", "[ 11/5 → 23/10 | s:hh pan:false ]", "[ 23/10 → 12/5 | s:hh pan:false ]", "[ 12/5 → 5/2 | s:hh pan:false ]", @@ -1599,14 +1599,14 @@ exports[`runs examples > example "brandBy" example index 0 1`] = ` "[ 29/10 → 3/1 | s:hh pan:false ]", "[ 3/1 → 31/10 | s:hh pan:false ]", "[ 31/10 → 16/5 | s:hh pan:true ]", - "[ 16/5 → 33/10 | s:hh pan:false ]", + "[ 16/5 → 33/10 | s:hh pan:true ]", "[ 33/10 → 17/5 | s:hh pan:false ]", "[ 17/5 → 7/2 | s:hh pan:false ]", "[ 7/2 → 18/5 | s:hh pan:false ]", "[ 18/5 → 37/10 | s:hh pan:false ]", "[ 37/10 → 19/5 | s:hh pan:false ]", - "[ 19/5 → 39/10 | s:hh pan:false ]", - "[ 39/10 → 4/1 | s:hh pan:true ]", + "[ 19/5 → 39/10 | s:hh pan:true ]", + "[ 39/10 → 4/1 | s:hh pan:false ]", ] `; @@ -1737,100 +1737,100 @@ exports[`runs examples > example "channels" example index 0 1`] = ` exports[`runs examples > example "choose" example index 0 1`] = ` [ - "[ 0/1 → 1/5 | note:c2 s:triangle ]", - "[ 1/5 → 2/5 | note:g2 s:triangle ]", + "[ 0/1 → 1/5 | note:c2 s:sine ]", + "[ 1/5 → 2/5 | note:g2 s:bd n:6 ]", "[ 2/5 → 3/5 | note:g2 s:triangle ]", - "[ 3/5 → 4/5 | note:d2 s:sine ]", - "[ 4/5 → 1/1 | note:f1 s:triangle ]", - "[ 1/1 → 6/5 | note:c2 s:sine ]", + "[ 3/5 → 4/5 | note:d2 s:bd n:6 ]", + "[ 4/5 → 1/1 | note:f1 s:sine ]", + "[ 1/1 → 6/5 | note:c2 s:triangle ]", "[ 6/5 → 7/5 | note:g2 s:triangle ]", - "[ 7/5 → 8/5 | note:g2 s:bd n:6 ]", + "[ 7/5 → 8/5 | note:g2 s:sine ]", "[ 8/5 → 9/5 | note:d2 s:triangle ]", - "[ 9/5 → 2/1 | note:f1 s:triangle ]", - "[ 2/1 → 11/5 | note:c2 s:triangle ]", + "[ 9/5 → 2/1 | note:f1 s:sine ]", + "[ 2/1 → 11/5 | note:c2 s:bd n:6 ]", "[ 11/5 → 12/5 | note:g2 s:bd n:6 ]", "[ 12/5 → 13/5 | note:g2 s:bd n:6 ]", - "[ 13/5 → 14/5 | note:d2 s:bd n:6 ]", - "[ 14/5 → 3/1 | note:f1 s:bd n:6 ]", - "[ 3/1 → 16/5 | note:c2 s:triangle ]", - "[ 16/5 → 17/5 | note:g2 s:triangle ]", - "[ 17/5 → 18/5 | note:g2 s:sine ]", + "[ 13/5 → 14/5 | note:d2 s:sine ]", + "[ 14/5 → 3/1 | note:f1 s:triangle ]", + "[ 3/1 → 16/5 | note:c2 s:sine ]", + "[ 16/5 → 17/5 | note:g2 s:sine ]", + "[ 17/5 → 18/5 | note:g2 s:triangle ]", "[ 18/5 → 19/5 | note:d2 s:triangle ]", - "[ 19/5 → 4/1 | note:f1 s:bd n:6 ]", + "[ 19/5 → 4/1 | note:f1 s:sine ]", ] `; exports[`runs examples > example "chooseCycles" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh ]", - "[ 1/8 → 1/4 | s:bd ]", - "[ 1/4 → 3/8 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", + "[ 0/1 → 1/8 | s:bd ]", + "[ 1/8 → 1/4 | s:hh ]", + "[ 1/4 → 3/8 | s:sd ]", + "[ 3/8 → 1/2 | s:bd ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:sd ]", - "[ 3/4 → 7/8 | s:bd ]", - "[ 7/8 → 1/1 | s:sd ]", - "[ 1/1 → 9/8 | s:hh ]", + "[ 5/8 → 3/4 | s:bd ]", + "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:bd ]", + "[ 1/1 → 9/8 | s:sd ]", "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:sd ]", - "[ 11/8 → 3/2 | s:sd ]", - "[ 3/2 → 13/8 | s:sd ]", - "[ 13/8 → 7/4 | s:bd ]", - "[ 7/4 → 15/8 | s:bd ]", + "[ 5/4 → 11/8 | s:bd ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:bd ]", + "[ 13/8 → 7/4 | s:sd ]", + "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:bd ]", "[ 2/1 → 17/8 | s:bd ]", "[ 17/8 → 9/4 | s:sd ]", "[ 9/4 → 19/8 | s:sd ]", - "[ 19/8 → 5/2 | s:sd ]", - "[ 5/2 → 21/8 | s:bd ]", - "[ 21/8 → 11/4 | s:hh ]", + "[ 19/8 → 5/2 | s:bd ]", + "[ 5/2 → 21/8 | s:hh ]", + "[ 21/8 → 11/4 | s:bd ]", "[ 11/4 → 23/8 | s:sd ]", - "[ 23/8 → 3/1 | s:sd ]", - "[ 3/1 → 25/8 | s:hh ]", + "[ 23/8 → 3/1 | s:bd ]", + "[ 3/1 → 25/8 | s:sd ]", "[ 25/8 → 13/4 | s:sd ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 13/4 → 27/8 | s:bd ]", "[ 27/8 → 7/2 | s:bd ]", - "[ 7/2 → 29/8 | s:sd ]", + "[ 7/2 → 29/8 | s:bd ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:bd ]", - "[ 31/8 → 4/1 | s:sd ]", + "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:bd ]", ] `; exports[`runs examples > example "chooseCycles" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | s:hh ]", - "[ 1/8 → 1/4 | s:bd ]", - "[ 1/4 → 3/8 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", + "[ 0/1 → 1/8 | s:bd ]", + "[ 1/8 → 1/4 | s:hh ]", + "[ 1/4 → 3/8 | s:sd ]", + "[ 3/8 → 1/2 | s:bd ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:sd ]", - "[ 3/4 → 7/8 | s:bd ]", - "[ 7/8 → 1/1 | s:sd ]", - "[ 1/1 → 9/8 | s:hh ]", + "[ 5/8 → 3/4 | s:bd ]", + "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:bd ]", + "[ 1/1 → 9/8 | s:sd ]", "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:sd ]", - "[ 11/8 → 3/2 | s:sd ]", - "[ 3/2 → 13/8 | s:sd ]", - "[ 13/8 → 7/4 | s:bd ]", - "[ 7/4 → 15/8 | s:bd ]", + "[ 5/4 → 11/8 | s:bd ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:bd ]", + "[ 13/8 → 7/4 | s:sd ]", + "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:bd ]", "[ 2/1 → 17/8 | s:bd ]", "[ 17/8 → 9/4 | s:sd ]", "[ 9/4 → 19/8 | s:sd ]", - "[ 19/8 → 5/2 | s:sd ]", - "[ 5/2 → 21/8 | s:bd ]", - "[ 21/8 → 11/4 | s:hh ]", + "[ 19/8 → 5/2 | s:bd ]", + "[ 5/2 → 21/8 | s:hh ]", + "[ 21/8 → 11/4 | s:bd ]", "[ 11/4 → 23/8 | s:sd ]", - "[ 23/8 → 3/1 | s:sd ]", - "[ 3/1 → 25/8 | s:hh ]", + "[ 23/8 → 3/1 | s:bd ]", + "[ 3/1 → 25/8 | s:sd ]", "[ 25/8 → 13/4 | s:sd ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 13/4 → 27/8 | s:bd ]", "[ 27/8 → 7/2 | s:bd ]", - "[ 7/2 → 29/8 | s:sd ]", + "[ 7/2 → 29/8 | s:bd ]", "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:bd ]", - "[ 31/8 → 4/1 | s:sd ]", + "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:bd ]", ] `; @@ -2494,57 +2494,81 @@ exports[`runs examples > example "decay" example index 0 1`] = ` exports[`runs examples > example "degrade" example index 0 1`] = ` [ "[ 1/8 → 1/4 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 7/8 → 1/1 | s:hh ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", - "[ 13/8 → 7/4 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", + "[ 17/8 → 9/4 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 5/2 → 21/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 25/8 → 13/4 | s:hh ]", + "[ 11/4 → 23/8 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; exports[`runs examples > example "degrade" example index 1 1`] = ` [ + "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 7/8 → 1/1 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", - "[ 3/2 → 13/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", + "[ 7/4 → 15/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh ]", - "[ 19/8 → 5/2 | s:hh ]", + "[ 5/2 → 21/8 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 7/2 → 29/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", ] `; exports[`runs examples > example "degradeBy" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", + "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", "[ 7/8 → 1/1 | s:hh ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", + "[ 7/4 → 15/8 | s:hh ]", + "[ 15/8 → 2/1 | s:hh ]", + "[ 2/1 → 17/8 | s:hh ]", + "[ 17/8 → 9/4 | s:hh ]", + "[ 9/4 → 19/8 | s:hh ]", + "[ 19/8 → 5/2 | s:hh ]", + "[ 5/2 → 21/8 | s:hh ]", + "[ 11/4 → 23/8 | s:hh ]", + "[ 3/1 → 25/8 | s:hh ]", + "[ 25/8 → 13/4 | s:hh ]", + "[ 13/4 → 27/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh ]", + "[ 7/2 → 29/8 | s:hh ]", + "[ 29/8 → 15/4 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", + "[ 31/8 → 4/1 | s:hh ]", +] +`; + +exports[`runs examples > example "degradeBy" example index 1 1`] = ` +[ + "[ 1/8 → 1/4 | s:hh ]", + "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", + "[ 3/4 → 7/8 | s:hh ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", @@ -2555,79 +2579,45 @@ exports[`runs examples > example "degradeBy" example index 0 1`] = ` "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", + "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh ]", ] `; -exports[`runs examples > example "degradeBy" example index 1 1`] = ` -[ - "[ 0/1 → 1/8 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", - "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh ]", - "[ 9/8 → 5/4 | s:hh ]", - "[ 5/4 → 11/8 | s:hh ]", - "[ 11/8 → 3/2 | s:hh ]", - "[ 3/2 → 13/8 | s:hh ]", - "[ 15/8 → 2/1 | s:hh ]", - "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", - "[ 19/8 → 5/2 | s:hh ]", - "[ 21/8 → 11/4 | s:hh ]", - "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", - "[ 7/2 → 29/8 | s:hh ]", - "[ 29/8 → 15/4 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", -] -`; - exports[`runs examples > example "degradeBy" example index 2 1`] = ` [ - "[ 1/16 → 1/8 | s:bd ]", "[ 1/8 → 3/16 | s:bd ]", - "[ 3/16 → 1/4 | s:bd ]", + "[ 1/4 → 5/16 | s:bd ]", "[ 5/16 → 3/8 | s:bd ]", - "[ 3/8 → 7/16 | s:bd ]", "[ 1/2 → 9/16 | s:bd ]", - "[ 13/16 → 7/8 | s:bd ]", - "[ 7/8 → 15/16 | s:bd ]", - "[ 17/16 → 9/8 | s:bd ]", + "[ 9/16 → 5/8 | s:bd ]", + "[ 11/16 → 3/4 | s:bd ]", + "[ 15/16 → 1/1 | s:bd ]", "[ 9/8 → 19/16 | s:bd ]", - "[ 19/16 → 5/4 | s:bd ]", + "[ 5/4 → 21/16 | s:bd ]", "[ 21/16 → 11/8 | s:bd ]", - "[ 11/8 → 23/16 | s:bd ]", "[ 3/2 → 25/16 | s:bd ]", - "[ 29/16 → 15/8 | s:bd ]", - "[ 15/8 → 31/16 | s:bd ]", - "[ 33/16 → 17/8 | s:bd ]", + "[ 25/16 → 13/8 | s:bd ]", + "[ 27/16 → 7/4 | s:bd ]", + "[ 31/16 → 2/1 | s:bd ]", "[ 17/8 → 35/16 | s:bd ]", - "[ 35/16 → 9/4 | s:bd ]", + "[ 9/4 → 37/16 | s:bd ]", "[ 37/16 → 19/8 | s:bd ]", - "[ 19/8 → 39/16 | s:bd ]", "[ 5/2 → 41/16 | s:bd ]", - "[ 45/16 → 23/8 | s:bd ]", - "[ 23/8 → 47/16 | s:bd ]", - "[ 49/16 → 25/8 | s:bd ]", + "[ 41/16 → 21/8 | s:bd ]", + "[ 43/16 → 11/4 | s:bd ]", + "[ 47/16 → 3/1 | s:bd ]", "[ 25/8 → 51/16 | s:bd ]", - "[ 51/16 → 13/4 | s:bd ]", + "[ 13/4 → 53/16 | s:bd ]", "[ 53/16 → 27/8 | s:bd ]", - "[ 27/8 → 55/16 | s:bd ]", "[ 7/2 → 57/16 | s:bd ]", - "[ 61/16 → 31/8 | s:bd ]", - "[ 31/8 → 63/16 | s:bd ]", + "[ 57/16 → 29/8 | s:bd ]", + "[ 59/16 → 15/4 | s:bd ]", + "[ 63/16 → 4/1 | s:bd ]", ] `; @@ -2950,14 +2940,14 @@ exports[`runs examples > example "distorttype" example index 0 1`] = ` exports[`runs examples > example "distorttype" example index 1 1`] = ` [ - "[ (0/1 → 1/2) ⇝ 1/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:3.71662513515912 distorttype:fold ]", - "[ 0/1 ⇜ (1/2 → 1/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:3.71662513515912 distorttype:fold ]", - "[ (1/1 → 3/2) ⇝ 2/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1.8276505067478865 distorttype:chebyshev ]", - "[ 1/1 ⇜ (3/2 → 2/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1.8276505067478865 distorttype:chebyshev ]", - "[ (2/1 → 5/2) ⇝ 3/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.068953953683376 distorttype:scurve ]", - "[ 2/1 ⇜ (5/2 → 3/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.068953953683376 distorttype:scurve ]", - "[ (3/1 → 7/2) ⇝ 4/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.303743980126455 distorttype:diode ]", - "[ 3/1 ⇜ (7/2 → 4/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:5.303743980126455 distorttype:diode ]", + "[ (0/1 → 1/2) ⇝ 1/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1 distorttype:fold ]", + "[ 0/1 ⇜ (1/2 → 1/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:1 distorttype:fold ]", + "[ (1/1 → 3/2) ⇝ 2/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:4.6367951557040215 distorttype:chebyshev ]", + "[ 1/1 ⇜ (3/2 → 2/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:4.6367951557040215 distorttype:chebyshev ]", + "[ (2/1 → 5/2) ⇝ 3/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:7.716689839959145 distorttype:scurve ]", + "[ 2/1 ⇜ (5/2 → 3/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:7.716689839959145 distorttype:scurve ]", + "[ (3/1 → 7/2) ⇝ 4/1 | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:2.5210237745195627 distorttype:diode ]", + "[ 3/1 ⇜ (7/2 → 4/1) | s:sine note:F1 release:1 penv:24 pdecay:0.05 distort:2.5210237745195627 distorttype:diode ]", ] `; @@ -2984,38 +2974,38 @@ exports[`runs examples > example "distortvol" example index 0 1`] = ` exports[`runs examples > example "djf" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | note:C4 s:supersaw djf:0.5 ]", + "[ 0/1 → 1/8 | note:D3 s:supersaw djf:0.5 ]", "[ 1/8 → 1/4 | note:G4 s:supersaw djf:0.5 ]", - "[ 1/4 → 3/8 | note:F3 s:supersaw djf:0.5 ]", - "[ 3/8 → 1/2 | note:C5 s:supersaw djf:0.5 ]", - "[ 1/2 → 5/8 | note:Bb3 s:supersaw djf:0.5 ]", - "[ 5/8 → 3/4 | note:A4 s:supersaw djf:0.5 ]", - "[ 3/4 → 7/8 | note:A3 s:supersaw djf:0.5 ]", - "[ 7/8 → 1/1 | note:D5 s:supersaw djf:0.5 ]", - "[ 1/1 → 9/8 | note:Eb3 s:supersaw djf:0.3 ]", - "[ 9/8 → 5/4 | note:D3 s:supersaw djf:0.3 ]", - "[ 5/4 → 11/8 | note:Eb5 s:supersaw djf:0.3 ]", - "[ 11/8 → 3/2 | note:D3 s:supersaw djf:0.3 ]", - "[ 3/2 → 13/8 | note:F3 s:supersaw djf:0.3 ]", - "[ 13/8 → 7/4 | note:G4 s:supersaw djf:0.3 ]", - "[ 7/4 → 15/8 | note:Bb3 s:supersaw djf:0.3 ]", - "[ 15/8 → 2/1 | note:G4 s:supersaw djf:0.3 ]", - "[ 2/1 → 17/8 | note:F4 s:supersaw djf:0.2 ]", - "[ 17/8 → 9/4 | note:D4 s:supersaw djf:0.2 ]", - "[ 9/4 → 19/8 | note:G3 s:supersaw djf:0.2 ]", + "[ 1/4 → 3/8 | note:Bb3 s:supersaw djf:0.5 ]", + "[ 3/8 → 1/2 | note:C4 s:supersaw djf:0.5 ]", + "[ 1/2 → 5/8 | note:A3 s:supersaw djf:0.5 ]", + "[ 5/8 → 3/4 | note:F3 s:supersaw djf:0.5 ]", + "[ 3/4 → 7/8 | note:G3 s:supersaw djf:0.5 ]", + "[ 7/8 → 1/1 | note:C4 s:supersaw djf:0.5 ]", + "[ 1/1 → 9/8 | note:Eb4 s:supersaw djf:0.3 ]", + "[ 9/8 → 5/4 | note:G4 s:supersaw djf:0.3 ]", + "[ 5/4 → 11/8 | note:A4 s:supersaw djf:0.3 ]", + "[ 11/8 → 3/2 | note:F3 s:supersaw djf:0.3 ]", + "[ 3/2 → 13/8 | note:F4 s:supersaw djf:0.3 ]", + "[ 13/8 → 7/4 | note:D4 s:supersaw djf:0.3 ]", + "[ 7/4 → 15/8 | note:G3 s:supersaw djf:0.3 ]", + "[ 15/8 → 2/1 | note:F4 s:supersaw djf:0.3 ]", + "[ 2/1 → 17/8 | note:Eb5 s:supersaw djf:0.2 ]", + "[ 17/8 → 9/4 | note:D5 s:supersaw djf:0.2 ]", + "[ 9/4 → 19/8 | note:Bb3 s:supersaw djf:0.2 ]", "[ 19/8 → 5/2 | note:C5 s:supersaw djf:0.2 ]", - "[ 5/2 → 21/8 | note:A4 s:supersaw djf:0.2 ]", - "[ 21/8 → 11/4 | note:Bb3 s:supersaw djf:0.2 ]", - "[ 11/4 → 23/8 | note:Bb3 s:supersaw djf:0.2 ]", - "[ 23/8 → 3/1 | note:C5 s:supersaw djf:0.2 ]", - "[ 3/1 → 25/8 | note:F4 s:supersaw djf:0.75 ]", - "[ 25/8 → 13/4 | note:F4 s:supersaw djf:0.75 ]", - "[ 13/4 → 27/8 | note:D5 s:supersaw djf:0.75 ]", - "[ 27/8 → 7/2 | note:D3 s:supersaw djf:0.75 ]", - "[ 7/2 → 29/8 | note:G3 s:supersaw djf:0.75 ]", - "[ 29/8 → 15/4 | note:F4 s:supersaw djf:0.75 ]", - "[ 15/4 → 31/8 | note:F4 s:supersaw djf:0.75 ]", - "[ 31/8 → 4/1 | note:F3 s:supersaw djf:0.75 ]", + "[ 5/2 → 21/8 | note:D4 s:supersaw djf:0.2 ]", + "[ 21/8 → 11/4 | note:F3 s:supersaw djf:0.2 ]", + "[ 11/4 → 23/8 | note:G4 s:supersaw djf:0.2 ]", + "[ 23/8 → 3/1 | note:D3 s:supersaw djf:0.2 ]", + "[ 3/1 → 25/8 | note:G3 s:supersaw djf:0.75 ]", + "[ 25/8 → 13/4 | note:Bb3 s:supersaw djf:0.75 ]", + "[ 13/4 → 27/8 | note:Eb5 s:supersaw djf:0.75 ]", + "[ 27/8 → 7/2 | note:C4 s:supersaw djf:0.75 ]", + "[ 7/2 → 29/8 | note:C4 s:supersaw djf:0.75 ]", + "[ 29/8 → 15/4 | note:Eb5 s:supersaw djf:0.75 ]", + "[ 15/4 → 31/8 | note:Bb4 s:supersaw djf:0.75 ]", + "[ 31/8 → 4/1 | note:A4 s:supersaw djf:0.75 ]", ] `; @@ -5173,71 +5163,71 @@ exports[`runs examples > example "invert" example index 0 1`] = ` exports[`runs examples > example "irand" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:F3 ]", - "[ 1/4 → 3/8 | note:D3 ]", - "[ 3/8 → 1/2 | note:Bb3 ]", + "[ 0/1 → 1/4 | note:C3 ]", + "[ 1/4 → 3/8 | note:Eb3 ]", + "[ 3/8 → 1/2 | note:F3 ]", "[ 1/2 → 3/4 | note:Eb3 ]", - "[ 3/4 → 5/6 | note:Eb3 ]", - "[ 5/6 → 11/12 | note:Ab3 ]", - "[ 11/12 → 1/1 | note:D3 ]", - "[ 1/1 → 5/4 | note:C3 ]", - "[ 5/4 → 11/8 | note:C4 ]", - "[ 11/8 → 3/2 | note:C3 ]", - "[ 3/2 → 7/4 | note:D3 ]", - "[ 7/4 → 11/6 | note:Eb3 ]", - "[ 11/6 → 23/12 | note:C3 ]", - "[ 23/12 → 2/1 | note:Ab3 ]", - "[ 2/1 → 9/4 | note:G3 ]", - "[ 9/4 → 19/8 | note:D3 ]", + "[ 3/4 → 5/6 | note:D3 ]", + "[ 5/6 → 11/12 | note:C3 ]", + "[ 11/12 → 1/1 | note:C4 ]", + "[ 1/1 → 5/4 | note:G3 ]", + "[ 5/4 → 11/8 | note:Ab3 ]", + "[ 11/8 → 3/2 | note:D3 ]", + "[ 3/2 → 7/4 | note:G3 ]", + "[ 7/4 → 11/6 | note:D3 ]", + "[ 11/6 → 23/12 | note:Bb3 ]", + "[ 23/12 → 2/1 | note:Eb3 ]", + "[ 2/1 → 9/4 | note:C4 ]", + "[ 9/4 → 19/8 | note:Eb3 ]", "[ 19/8 → 5/2 | note:Bb3 ]", - "[ 5/2 → 11/4 | note:Ab3 ]", - "[ 11/4 → 17/6 | note:Eb3 ]", - "[ 17/6 → 35/12 | note:Ab3 ]", - "[ 35/12 → 3/1 | note:D3 ]", - "[ 3/1 → 13/4 | note:G3 ]", + "[ 5/2 → 11/4 | note:F3 ]", + "[ 11/4 → 17/6 | note:Ab3 ]", + "[ 17/6 → 35/12 | note:D3 ]", + "[ 35/12 → 3/1 | note:F3 ]", + "[ 3/1 → 13/4 | note:D3 ]", "[ 13/4 → 27/8 | note:C4 ]", - "[ 27/8 → 7/2 | note:C3 ]", - "[ 7/2 → 15/4 | note:D3 ]", - "[ 15/4 → 23/6 | note:G3 ]", + "[ 27/8 → 7/2 | note:F3 ]", + "[ 7/2 → 15/4 | note:F3 ]", + "[ 15/4 → 23/6 | note:Bb3 ]", "[ 23/6 → 47/12 | note:Ab3 ]", - "[ 47/12 → 4/1 | note:Ab3 ]", + "[ 47/12 → 4/1 | note:C3 ]", ] `; exports[`runs examples > example "irbegin" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", "[ 1/8 → 1/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.0625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", - "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.5 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0 roomsize:0.6 ]", + "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", "[ 19/8 → 5/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", - "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.75 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", + "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.65 irspeed:-2 irbegin:0.5 roomsize:0.6 ]", ] `; @@ -5264,38 +5254,38 @@ exports[`runs examples > example "iresponse" example index 0 1`] = ` exports[`runs examples > example "irspeed" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 0/1 → 1/8 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", "[ 1/8 → 1/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.0625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", - "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 1/4 → 3/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/8 → 1/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/2 → 5/8 | s:brk speed:0.5 unit:c begin:0.25 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 5/8 → 3/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/4 → 7/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 7/8 → 1/1 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 1/1 → 9/8 | s:brk speed:0.5 unit:c begin:0.5 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 9/8 → 5/4 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 5/4 → 11/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 11/8 → 3/2 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 3/2 → 13/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 13/8 → 7/4 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 7/4 → 15/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 15/8 → 2/1 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:2 irbegin:0.5 roomsize:0.5 ]", + "[ 2/1 → 17/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 17/8 → 9/4 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 9/4 → 19/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", "[ 19/8 → 5/2 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0.8125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.5625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", - "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 5/2 → 21/8 | s:brk speed:0.5 unit:c begin:0.4375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 21/8 → 11/4 | s:brk speed:0.5 unit:c begin:0.125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 11/4 → 23/8 | s:brk speed:0.5 unit:c begin:0.625 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 23/8 → 3/1 | s:brk speed:0.5 unit:c begin:0 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 3/1 → 25/8 | s:brk speed:0.5 unit:c begin:0.1875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 25/8 → 13/4 | s:brk speed:0.5 unit:c begin:0.3125 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 13/4 → 27/8 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 27/8 → 7/2 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 7/2 → 29/8 | s:brk speed:0.5 unit:c begin:0.375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 29/8 → 15/4 | s:brk speed:0.5 unit:c begin:0.9375 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 15/4 → 31/8 | s:brk speed:0.5 unit:c begin:0.75 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", + "[ 31/8 → 4/1 | s:brk speed:0.5 unit:c begin:0.6875 clip:1 ir:swpad i:4 room:0.2 irspeed:1 irbegin:0.5 roomsize:0.5 ]", ] `; @@ -6985,34 +6975,34 @@ exports[`runs examples > example "often" example index 0 1`] = ` "[ 0/1 → 1/8 | s:hh speed:0.5 ]", "[ 1/8 → 1/4 | s:hh speed:0.5 ]", "[ 1/4 → 3/8 | s:hh speed:0.5 ]", - "[ 3/8 → 1/2 | s:hh ]", + "[ 3/8 → 1/2 | s:hh speed:0.5 ]", "[ 1/2 → 5/8 | s:hh speed:0.5 ]", "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh ]", + "[ 7/8 → 1/1 | s:hh speed:0.5 ]", "[ 1/1 → 9/8 | s:hh speed:0.5 ]", "[ 9/8 → 5/4 | s:hh speed:0.5 ]", - "[ 5/4 → 11/8 | s:hh ]", + "[ 5/4 → 11/8 | s:hh speed:0.5 ]", "[ 11/8 → 3/2 | s:hh speed:0.5 ]", "[ 3/2 → 13/8 | s:hh speed:0.5 ]", "[ 13/8 → 7/4 | s:hh speed:0.5 ]", "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh speed:0.5 ]", - "[ 2/1 → 17/8 | s:hh speed:0.5 ]", - "[ 17/8 → 9/4 | s:hh speed:0.5 ]", + "[ 2/1 → 17/8 | s:hh ]", + "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh speed:0.5 ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh speed:0.5 ]", - "[ 23/8 → 3/1 | s:hh ]", + "[ 23/8 → 3/1 | s:hh speed:0.5 ]", "[ 3/1 → 25/8 | s:hh speed:0.5 ]", "[ 25/8 → 13/4 | s:hh speed:0.5 ]", "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", - "[ 29/8 → 15/4 | s:hh speed:0.5 ]", - "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 29/8 → 15/4 | s:hh ]", + "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -7283,54 +7273,54 @@ exports[`runs examples > example "penv" example index 0 1`] = ` exports[`runs examples > example "perlin" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh cutoff:3410.6697876704857 ]", - "[ 0/1 → 1/4 | s:bd cutoff:3410.6697876704857 ]", - "[ 1/8 → 1/4 | s:hh cutoff:3378.181624527514 ]", - "[ 1/4 → 3/8 | s:hh cutoff:3201.164370596416 ]", - "[ 1/4 → 1/2 | s:bd cutoff:3201.164370596416 ]", - "[ 3/8 → 1/2 | s:hh cutoff:2853.676907017785 ]", - "[ 1/2 → 5/8 | s:hh cutoff:2398.7190938787535 ]", - "[ 1/2 → 3/4 | s:bd cutoff:2398.7190938787535 ]", - "[ 5/8 → 3/4 | s:hh cutoff:1943.7612807397215 ]", - "[ 3/4 → 7/8 | s:hh cutoff:1596.2738171610908 ]", - "[ 3/4 → 1/1 | s:bd cutoff:1596.2738171610908 ]", - "[ 7/8 → 1/1 | s:hh cutoff:1419.2565632299932 ]", - "[ 1/1 → 9/8 | s:hh cutoff:1386.7684000870213 ]", - "[ 1/1 → 5/4 | s:bd cutoff:1386.7684000870213 ]", - "[ 9/8 → 5/4 | s:hh cutoff:1442.5150435813734 ]", - "[ 5/4 → 11/8 | s:hh cutoff:1746.2600630772158 ]", - "[ 5/4 → 3/2 | s:bd cutoff:1746.2600630772158 ]", - "[ 11/8 → 3/2 | s:hh cutoff:2342.5159876004573 ]", - "[ 3/2 → 13/8 | s:hh cutoff:3123.1809609453194 ]", - "[ 3/2 → 7/4 | s:bd cutoff:3123.1809609453194 ]", - "[ 13/8 → 7/4 | s:hh cutoff:3903.8459342901815 ]", - "[ 7/4 → 15/8 | s:hh cutoff:4500.101858813423 ]", - "[ 7/4 → 2/1 | s:bd cutoff:4500.101858813423 ]", - "[ 15/8 → 2/1 | s:hh cutoff:4803.846878309266 ]", - "[ 2/1 → 17/8 | s:hh cutoff:4859.5935218036175 ]", - "[ 2/1 → 9/4 | s:bd cutoff:4859.5935218036175 ]", - "[ 17/8 → 9/4 | s:hh cutoff:4863.631636751641 ]", - "[ 9/4 → 19/8 | s:hh cutoff:4885.633989301141 ]", - "[ 9/4 → 5/2 | s:bd cutoff:4885.633989301141 ]", - "[ 19/8 → 5/2 | s:hh cutoff:4928.824929790842 ]", - "[ 5/2 → 21/8 | s:hh cutoff:4985.37389311241 ]", - "[ 5/2 → 11/4 | s:bd cutoff:4985.37389311241 ]", - "[ 21/8 → 11/4 | s:hh cutoff:5041.922856433977 ]", - "[ 11/4 → 23/8 | s:hh cutoff:5085.113796923679 ]", - "[ 11/4 → 3/1 | s:bd cutoff:5085.113796923679 ]", - "[ 23/8 → 3/1 | s:hh cutoff:5107.116149473179 ]", - "[ 3/1 → 25/8 | s:hh cutoff:5111.154264421202 ]", - "[ 3/1 → 13/4 | s:bd cutoff:5111.154264421202 ]", - "[ 25/8 → 13/4 | s:hh cutoff:5054.286698772394 ]", - "[ 13/4 → 27/8 | s:hh cutoff:4744.434145256264 ]", - "[ 13/4 → 7/2 | s:bd cutoff:4744.434145256264 ]", - "[ 27/8 → 7/2 | s:hh cutoff:4136.189041947908 ]", - "[ 7/2 → 29/8 | s:hh cutoff:3339.826896379236 ]", - "[ 7/2 → 15/4 | s:bd cutoff:3339.826896379236 ]", - "[ 29/8 → 15/4 | s:hh cutoff:2543.464750810564 ]", - "[ 15/4 → 31/8 | s:hh cutoff:1935.2196475022083 ]", - "[ 15/4 → 4/1 | s:bd cutoff:1935.2196475022083 ]", - "[ 31/8 → 4/1 | s:hh cutoff:1625.3670939860783 ]", + "[ 0/1 → 1/8 | s:hh cutoff:500 ]", + "[ 0/1 → 1/4 | s:bd cutoff:500 ]", + "[ 1/8 → 1/4 | s:hh cutoff:562.5486401770559 ]", + "[ 1/4 → 3/8 | s:hh cutoff:903.3554895067937 ]", + "[ 1/4 → 1/2 | s:bd cutoff:903.3554895067937 ]", + "[ 3/8 → 1/2 | s:hh cutoff:1572.364329119182 ]", + "[ 1/2 → 5/8 | s:hh cutoff:2448.2831191271544 ]", + "[ 1/2 → 3/4 | s:bd cutoff:2448.2831191271544 ]", + "[ 5/8 → 3/4 | s:hh cutoff:3324.2019091351267 ]", + "[ 3/4 → 7/8 | s:hh cutoff:3993.210748747515 ]", + "[ 3/4 → 1/1 | s:bd cutoff:3993.210748747515 ]", + "[ 7/8 → 1/1 | s:hh cutoff:4334.017598077253 ]", + "[ 1/1 → 9/8 | s:hh cutoff:4396.566238254309 ]", + "[ 1/1 → 5/4 | s:bd cutoff:4396.566238254309 ]", + "[ 9/8 → 5/4 | s:hh cutoff:4449.536839055554 ]", + "[ 5/4 → 11/8 | s:hh cutoff:4738.156120227359 ]", + "[ 5/4 → 3/2 | s:bd cutoff:4738.156120227359 ]", + "[ 11/8 → 3/2 | s:hh cutoff:5304.71999875931 ]", + "[ 3/2 → 13/8 | s:hh cutoff:6046.5098191052675 ]", + "[ 3/2 → 7/4 | s:bd cutoff:6046.5098191052675 ]", + "[ 13/8 → 7/4 | s:hh cutoff:6788.299639451225 ]", + "[ 7/4 → 15/8 | s:hh cutoff:7354.863517983176 ]", + "[ 7/4 → 2/1 | s:bd cutoff:7354.863517983176 ]", + "[ 15/8 → 2/1 | s:hh cutoff:7643.482799154981 ]", + "[ 2/1 → 17/8 | s:hh cutoff:7696.453399956226 ]", + "[ 2/1 → 9/4 | s:bd cutoff:7696.453399956226 ]", + "[ 17/8 → 9/4 | s:hh cutoff:7607.093996059746 ]", + "[ 9/4 → 19/8 | s:hh cutoff:7120.204164182724 ]", + "[ 9/4 → 5/2 | s:bd cutoff:7120.204164182724 ]", + "[ 19/8 → 5/2 | s:hh cutoff:6164.432289046601 ]", + "[ 5/2 → 21/8 | s:hh cutoff:4913.0608648993075 ]", + "[ 5/2 → 11/4 | s:bd cutoff:4913.0608648993075 ]", + "[ 21/8 → 11/4 | s:hh cutoff:3661.6894407520135 ]", + "[ 11/4 → 23/8 | s:hh cutoff:2705.9175656158914 ]", + "[ 11/4 → 3/1 | s:bd cutoff:2705.9175656158914 ]", + "[ 23/8 → 3/1 | s:hh cutoff:2219.0277337388693 ]", + "[ 3/1 → 25/8 | s:hh cutoff:2129.6683298423886 ]", + "[ 3/1 → 13/4 | s:bd cutoff:2129.6683298423886 ]", + "[ 25/8 → 13/4 | s:hh cutoff:2113.2537022102156 ]", + "[ 13/4 → 27/8 | s:hh cutoff:2023.8158261763601 ]", + "[ 13/4 → 7/2 | s:bd cutoff:2023.8158261763601 ]", + "[ 27/8 → 7/2 | s:hh cutoff:1848.2479648482126 ]", + "[ 7/2 → 29/8 | s:hh cutoff:1618.380764964968 ]", + "[ 7/2 → 15/4 | s:bd cutoff:1618.380764964968 ]", + "[ 29/8 → 15/4 | s:hh cutoff:1388.5135650817233 ]", + "[ 15/4 → 31/8 | s:hh cutoff:1212.9457037535758 ]", + "[ 15/4 → 4/1 | s:bd cutoff:1212.9457037535758 ]", + "[ 31/8 → 4/1 | s:hh cutoff:1123.5078277197204 ]", ] `; @@ -8152,54 +8142,54 @@ exports[`runs examples > example "queryArc" example index 0 1`] = `[]`; exports[`runs examples > example "rand" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh cutoff:3410.6697876704857 ]", - "[ 0/1 → 1/4 | s:bd cutoff:3410.6697876704857 ]", - "[ 1/8 → 1/4 | s:hh cutoff:5409.978067153133 ]", - "[ 1/4 → 3/8 | s:hh cutoff:1470.4432229045779 ]", - "[ 1/4 → 1/2 | s:bd cutoff:1470.4432229045779 ]", - "[ 3/8 → 1/2 | s:hh cutoff:6906.840303097852 ]", - "[ 1/2 → 5/8 | s:hh cutoff:2951.713348273188 ]", - "[ 1/2 → 3/4 | s:bd cutoff:2951.713348273188 ]", - "[ 5/8 → 3/4 | s:hh cutoff:5732.849565800279 ]", - "[ 3/4 → 7/8 | s:hh cutoff:2621.97931134142 ]", - "[ 3/4 → 1/1 | s:bd cutoff:2621.97931134142 ]", - "[ 7/8 → 1/1 | s:hh cutoff:7323.85477644857 ]", - "[ 1/1 → 9/8 | s:hh cutoff:1386.7684000870213 ]", - "[ 1/1 → 5/4 | s:bd cutoff:1386.7684000870213 ]", - "[ 9/8 → 5/4 | s:hh cutoff:968.4956459095702 ]", - "[ 5/4 → 11/8 | s:hh cutoff:7674.6532345423475 ]", - "[ 5/4 → 3/2 | s:bd cutoff:7674.6532345423475 ]", - "[ 11/8 → 3/2 | s:hh cutoff:863.651579245925 ]", - "[ 3/2 → 13/8 | s:hh cutoff:1476.3008129084483 ]", - "[ 3/2 → 7/4 | s:bd cutoff:1476.3008129084483 ]", - "[ 13/8 → 7/4 | s:hh cutoff:5232.728436938487 ]", - "[ 7/4 → 15/8 | s:hh cutoff:3057.402160600759 ]", - "[ 7/4 → 2/1 | s:bd cutoff:3057.402160600759 ]", - "[ 15/8 → 2/1 | s:hh cutoff:5307.644687825814 ]", - "[ 2/1 → 17/8 | s:hh cutoff:4859.5935218036175 ]", - "[ 2/1 → 9/4 | s:bd cutoff:4859.5935218036175 ]", - "[ 17/8 → 9/4 | s:hh cutoff:3798.551473999396 ]", - "[ 9/4 → 19/8 | s:hh cutoff:2020.6333762034774 ]", - "[ 9/4 → 5/2 | s:bd cutoff:2020.6333762034774 ]", - "[ 19/8 → 5/2 | s:hh cutoff:6903.368854080327 ]", - "[ 5/2 → 21/8 | s:hh cutoff:5992.341757635586 ]", - "[ 5/2 → 11/4 | s:bd cutoff:5992.341757635586 ]", - "[ 21/8 → 11/4 | s:hh cutoff:3192.4760919064283 ]", - "[ 11/4 → 23/8 | s:hh cutoff:3188.529685838148 ]", - "[ 11/4 → 3/1 | s:bd cutoff:3188.529685838148 ]", - "[ 23/8 → 3/1 | s:hh cutoff:6837.369324173778 ]", - "[ 3/1 → 25/8 | s:hh cutoff:5111.154264421202 ]", - "[ 3/1 → 13/4 | s:bd cutoff:5111.154264421202 ]", - "[ 25/8 → 13/4 | s:hh cutoff:4812.422384973615 ]", - "[ 13/4 → 27/8 | s:hh cutoff:7517.148802988231 ]", - "[ 13/4 → 7/2 | s:bd cutoff:7517.148802988231 ]", - "[ 27/8 → 7/2 | s:hh cutoff:821.3959728600457 ]", - "[ 7/2 → 29/8 | s:hh cutoff:2354.0139601100236 ]", - "[ 7/2 → 15/4 | s:bd cutoff:2354.0139601100236 ]", - "[ 29/8 → 15/4 | s:hh cutoff:4901.923676487058 ]", - "[ 15/4 → 31/8 | s:hh cutoff:4723.308931104839 ]", - "[ 15/4 → 4/1 | s:bd cutoff:4723.308931104839 ]", - "[ 31/8 → 4/1 | s:hh cutoff:1649.9183619162068 ]", + "[ 0/1 → 1/8 | s:hh cutoff:500 ]", + "[ 0/1 → 1/4 | s:bd cutoff:500 ]", + "[ 1/8 → 1/4 | s:hh cutoff:5639.116775244474 ]", + "[ 1/4 → 3/8 | s:hh cutoff:3273.1976890936494 ]", + "[ 1/4 → 1/2 | s:bd cutoff:3273.1976890936494 ]", + "[ 3/8 → 1/2 | s:hh cutoff:3510.4438681155443 ]", + "[ 1/2 → 5/8 | s:hh cutoff:2453.604621812701 ]", + "[ 1/2 → 3/4 | s:bd cutoff:2453.604621812701 ]", + "[ 5/8 → 3/4 | s:hh cutoff:1517.2690078616142 ]", + "[ 3/4 → 7/8 | s:hh cutoff:1968.6986012384295 ]", + "[ 3/4 → 1/1 | s:bd cutoff:1968.6986012384295 ]", + "[ 7/8 → 1/1 | s:hh cutoff:3482.2331061586738 ]", + "[ 1/1 → 9/8 | s:hh cutoff:4396.566238254309 ]", + "[ 1/1 → 5/4 | s:bd cutoff:4396.566238254309 ]", + "[ 9/8 → 5/4 | s:hh cutoff:5543.671359308064 ]", + "[ 5/4 → 11/8 | s:hh cutoff:5965.461523272097 ]", + "[ 5/4 → 3/2 | s:bd cutoff:5965.461523272097 ]", + "[ 11/8 → 3/2 | s:hh cutoff:1871.028139255941 ]", + "[ 3/2 → 13/8 | s:hh cutoff:5063.060561195016 ]", + "[ 3/2 → 7/4 | s:bd cutoff:5063.060561195016 ]", + "[ 13/8 → 7/4 | s:hh cutoff:4225.660336203873 ]", + "[ 7/4 → 15/8 | s:hh cutoff:2035.5342207476497 ]", + "[ 7/4 → 2/1 | s:bd cutoff:2035.5342207476497 ]", + "[ 15/8 → 2/1 | s:hh cutoff:4959.178843535483 ]", + "[ 2/1 → 17/8 | s:hh cutoff:7696.453399956226 ]", + "[ 2/1 → 9/4 | s:bd cutoff:7696.453399956226 ]", + "[ 17/8 → 9/4 | s:hh cutoff:7275.427204556763 ]", + "[ 9/4 → 19/8 | s:hh cutoff:3091.1188358440995 ]", + "[ 9/4 → 5/2 | s:bd cutoff:3091.1188358440995 ]", + "[ 19/8 → 5/2 | s:hh cutoff:6773.7998040392995 ]", + "[ 5/2 → 21/8 | s:hh cutoff:3939.620556309819 ]", + "[ 5/2 → 11/4 | s:bd cutoff:3939.620556309819 ]", + "[ 21/8 → 11/4 | s:hh cutoff:1701.4511320739985 ]", + "[ 11/4 → 23/8 | s:hh cutoff:5249.245778657496 ]", + "[ 11/4 → 3/1 | s:bd cutoff:5249.245778657496 ]", + "[ 23/8 → 3/1 | s:hh cutoff:621.9062879681587 ]", + "[ 3/1 → 25/8 | s:hh cutoff:2129.6683298423886 ]", + "[ 3/1 → 13/4 | s:bd cutoff:2129.6683298423886 ]", + "[ 25/8 → 13/4 | s:hh cutoff:3074.329087510705 ]", + "[ 13/4 → 27/8 | s:hh cutoff:7942.738036625087 ]", + "[ 13/4 → 7/2 | s:bd cutoff:7942.738036625087 ]", + "[ 27/8 → 7/2 | s:hh cutoff:3565.1885084807873 ]", + "[ 7/2 → 29/8 | s:hh cutoff:3574.6161099523306 ]", + "[ 7/2 → 15/4 | s:bd cutoff:3574.6161099523306 ]", + "[ 29/8 → 15/4 | s:hh cutoff:7543.614340946078 ]", + "[ 15/4 → 31/8 | s:hh cutoff:6591.254916973412 ]", + "[ 15/4 → 4/1 | s:bd cutoff:6591.254916973412 ]", + "[ 31/8 → 4/1 | s:hh cutoff:6021.249040029943 ]", ] `; @@ -8364,38 +8354,38 @@ exports[`runs examples > example "rangex" example index 0 1`] = ` exports[`runs examples > example "rarely" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh ]", + "[ 0/1 → 1/8 | s:hh speed:0.5 ]", "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh speed:0.5 ]", + "[ 1/4 → 3/8 | s:hh ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh speed:0.5 ]", + "[ 3/4 → 7/8 | s:hh speed:0.5 ]", "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh speed:0.5 ]", + "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", - "[ 7/4 → 15/8 | s:hh ]", + "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh speed:0.5 ]", + "[ 9/4 → 19/8 | s:hh ]", "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", - "[ 21/8 → 11/4 | s:hh ]", + "[ 21/8 → 11/4 | s:hh speed:0.5 ]", "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh speed:0.5 ]", + "[ 3/1 → 25/8 | s:hh speed:0.5 ]", "[ 25/8 → 13/4 | s:hh ]", "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh speed:0.5 ]", - "[ 7/2 → 29/8 | s:hh speed:0.5 ]", + "[ 27/8 → 7/2 | s:hh ]", + "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -8439,22 +8429,22 @@ exports[`runs examples > example "release" example index 0 1`] = ` exports[`runs examples > example "repeatCycles" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:38 s:gm_acoustic_guitar_nylon ]", - "[ 1/4 → 1/2 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 0/1 → 1/4 | note:34 s:gm_acoustic_guitar_nylon ]", + "[ 1/4 → 1/2 | note:38 s:gm_acoustic_guitar_nylon ]", "[ 1/2 → 3/4 | note:37 s:gm_acoustic_guitar_nylon ]", - "[ 3/4 → 1/1 | note:37 s:gm_acoustic_guitar_nylon ]", - "[ 1/1 → 5/4 | note:38 s:gm_acoustic_guitar_nylon ]", - "[ 5/4 → 3/2 | note:35 s:gm_acoustic_guitar_nylon ]", + "[ 3/4 → 1/1 | note:36 s:gm_acoustic_guitar_nylon ]", + "[ 1/1 → 5/4 | note:34 s:gm_acoustic_guitar_nylon ]", + "[ 5/4 → 3/2 | note:38 s:gm_acoustic_guitar_nylon ]", "[ 3/2 → 7/4 | note:37 s:gm_acoustic_guitar_nylon ]", - "[ 7/4 → 2/1 | note:37 s:gm_acoustic_guitar_nylon ]", - "[ 2/1 → 9/4 | note:35 s:gm_acoustic_guitar_nylon ]", - "[ 9/4 → 5/2 | note:45 s:gm_acoustic_guitar_nylon ]", - "[ 5/2 → 11/4 | note:35 s:gm_acoustic_guitar_nylon ]", - "[ 11/4 → 3/1 | note:38 s:gm_acoustic_guitar_nylon ]", - "[ 3/1 → 13/4 | note:35 s:gm_acoustic_guitar_nylon ]", - "[ 13/4 → 7/2 | note:45 s:gm_acoustic_guitar_nylon ]", - "[ 7/2 → 15/4 | note:35 s:gm_acoustic_guitar_nylon ]", - "[ 15/4 → 4/1 | note:38 s:gm_acoustic_guitar_nylon ]", + "[ 7/4 → 2/1 | note:36 s:gm_acoustic_guitar_nylon ]", + "[ 2/1 → 9/4 | note:40 s:gm_acoustic_guitar_nylon ]", + "[ 9/4 → 5/2 | note:42 s:gm_acoustic_guitar_nylon ]", + "[ 5/2 → 11/4 | note:41 s:gm_acoustic_guitar_nylon ]", + "[ 11/4 → 3/1 | note:36 s:gm_acoustic_guitar_nylon ]", + "[ 3/1 → 13/4 | note:40 s:gm_acoustic_guitar_nylon ]", + "[ 13/4 → 7/2 | note:42 s:gm_acoustic_guitar_nylon ]", + "[ 7/2 → 15/4 | note:41 s:gm_acoustic_guitar_nylon ]", + "[ 15/4 → 4/1 | note:36 s:gm_acoustic_guitar_nylon ]", ] `; @@ -8619,43 +8609,67 @@ exports[`runs examples > example "ribbon" example index 0 1`] = ` exports[`runs examples > example "ribbon" example index 1 1`] = ` [ - "[ 0/1 → 1/4 | note:D3 ]", - "[ 1/4 → 1/2 | note:A3 ]", + "[ 0/1 → 1/4 | note:A3 ]", + "[ 1/4 → 1/2 | note:C3 ]", "[ 1/2 → 3/4 | note:D3 ]", - "[ 3/4 → 1/1 | note:E3 ]", - "[ 1/1 → 5/4 | note:C3 ]", - "[ 5/4 → 3/2 | note:D3 ]", - "[ 3/2 → 7/4 | note:D3 ]", - "[ 7/4 → 2/1 | note:C4 ]", - "[ 2/1 → 9/4 | note:D3 ]", - "[ 9/4 → 5/2 | note:A3 ]", + "[ 3/4 → 1/1 | note:G3 ]", + "[ 1/1 → 5/4 | note:E3 ]", + "[ 5/4 → 3/2 | note:C4 ]", + "[ 3/2 → 7/4 | note:A3 ]", + "[ 7/4 → 2/1 | note:E4 ]", + "[ 2/1 → 9/4 | note:A3 ]", + "[ 9/4 → 5/2 | note:C3 ]", "[ 5/2 → 11/4 | note:D3 ]", - "[ 11/4 → 3/1 | note:E3 ]", - "[ 3/1 → 13/4 | note:C3 ]", - "[ 13/4 → 7/2 | note:D3 ]", - "[ 7/2 → 15/4 | note:D3 ]", - "[ 15/4 → 4/1 | note:C4 ]", + "[ 11/4 → 3/1 | note:G3 ]", + "[ 3/1 → 13/4 | note:E3 ]", + "[ 13/4 → 7/2 | note:C4 ]", + "[ 7/2 → 15/4 | note:A3 ]", + "[ 15/4 → 4/1 | note:E4 ]", ] `; exports[`runs examples > example "ribbon" example index 2 1`] = ` [ "[ 1/16 → 1/8 | s:bd ]", + "[ 1/8 → 3/16 | s:bd ]", "[ 3/16 → 1/4 | s:bd ]", + "[ 1/4 → 5/16 | s:bd ]", + "[ 3/8 → 7/16 | s:bd ]", "[ 9/16 → 5/8 | s:bd ]", + "[ 5/8 → 11/16 | s:bd ]", "[ 11/16 → 3/4 | s:bd ]", + "[ 3/4 → 13/16 | s:bd ]", + "[ 7/8 → 15/16 | s:bd ]", "[ 17/16 → 9/8 | s:bd ]", + "[ 9/8 → 19/16 | s:bd ]", "[ 19/16 → 5/4 | s:bd ]", + "[ 5/4 → 21/16 | s:bd ]", + "[ 11/8 → 23/16 | s:bd ]", "[ 25/16 → 13/8 | s:bd ]", + "[ 13/8 → 27/16 | s:bd ]", "[ 27/16 → 7/4 | s:bd ]", + "[ 7/4 → 29/16 | s:bd ]", + "[ 15/8 → 31/16 | s:bd ]", "[ 33/16 → 17/8 | s:bd ]", + "[ 17/8 → 35/16 | s:bd ]", "[ 35/16 → 9/4 | s:bd ]", + "[ 9/4 → 37/16 | s:bd ]", + "[ 19/8 → 39/16 | s:bd ]", "[ 41/16 → 21/8 | s:bd ]", + "[ 21/8 → 43/16 | s:bd ]", "[ 43/16 → 11/4 | s:bd ]", + "[ 11/4 → 45/16 | s:bd ]", + "[ 23/8 → 47/16 | s:bd ]", "[ 49/16 → 25/8 | s:bd ]", + "[ 25/8 → 51/16 | s:bd ]", "[ 51/16 → 13/4 | s:bd ]", + "[ 13/4 → 53/16 | s:bd ]", + "[ 27/8 → 55/16 | s:bd ]", "[ 57/16 → 29/8 | s:bd ]", + "[ 29/8 → 59/16 | s:bd ]", "[ 59/16 → 15/4 | s:bd ]", + "[ 15/4 → 61/16 | s:bd ]", + "[ 31/8 → 63/16 | s:bd ]", ] `; @@ -9186,38 +9200,38 @@ exports[`runs examples > example "scale" example index 1 1`] = ` exports[`runs examples > example "scale" example index 2 1`] = ` [ - "[ 0/1 → 1/8 | note:C4 s:piano ]", - "[ 1/8 → 1/4 | note:G4 s:piano ]", - "[ 1/4 → 3/8 | note:F3 s:piano ]", - "[ 3/8 → 1/2 | note:D5 s:piano ]", + "[ 0/1 → 1/8 | note:C3 s:piano ]", + "[ 1/8 → 1/4 | note:A4 s:piano ]", + "[ 1/4 → 3/8 | note:C4 s:piano ]", + "[ 3/8 → 1/2 | note:C4 s:piano ]", "[ 1/2 → 5/8 | note:A3 s:piano ]", - "[ 5/8 → 3/4 | note:A4 s:piano ]", - "[ 3/4 → 7/8 | note:A3 s:piano ]", - "[ 7/8 → 1/1 | note:D5 s:piano ]", - "[ 1/1 → 9/8 | note:F3 s:piano ]", - "[ 9/8 → 5/4 | note:D3 s:piano ]", - "[ 5/4 → 11/8 | note:F5 s:piano ]", - "[ 11/8 → 3/2 | note:D3 s:piano ]", - "[ 3/2 → 13/8 | note:F3 s:piano ]", - "[ 13/8 → 7/4 | note:G4 s:piano ]", - "[ 7/4 → 15/8 | note:C4 s:piano ]", + "[ 5/8 → 3/4 | note:F3 s:piano ]", + "[ 3/4 → 7/8 | note:G3 s:piano ]", + "[ 7/8 → 1/1 | note:C4 s:piano ]", + "[ 1/1 → 9/8 | note:F4 s:piano ]", + "[ 9/8 → 5/4 | note:A4 s:piano ]", + "[ 5/4 → 11/8 | note:A4 s:piano ]", + "[ 11/8 → 3/2 | note:G3 s:piano ]", + "[ 3/2 → 13/8 | note:G4 s:piano ]", + "[ 13/8 → 7/4 | note:D4 s:piano ]", + "[ 7/4 → 15/8 | note:G3 s:piano ]", "[ 15/8 → 2/1 | note:G4 s:piano ]", - "[ 2/1 → 17/8 | note:F4 s:piano ]", - "[ 17/8 → 9/4 | note:D4 s:piano ]", - "[ 9/4 → 19/8 | note:G3 s:piano ]", + "[ 2/1 → 17/8 | note:F5 s:piano ]", + "[ 17/8 → 9/4 | note:D5 s:piano ]", + "[ 9/4 → 19/8 | note:C4 s:piano ]", "[ 19/8 → 5/2 | note:D5 s:piano ]", - "[ 5/2 → 21/8 | note:A4 s:piano ]", - "[ 21/8 → 11/4 | note:C4 s:piano ]", - "[ 11/4 → 23/8 | note:C4 s:piano ]", - "[ 23/8 → 3/1 | note:D5 s:piano ]", - "[ 3/1 → 25/8 | note:G4 s:piano ]", - "[ 25/8 → 13/4 | note:F4 s:piano ]", + "[ 5/2 → 21/8 | note:D4 s:piano ]", + "[ 21/8 → 11/4 | note:F3 s:piano ]", + "[ 11/4 → 23/8 | note:G4 s:piano ]", + "[ 23/8 → 3/1 | note:D3 s:piano ]", + "[ 3/1 → 25/8 | note:G3 s:piano ]", + "[ 25/8 → 13/4 | note:C4 s:piano ]", "[ 13/4 → 27/8 | note:F5 s:piano ]", - "[ 27/8 → 7/2 | note:D3 s:piano ]", - "[ 7/2 → 29/8 | note:G3 s:piano ]", - "[ 29/8 → 15/4 | note:G4 s:piano ]", - "[ 15/4 → 31/8 | note:F4 s:piano ]", - "[ 31/8 → 4/1 | note:F3 s:piano ]", + "[ 27/8 → 7/2 | note:C4 s:piano ]", + "[ 7/2 → 29/8 | note:C4 s:piano ]", + "[ 29/8 → 15/4 | note:F5 s:piano ]", + "[ 15/4 → 31/8 | note:C5 s:piano ]", + "[ 31/8 → 4/1 | note:A4 s:piano ]", ] `; @@ -9256,70 +9270,70 @@ exports[`runs examples > example "scale" example index 3 1`] = ` exports[`runs examples > example "scale" example index 4 1`] = ` [ - "[ 0/1 → 1/16 | note:Gb2 ]", - "[ 1/16 → 1/8 | note:Gb2 ]", - "[ 1/8 → 3/16 | note:Gb2 ]", - "[ 3/16 → 1/4 | note:Gb2 ]", - "[ 1/4 → 5/16 | note:Gb2 ]", - "[ 5/16 → 3/8 | note:Gb2 ]", - "[ 3/8 → 7/16 | note:Gb2 ]", - "[ 7/16 → 1/2 | note:Gb2 ]", - "[ 1/2 → 9/16 | note:Gb2 ]", - "[ 9/16 → 5/8 | note:Gb2 ]", - "[ 5/8 → 11/16 | note:Gb2 ]", - "[ 11/16 → 3/4 | note:Gb2 ]", - "[ 3/4 → 13/16 | note:Gb2 ]", - "[ 13/16 → 7/8 | note:Gb2 ]", - "[ 7/8 → 15/16 | note:Gb2 ]", - "[ 15/16 → 1/1 | note:Gb2 ]", - "[ 1/1 → 17/16 | note:Bb1 ]", - "[ 17/16 → 9/8 | note:Bb1 ]", - "[ 9/8 → 19/16 | note:Bb1 ]", - "[ 19/16 → 5/4 | note:Bb1 ]", - "[ 5/4 → 21/16 | note:Bb1 ]", - "[ 21/16 → 11/8 | note:Bb1 ]", - "[ 11/8 → 23/16 | note:Bb1 ]", - "[ 23/16 → 3/2 | note:Bb1 ]", - "[ 3/2 → 25/16 | note:Bb1 ]", - "[ 25/16 → 13/8 | note:Bb1 ]", - "[ 13/8 → 27/16 | note:Bb1 ]", - "[ 27/16 → 7/4 | note:Bb1 ]", - "[ 7/4 → 29/16 | note:Bb1 ]", - "[ 29/16 → 15/8 | note:Bb1 ]", - "[ 15/8 → 31/16 | note:Bb1 ]", - "[ 31/16 → 2/1 | note:Bb1 ]", - "[ 2/1 → 33/16 | note:Db3 ]", - "[ 33/16 → 17/8 | note:Db3 ]", - "[ 17/8 → 35/16 | note:Db3 ]", - "[ 35/16 → 9/4 | note:Db3 ]", - "[ 9/4 → 37/16 | note:Db3 ]", - "[ 37/16 → 19/8 | note:Db3 ]", - "[ 19/8 → 39/16 | note:Db3 ]", - "[ 39/16 → 5/2 | note:Db3 ]", - "[ 5/2 → 41/16 | note:Db3 ]", - "[ 41/16 → 21/8 | note:Db3 ]", - "[ 21/8 → 43/16 | note:Db3 ]", - "[ 43/16 → 11/4 | note:Db3 ]", - "[ 11/4 → 45/16 | note:Db3 ]", - "[ 45/16 → 23/8 | note:Db3 ]", - "[ 23/8 → 47/16 | note:Db3 ]", - "[ 47/16 → 3/1 | note:Db3 ]", - "[ 3/1 → 49/16 | note:Eb3 ]", - "[ 49/16 → 25/8 | note:Eb3 ]", - "[ 25/8 → 51/16 | note:Eb3 ]", - "[ 51/16 → 13/4 | note:Eb3 ]", - "[ 13/4 → 53/16 | note:Eb3 ]", - "[ 53/16 → 27/8 | note:Eb3 ]", - "[ 27/8 → 55/16 | note:Eb3 ]", - "[ 55/16 → 7/2 | note:Eb3 ]", - "[ 7/2 → 57/16 | note:Eb3 ]", - "[ 57/16 → 29/8 | note:Eb3 ]", - "[ 29/8 → 59/16 | note:Eb3 ]", - "[ 59/16 → 15/4 | note:Eb3 ]", - "[ 15/4 → 61/16 | note:Eb3 ]", - "[ 61/16 → 31/8 | note:Eb3 ]", - "[ 31/8 → 63/16 | note:Eb3 ]", - "[ 63/16 → 4/1 | note:Eb3 ]", + "[ 0/1 → 1/16 | note:Gb1 ]", + "[ 1/16 → 1/8 | note:Gb1 ]", + "[ 1/8 → 3/16 | note:Gb1 ]", + "[ 3/16 → 1/4 | note:Gb1 ]", + "[ 1/4 → 5/16 | note:Gb1 ]", + "[ 5/16 → 3/8 | note:Gb1 ]", + "[ 3/8 → 7/16 | note:Gb1 ]", + "[ 7/16 → 1/2 | note:Gb1 ]", + "[ 1/2 → 9/16 | note:Gb1 ]", + "[ 9/16 → 5/8 | note:Gb1 ]", + "[ 5/8 → 11/16 | note:Gb1 ]", + "[ 11/16 → 3/4 | note:Gb1 ]", + "[ 3/4 → 13/16 | note:Gb1 ]", + "[ 13/16 → 7/8 | note:Gb1 ]", + "[ 7/8 → 15/16 | note:Gb1 ]", + "[ 15/16 → 1/1 | note:Gb1 ]", + "[ 1/1 → 17/16 | note:Cb3 ]", + "[ 17/16 → 9/8 | note:Cb3 ]", + "[ 9/8 → 19/16 | note:Cb3 ]", + "[ 19/16 → 5/4 | note:Cb3 ]", + "[ 5/4 → 21/16 | note:Cb3 ]", + "[ 21/16 → 11/8 | note:Cb3 ]", + "[ 11/8 → 23/16 | note:Cb3 ]", + "[ 23/16 → 3/2 | note:Cb3 ]", + "[ 3/2 → 25/16 | note:Cb3 ]", + "[ 25/16 → 13/8 | note:Cb3 ]", + "[ 13/8 → 27/16 | note:Cb3 ]", + "[ 27/16 → 7/4 | note:Cb3 ]", + "[ 7/4 → 29/16 | note:Cb3 ]", + "[ 29/16 → 15/8 | note:Cb3 ]", + "[ 15/8 → 31/16 | note:Cb3 ]", + "[ 31/16 → 2/1 | note:Cb3 ]", + "[ 2/1 → 33/16 | note:Eb4 ]", + "[ 33/16 → 17/8 | note:Eb4 ]", + "[ 17/8 → 35/16 | note:Eb4 ]", + "[ 35/16 → 9/4 | note:Eb4 ]", + "[ 9/4 → 37/16 | note:Eb4 ]", + "[ 37/16 → 19/8 | note:Eb4 ]", + "[ 19/8 → 39/16 | note:Eb4 ]", + "[ 39/16 → 5/2 | note:Eb4 ]", + "[ 5/2 → 41/16 | note:Eb4 ]", + "[ 41/16 → 21/8 | note:Eb4 ]", + "[ 21/8 → 43/16 | note:Eb4 ]", + "[ 43/16 → 11/4 | note:Eb4 ]", + "[ 11/4 → 45/16 | note:Eb4 ]", + "[ 45/16 → 23/8 | note:Eb4 ]", + "[ 23/8 → 47/16 | note:Eb4 ]", + "[ 47/16 → 3/1 | note:Eb4 ]", + "[ 3/1 → 49/16 | note:Db2 ]", + "[ 49/16 → 25/8 | note:Db2 ]", + "[ 25/8 → 51/16 | note:Db2 ]", + "[ 51/16 → 13/4 | note:Db2 ]", + "[ 13/4 → 53/16 | note:Db2 ]", + "[ 53/16 → 27/8 | note:Db2 ]", + "[ 27/8 → 55/16 | note:Db2 ]", + "[ 55/16 → 7/2 | note:Db2 ]", + "[ 7/2 → 57/16 | note:Db2 ]", + "[ 57/16 → 29/8 | note:Db2 ]", + "[ 29/8 → 59/16 | note:Db2 ]", + "[ 59/16 → 15/4 | note:Db2 ]", + "[ 15/4 → 61/16 | note:Db2 ]", + "[ 61/16 → 31/8 | note:Db2 ]", + "[ 31/8 → 63/16 | note:Db2 ]", + "[ 63/16 → 4/1 | note:Db2 ]", ] `; @@ -9392,46 +9406,46 @@ exports[`runs examples > example "scope" example index 0 1`] = ` exports[`runs examples > example "scramble" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:d s:piano ]", - "[ 1/4 → 1/2 | note:c s:piano ]", + "[ 0/1 → 1/4 | note:c s:piano ]", + "[ 1/4 → 1/2 | note:d s:piano ]", "[ 1/2 → 3/4 | note:d s:piano ]", - "[ 3/4 → 1/1 | note:d s:piano ]", - "[ 1/1 → 5/4 | note:c s:piano ]", - "[ 5/4 → 3/2 | note:f s:piano ]", - "[ 3/2 → 7/4 | note:c s:piano ]", - "[ 7/4 → 2/1 | note:d s:piano ]", - "[ 2/1 → 9/4 | note:e s:piano ]", - "[ 9/4 → 5/2 | note:c s:piano ]", - "[ 5/2 → 11/4 | note:e s:piano ]", - "[ 11/4 → 3/1 | note:d s:piano ]", - "[ 3/1 → 13/4 | note:e s:piano ]", + "[ 3/4 → 1/1 | note:c s:piano ]", + "[ 1/1 → 5/4 | note:e s:piano ]", + "[ 5/4 → 3/2 | note:e s:piano ]", + "[ 3/2 → 7/4 | note:e s:piano ]", + "[ 7/4 → 2/1 | note:c s:piano ]", + "[ 2/1 → 9/4 | note:f s:piano ]", + "[ 9/4 → 5/2 | note:d s:piano ]", + "[ 5/2 → 11/4 | note:d s:piano ]", + "[ 11/4 → 3/1 | note:e s:piano ]", + "[ 3/1 → 13/4 | note:c s:piano ]", "[ 13/4 → 7/2 | note:f s:piano ]", - "[ 7/2 → 15/4 | note:c s:piano ]", - "[ 15/4 → 4/1 | note:e s:piano ]", + "[ 7/2 → 15/4 | note:d s:piano ]", + "[ 15/4 → 4/1 | note:f s:piano ]", ] `; exports[`runs examples > example "scramble" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | note:d s:piano ]", - "[ 1/8 → 1/4 | note:c s:piano ]", + "[ 0/1 → 1/8 | note:c s:piano ]", + "[ 1/8 → 1/4 | note:d s:piano ]", "[ 1/4 → 3/8 | note:d s:piano ]", - "[ 3/8 → 1/2 | note:d 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:f s:piano ]", - "[ 5/4 → 11/8 | note:c s:piano ]", - "[ 11/8 → 3/2 | note:d s:piano ]", + "[ 1/1 → 9/8 | note:e s:piano ]", + "[ 9/8 → 5/4 | note:e s:piano ]", + "[ 5/4 → 11/8 | note:e s:piano ]", + "[ 11/8 → 3/2 | note:c s:piano ]", "[ 3/2 → 2/1 | note:g s:piano ]", - "[ 2/1 → 17/8 | note:e s:piano ]", - "[ 17/8 → 9/4 | note:c s:piano ]", - "[ 9/4 → 19/8 | note:e s:piano ]", - "[ 19/8 → 5/2 | note:d s:piano ]", + "[ 2/1 → 17/8 | note:f s:piano ]", + "[ 17/8 → 9/4 | note:d s:piano ]", + "[ 9/4 → 19/8 | note:d s:piano ]", + "[ 19/8 → 5/2 | note:e s:piano ]", "[ 5/2 → 3/1 | note:g s:piano ]", - "[ 3/1 → 25/8 | note:e s:piano ]", + "[ 3/1 → 25/8 | note:c s:piano ]", "[ 25/8 → 13/4 | note:f s:piano ]", - "[ 13/4 → 27/8 | note:c s:piano ]", - "[ 27/8 → 7/2 | note:e s:piano ]", + "[ 13/4 → 27/8 | note:d s:piano ]", + "[ 27/8 → 7/2 | note:f s:piano ]", "[ 7/2 → 4/1 | note:g s:piano ]", ] `; @@ -9484,18 +9498,13 @@ exports[`runs examples > example "scrub" example index 1 1`] = ` exports[`runs examples > example "seed" example index 0 1`] = ` [ + "[ 0/1 → 1/4 | s:bd ]", "[ 1/4 → 1/2 | s:bd ]", "[ 1/2 → 3/4 | s:bd ]", - "[ 3/4 → 1/1 | s:bd ]", "[ 1/1 → 5/4 | s:bd ]", - "[ 5/4 → 3/2 | s:bd ]", - "[ 3/2 → 7/4 | s:bd ]", "[ 7/4 → 2/1 | s:bd ]", - "[ 2/1 → 9/4 | s:bd ]", + "[ 9/4 → 5/2 | s:bd ]", "[ 11/4 → 3/1 | s:bd ]", - "[ 3/1 → 13/4 | s:bd ]", - "[ 13/4 → 7/2 | s:bd ]", - "[ 7/2 → 15/4 | s:bd ]", ] `; @@ -9705,38 +9714,38 @@ exports[`runs examples > example "setGainCurve" example index 0 1`] = ` exports[`runs examples > example "setMaxPolyphony" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | note:E4 room:1 release:4 gain:0.5 ]", - "[ 1/8 → 1/4 | note:D#5 room:1 release:4 gain:0.5 ]", - "[ 1/4 → 3/8 | note:F#3 room:1 release:4 gain:0.5 ]", - "[ 3/8 → 1/2 | note:B5 room:1 release:4 gain:0.5 ]", - "[ 1/2 → 5/8 | note:C#4 room:1 release:4 gain:0.5 ]", - "[ 5/8 → 3/4 | note:E5 room:1 release:4 gain:0.5 ]", - "[ 3/4 → 7/8 | note:B3 room:1 release:4 gain:0.5 ]", - "[ 7/8 → 1/1 | note:C#6 room:1 release:4 gain:0.5 ]", - "[ 1/1 → 9/8 | note:E3 room:1 release:4 gain:0.5 ]", - "[ 9/8 → 5/4 | note:D#3 room:1 release:4 gain:0.5 ]", - "[ 5/4 → 11/8 | note:D#6 room:1 release:4 gain:0.5 ]", - "[ 11/8 → 3/2 | note:D#3 room:1 release:4 gain:0.5 ]", - "[ 3/2 → 13/8 | note:F#3 room:1 release:4 gain:0.5 ]", - "[ 13/8 → 7/4 | note:D#5 room:1 release:4 gain:0.5 ]", - "[ 7/4 → 15/8 | note:D#4 room:1 release:4 gain:0.5 ]", - "[ 15/8 → 2/1 | note:D#5 room:1 release:4 gain:0.5 ]", - "[ 2/1 → 17/8 | note:B4 room:1 release:4 gain:0.5 ]", - "[ 17/8 → 9/4 | note:F#4 room:1 release:4 gain:0.5 ]", - "[ 9/4 → 19/8 | note:G#3 room:1 release:4 gain:0.5 ]", + "[ 0/1 → 1/8 | note:C#3 room:1 release:4 gain:0.5 ]", + "[ 1/8 → 1/4 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 1/4 → 3/8 | note:D#4 room:1 release:4 gain:0.5 ]", + "[ 3/8 → 1/2 | note:E4 room:1 release:4 gain:0.5 ]", + "[ 1/2 → 5/8 | note:B3 room:1 release:4 gain:0.5 ]", + "[ 5/8 → 3/4 | note:F#3 room:1 release:4 gain:0.5 ]", + "[ 3/4 → 7/8 | note:G#3 room:1 release:4 gain:0.5 ]", + "[ 7/8 → 1/1 | note:E4 room:1 release:4 gain:0.5 ]", + "[ 1/1 → 9/8 | note:A4 room:1 release:4 gain:0.5 ]", + "[ 9/8 → 5/4 | note:E5 room:1 release:4 gain:0.5 ]", + "[ 5/4 → 11/8 | note:F#5 room:1 release:4 gain:0.5 ]", + "[ 11/8 → 3/2 | note:G#3 room:1 release:4 gain:0.5 ]", + "[ 3/2 → 13/8 | note:C#5 room:1 release:4 gain:0.5 ]", + "[ 13/8 → 7/4 | note:G#4 room:1 release:4 gain:0.5 ]", + "[ 7/4 → 15/8 | note:G#3 room:1 release:4 gain:0.5 ]", + "[ 15/8 → 2/1 | note:C#5 room:1 release:4 gain:0.5 ]", + "[ 2/1 → 17/8 | note:E6 room:1 release:4 gain:0.5 ]", + "[ 17/8 → 9/4 | note:C#6 room:1 release:4 gain:0.5 ]", + "[ 9/4 → 19/8 | note:D#4 room:1 release:4 gain:0.5 ]", "[ 19/8 → 5/2 | note:B5 room:1 release:4 gain:0.5 ]", - "[ 5/2 → 21/8 | note:F#5 room:1 release:4 gain:0.5 ]", - "[ 21/8 → 11/4 | note:D#4 room:1 release:4 gain:0.5 ]", - "[ 11/4 → 23/8 | note:D#4 room:1 release:4 gain:0.5 ]", - "[ 23/8 → 3/1 | note:B5 room:1 release:4 gain:0.5 ]", - "[ 3/1 → 25/8 | note:C#5 room:1 release:4 gain:0.5 ]", - "[ 25/8 → 13/4 | note:B4 room:1 release:4 gain:0.5 ]", - "[ 13/4 → 27/8 | note:D#6 room:1 release:4 gain:0.5 ]", - "[ 27/8 → 7/2 | note:D#3 room:1 release:4 gain:0.5 ]", - "[ 7/2 → 29/8 | note:A3 room:1 release:4 gain:0.5 ]", - "[ 29/8 → 15/4 | note:C#5 room:1 release:4 gain:0.5 ]", - "[ 15/4 → 31/8 | note:B4 room:1 release:4 gain:0.5 ]", - "[ 31/8 → 4/1 | note:F#3 room:1 release:4 gain:0.5 ]", + "[ 5/2 → 21/8 | note:G#4 room:1 release:4 gain:0.5 ]", + "[ 21/8 → 11/4 | note:F#3 room:1 release:4 gain:0.5 ]", + "[ 11/4 → 23/8 | note:D#5 room:1 release:4 gain:0.5 ]", + "[ 23/8 → 3/1 | note:C#3 room:1 release:4 gain:0.5 ]", + "[ 3/1 → 25/8 | note:A3 room:1 release:4 gain:0.5 ]", + "[ 25/8 → 13/4 | note:D#4 room:1 release:4 gain:0.5 ]", + "[ 13/4 → 27/8 | note:E6 room:1 release:4 gain:0.5 ]", + "[ 27/8 → 7/2 | note:E4 room:1 release:4 gain:0.5 ]", + "[ 7/2 → 29/8 | note:E4 room:1 release:4 gain:0.5 ]", + "[ 29/8 → 15/4 | note:D#6 room:1 release:4 gain:0.5 ]", + "[ 15/4 → 31/8 | note:A5 room:1 release:4 gain:0.5 ]", + "[ 31/8 → 4/1 | note:F#5 room:1 release:4 gain:0.5 ]", ] `; @@ -9972,45 +9981,45 @@ exports[`runs examples > example "shrink" example index 3 1`] = ` exports[`runs examples > example "shuffle" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:f s:piano ]", + "[ 0/1 → 1/4 | note:e s:piano ]", "[ 1/4 → 1/2 | note:d s:piano ]", - "[ 1/2 → 3/4 | note:c s:piano ]", - "[ 3/4 → 1/1 | note:e s:piano ]", - "[ 1/1 → 5/4 | note:c s:piano ]", - "[ 5/4 → 3/2 | note:f s:piano ]", - "[ 3/2 → 7/4 | note:d s:piano ]", - "[ 7/4 → 2/1 | note:e s:piano ]", - "[ 2/1 → 9/4 | note:e s:piano ]", - "[ 9/4 → 5/2 | note:d s:piano ]", - "[ 5/2 → 11/4 | note:f s:piano ]", - "[ 11/4 → 3/1 | note:c s:piano ]", - "[ 3/1 → 13/4 | note:f s:piano ]", - "[ 13/4 → 7/2 | note:c s:piano ]", - "[ 7/2 → 15/4 | note:e 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: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:f s:piano ]", + "[ 0/1 → 1/8 | note:e s:piano ]", "[ 1/8 → 1/4 | note:d s:piano ]", - "[ 1/4 → 3/8 | note:c s:piano ]", - "[ 3/8 → 1/2 | note:e 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:f s:piano ]", - "[ 5/4 → 11/8 | note:d s:piano ]", - "[ 11/8 → 3/2 | note:e 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:e s:piano ]", - "[ 17/8 → 9/4 | note:d s:piano ]", - "[ 9/4 → 19/8 | note:f s:piano ]", - "[ 19/8 → 5/2 | note:c 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:f s:piano ]", - "[ 25/8 → 13/4 | note:c s:piano ]", - "[ 13/4 → 27/8 | note:e s:piano ]", + "[ 3/1 → 25/8 | note:c 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 ]", ] @@ -10198,15 +10207,15 @@ exports[`runs examples > example "someCycles" example index 0 1`] = ` "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", "[ 7/8 → 1/1 | s:hh speed:0.5 ]", - "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 1/1 → 2/1 | s:bd speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh speed:0.5 ]", - "[ 5/4 → 11/8 | s:hh speed:0.5 ]", - "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh speed:0.5 ]", - "[ 13/8 → 7/4 | s:hh speed:0.5 ]", - "[ 7/4 → 15/8 | s:hh speed:0.5 ]", - "[ 15/8 → 2/1 | s:hh speed:0.5 ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 1/1 → 2/1 | s:bd ]", + "[ 9/8 → 5/4 | s:hh ]", + "[ 5/4 → 11/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", + "[ 7/4 → 15/8 | s:hh ]", + "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 2/1 → 3/1 | s:bd ]", "[ 17/8 → 9/4 | s:hh ]", @@ -10216,38 +10225,38 @@ exports[`runs examples > example "someCycles" example index 0 1`] = ` "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 3/1 → 4/1 | s:bd ]", - "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", - "[ 7/2 → 29/8 | s:hh ]", - "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", + "[ 3/1 → 25/8 | s:hh speed:0.5 ]", + "[ 3/1 → 4/1 | s:bd speed:0.5 ]", + "[ 25/8 → 13/4 | s:hh speed:0.5 ]", + "[ 13/4 → 27/8 | s:hh speed:0.5 ]", + "[ 27/8 → 7/2 | s:hh speed:0.5 ]", + "[ 7/2 → 29/8 | s:hh speed:0.5 ]", + "[ 29/8 → 15/4 | s:hh speed:0.5 ]", + "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; exports[`runs examples > example "someCyclesBy" example index 0 1`] = ` [ - "[ 0/1 → 1/8 | s:hh ]", - "[ 0/1 → 1/1 | s:bd ]", - "[ 1/8 → 1/4 | s:hh ]", - "[ 1/4 → 3/8 | s:hh ]", - "[ 3/8 → 1/2 | s:hh ]", - "[ 1/2 → 5/8 | s:hh ]", - "[ 5/8 → 3/4 | s:hh ]", - "[ 3/4 → 7/8 | s:hh ]", - "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 1/1 → 2/1 | s:bd speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh speed:0.5 ]", - "[ 5/4 → 11/8 | s:hh speed:0.5 ]", - "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh speed:0.5 ]", - "[ 13/8 → 7/4 | s:hh speed:0.5 ]", - "[ 7/4 → 15/8 | s:hh speed:0.5 ]", - "[ 15/8 → 2/1 | s:hh speed:0.5 ]", + "[ 0/1 → 1/8 | s:hh speed:0.5 ]", + "[ 0/1 → 1/1 | s:bd speed:0.5 ]", + "[ 1/8 → 1/4 | s:hh speed:0.5 ]", + "[ 1/4 → 3/8 | s:hh speed:0.5 ]", + "[ 3/8 → 1/2 | s:hh speed:0.5 ]", + "[ 1/2 → 5/8 | s:hh speed:0.5 ]", + "[ 5/8 → 3/4 | s:hh speed:0.5 ]", + "[ 3/4 → 7/8 | s:hh speed:0.5 ]", + "[ 7/8 → 1/1 | s:hh speed:0.5 ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 1/1 → 2/1 | s:bd ]", + "[ 9/8 → 5/4 | s:hh ]", + "[ 5/4 → 11/8 | s:hh ]", + "[ 11/8 → 3/2 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", + "[ 7/4 → 15/8 | s:hh ]", + "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", "[ 2/1 → 3/1 | s:bd ]", "[ 17/8 → 9/4 | s:hh ]", @@ -10257,15 +10266,15 @@ exports[`runs examples > example "someCyclesBy" example index 0 1`] = ` "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 3/1 → 4/1 | s:bd ]", - "[ 25/8 → 13/4 | s:hh ]", - "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh ]", - "[ 7/2 → 29/8 | s:hh ]", - "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", + "[ 3/1 → 25/8 | s:hh speed:0.5 ]", + "[ 3/1 → 4/1 | s:bd speed:0.5 ]", + "[ 25/8 → 13/4 | s:hh speed:0.5 ]", + "[ 13/4 → 27/8 | s:hh speed:0.5 ]", + "[ 27/8 → 7/2 | s:hh speed:0.5 ]", + "[ 7/2 → 29/8 | s:hh speed:0.5 ]", + "[ 29/8 → 15/4 | s:hh speed:0.5 ]", + "[ 15/4 → 31/8 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh speed:0.5 ]", ] `; @@ -10274,35 +10283,35 @@ exports[`runs examples > example "sometimes" example index 0 1`] = ` "[ 0/1 → 1/8 | s:hh speed:0.5 ]", "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh speed:0.5 ]", - "[ 3/8 → 1/2 | s:hh ]", + "[ 3/8 → 1/2 | s:hh speed:0.5 ]", "[ 1/2 → 5/8 | s:hh speed:0.5 ]", - "[ 5/8 → 3/4 | s:hh ]", + "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 7/8 → 1/1 | s:hh speed:0.5 ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh speed:0.5 ]", - "[ 13/8 → 7/4 | s:hh ]", + "[ 3/2 → 13/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh speed:0.5 ]", "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh ]", "[ 2/1 → 17/8 | s:hh ]", - "[ 17/8 → 9/4 | s:hh speed:0.5 ]", + "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh speed:0.5 ]", "[ 19/8 → 5/2 | s:hh ]", - "[ 5/2 → 21/8 | s:hh ]", + "[ 5/2 → 21/8 | s:hh speed:0.5 ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", - "[ 11/4 → 23/8 | s:hh speed:0.5 ]", - "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 25/8 → 13/4 | s:hh ]", + "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh speed:0.5 ]", + "[ 3/1 → 25/8 | s:hh speed:0.5 ]", + "[ 25/8 → 13/4 | s:hh speed:0.5 ]", "[ 13/4 → 27/8 | s:hh ]", "[ 27/8 → 7/2 | s:hh speed:0.5 ]", "[ 7/2 → 29/8 | s:hh speed:0.5 ]", "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -10313,14 +10322,14 @@ exports[`runs examples > example "sometimesBy" example index 0 1`] = ` "[ 1/4 → 3/8 | s:hh speed:0.5 ]", "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh speed:0.5 ]", - "[ 5/8 → 3/4 | s:hh ]", + "[ 5/8 → 3/4 | s:hh speed:0.5 ]", "[ 3/4 → 7/8 | s:hh speed:0.5 ]", - "[ 7/8 → 1/1 | s:hh ]", - "[ 1/1 → 9/8 | s:hh speed:0.5 ]", - "[ 9/8 → 5/4 | s:hh speed:0.5 ]", + "[ 7/8 → 1/1 | s:hh speed:0.5 ]", + "[ 1/1 → 9/8 | s:hh ]", + "[ 9/8 → 5/4 | s:hh ]", "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh speed:0.5 ]", - "[ 3/2 → 13/8 | s:hh speed:0.5 ]", + "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh speed:0.5 ]", "[ 15/8 → 2/1 | s:hh ]", @@ -10330,16 +10339,16 @@ exports[`runs examples > example "sometimesBy" example index 0 1`] = ` "[ 19/8 → 5/2 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh speed:0.5 ]", - "[ 11/4 → 23/8 | s:hh speed:0.5 ]", - "[ 23/8 → 3/1 | s:hh ]", - "[ 3/1 → 25/8 | s:hh ]", - "[ 25/8 → 13/4 | s:hh ]", + "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh speed:0.5 ]", + "[ 3/1 → 25/8 | s:hh speed:0.5 ]", + "[ 25/8 → 13/4 | s:hh speed:0.5 ]", "[ 13/4 → 27/8 | s:hh ]", - "[ 27/8 → 7/2 | s:hh speed:0.5 ]", - "[ 7/2 → 29/8 | s:hh speed:0.5 ]", + "[ 27/8 → 7/2 | s:hh ]", + "[ 7/2 → 29/8 | s:hh ]", "[ 29/8 → 15/4 | s:hh ]", "[ 15/4 → 31/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh speed:0.5 ]", + "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -11724,20 +11733,22 @@ exports[`runs examples > example "undegrade" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", + "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", - "[ 1/1 → 9/8 | s:hh ]", - "[ 9/8 → 5/4 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", "[ 11/8 → 3/2 | s:hh ]", - "[ 3/2 → 13/8 | s:hh ]", + "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", - "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh ]", + "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", - "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh ]", + "[ 3/1 → 25/8 | s:hh ]", + "[ 25/8 → 13/4 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", - "[ 31/8 → 4/1 | s:hh ]", ] `; @@ -11746,42 +11757,42 @@ exports[`runs examples > example "undegrade" example index 1 1`] = ` "[ 0/1 → 1/10 | s:hh pan:1 ]", "[ 1/10 → 1/5 | s:hh pan:1 ]", "[ 1/5 → 3/10 | s:hh pan:0 ]", - "[ 3/10 → 2/5 | s:hh pan:1 ]", + "[ 3/10 → 2/5 | s:hh pan:0 ]", "[ 2/5 → 1/2 | s:hh pan:0 ]", "[ 1/2 → 3/5 | s:hh pan:1 ]", - "[ 3/5 → 7/10 | s:hh pan:1 ]", - "[ 7/10 → 4/5 | s:hh pan:1 ]", + "[ 3/5 → 7/10 | s:hh pan:0 ]", + "[ 7/10 → 4/5 | s:hh pan:0 ]", "[ 4/5 → 9/10 | s:hh pan:1 ]", "[ 9/10 → 1/1 | s:hh pan:0 ]", - "[ 1/1 → 11/10 | s:hh pan:1 ]", - "[ 11/10 → 6/5 | s:hh pan:1 ]", - "[ 6/5 → 13/10 | s:hh pan:0 ]", + "[ 1/1 → 11/10 | s:hh pan:0 ]", + "[ 11/10 → 6/5 | s:hh pan:0 ]", + "[ 6/5 → 13/10 | s:hh pan:1 ]", "[ 13/10 → 7/5 | s:hh pan:1 ]", - "[ 7/5 → 3/2 | s:hh pan:0 ]", - "[ 3/2 → 8/5 | s:hh pan:1 ]", - "[ 8/5 → 17/10 | s:hh pan:0 ]", + "[ 7/5 → 3/2 | s:hh pan:1 ]", + "[ 3/2 → 8/5 | s:hh pan:0 ]", + "[ 8/5 → 17/10 | s:hh pan:1 ]", "[ 17/10 → 9/5 | s:hh pan:1 ]", - "[ 9/5 → 19/10 | s:hh pan:0 ]", + "[ 9/5 → 19/10 | s:hh pan:1 ]", "[ 19/10 → 2/1 | s:hh pan:1 ]", "[ 2/1 → 21/10 | s:hh pan:0 ]", "[ 21/10 → 11/5 | s:hh pan:1 ]", "[ 11/5 → 23/10 | s:hh pan:0 ]", - "[ 23/10 → 12/5 | s:hh pan:1 ]", + "[ 23/10 → 12/5 | s:hh pan:0 ]", "[ 12/5 → 5/2 | s:hh pan:0 ]", - "[ 5/2 → 13/5 | s:hh pan:0 ]", - "[ 13/5 → 27/10 | s:hh pan:0 ]", + "[ 5/2 → 13/5 | s:hh pan:1 ]", + "[ 13/5 → 27/10 | s:hh pan:1 ]", "[ 27/10 → 14/5 | s:hh pan:1 ]", "[ 14/5 → 29/10 | s:hh pan:0 ]", - "[ 29/10 → 3/1 | s:hh pan:0 ]", - "[ 3/1 → 31/10 | s:hh pan:0 ]", + "[ 29/10 → 3/1 | s:hh pan:1 ]", + "[ 3/1 → 31/10 | s:hh pan:1 ]", "[ 31/10 → 16/5 | s:hh pan:1 ]", "[ 16/5 → 33/10 | s:hh pan:1 ]", "[ 33/10 → 17/5 | s:hh pan:0 ]", - "[ 17/5 → 7/2 | s:hh pan:1 ]", + "[ 17/5 → 7/2 | s:hh pan:0 ]", "[ 7/2 → 18/5 | s:hh pan:1 ]", - "[ 18/5 → 37/10 | s:hh pan:1 ]", - "[ 37/10 → 19/5 | s:hh pan:1 ]", - "[ 19/5 → 39/10 | s:hh pan:0 ]", + "[ 18/5 → 37/10 | s:hh pan:0 ]", + "[ 37/10 → 19/5 | s:hh pan:0 ]", + "[ 19/5 → 39/10 | s:hh pan:1 ]", "[ 39/10 → 4/1 | s:hh pan:1 ]", ] `; @@ -11791,36 +11802,36 @@ exports[`runs examples > example "undegradeBy" example index 0 1`] = ` "[ 0/1 → 1/8 | s:hh ]", "[ 1/8 → 1/4 | s:hh ]", "[ 1/4 → 3/8 | s:hh ]", + "[ 3/8 → 1/2 | s:hh ]", "[ 1/2 → 5/8 | s:hh ]", "[ 5/8 → 3/4 | s:hh ]", "[ 3/4 → 7/8 | s:hh ]", + "[ 7/8 → 1/1 | s:hh ]", "[ 1/1 → 9/8 | s:hh ]", "[ 9/8 → 5/4 | s:hh ]", + "[ 5/4 → 11/8 | s:hh ]", "[ 11/8 → 3/2 | s:hh ]", "[ 3/2 → 13/8 | s:hh ]", "[ 13/8 → 7/4 | s:hh ]", "[ 7/4 → 15/8 | s:hh ]", "[ 15/8 → 2/1 | s:hh ]", - "[ 2/1 → 17/8 | s:hh ]", - "[ 17/8 → 9/4 | s:hh ]", "[ 9/4 → 19/8 | s:hh ]", "[ 5/2 → 21/8 | s:hh ]", "[ 21/8 → 11/4 | s:hh ]", "[ 11/4 → 23/8 | s:hh ]", + "[ 23/8 → 3/1 | s:hh ]", "[ 3/1 → 25/8 | s:hh ]", "[ 25/8 → 13/4 | s:hh ]", "[ 27/8 → 7/2 | s:hh ]", "[ 7/2 → 29/8 | s:hh ]", - "[ 29/8 → 15/4 | s:hh ]", - "[ 15/4 → 31/8 | s:hh ]", "[ 31/8 → 4/1 | s:hh ]", ] `; exports[`runs examples > example "undegradeBy" example index 1 1`] = ` [ - "[ 0/1 → 1/10 | s:hh pan:0 ]", - "[ 1/10 → 1/5 | s:hh pan:0 ]", + "[ 0/1 → 1/10 | s:hh pan:1 ]", + "[ 1/10 → 1/5 | s:hh pan:1 ]", "[ 1/5 → 3/10 | s:hh pan:0 ]", "[ 3/10 → 2/5 | s:hh pan:0 ]", "[ 2/5 → 1/2 | s:hh pan:0 ]", @@ -11829,18 +11840,18 @@ exports[`runs examples > example "undegradeBy" example index 1 1`] = ` "[ 7/10 → 4/5 | s:hh pan:0 ]", "[ 4/5 → 9/10 | s:hh pan:0 ]", "[ 9/10 → 1/1 | s:hh pan:0 ]", - "[ 1/1 → 11/10 | s:hh pan:1 ]", + "[ 1/1 → 11/10 | s:hh pan:0 ]", "[ 11/10 → 6/5 | s:hh pan:0 ]", "[ 6/5 → 13/10 | s:hh pan:0 ]", - "[ 13/10 → 7/5 | s:hh pan:1 ]", + "[ 13/10 → 7/5 | s:hh pan:0 ]", "[ 7/5 → 3/2 | s:hh pan:0 ]", - "[ 3/2 → 8/5 | s:hh pan:1 ]", + "[ 3/2 → 8/5 | s:hh pan:0 ]", "[ 8/5 → 17/10 | s:hh pan:0 ]", "[ 17/10 → 9/5 | s:hh pan:0 ]", "[ 9/5 → 19/10 | s:hh pan:0 ]", - "[ 19/10 → 2/1 | s:hh pan:0 ]", + "[ 19/10 → 2/1 | s:hh pan:1 ]", "[ 2/1 → 21/10 | s:hh pan:0 ]", - "[ 21/10 → 11/5 | s:hh pan:1 ]", + "[ 21/10 → 11/5 | s:hh pan:0 ]", "[ 11/5 → 23/10 | s:hh pan:0 ]", "[ 23/10 → 12/5 | s:hh pan:0 ]", "[ 12/5 → 5/2 | s:hh pan:0 ]", @@ -11851,14 +11862,14 @@ exports[`runs examples > example "undegradeBy" example index 1 1`] = ` "[ 29/10 → 3/1 | s:hh pan:0 ]", "[ 3/1 → 31/10 | s:hh pan:0 ]", "[ 31/10 → 16/5 | s:hh pan:1 ]", - "[ 16/5 → 33/10 | s:hh pan:0 ]", + "[ 16/5 → 33/10 | s:hh pan:1 ]", "[ 33/10 → 17/5 | s:hh pan:0 ]", "[ 17/5 → 7/2 | s:hh pan:0 ]", "[ 7/2 → 18/5 | s:hh pan:0 ]", "[ 18/5 → 37/10 | s:hh pan:0 ]", "[ 37/10 → 19/5 | s:hh pan:0 ]", - "[ 19/5 → 39/10 | s:hh pan:0 ]", - "[ 39/10 → 4/1 | s:hh pan:1 ]", + "[ 19/5 → 39/10 | s:hh pan:1 ]", + "[ 39/10 → 4/1 | s:hh pan:0 ]", ] `; @@ -11936,7 +11947,7 @@ exports[`runs examples > example "unit" example index 0 1`] = ` ] `; -exports[`runs examples > example "useOldRandom" example index 0 1`] = ` +exports[`runs examples > example "useRNG" example index 0 1`] = ` [ "[ 0/1 → 1/16 | note:D8 ]", "[ 1/16 → 1/8 | note:Bb7 ]", @@ -12163,38 +12174,38 @@ exports[`runs examples > example "vowel" example index 0 1`] = ` exports[`runs examples > example "vowel" example index 1 1`] = ` [ - "[ 0/1 → 1/8 | s:bd vowel:e ]", - "[ 1/8 → 1/4 | s:sd vowel:e ]", - "[ 1/4 → 3/8 | s:mt vowel:e ]", - "[ 3/8 → 1/2 | s:ht vowel:e ]", - "[ 1/2 → 5/8 | s:bd vowel:e ]", - "[ 11/16 → 3/4 | s:cp vowel:e ]", - "[ 3/4 → 7/8 | s:ht vowel:e ]", - "[ 7/8 → 1/1 | s:lt vowel:e ]", - "[ 1/1 → 9/8 | s:bd vowel:a ]", - "[ 9/8 → 5/4 | s:sd vowel:a ]", - "[ 5/4 → 11/8 | s:mt vowel:a ]", - "[ 11/8 → 3/2 | s:ht vowel:a ]", - "[ 3/2 → 13/8 | s:bd vowel:a ]", - "[ 27/16 → 7/4 | s:cp vowel:a ]", - "[ 7/4 → 15/8 | s:ht vowel:a ]", - "[ 15/8 → 2/1 | s:lt vowel:a ]", - "[ 2/1 → 17/8 | s:bd vowel:i ]", - "[ 17/8 → 9/4 | s:sd vowel:i ]", - "[ 9/4 → 19/8 | s:mt vowel:i ]", - "[ 19/8 → 5/2 | s:ht vowel:i ]", - "[ 5/2 → 21/8 | s:bd vowel:i ]", - "[ 43/16 → 11/4 | s:cp vowel:i ]", - "[ 11/4 → 23/8 | s:ht vowel:i ]", - "[ 23/8 → 3/1 | s:lt vowel:i ]", - "[ 3/1 → 25/8 | s:bd vowel:o ]", - "[ 25/8 → 13/4 | s:sd vowel:o ]", - "[ 13/4 → 27/8 | s:mt vowel:o ]", - "[ 27/8 → 7/2 | s:ht vowel:o ]", - "[ 7/2 → 29/8 | s:bd vowel:o ]", - "[ 59/16 → 15/4 | s:cp vowel:o ]", - "[ 15/4 → 31/8 | s:ht vowel:o ]", - "[ 31/8 → 4/1 | s:lt vowel:o ]", + "[ 0/1 → 1/8 | s:bd vowel:a ]", + "[ 1/8 → 1/4 | s:sd vowel:a ]", + "[ 1/4 → 3/8 | s:mt vowel:a ]", + "[ 3/8 → 1/2 | s:ht vowel:a ]", + "[ 1/2 → 5/8 | s:bd vowel:a ]", + "[ 11/16 → 3/4 | s:cp vowel:a ]", + "[ 3/4 → 7/8 | s:ht vowel:a ]", + "[ 7/8 → 1/1 | s:lt vowel:a ]", + "[ 1/1 → 9/8 | s:bd vowel:i ]", + "[ 9/8 → 5/4 | s:sd vowel:i ]", + "[ 5/4 → 11/8 | s:mt vowel:i ]", + "[ 11/8 → 3/2 | s:ht vowel:i ]", + "[ 3/2 → 13/8 | s:bd vowel:i ]", + "[ 27/16 → 7/4 | s:cp vowel:i ]", + "[ 7/4 → 15/8 | s:ht vowel:i ]", + "[ 15/8 → 2/1 | s:lt vowel:i ]", + "[ 2/1 → 17/8 | s:bd vowel:u ]", + "[ 17/8 → 9/4 | s:sd vowel:u ]", + "[ 9/4 → 19/8 | s:mt vowel:u ]", + "[ 19/8 → 5/2 | s:ht vowel:u ]", + "[ 5/2 → 21/8 | s:bd vowel:u ]", + "[ 43/16 → 11/4 | s:cp vowel:u ]", + "[ 11/4 → 23/8 | s:ht vowel:u ]", + "[ 23/8 → 3/1 | s:lt vowel:u ]", + "[ 3/1 → 25/8 | s:bd vowel:e ]", + "[ 25/8 → 13/4 | s:sd vowel:e ]", + "[ 13/4 → 27/8 | s:mt vowel:e ]", + "[ 27/8 → 7/2 | s:ht vowel:e ]", + "[ 7/2 → 29/8 | s:bd vowel:e ]", + "[ 59/16 → 15/4 | s:cp vowel:e ]", + "[ 15/4 → 31/8 | s:ht vowel:e ]", + "[ 31/8 → 4/1 | s:lt vowel:e ]", ] `; @@ -12316,16 +12327,16 @@ exports[`runs examples > example "wchoose" example index 0 1`] = ` "[ 7/5 → 8/5 | note:g2 s:sine ]", "[ 8/5 → 9/5 | note:d2 s:sine ]", "[ 9/5 → 2/1 | note:f1 s:sine ]", - "[ 2/1 → 11/5 | note:c2 s:sine ]", - "[ 11/5 → 12/5 | note:g2 s:bd n:6 ]", - "[ 12/5 → 13/5 | note:g2 s:sine ]", + "[ 2/1 → 11/5 | note:c2 s:bd n:6 ]", + "[ 11/5 → 12/5 | note:g2 s:sine ]", + "[ 12/5 → 13/5 | note:g2 s:bd n:6 ]", "[ 13/5 → 14/5 | note:d2 s:sine ]", "[ 14/5 → 3/1 | note:f1 s:sine ]", "[ 3/1 → 16/5 | note:c2 s:sine ]", "[ 16/5 → 17/5 | note:g2 s:sine ]", "[ 17/5 → 18/5 | note:g2 s:sine ]", "[ 18/5 → 19/5 | note:d2 s:sine ]", - "[ 19/5 → 4/1 | note:f1 s:bd n:6 ]", + "[ 19/5 → 4/1 | note:f1 s:sine ]", ] `; @@ -12333,33 +12344,33 @@ exports[`runs examples > example "wchooseCycles" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:bd ]", "[ 1/8 → 1/4 | s:bd ]", - "[ 1/4 → 3/8 | s:bd ]", + "[ 1/4 → 3/8 | s:sd ]", "[ 3/8 → 1/2 | s:bd ]", "[ 1/2 → 5/8 | s:bd ]", - "[ 5/8 → 3/4 | s:hh ]", + "[ 5/8 → 3/4 | s:bd ]", "[ 3/4 → 7/8 | s:bd ]", "[ 7/8 → 1/1 | s:bd ]", - "[ 1/1 → 9/8 | s:bd ]", + "[ 1/1 → 9/8 | s:hh ]", "[ 9/8 → 5/4 | s:bd ]", "[ 5/4 → 11/8 | s:bd ]", - "[ 11/8 → 3/2 | s:sd ]", + "[ 11/8 → 3/2 | s:bd ]", "[ 3/2 → 13/8 | s:bd ]", - "[ 13/8 → 7/4 | s:bd ]", + "[ 13/8 → 7/4 | s:sd ]", "[ 7/4 → 15/8 | s:bd ]", "[ 15/8 → 2/1 | s:bd ]", "[ 2/1 → 17/8 | s:bd ]", - "[ 17/8 → 9/4 | s:hh ]", - "[ 9/4 → 19/8 | s:hh ]", - "[ 19/8 → 5/2 | s:hh ]", + "[ 17/8 → 9/4 | s:bd ]", + "[ 9/4 → 19/8 | s:bd ]", + "[ 19/8 → 5/2 | s:bd ]", "[ 5/2 → 21/8 | s:bd ]", "[ 21/8 → 11/4 | s:bd ]", - "[ 11/4 → 23/8 | s:hh ]", - "[ 23/8 → 3/1 | s:sd ]", + "[ 11/4 → 23/8 | s:sd ]", + "[ 23/8 → 3/1 | s:bd ]", "[ 3/1 → 25/8 | s:bd ]", - "[ 25/8 → 13/4 | s:hh ]", + "[ 25/8 → 13/4 | s:bd ]", "[ 13/4 → 27/8 | s:bd ]", "[ 27/8 → 7/2 | s:bd ]", - "[ 7/2 → 29/8 | s:sd ]", + "[ 7/2 → 29/8 | s:bd ]", "[ 29/8 → 15/4 | s:bd ]", "[ 15/4 → 31/8 | s:bd ]", "[ 31/8 → 4/1 | s:bd ]", @@ -12374,45 +12385,45 @@ exports[`runs examples > example "wchooseCycles" example index 1 1`] = ` "[ 1/4 → 1/3 | s:bd ]", "[ 1/3 → 5/12 | s:bd ]", "[ 5/12 → 1/2 | s:bd ]", - "[ 1/2 → 7/12 | s:hh ]", - "[ 7/12 → 2/3 | s:hh ]", - "[ 2/3 → 3/4 | s:hh ]", - "[ 3/4 → 5/6 | s:hh ]", - "[ 5/6 → 11/12 | s:hh ]", - "[ 11/12 → 1/1 | s:hh ]", + "[ 1/2 → 7/12 | s:sd ]", + "[ 7/12 → 2/3 | s:sd ]", + "[ 2/3 → 3/4 | s:sd ]", + "[ 3/4 → 5/6 | s:bd ]", + "[ 5/6 → 11/12 | s:bd ]", + "[ 11/12 → 1/1 | s:bd ]", "[ 1/1 → 13/12 | s:bd ]", "[ 13/12 → 7/6 | s:bd ]", "[ 7/6 → 5/4 | s:bd ]", - "[ 5/4 → 4/3 | s:hh ]", - "[ 4/3 → 17/12 | s:hh ]", - "[ 17/12 → 3/2 | s:hh ]", - "[ 3/2 → 19/12 | s:bd ]", - "[ 19/12 → 5/3 | s:bd ]", - "[ 5/3 → 7/4 | s:bd ]", - "[ 7/4 → 11/6 | s:hh ]", - "[ 11/6 → 23/12 | s:hh ]", - "[ 23/12 → 2/1 | s:hh ]", + "[ 5/4 → 4/3 | s:bd ]", + "[ 4/3 → 17/12 | s:bd ]", + "[ 17/12 → 3/2 | s:bd ]", + "[ 3/2 → 19/12 | s:hh ]", + "[ 19/12 → 5/3 | s:hh ]", + "[ 5/3 → 7/4 | s:hh ]", + "[ 7/4 → 11/6 | s:bd ]", + "[ 11/6 → 23/12 | s:bd ]", + "[ 23/12 → 2/1 | s:bd ]", "[ 2/1 → 25/12 | s:hh ]", "[ 25/12 → 13/6 | s:hh ]", "[ 13/6 → 9/4 | s:hh ]", "[ 9/4 → 7/3 | s:hh ]", "[ 7/3 → 29/12 | s:hh ]", "[ 29/12 → 5/2 | s:hh ]", - "[ 5/2 → 31/12 | s:hh ]", - "[ 31/12 → 8/3 | s:hh ]", - "[ 8/3 → 11/4 | s:hh ]", - "[ 11/4 → 17/6 | s:sd ]", - "[ 17/6 → 35/12 | s:sd ]", - "[ 35/12 → 3/1 | s:sd ]", - "[ 3/1 → 37/12 | s:hh ]", - "[ 37/12 → 19/6 | s:hh ]", - "[ 19/6 → 13/4 | s:hh ]", - "[ 13/4 → 10/3 | s:bd ]", - "[ 10/3 → 41/12 | s:bd ]", - "[ 41/12 → 7/2 | s:bd ]", - "[ 7/2 → 43/12 | s:bd ]", - "[ 43/12 → 11/3 | s:bd ]", - "[ 11/3 → 15/4 | s:bd ]", + "[ 5/2 → 31/12 | s:bd ]", + "[ 31/12 → 8/3 | s:bd ]", + "[ 8/3 → 11/4 | s:bd ]", + "[ 11/4 → 17/6 | s:bd ]", + "[ 17/6 → 35/12 | s:bd ]", + "[ 35/12 → 3/1 | s:bd ]", + "[ 3/1 → 37/12 | s:bd ]", + "[ 37/12 → 19/6 | s:bd ]", + "[ 19/6 → 13/4 | s:bd ]", + "[ 13/4 → 10/3 | s:sd ]", + "[ 10/3 → 41/12 | s:sd ]", + "[ 41/12 → 7/2 | s:sd ]", + "[ 7/2 → 43/12 | s:hh ]", + "[ 43/12 → 11/3 | s:hh ]", + "[ 11/3 → 15/4 | s:hh ]", "[ 15/4 → 23/6 | s:bd ]", "[ 23/6 → 47/12 | s:bd ]", "[ 47/12 → 4/1 | s:bd ]", @@ -12427,9 +12438,9 @@ exports[`runs examples > example "wchooseCycles" example index 2 1`] = ` "[ 1/4 → 1/3 | s:hh ]", "[ 1/3 → 5/12 | s:hh ]", "[ 5/12 → 1/2 | s:hh ]", - "[ 1/2 → 17/32 | s:bd ]", - "[ 19/32 → 5/8 | s:bd ]", - "[ 11/16 → 23/32 | s:bd ]", + "[ 1/2 → 7/12 | s:hh ]", + "[ 7/12 → 2/3 | s:hh ]", + "[ 2/3 → 3/4 | s:hh ]", "[ 3/4 → 5/6 | s:hh ]", "[ 5/6 → 11/12 | s:hh ]", "[ 11/12 → 1/1 | s:hh ]", @@ -12445,27 +12456,27 @@ exports[`runs examples > example "wchooseCycles" example index 2 1`] = ` "[ 7/4 → 11/6 | s:hh ]", "[ 11/6 → 23/12 | s:hh ]", "[ 23/12 → 2/1 | s:hh ]", - "[ 2/1 → 65/32 | s:bd ]", - "[ 67/32 → 17/8 | s:bd ]", - "[ 35/16 → 71/32 | s:bd ]", + "[ 2/1 → 25/12 | s:hh ]", + "[ 25/12 → 13/6 | s:hh ]", + "[ 13/6 → 9/4 | s:hh ]", "[ 9/4 → 7/3 | s:hh ]", "[ 7/3 → 29/12 | s:hh ]", "[ 29/12 → 5/2 | s:hh ]", - "[ 5/2 → 31/12 | s:hh ]", - "[ 31/12 → 8/3 | s:hh ]", - "[ 8/3 → 11/4 | s:hh ]", + "[ 5/2 → 81/32 | s:bd ]", + "[ 83/32 → 21/8 | s:bd ]", + "[ 43/16 → 87/32 | s:bd ]", "[ 11/4 → 17/6 | s:hh ]", "[ 17/6 → 35/12 | s:hh ]", "[ 35/12 → 3/1 | s:hh ]", - "[ 3/1 → 37/12 | s:hh ]", - "[ 37/12 → 19/6 | s:hh ]", - "[ 19/6 → 13/4 | s:hh ]", + "[ 3/1 → 97/32 | s:bd ]", + "[ 99/32 → 25/8 | s:bd ]", + "[ 51/16 → 103/32 | s:bd ]", "[ 13/4 → 10/3 | s:hh ]", "[ 10/3 → 41/12 | s:hh ]", "[ 41/12 → 7/2 | s:hh ]", - "[ 7/2 → 113/32 | s:bd ]", - "[ 115/32 → 29/8 | s:bd ]", - "[ 59/16 → 119/32 | s:bd ]", + "[ 7/2 → 43/12 | s:hh ]", + "[ 43/12 → 11/3 | s:hh ]", + "[ 11/3 → 15/4 | s:hh ]", "[ 15/4 → 23/6 | s:hh ]", "[ 23/6 → 47/12 | s:hh ]", "[ 47/12 → 4/1 | s:hh ]", diff --git a/vitest.setup.mjs b/vitest.setup.mjs index bb9d24b07..ea965df6d 100644 --- a/vitest.setup.mjs +++ b/vitest.setup.mjs @@ -1,7 +1,7 @@ import { afterEach } from 'vitest'; -import { useOldRandom } from './packages/core/signal.mjs'; +import { useRNG } from './packages/core/signal.mjs'; afterEach(() => { // Avoid bleed between tests - useOldRandom(false); + useRNG('legacy'); }); diff --git a/website/src/repl/tunes.mjs b/website/src/repl/tunes.mjs index 23efb6062..697e83c9d 100644 --- a/website/src/repl/tunes.mjs +++ b/website/src/repl/tunes.mjs @@ -393,7 +393,7 @@ samples({ bass: { d2: 'https://cdn.freesound.org/previews/608/608286_13074022-lq.mp3' } }) -useOldRandom(true) +useRNG('legacy') stack( // bells @@ -432,7 +432,7 @@ export const festivalOfFingers3 = `// "Festival of fingers 3" // @by Felix Roos setcps(1) -useOldRandom(true) +useRNG('legacy') n("[-7*3],0,2,6,[8 7]") .echoWith( @@ -457,7 +457,7 @@ export const meltingsubmarine = `// "Melting submarine" // @by Felix Roos samples('github:tidalcycles/dirt-samples') -useOldRandom(true) +useRNG('legacy') stack( s("bd:5,[~ ],hh27(3,4,1)") // drums @@ -608,7 +608,7 @@ export const belldub = `// "Belldub" samples({ bell: {b4:'https://cdn.freesound.org/previews/339/339809_5121236-lq.mp3'}}) // "Hand Bells, B, Single.wav" by InspectorJ (www.jshaw.co.uk) of Freesound.org -useOldRandom(true) +useRNG('legacy') stack( // bass @@ -646,7 +646,7 @@ export const dinofunk = `// "Dinofunk" // @by Felix Roos setcps(1) -useOldRandom(true) +useRNG('legacy') samples({bass:'https://cdn.freesound.org/previews/614/614637_2434927-hq.mp3', dino:{b4:'https://cdn.freesound.org/previews/316/316403_5123851-hq.mp3'}}) @@ -675,7 +675,7 @@ export const sampleDemo = `// "Sample demo" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos -useOldRandom(true) +useRNG('legacy') stack( // percussion @@ -695,7 +695,7 @@ export const holyflute = `// "Holy flute" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos -useOldRandom(true) +useRNG('legacy') "c3 eb3(3,8) c4/2 g3*2" .superimpose( @@ -712,7 +712,7 @@ export const flatrave = `// "Flatrave" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos -useOldRandom(true) +useRNG('legacy') stack( s("bd*2,~ [cp,sd]").bank('RolandTR909'), @@ -742,7 +742,7 @@ export const amensister = `// "Amensister" samples('github:tidalcycles/dirt-samples') -useOldRandom(true) +useRNG('legacy') stack( // amen @@ -851,7 +851,7 @@ export const arpoon = `// "Arpoon" // @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ // @by Felix Roos -useOldRandom(true) +useRNG('legacy') samples('github:tidalcycles/dirt-samples') From e0344dbd67c741a4586e0d345bf4cbe85d43d4c6 Mon Sep 17 00:00:00 2001 From: Aria Date: Sat, 13 Dec 2025 17:49:19 -0600 Subject: [PATCH 64/66] Simple seeding for this first iteration --- packages/core/signal.mjs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index a56009add..c7e143ae6 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -359,7 +359,7 @@ export const binaryNL = (n, nBits = 16) => { * .partials(randL(8)) */ export const randL = (n) => { - return signal((t) => (nVal) => timeToRands(t, nVal).map(Math.abs)).appLeft(reify(n)); + return signal((t) => (nVal) => getRandsAtTime(t, nVal).map(Math.abs)).appLeft(reify(n)); }; export const randrun = (n) => { @@ -434,19 +434,6 @@ export const withSeed = (func, pat) => { * $: s("bd*4").degrade().seed(1); // Will degrade different events from the hi-hat */ export const seed = register('seed', (n, pat) => { - return withSeed((prev) => (prev !== undefined ? randAt(prev, n) * Number.MAX_SAFE_INTEGER : n), pat); -}); - -/** - * Set the seed for random signals. Differs from `seed` in that `seed` can be used - * multiple times with the final signal depending on all seeds. `setSeed` on the - * other hand overwrites the previous calls to `seed`. - * - * @name setSeed - * @param {number} n An arbitrary number to be used as the new seed. 0 is the same - * as the default random behavior. - */ -export const setSeed = register('setSeed', (n, pat) => { return withSeed(() => n, pat); }); From 34991e9602a3d1f194d99ff45c48a4640edcdaaa Mon Sep 17 00:00:00 2001 From: jeromew Date: Sun, 14 Dec 2025 11:27:41 +0000 Subject: [PATCH 65/66] Fix: wrong warning in build environments --- packages/superdough/helpers.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superdough/helpers.mjs b/packages/superdough/helpers.mjs index 5abc2bad1..a3ba7df99 100644 --- a/packages/superdough/helpers.mjs +++ b/packages/superdough/helpers.mjs @@ -593,7 +593,7 @@ export const releaseAudioNode = (node) => { // make sure all AudioScheduledSourceNodes are in a stopped state // https://developer.mozilla.org/en-US/docs/Web/API/AudioScheduledSourceNode if (node instanceof AudioScheduledSourceNode) { - if (node.onended && node.onended.name !== 'cleanup') { + if (process.env.NODE_ENV === 'development' && node.onended && node.onended.name !== 'cleanup') { logger( `[superdough] Deprecation warning: it seems your code path is setting 'node.onended = callback' instead of using the onceEnded helper`, ); From 0de212c12f1ecb7a6905c9073b21907b88529245 Mon Sep 17 00:00:00 2001 From: Dsm0 Date: Thu, 18 Dec 2025 22:55:44 -0800 Subject: [PATCH 66/66] fix visual block mode --- packages/codemirror/keybindings.mjs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/keybindings.mjs b/packages/codemirror/keybindings.mjs index 81dc87a52..d92e9c959 100644 --- a/packages/codemirror/keybindings.mjs +++ b/packages/codemirror/keybindings.mjs @@ -1,5 +1,5 @@ import { defaultKeymap } from '@codemirror/commands'; -import { Prec } from '@codemirror/state'; +import { Prec, EditorState } from '@codemirror/state'; import { keymap, ViewPlugin } from '@codemirror/view'; // import { searchKeymap } from '@codemirror/search'; import { emacs } from '@replit/codemirror-emacs'; @@ -133,5 +133,9 @@ const keymaps = { export function keybindings(name) { const active = keymaps[name]; - return [active ? Prec.high(active()) : []]; + const extensions = active ? [Prec.high(active())] : []; + if (name === 'vim') { + extensions.push(EditorState.allowMultipleSelections.of(true)); + } + return extensions; }