mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-13 22:58:36 +00:00
documentation
This commit is contained in:
parent
e6f272dd0c
commit
a8eafbc309
@ -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');
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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') {
|
||||
|
||||
@ -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++) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user