mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-12 06:08:34 +00:00
fix: use custom version of ZZFX
- ZZFX audio context broke tests - only needed buildSamples function
This commit is contained in:
parent
90cdea3656
commit
b991cfc493
@ -161,5 +161,6 @@ Then just make sure your first call of `superdough` happens after a click of som
|
||||
|
||||
## Credits
|
||||
|
||||
- [ZZFX](https://github.com/KilledByAPixel/ZzFX) used for synths starting with z
|
||||
- [SuperDirt](https://github.com/musikinformatik/SuperDirt)
|
||||
- [WebDirt](https://github.com/dktr0/WebDirt)
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
"vite": "^4.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"nanostores": "^0.8.1",
|
||||
"zzfx": "^1.2.0"
|
||||
"nanostores": "^0.8.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ZZFX } from 'zzfx';
|
||||
//import { ZZFX } from 'zzfx';
|
||||
import { midiToFreq, noteToMidi } from './util.mjs';
|
||||
import { registerSound, getAudioContext } from './superdough.mjs';
|
||||
|
||||
@ -82,7 +82,7 @@ export const getZZFX = (value, t, duration) => {
|
||||
const readableParams = Object.fromEntries(paramOrder.map((param, i) => [param, params[i]]));
|
||||
console.log(readableParams);
|
||||
|
||||
const samples = ZZFX.buildSamples(...params);
|
||||
const samples = /* ZZFX. */ buildSamples(...params);
|
||||
const context = getAudioContext();
|
||||
const buffer = context.createBuffer(1, samples.length, context.sampleRate);
|
||||
buffer.getChannelData(0).set(samples);
|
||||
@ -98,7 +98,7 @@ export function registerZZFXSounds() {
|
||||
console.log('registerZZFXSounds');
|
||||
['zsine', 'zsaw', 'ztri', 'ztan', 'znoise'].forEach((wave) => {
|
||||
registerSound(wave, (t, value, onended) => {
|
||||
const duration = 0.2;
|
||||
const duration = 0.3;
|
||||
const { node: o } = getZZFX({ s: wave, ...value }, t, duration);
|
||||
o.onended = () => {
|
||||
o.disconnect();
|
||||
@ -111,3 +111,122 @@ export function registerZZFXSounds() {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
13
pnpm-lock.yaml
generated
13
pnpm-lock.yaml
generated
@ -1,9 +1,5 @@
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
@ -395,9 +391,6 @@ importers:
|
||||
nanostores:
|
||||
specifier: ^0.8.1
|
||||
version: 0.8.1
|
||||
zzfx:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0
|
||||
devDependencies:
|
||||
vite:
|
||||
specifier: ^4.3.3
|
||||
@ -14038,6 +14031,6 @@ packages:
|
||||
/zwitch@2.0.4:
|
||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||
|
||||
/zzfx@1.2.0:
|
||||
resolution: {integrity: sha512-RtFz6PTMfCmxTfaCOv6GWAV4YaL/T0hltiMGkd87clybO8WLPlH6kX8sNkZGFKw9YPyu1UNsUYf/5/Vn4dondA==}
|
||||
dev: false
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user