diff --git a/packages/superdough/dough.mjs b/packages/superdough/dough.mjs index f3365b06c..876cfdf11 100644 --- a/packages/superdough/dough.mjs +++ b/packages/superdough/dough.mjs @@ -351,7 +351,7 @@ const defaultDefaultValues = { let getDefaultValue = (key) => defaultDefaultValues[key]; export class Dough { - init(value) { + init(value, sampleRate) { // params without defaults: /* bank, @@ -424,6 +424,14 @@ export class Dough { this._sound = new SourceClass(); this._lpf = this.cutoff ? new Lpf() : null; 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) { if (!this._sound) { @@ -432,14 +440,19 @@ export class Dough { // sound source let s = this._sound.update(this.freq); // 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 s = s * this.gain; // envelope 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); s = s * env; - s = s * this.postgain; + + s = s * this.postgain * 0.3; return s; } } diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index 43a21477b..7633c6441 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -901,42 +901,30 @@ class DoughProcessor extends AudioWorkletProcessor { constructor() { super(); this.dough = new Dough(); - this.port.onmessage = (event) => this.dough.init(event.data); - } - static get parameterDescriptors() { - return [ - { - name: 'begin', - defaultValue: 0, - max: Number.POSITIVE_INFINITY, - min: 0, - }, - { - name: 'end', - defaultValue: 0, - max: Number.POSITIVE_INFINITY, - min: 0, - }, - ]; + this.port.onmessage = (event) => this.dough.init(event.data, sampleRate); } process(inputs, outputs, params) { if (this.disconnected) { return false; } - if (currentTime <= params.begin[0]) { + if (this.dough._begin === undefined) { return true; } - if (currentTime >= params.end[0]) { - return false; + if (currentTime <= this.dough._begin) { + return true; } - if (this.t == null) { - this.t = params.begin[0] * sampleRate; + if (currentTime >= this.dough._end + 1) { + 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]; 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++) { //prevent speaker blowout via clipping if threshold exceeds output[c][i] = clamp(out, -1, 1); diff --git a/packages/webaudio/supradough.mjs b/packages/webaudio/supradough.mjs index 514d5e606..8887a4132 100644 --- a/packages/webaudio/supradough.mjs +++ b/packages/webaudio/supradough.mjs @@ -22,10 +22,7 @@ Pattern.prototype.supradough = function () { let o = getWorklet( ac, 'dough-processor', - { - begin, // we might not need these, as we could send them via postMessage below - end, - }, + {}, { outputChannelCount: [2], }, diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 44a683480..8f7d041a9 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -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 { superdough, getAudioContext, setLogger, doughTrigger } from 'superdough'; +import './supradough.mjs'; const { Pattern, logger, repl } = strudel; setLogger(logger);