mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-14 15:18:33 +00:00
integrated with envelopes
This commit is contained in:
parent
d49c9dce4f
commit
4160639d88
@ -103,14 +103,22 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => {
|
||||
return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)];
|
||||
};
|
||||
|
||||
export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor) {
|
||||
export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model) {
|
||||
const curve = 'exponential';
|
||||
const [attack, decay, sustain, release] = getADSRValues([att, dec, sus, rel], curve, [0.005, 0.14, 0, 0.1]);
|
||||
const filter = context.createBiquadFilter();
|
||||
let filter;
|
||||
let frequencyParam;
|
||||
if (model === 'ladder') {
|
||||
filter = getWorklet(context, 'ladder-processor', { frequency, q: Q, drive: 1 });
|
||||
frequencyParam = filter.parameters.get('frequency');
|
||||
} else {
|
||||
filter = context.createBiquadFilter();
|
||||
filter.type = type;
|
||||
filter.Q.value = Q;
|
||||
filter.frequency.value = frequency;
|
||||
frequencyParam = filter.frequency;
|
||||
}
|
||||
|
||||
filter.type = type;
|
||||
filter.Q.value = Q;
|
||||
filter.frequency.value = frequency;
|
||||
// envelope is active when any of these values is set
|
||||
const hasEnvelope = att ?? dec ?? sus ?? rel ?? fenv;
|
||||
// Apply ADSR to filter frequency
|
||||
@ -122,7 +130,7 @@ export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fe
|
||||
let min = clamp(2 ** -offset * frequency, 0, 20000);
|
||||
let max = clamp(2 ** (fenvAbs - offset) * frequency, 0, 20000);
|
||||
if (fenv < 0) [min, max] = [max, min];
|
||||
getParamADSR(filter.frequency, attack, decay, sustain, release, min, max, start, end, curve);
|
||||
getParamADSR(frequencyParam, attack, decay, sustain, release, min, max, start, end, curve);
|
||||
return filter;
|
||||
}
|
||||
return filter;
|
||||
|
||||
@ -395,6 +395,8 @@ export const superdough = async (value, t, hapDuration) => {
|
||||
chain.push(gainNode(gain));
|
||||
|
||||
if (cutoff !== undefined) {
|
||||
// chain.push(getWorklet(ac, 'ladder-processor', { frequency: cutoff, q: resonance, drive: 1 }));
|
||||
|
||||
let lp = () =>
|
||||
createFilter(
|
||||
ac,
|
||||
@ -409,6 +411,7 @@ export const superdough = async (value, t, hapDuration) => {
|
||||
t,
|
||||
t + hapDuration,
|
||||
fanchor,
|
||||
ftype,
|
||||
);
|
||||
chain.push(lp());
|
||||
if (ftype === '24db') {
|
||||
@ -471,8 +474,6 @@ export const superdough = async (value, t, hapDuration) => {
|
||||
shape !== undefined && chain.push(getWorklet(ac, 'shape-processor', { shape, postgain: shapevol }));
|
||||
distort !== undefined && chain.push(getWorklet(ac, 'distort-processor', { distort, postgain: distortvol }));
|
||||
|
||||
chain.push(getWorklet(ac, 'ladder-processor', { cutoff: 500, q: 1 }));
|
||||
|
||||
compressorThreshold !== undefined &&
|
||||
chain.push(
|
||||
getCompressor(ac, compressorThreshold, compressorRatio, compressorKnee, compressorAttack, compressorRelease),
|
||||
|
||||
@ -115,8 +115,9 @@ const _PI = 3.14159265359;
|
||||
class LadderProcessor extends AudioWorkletProcessor {
|
||||
static get parameterDescriptors() {
|
||||
return [
|
||||
{ name: 'cutoff', defaultValue: 500 },
|
||||
{ name: 'frequency', defaultValue: 500 },
|
||||
{ name: 'q', defaultValue: 1 },
|
||||
{ name: 'drive', defaultValue: 1 },
|
||||
];
|
||||
}
|
||||
|
||||
@ -143,11 +144,13 @@ class LadderProcessor extends AudioWorkletProcessor {
|
||||
this.started = hasInput;
|
||||
|
||||
const resonance = parameters.q[0];
|
||||
let cutoff = parameters.cutoff[0];
|
||||
const drive = parameters.drive[0] * 2;
|
||||
let cutoff = parameters.frequency[0];
|
||||
cutoff = (cutoff * 2 * _PI) / sampleRate;
|
||||
cutoff = cutoff > 1 ? 1 : cutoff;
|
||||
|
||||
const k = resonance * 4;
|
||||
const makeupgain = 1 / drive;
|
||||
|
||||
for (let n = 0; n < blockSize; n++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
@ -157,12 +160,12 @@ class LadderProcessor extends AudioWorkletProcessor {
|
||||
this.p33 = this.p32;
|
||||
this.p32 = this.p3;
|
||||
|
||||
this.p0 += (fast_tanh(input[i][n] - k * out) - fast_tanh(this.p0)) * cutoff;
|
||||
this.p0 += (fast_tanh(input[i][n] * drive - k * out) - fast_tanh(this.p0)) * cutoff;
|
||||
this.p1 += (fast_tanh(this.p0) - fast_tanh(this.p1)) * cutoff;
|
||||
this.p2 += (fast_tanh(this.p1) - fast_tanh(this.p2)) * cutoff;
|
||||
this.p3 += (fast_tanh(this.p2) - fast_tanh(this.p3)) * cutoff;
|
||||
|
||||
output[i][n] = out;
|
||||
output[i][n] = out * makeupgain;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user