This commit is contained in:
Jade (Rose) Rowland 2025-09-24 00:23:05 -07:00
parent 1eb9dc73fa
commit 0633954e24
3 changed files with 259 additions and 167 deletions

View file

@ -458,6 +458,7 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
duckonset, duckonset,
duckattack, duckattack,
duckdepth, duckdepth,
djf,
// filters // filters
fanchor = getDefaultValue('fanchor'), fanchor = getDefaultValue('fanchor'),
drive = 0.69, drive = 0.69,
@ -747,6 +748,10 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
orbitBus.sendReverb(post, room); orbitBus.sendReverb(post, room);
} }
if (djf != null) {
orbitBus.getDjf(djf, t)
}
// analyser // analyser
if (analyze) { if (analyze) {
const analyserNode = getAnalyserById(analyze, 2 ** (fft + 5)); const analyserNode = getAnalyserById(analyze, 2 ** (fft + 5));

View file

@ -1,4 +1,4 @@
import { effectSend, webAudioTimeout } from './helpers.mjs'; import { effectSend, getWorklet, webAudioTimeout } from './helpers.mjs';
import { errorLogger } from './logger.mjs'; import { errorLogger } from './logger.mjs';
import { clamp } from './util.mjs'; import { clamp } from './util.mjs';
@ -9,6 +9,7 @@ export class Orbit {
delayNode; delayNode;
output; output;
summingNode; summingNode;
djfNode;
audioContext; audioContext;
constructor(audioContext) { constructor(audioContext) {
this.audioContext = audioContext; this.audioContext = audioContext;
@ -24,6 +25,17 @@ export class Orbit {
this.reverbNode?.disconnect(); this.reverbNode?.disconnect();
} }
getDjf(value, t = 0) {
if (this.djfNode == null){
this.djfNode = getWorklet(this.audioContext, 'djf-processor', {value})
this.summingNode.disconnect()
this.summingNode.connect(this.djfNode)
this.djfNode.connect(this.output)
}
const val = this.djfNode.parameters.get('value')
val.setValueAtTime(value, t)
}
getDelay(delaytime = 0, feedback = 0.5, t) { getDelay(delaytime = 0, feedback = 0.5, t) {
const maxfeedback = 0.98; const maxfeedback = 0.98;
if (feedback > maxfeedback) { if (feedback > maxfeedback) {

View file

@ -271,6 +271,81 @@ class ShapeProcessor extends AudioWorkletProcessor {
} }
registerProcessor('shape-processor', ShapeProcessor); registerProcessor('shape-processor', ShapeProcessor);
class TwoPoleFilter {
s0 = 0;
s1 = 0;
update(s, cutoff, resonance = 0) {
// Out of bound values can produce NaNs
resonance = clamp(resonance, 0, 1)
cutoff = clamp(cutoff, 0, sampleRate / 2 - 1)
const c = clamp(2 * Math.sin(cutoff * (_PI / sampleRate)), 0, 1.14);
const r = Math.pow(0.5, (resonance + 0.125) / 0.125);
const mrc = 1 - r * c;
this.s0 = mrc * this.s0 - c * this.s1 + c * s; // bpf
this.s1 = mrc * this.s1 + c * this.s0; // lpf
return this.s1; // return lpf by default
}
}
class DJFProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() {
return [
{ name: 'value', defaultValue: 0.5 },
];
}
constructor() {
super();
this.filters = [new TwoPoleFilter(), new TwoPoleFilter()]
}
process(inputs, outputs, parameters) {
const input = inputs[0];
const output = outputs[0];
const hasInput = !(input[0] === undefined);
this.started = hasInput;
const value = clamp(parameters.value[0], 0, 1);
let filterType = 'none'
let cutoff
let v = 1;
if (value > 0.5) {
filterType = 'hipass'
v = (value - .5) * 2
} else if (value < 0.5) {
filterType = 'lopass'
v = value * 2
}
cutoff = Math.pow((v * 11), 4)
// let cutoff = parameters.frequency[0];
for (let i = 0; i < input.length; i++) {
for (let n = 0; n < blockSize; n++) {
if (filterType == 'none') {
output[i][n] = input[i][n]
} else {
this.filters[i].update(input[i][n], cutoff, 0.2)
if (filterType === 'lopass') {
output[i][n] = this.filters[i].s1
} else if (filterType === 'hipass') {
output[i][n] = input[i][n] - this.filters[i].s1
} else {
output[i][n] = input[i][n]
}
}
}
}
return true;
}
}
registerProcessor('djf-processor', DJFProcessor);
function fast_tanh(x) { function fast_tanh(x) {
const x2 = x * x; const x2 = x * x;
return (x * (27.0 + x2)) / (27.0 + 9.0 * x2); return (x * (27.0 + x2)) / (27.0 + 9.0 * x2);