First pass at transient processor
This commit is contained in:
parent
132a124644
commit
020a6bc75f
2 changed files with 72 additions and 0 deletions
|
|
@ -2584,3 +2584,5 @@ export const scrub = register(
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const { transient } = registerControl(['transient', 'transsustain', 'transattack']);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ const PI = Math.PI;
|
||||||
const TWO_PI = 2 * PI;
|
const TWO_PI = 2 * PI;
|
||||||
const INVSR = 1 / sampleRate;
|
const INVSR = 1 / sampleRate;
|
||||||
|
|
||||||
|
const timeToCoeff = (t) => Math.exp(-INVSR / t);
|
||||||
|
const dbToLin = (db) => Math.pow(10, db / 20);
|
||||||
|
|
||||||
const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
|
const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
|
||||||
const mod = (n, m) => ((n % m) + m) % m;
|
const mod = (n, m) => ((n % m) + m) % m;
|
||||||
const lerp = (a, b, n) => n * (b - a) + a;
|
const lerp = (a, b, n) => n * (b - a) + a;
|
||||||
|
|
@ -1383,3 +1386,70 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerProcessor('wavetable-oscillator-processor', WavetableOscillatorProcessor);
|
registerProcessor('wavetable-oscillator-processor', WavetableOscillatorProcessor);
|
||||||
|
|
||||||
|
class TransientProcessor extends AudioWorkletProcessor {
|
||||||
|
static get parameterDescriptors() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(options) {
|
||||||
|
super();
|
||||||
|
this.gainCoeff = timeToCoeff(0.2);
|
||||||
|
this.avgGain = 1;
|
||||||
|
let {
|
||||||
|
attackTime = 0.003,
|
||||||
|
sustainTime = 0.08,
|
||||||
|
attack = 0,
|
||||||
|
sustain = 0,
|
||||||
|
sensitivity = 0.1,
|
||||||
|
mix = 1,
|
||||||
|
} = options.processorOptions;
|
||||||
|
attackTime = clamp(attackTime, 0.0005, 0.05);
|
||||||
|
sustainTime = clamp(sustainTime, 0.01, 0.5);
|
||||||
|
this.attackCoeff = timeToCoeff(attackTime);
|
||||||
|
this.sustainCoeff = timeToCoeff(sustainTime);
|
||||||
|
this.attackAmt = clamp(attack, -1, 1);
|
||||||
|
this.sustainAmt = clamp(sustain, -1, 1);
|
||||||
|
this.scaling = 0.5 + 5 * clamp(sensitivity, 0, 1);
|
||||||
|
this.mix = clamp(mix, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
process(inputs, outputs, _params) {
|
||||||
|
const input = inputs[0];
|
||||||
|
const output = outputs[0];
|
||||||
|
if (!input || !output) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const channels = output.length;
|
||||||
|
this.attackEnv ??= new Float32Array(channels);
|
||||||
|
this.sustainEnv ??= new Float32Array(channels);
|
||||||
|
let avgGain = this.avgGain;
|
||||||
|
for (let ch = 0; ch < channels; ch++) {
|
||||||
|
const inCh = input[ch];
|
||||||
|
const outCh = output[ch];
|
||||||
|
let attEnv = this.attackEnv[ch];
|
||||||
|
let susEnv = this.sustainEnv[ch];
|
||||||
|
for (let i = 0; i < blockSize; i++) {
|
||||||
|
const x = Math.abs(inCh[i]);
|
||||||
|
attEnv = lerp(attEnv, x, this.attackCoeff);
|
||||||
|
susEnv = lerp(susEnv, x, this.sustainCoeff);
|
||||||
|
const peakiness = clamp((this.scaling * (attEnv - susEnv)) / (susEnv + 1e-6), -1.5, 1.5);
|
||||||
|
const attScale = Math.max(0, peakiness);
|
||||||
|
const susScale = Math.max(0, -peakiness);
|
||||||
|
const attackGain = dbToLin(this.attackAmt * attScale * 18); // max 18db
|
||||||
|
const sustainGain = dbToLin(this.sustainAmt * susScale * 36); // max 36db
|
||||||
|
const gain = clamp(attackGain * sustainGain, 0, 8);
|
||||||
|
avgGain = lerp(avgGain, gain, this.gainCoeff);
|
||||||
|
const makeup = avgGain > 1e-3 ? 1 / avgGain : 1;
|
||||||
|
const wet = x * gain * makeup;
|
||||||
|
outCh[i] = lerp(x, wet, this.mix);
|
||||||
|
}
|
||||||
|
this.attackEnv[ch] = attEnv;
|
||||||
|
this.sustainEnv[ch] = susEnv;
|
||||||
|
}
|
||||||
|
this.avgGain = avgGain;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerProcessor('transient-processor', TransientProcessor);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue