documentation

This commit is contained in:
Jade (Rose) Rowland 2024-05-18 00:51:56 -04:00
parent e6f272dd0c
commit a8eafbc309
4 changed files with 24 additions and 10 deletions

View File

@ -430,6 +430,17 @@ export const { crush } = registerControl('crush');
*/ */
export const { coarse } = registerControl('coarse'); export const { coarse } = registerControl('coarse');
/**
* filter overdrive for supported filter types
*
* @name drive
* @param {number | Pattern} amount
* @example
* note("{f g g c d a a#}%16".sub(17)).s("supersaw").lpenv(8).lpf(150).lpq(.8).ftype('ladder').drive("<.5 4>")
*
*/
export const { drive } = registerControl('drive');
/** /**
* Allows you to set the output channels on the interface * Allows you to set the output channels on the interface
* *
@ -750,7 +761,7 @@ export const { bprelease, bpr } = registerControl('bprelease', 'bpr');
* .sound('sawtooth') * .sound('sawtooth')
* .lpf(500) * .lpf(500)
* .bpenv(4) * .bpenv(4)
* .ftype("12db 24db") * .ftype("<ladder 12db 24db>")
*/ */
export const { ftype } = registerControl('ftype'); export const { ftype } = registerControl('ftype');
export const { fanchor } = registerControl('fanchor'); export const { fanchor } = registerControl('fanchor');

View File

@ -103,13 +103,13 @@ export const getADSRValues = (params, curve = 'linear', defaultValues) => {
return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)]; return [Math.max(a ?? 0, envmin), Math.max(d ?? 0, envmin), Math.min(sustain, envmax), Math.max(r ?? 0, releaseMin)];
}; };
export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model) { export function createFilter(context, type, frequency, Q, att, dec, sus, rel, fenv, start, end, fanchor, model, drive) {
const curve = 'exponential'; const curve = 'exponential';
const [attack, decay, sustain, release] = getADSRValues([att, dec, sus, rel], curve, [0.005, 0.14, 0, 0.1]); const [attack, decay, sustain, release] = getADSRValues([att, dec, sus, rel], curve, [0.005, 0.14, 0, 0.1]);
let filter; let filter;
let frequencyParam; let frequencyParam;
if (model === 'ladder') { if (model === 'ladder') {
filter = getWorklet(context, 'ladder-processor', { frequency, q: Q, drive: 1 }); filter = getWorklet(context, 'ladder-processor', { frequency, q: Q, drive });
frequencyParam = filter.parameters.get('frequency'); frequencyParam = filter.parameters.get('frequency');
} else { } else {
filter = context.createBiquadFilter(); filter = context.createBiquadFilter();

View File

@ -290,6 +290,7 @@ export const superdough = async (value, t, hapDuration) => {
// filters // filters
ftype = '12db', ftype = '12db',
fanchor = 0.5, fanchor = 0.5,
drive = 0.69,
// low pass // low pass
cutoff, cutoff,
lpenv, lpenv,
@ -297,7 +298,7 @@ export const superdough = async (value, t, hapDuration) => {
lpdecay, lpdecay,
lpsustain, lpsustain,
lprelease, lprelease,
resonance = 1, resonance = 0.5,
// high pass // high pass
hpenv, hpenv,
hcutoff, hcutoff,
@ -412,6 +413,7 @@ export const superdough = async (value, t, hapDuration) => {
t + hapDuration, t + hapDuration,
fanchor, fanchor,
ftype, ftype,
drive,
); );
chain.push(lp()); chain.push(lp());
if (ftype === '24db') { if (ftype === '24db') {

View File

@ -1,6 +1,6 @@
// coarse, crush, and shape processors adapted from dktr0's webdirt: https://github.com/dktr0/WebDirt/blob/5ce3d698362c54d6e1b68acc47eb2955ac62c793/dist/AudioWorklets.js // coarse, crush, and shape processors adapted from dktr0's webdirt: https://github.com/dktr0/WebDirt/blob/5ce3d698362c54d6e1b68acc47eb2955ac62c793/dist/AudioWorklets.js
// LICENSE GNU General Public License v3.0 see https://github.com/dktr0/WebDirt/blob/main/LICENSE // LICENSE GNU General Public License v3.0 see https://github.com/dktr0/WebDirt/blob/main/LICENSE
import { clamp } from './util.mjs';
const blockSize = 128; const blockSize = 128;
class CoarseProcessor extends AudioWorkletProcessor { class CoarseProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() { static get parameterDescriptors() {
@ -111,13 +111,13 @@ function fast_tanh(x) {
return (x * (27.0 + x2)) / (27.0 + 9.0 * x2); return (x * (27.0 + x2)) / (27.0 + 9.0 * x2);
} }
const _PI = 3.14159265359; const _PI = 3.14159265359;
//adapted from https://github.com/TheBouteillacBear/webaudioworklet-wasm?tab=MIT-1-ov-file
class LadderProcessor extends AudioWorkletProcessor { class LadderProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() { static get parameterDescriptors() {
return [ return [
{ name: 'frequency', defaultValue: 500 }, { name: 'frequency', defaultValue: 500 },
{ name: 'q', defaultValue: 1 }, { name: 'q', defaultValue: 1 },
{ name: 'drive', defaultValue: 1 }, { name: 'drive', defaultValue: 0.69 },
]; ];
} }
@ -145,13 +145,14 @@ class LadderProcessor extends AudioWorkletProcessor {
this.started = hasInput; this.started = hasInput;
const resonance = parameters.q[0]; const resonance = parameters.q[0];
const drive = parameters.drive[0] * 2; const drive = clamp(Math.exp(parameters.drive[0]), 0.1, 2000);
let cutoff = parameters.frequency[0]; let cutoff = parameters.frequency[0];
cutoff = (cutoff * 2 * _PI) / sampleRate; cutoff = (cutoff * 2 * _PI) / sampleRate;
cutoff = cutoff > 1 ? 1 : cutoff; cutoff = cutoff > 1 ? 1 : cutoff;
const k = resonance * 4; const k = Math.min(8, resonance * 2);
const makeupgain = 1 / drive; // drive makeup * resonance volume loss makeup
const makeupgain = (1 / drive) * Math.min(1.75, 1 + k);
for (let n = 0; n < blockSize; n++) { for (let n = 0; n < blockSize; n++) {
for (let i = 0; i < input.length; i++) { for (let i = 0; i < input.length; i++) {