proper lpf mapping + remove redundant worklet params,

This commit is contained in:
Felix Roos 2025-06-01 21:20:28 +02:00
parent 483843bd0a
commit 5336569c25
No known key found for this signature in database
4 changed files with 30 additions and 31 deletions

View file

@ -351,7 +351,7 @@ const defaultDefaultValues = {
let getDefaultValue = (key) => defaultDefaultValues[key]; let getDefaultValue = (key) => defaultDefaultValues[key];
export class Dough { export class Dough {
init(value) { init(value, sampleRate) {
// params without defaults: // params without defaults:
/* /*
bank, bank,
@ -424,6 +424,14 @@ export class Dough {
this._sound = new SourceClass(); this._sound = new SourceClass();
this._lpf = this.cutoff ? new Lpf() : null; this._lpf = this.cutoff ? new Lpf() : null;
this._adsr = new ADSR(); this._adsr = new ADSR();
this.piOverSr = Math.PI / sampleRate;
this.eighthOverLogHalf = 0.125 / Math.log(0.5);
}
// credits to pulu: https://github.com/felixroos/kabelsalat/issues/35
freq2cutoff(freq) {
const c = 2 * Math.sin(freq * this.piOverSr);
return 1 - Math.log(c) * this.eighthOverLogHalf;
} }
update(t) { update(t) {
if (!this._sound) { if (!this._sound) {
@ -432,14 +440,19 @@ export class Dough {
// sound source // sound source
let s = this._sound.update(this.freq); let s = this._sound.update(this.freq);
// lpf // lpf
s = this._lpf ? this._lpf.update(s, this.cutoff, this.resonance) : s; if (this._lpf) {
const cutoff = this.freq2cutoff(this.cutoff);
s = this._lpf ? this._lpf.update(s, cutoff, this.resonance) : s;
}
// not sure if gain is applied here // not sure if gain is applied here
s = s * this.gain; s = s * this.gain;
// envelope // envelope
let gate = Number(t >= this._begin && t <= this._end); let gate = Number(t >= this._begin && t <= this._end);
/* Math.random() > 0.99 && console.log('gate', gate); */
const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release); const env = this._adsr.update(t, gate, this.attack, this.decay, this.sustain, this.release);
s = s * env; s = s * env;
s = s * this.postgain;
s = s * this.postgain * 0.3;
return s; return s;
} }
} }

View file

@ -901,42 +901,30 @@ class DoughProcessor extends AudioWorkletProcessor {
constructor() { constructor() {
super(); super();
this.dough = new Dough(); this.dough = new Dough();
this.port.onmessage = (event) => this.dough.init(event.data); this.port.onmessage = (event) => this.dough.init(event.data, sampleRate);
}
static get parameterDescriptors() {
return [
{
name: 'begin',
defaultValue: 0,
max: Number.POSITIVE_INFINITY,
min: 0,
},
{
name: 'end',
defaultValue: 0,
max: Number.POSITIVE_INFINITY,
min: 0,
},
];
} }
process(inputs, outputs, params) { process(inputs, outputs, params) {
if (this.disconnected) { if (this.disconnected) {
return false; return false;
} }
if (currentTime <= params.begin[0]) { if (this.dough._begin === undefined) {
return true; return true;
} }
if (currentTime >= params.end[0]) { if (currentTime <= this.dough._begin) {
return false; return true;
} }
if (this.t == null) { if (currentTime >= this.dough._end + 1) {
this.t = params.begin[0] * sampleRate; return false; // this causes cracks for some reason (seems to kick in too early for some reason)
// it works with + 1 but not sure why this is needed
}
if (this.t === undefined) {
this.t = Math.floor(this.dough._begin * sampleRate);
} }
const output = outputs[0]; const output = outputs[0];
for (let i = 0; i < output[0].length; i++) { for (let i = 0; i < output[0].length; i++) {
const out = this.dough.update(currentTime); // const out = this.dough.update(currentTime);
const out = this.dough.update(this.t / sampleRate);
for (let c = 0; c < output.length; c++) { for (let c = 0; c < output.length; c++) {
//prevent speaker blowout via clipping if threshold exceeds //prevent speaker blowout via clipping if threshold exceeds
output[c][i] = clamp(out, -1, 1); output[c][i] = clamp(out, -1, 1);

View file

@ -22,10 +22,7 @@ Pattern.prototype.supradough = function () {
let o = getWorklet( let o = getWorklet(
ac, ac,
'dough-processor', 'dough-processor',
{ {},
begin, // we might not need these, as we could send them via postMessage below
end,
},
{ {
outputChannelCount: [2], outputChannelCount: [2],
}, },

View file

@ -6,6 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th
import * as strudel from '@strudel/core'; import * as strudel from '@strudel/core';
import { superdough, getAudioContext, setLogger, doughTrigger } from 'superdough'; import { superdough, getAudioContext, setLogger, doughTrigger } from 'superdough';
import './supradough.mjs';
const { Pattern, logger, repl } = strudel; const { Pattern, logger, repl } = strudel;
setLogger(logger); setLogger(logger);