proper lpf mapping + remove redundant worklet params,
This commit is contained in:
parent
483843bd0a
commit
5336569c25
4 changed files with 30 additions and 31 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue