From 1241911ec0098cd10d7847f64e2e5afe7a2599a4 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 31 Aug 2023 07:53:41 +0200 Subject: [PATCH] rename more stuff + pull out fork --- packages/core/controls.mjs | 2 +- packages/superdough/zzfx.mjs | 134 ++---------------------------- packages/superdough/zzfx_fork.mjs | 118 ++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 127 deletions(-) create mode 100644 packages/superdough/zzfx_fork.mjs diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 109fda87..47d77253 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -805,7 +805,7 @@ const generic_params = [ // ZZFX ['zrand'], - ['shapeCurve'], + ['curve'], ['slide'], // superdirt duplicate ['deltaSlide'], ['pitchJump'], diff --git a/packages/superdough/zzfx.mjs b/packages/superdough/zzfx.mjs index 4ec77632..c57901fb 100644 --- a/packages/superdough/zzfx.mjs +++ b/packages/superdough/zzfx.mjs @@ -1,6 +1,7 @@ //import { ZZFX } from 'zzfx'; import { midiToFreq, noteToMidi } from './util.mjs'; import { registerSound, getAudioContext } from './superdough.mjs'; +import { buildSamples } from './zzfx_fork.mjs'; export const getZZFX = (value, t) => { let { @@ -13,14 +14,14 @@ export const getZZFX = (value, t) => { decay = 0, sustain = 0.8, release = 0.1, - shapeCurve = 1, + curve = 1, slide = 0, deltaSlide = 0, pitchJump = 0, pitchJumpTime = 0, repeatTime = 0, noise = 0, - modulation = 0, + zmod = 0, zcrush = 0, zdelay = 0, tremolo = 0, @@ -36,7 +37,7 @@ export const getZZFX = (value, t) => { } s = s.replace('z_', ''); const shape = ['sine', 'triangle', 'sawtooth', 'tan', 'noise'].indexOf(s) || 0; - shapeCurve = s === 'square' ? 0 : shapeCurve; + curve = s === 'square' ? 0 : curve; const params = [ 0.25, // volume @@ -46,14 +47,14 @@ export const getZZFX = (value, t) => { sustainTime, release, shape, - shapeCurve, + curve, slide, deltaSlide, pitchJump, pitchJumpTime, repeatTime, noise, - modulation, + zmod, zcrush, zdelay, sustain, // sustain volume! @@ -104,14 +105,14 @@ function redableZZFX(params) { 'sustain', 'release', 'shape', - 'shapeCurve', + 'curve', 'slide', 'deltaSlide', 'pitchJump', 'pitchJumpTime', 'repeatTime', 'noise', - 'modulation', + 'zmod', 'zcrush', 'zdelay', 'sustainVolume', @@ -120,122 +121,3 @@ function redableZZFX(params) { ]; return Object.fromEntries(paramOrder.map((param, i) => [param, params[i]])); } - -// https://github.com/KilledByAPixel/ZzFX/blob/master/ZzFX.js#L85C5-L180C6 -// changes: replaced this.volume with 1 + using sampleRate from getAudioContext() -function buildSamples( - volume = 1, - randomness = 0.05, - frequency = 220, - attack = 0, - sustain = 0, - release = 0.1, - shape = 0, - shapeCurve = 1, - slide = 0, - deltaSlide = 0, - pitchJump = 0, - pitchJumpTime = 0, - repeatTime = 0, - noise = 0, - modulation = 0, - bitCrush = 0, - delay = 0, - sustainVolume = 1, - decay = 0, - tremolo = 0, -) { - // init parameters - let PI2 = Math.PI * 2, - sampleRate = getAudioContext().sampleRate, - sign = (v) => (v > 0 ? 1 : -1), - startSlide = (slide *= (500 * PI2) / sampleRate / sampleRate), - startFrequency = (frequency *= ((1 + randomness * 2 * Math.random() - randomness) * PI2) / sampleRate), - b = [], - t = 0, - tm = 0, - i = 0, - j = 1, - r = 0, - c = 0, - s = 0, - f, - length; - - // scale by sample rate - attack = attack * sampleRate + 9; // minimum attack to prevent pop - decay *= sampleRate; - sustain *= sampleRate; - release *= sampleRate; - delay *= sampleRate; - deltaSlide *= (500 * PI2) / sampleRate ** 3; - modulation *= PI2 / sampleRate; - pitchJump *= PI2 / sampleRate; - pitchJumpTime *= sampleRate; - repeatTime = (repeatTime * sampleRate) | 0; - - // generate waveform - for (length = (attack + decay + sustain + release + delay) | 0; i < length; b[i++] = s) { - if (!(++c % ((bitCrush * 100) | 0))) { - // bit crush - s = shape - ? shape > 1 - ? shape > 2 - ? shape > 3 // wave shape - ? Math.sin((t % PI2) ** 3) // 4 noise - : Math.max(Math.min(Math.tan(t), 1), -1) // 3 tan - : 1 - (((((2 * t) / PI2) % 2) + 2) % 2) // 2 saw - : 1 - 4 * Math.abs(Math.round(t / PI2) - t / PI2) // 1 triangle - : Math.sin(t); // 0 sin - - s = - (repeatTime - ? 1 - tremolo + tremolo * Math.sin((PI2 * i) / repeatTime) // tremolo - : 1) * - sign(s) * - Math.abs(s) ** shapeCurve * // curve 0=square, 2=pointy - volume * - 1 * // envelope - (i < attack - ? i / attack // attack - : i < attack + decay // decay - ? 1 - ((i - attack) / decay) * (1 - sustainVolume) // decay falloff - : i < attack + decay + sustain // sustain - ? sustainVolume // sustain volume - : i < length - delay // release - ? ((length - i - delay) / release) * // release falloff - sustainVolume // release volume - : 0); // post release - - s = delay - ? s / 2 + - (delay > i - ? 0 // delay - : ((i < length - delay ? 1 : (length - i) / delay) * // release delay - b[(i - delay) | 0]) / - 2) - : s; // sample delay - } - - f = - (frequency += slide += deltaSlide) * // frequency - Math.cos(modulation * tm++); // modulation - t += f - f * noise * (1 - (((Math.sin(i) + 1) * 1e9) % 2)); // noise - - if (j && ++j > pitchJumpTime) { - // pitch jump - frequency += pitchJump; // apply pitch jump - startFrequency += pitchJump; // also apply to start - j = 0; // stop pitch jump time - } - - if (repeatTime && !(++r % repeatTime)) { - // repeat - frequency = startFrequency; // reset frequency - slide = startSlide; // reset slide - j ||= 1; // reset pitch jump time - } - } - - return b; -} diff --git a/packages/superdough/zzfx_fork.mjs b/packages/superdough/zzfx_fork.mjs new file mode 100644 index 00000000..a2e496ff --- /dev/null +++ b/packages/superdough/zzfx_fork.mjs @@ -0,0 +1,118 @@ +// https://github.com/KilledByAPixel/ZzFX/blob/master/ZzFX.js#L85C5-L180C6 +// changes: replaced this.volume with 1 + using sampleRate from getAudioContext() +export function buildSamples( + volume = 1, + randomness = 0.05, + frequency = 220, + attack = 0, + sustain = 0, + release = 0.1, + shape = 0, + shapeCurve = 1, + slide = 0, + deltaSlide = 0, + pitchJump = 0, + pitchJumpTime = 0, + repeatTime = 0, + noise = 0, + modulation = 0, + bitCrush = 0, + delay = 0, + sustainVolume = 1, + decay = 0, + tremolo = 0, +) { + // init parameters + let PI2 = Math.PI * 2, + sampleRate = getAudioContext().sampleRate, + sign = (v) => (v > 0 ? 1 : -1), + startSlide = (slide *= (500 * PI2) / sampleRate / sampleRate), + startFrequency = (frequency *= ((1 + randomness * 2 * Math.random() - randomness) * PI2) / sampleRate), + b = [], + t = 0, + tm = 0, + i = 0, + j = 1, + r = 0, + c = 0, + s = 0, + f, + length; + + // scale by sample rate + attack = attack * sampleRate + 9; // minimum attack to prevent pop + decay *= sampleRate; + sustain *= sampleRate; + release *= sampleRate; + delay *= sampleRate; + deltaSlide *= (500 * PI2) / sampleRate ** 3; + modulation *= PI2 / sampleRate; + pitchJump *= PI2 / sampleRate; + pitchJumpTime *= sampleRate; + repeatTime = (repeatTime * sampleRate) | 0; + + // generate waveform + for (length = (attack + decay + sustain + release + delay) | 0; i < length; b[i++] = s) { + if (!(++c % ((bitCrush * 100) | 0))) { + // bit crush + s = shape + ? shape > 1 + ? shape > 2 + ? shape > 3 // wave shape + ? Math.sin((t % PI2) ** 3) // 4 noise + : Math.max(Math.min(Math.tan(t), 1), -1) // 3 tan + : 1 - (((((2 * t) / PI2) % 2) + 2) % 2) // 2 saw + : 1 - 4 * Math.abs(Math.round(t / PI2) - t / PI2) // 1 triangle + : Math.sin(t); // 0 sin + + s = + (repeatTime + ? 1 - tremolo + tremolo * Math.sin((PI2 * i) / repeatTime) // tremolo + : 1) * + sign(s) * + Math.abs(s) ** shapeCurve * // curve 0=square, 2=pointy + volume * + 1 * // envelope + (i < attack + ? i / attack // attack + : i < attack + decay // decay + ? 1 - ((i - attack) / decay) * (1 - sustainVolume) // decay falloff + : i < attack + decay + sustain // sustain + ? sustainVolume // sustain volume + : i < length - delay // release + ? ((length - i - delay) / release) * // release falloff + sustainVolume // release volume + : 0); // post release + + s = delay + ? s / 2 + + (delay > i + ? 0 // delay + : ((i < length - delay ? 1 : (length - i) / delay) * // release delay + b[(i - delay) | 0]) / + 2) + : s; // sample delay + } + + f = + (frequency += slide += deltaSlide) * // frequency + Math.cos(modulation * tm++); // modulation + t += f - f * noise * (1 - (((Math.sin(i) + 1) * 1e9) % 2)); // noise + + if (j && ++j > pitchJumpTime) { + // pitch jump + frequency += pitchJump; // apply pitch jump + startFrequency += pitchJump; // also apply to start + j = 0; // stop pitch jump time + } + + if (repeatTime && !(++r % repeatTime)) { + // repeat + frequency = startFrequency; // reset frequency + slide = startSlide; // reset slide + j ||= 1; // reset pitch jump time + } + } + + return b; +}