From 3d37c731036db98593617bbb031c1d46dc292125 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Thu, 29 May 2025 14:32:52 +0200 Subject: [PATCH 1/3] fixed --- packages/core/controls.mjs | 4 ++-- packages/superdough/synth.mjs | 2 +- packages/superdough/worklets.mjs | 17 +++++++++-------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 3fa4b0507..21c183da9 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -464,9 +464,9 @@ export const { byteBeatExpression, bbexpr } = registerControl('byteBeatExpressio * @name byteBeatStartTime * @synonyms bbst * - * @param {number | Pattern} byteBeatStartTime in seconds + * @param {number | Pattern} byteBeatStartTime in samples (t) * @example - * note("{c g a b c d}%16").s("bytebeat").bbexpr('t&t>>8').bbst("<0 300>") + * note("c3!8".add("{0 0 12 0 7 5 3}%8")).s("bytebeat:5").bbst("<3 1>".mul(10000))._scope() * */ export const { byteBeatStartTime, bbst } = registerControl('byteBeatStartTime', 'bbst'); diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 670ef44bb..834e54c6d 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -192,7 +192,7 @@ export function registerSynthSounds() { }, ); - o.port.postMessage({ codeText: byteBeatExpression, startTimeSeconds: byteBeatStartTime, frequency }); + o.port.postMessage({ codeText: byteBeatExpression, byteBeatStartTime, frequency }); let envGain = gainNode(1); envGain = o.connect(envGain); diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index ec1f41e7b..aa0fe5662 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -811,11 +811,10 @@ class ByteBeatProcessor extends AudioWorkletProcessor { super(); this.port.onmessage = (event) => { let { codeText } = event.data; - const { startTimeSeconds, frequency } = event.data; - if (startTimeSeconds != null) { - const t = startTimeSeconds * sampleRate; - this.t = t; - this.t = (t / (sampleRate / 256)) * frequency; + const { byteBeatStartTime } = event.data; + if (byteBeatStartTime != null) { + this.t = 0 + this.initialOffset = Math.floor(byteBeatStartTime) } //Optimization pulled from dollchan.net: https://github.com/Chasyxx/EnBeat_NEW, it seemed important @@ -829,6 +828,7 @@ class ByteBeatProcessor extends AudioWorkletProcessor { this.func = getByteBeatFunc(codeText); }; + this.initialOffset = null; this.t = null; this.func = null; } @@ -878,13 +878,14 @@ class ByteBeatProcessor extends AudioWorkletProcessor { for (let i = 0; i < output[0].length; i++) { const detune = getParamValue(i, params.detune); const freq = applySemitoneDetuneToFrequency(getParamValue(i, params.frequency), detune / 100); - let t = (this.t / (sampleRate / 256)) * freq; - const funcValue = this.func(t); + let local_t = ((this.t / (sampleRate / 256)) * freq) + this.initialOffset + const funcValue = this.func(local_t); let signal = (funcValue & 255) / 127.5 - 1; const out = signal * 0.2; for (let c = 0; c < output.length; c++) { - output[c][i] = clamp(out, -0.2, 0.2); + //prevent speaker blowout via clipping if threshold exceeds + output[c][i] = clamp(out, -0.4, 0.4); } this.t = this.t + 1; } From 009f5445bef7571675e03b7be41e5cd55f94a2be Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Thu, 29 May 2025 14:33:25 +0200 Subject: [PATCH 2/3] codeformat --- packages/superdough/worklets.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index aa0fe5662..24f7434a9 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -813,8 +813,8 @@ class ByteBeatProcessor extends AudioWorkletProcessor { let { codeText } = event.data; const { byteBeatStartTime } = event.data; if (byteBeatStartTime != null) { - this.t = 0 - this.initialOffset = Math.floor(byteBeatStartTime) + this.t = 0; + this.initialOffset = Math.floor(byteBeatStartTime); } //Optimization pulled from dollchan.net: https://github.com/Chasyxx/EnBeat_NEW, it seemed important @@ -878,7 +878,7 @@ class ByteBeatProcessor extends AudioWorkletProcessor { for (let i = 0; i < output[0].length; i++) { const detune = getParamValue(i, params.detune); const freq = applySemitoneDetuneToFrequency(getParamValue(i, params.frequency), detune / 100); - let local_t = ((this.t / (sampleRate / 256)) * freq) + this.initialOffset + let local_t = (this.t / (sampleRate / 256)) * freq + this.initialOffset; const funcValue = this.func(local_t); let signal = (funcValue & 255) / 127.5 - 1; const out = signal * 0.2; From 14a0dea826293f31d7fc39a908ad40877cbeab79 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Thu, 29 May 2025 14:35:37 +0200 Subject: [PATCH 3/3] fixtest --- test/__snapshots__/examples.test.mjs.snap | 146 +++++----------------- 1 file changed, 32 insertions(+), 114 deletions(-) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index f886987ab..34914664d 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -1527,70 +1527,38 @@ exports[`runs examples > example "byteBeatExpression" example index 0 1`] = ` exports[`runs examples > example "byteBeatStartTime" example index 0 1`] = ` [ - "[ 0/1 → 1/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 1/16 → 1/8 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 1/8 → 3/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 3/16 → 1/4 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 1/4 → 5/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 5/16 → 3/8 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 3/8 → 7/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 7/16 → 1/2 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 1/2 → 9/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 9/16 → 5/8 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 5/8 → 11/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 11/16 → 3/4 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 3/4 → 13/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 13/16 → 7/8 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 7/8 → 15/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 15/16 → 1/1 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 1/1 → 17/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 17/16 → 9/8 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 9/8 → 19/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 19/16 → 5/4 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 5/4 → 21/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 21/16 → 11/8 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 11/8 → 23/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 23/16 → 3/2 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 3/2 → 25/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 25/16 → 13/8 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 13/8 → 27/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 27/16 → 7/4 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 7/4 → 29/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 29/16 → 15/8 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 15/8 → 31/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 31/16 → 2/1 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 2/1 → 33/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 33/16 → 17/8 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 17/8 → 35/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 35/16 → 9/4 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 9/4 → 37/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 37/16 → 19/8 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 19/8 → 39/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 39/16 → 5/2 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 5/2 → 41/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 41/16 → 21/8 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 21/8 → 43/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 43/16 → 11/4 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 11/4 → 45/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 45/16 → 23/8 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 23/8 → 47/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 47/16 → 3/1 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:0 ]", - "[ 3/1 → 49/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 49/16 → 25/8 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 25/8 → 51/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 51/16 → 13/4 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 13/4 → 53/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 53/16 → 27/8 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 27/8 → 55/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 55/16 → 7/2 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 7/2 → 57/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 57/16 → 29/8 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 29/8 → 59/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 59/16 → 15/4 | note:d s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 15/4 → 61/16 | note:c s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 61/16 → 31/8 | note:g s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 31/8 → 63/16 | note:a s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", - "[ 63/16 → 4/1 | note:b s:bytebeat byteBeatExpression:t&t>>8 byteBeatStartTime:300 ]", + "[ 0/1 → 1/8 | note:48 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 1/8 → 1/4 | note:48 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 1/4 → 3/8 | note:60 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 3/8 → 1/2 | note:48 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 1/2 → 5/8 | note:55 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 5/8 → 3/4 | note:53 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 3/4 → 7/8 | note:51 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 7/8 → 1/1 | note:48 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 1/1 → 9/8 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 9/8 → 5/4 | note:60 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 5/4 → 11/8 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 11/8 → 3/2 | note:55 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 3/2 → 13/8 | note:53 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 13/8 → 7/4 | note:51 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 7/4 → 15/8 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 15/8 → 2/1 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 2/1 → 17/8 | note:60 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 17/8 → 9/4 | note:48 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 9/4 → 19/8 | note:55 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 19/8 → 5/2 | note:53 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 5/2 → 21/8 | note:51 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 21/8 → 11/4 | note:48 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 11/4 → 23/8 | note:48 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 23/8 → 3/1 | note:60 s:bytebeat n:5 byteBeatStartTime:30000 ]", + "[ 3/1 → 25/8 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 25/8 → 13/4 | note:55 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 13/4 → 27/8 | note:53 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 27/8 → 7/2 | note:51 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 7/2 → 29/8 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 29/8 → 15/4 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 15/4 → 31/8 | note:60 s:bytebeat n:5 byteBeatStartTime:10000 ]", + "[ 31/8 → 4/1 | note:48 s:bytebeat n:5 byteBeatStartTime:10000 ]", ] `; @@ -8100,56 +8068,6 @@ exports[`runs examples > example "scope" example index 0 1`] = ` ] `; -exports[`runs examples > example "scramble -Slices a pattern into the given number of parts, then plays those parts at random. Similar to \`shuffle\`, -but parts might be played more than once, or not at all, per cycle." example index 0 1`] = ` -[ - "[ 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: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:d s:piano ]", - "[ 15/4 → 4/1 | note:f s:piano ]", -] -`; - -exports[`runs examples > example "scramble -Slices a pattern into the given number of parts, then plays those parts at random. Similar to \`shuffle\`, -but parts might be played more than once, or not at all, per cycle." example index 1 1`] = ` -[ - "[ 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:c s:piano ]", - "[ 1/2 → 1/1 | note:g 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: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:c s:piano ]", - "[ 25/8 → 13/4 | note:f 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 ]", -] -`; - exports[`runs examples > example "scramble" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:c s:piano ]",