UNPKG

@thi.ng/dsp

Version:

Composable signal generators, oscillators, filters, FFT, spectrum, windowing & related DSP utils

80 lines (79 loc) 1.83 kB
import { PI } from "@thi.ng/math/api"; import { clamp05 } from "@thi.ng/math/interval"; import { AProc } from "./aproc.js"; const svfLP = (fc, q) => new SVF("lp", fc, q); const svfHP = (fc, q) => new SVF("hp", fc, q); const svfBP = (fc, q) => new SVF("bp", fc, q); const svfNotch = (fc, q) => new SVF("notch", fc, q); const svfPeak = (fc, q) => new SVF("peak", fc, q); const svfAllpass = (fc, q) => new SVF("all", fc, q); class SVF extends AProc { constructor(_type, _freq, _q = 0.5) { super(0); this._type = _type; this._freq = _freq; this._q = _q; this.reset(); this.computeCoeffs(); } _a1; _a2; _c1; _c2; _g; _k; reset() { this._c1 = this._c2 = this._val = 0; return this; } next(x) { const { _c1, _c2 } = this; const x1 = this._a1 * _c1 + this._a2 * (x - _c2); const x2 = _c2 + this._g * x1; this._c1 = 2 * x1 - _c1; this._c2 = 2 * x2 - _c2; switch (this._type) { case "lp": return this._val = x2; case "hp": return this._val = x - this._k * x1 - x2; case "bp": return this._val = x1; case "notch": return this._val = x - this._k * x1; case "peak": return this._val = 2 * x2 - x + this._k * x1; case "all": return this._val = x - 2 * this._k * x1; } } set(fc, q) { this._freq = fc; this._q = q; this.computeCoeffs(); } setFreq(fc) { this._freq = fc; this.computeCoeffs(); } setQ(q) { this._q = q; this.computeCoeffs(); } computeCoeffs() { this._freq = clamp05(this._freq); const g = this._g = Math.tan(PI * this._freq); this._k = 2 - 2 * this._q; this._a1 = 1 / (1 + g * (g + this._k)); this._a2 = g * this._a1; } } export { SVF, svfAllpass, svfBP, svfHP, svfLP, svfNotch, svfPeak };