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');
/**
* 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
*
@ -750,7 +761,7 @@ export const { bprelease, bpr } = registerControl('bprelease', 'bpr');
* .sound('sawtooth')
* .lpf(500)
* .bpenv(4)
* .ftype("12db 24db")
* .ftype("<ladder 12db 24db>")
*/
export const { ftype } = registerControl('ftype');
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)];
};
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 [attack, decay, sustain, release] = getADSRValues([att, dec, sus, rel], curve, [0.005, 0.14, 0, 0.1]);
let filter;
let frequencyParam;
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');
} else {
filter = context.createBiquadFilter();

View File

@ -290,6 +290,7 @@ export const superdough = async (value, t, hapDuration) => {
// filters
ftype = '12db',
fanchor = 0.5,
drive = 0.69,
// low pass
cutoff,
lpenv,
@ -297,7 +298,7 @@ export const superdough = async (value, t, hapDuration) => {
lpdecay,
lpsustain,
lprelease,
resonance = 1,
resonance = 0.5,
// high pass
hpenv,
hcutoff,
@ -412,6 +413,7 @@ export const superdough = async (value, t, hapDuration) => {
t + hapDuration,
fanchor,
ftype,
drive,
);
chain.push(lp());
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
// LICENSE GNU General Public License v3.0 see https://github.com/dktr0/WebDirt/blob/main/LICENSE
import { clamp } from './util.mjs';
const blockSize = 128;
class CoarseProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() {
@ -111,13 +111,13 @@ function fast_tanh(x) {
return (x * (27.0 + x2)) / (27.0 + 9.0 * x2);
}
const _PI = 3.14159265359;
//adapted from https://github.com/TheBouteillacBear/webaudioworklet-wasm?tab=MIT-1-ov-file
class LadderProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() {
return [
{ name: 'frequency', defaultValue: 500 },
{ name: 'q', defaultValue: 1 },
{ name: 'drive', defaultValue: 1 },
{ name: 'drive', defaultValue: 0.69 },
];
}
@ -145,13 +145,14 @@ class LadderProcessor extends AudioWorkletProcessor {
this.started = hasInput;
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];
cutoff = (cutoff * 2 * _PI) / sampleRate;
cutoff = cutoff > 1 ? 1 : cutoff;
const k = resonance * 4;
const makeupgain = 1 / drive;
const k = Math.min(8, resonance * 2);
// 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 i = 0; i < input.length; i++) {