import type { IClear , IReset } from "@thi.ng/api" ; import { TAU } from "@thi.ng/math/api" ; import { clamp05 } from "@thi.ng/math/interval" ; import type { FilterConfig , IFilter , OnepoleType } from "./api.js" ; import { AProc } from "./aproc.js" ; export const onepoleLP = ( fc ) => new OnePole ( "lp" , fc ) ; export const onepoleHP = ( fc ) => new OnePole ( "hp" , fc ) ; /**
 * https://www.earlevel.com/main/2012/12/15/a-one-pole-filter/
 */ export class OnePole extends AProc < number , number > implements IClear , IFilter , IReset { protected _a0 ! : number ; protected _b1 ! : number ; constructor ( protected _type , protected _freq ) { super ( 0 ) ; this . setFreq ( _freq ) ; } clear ( ) { this . _val = 0 ; } reset ( ) { this . clear ( ) ; return this ; } next ( x ) { return ( this . _val = x * this . _a0 + this . _val * this . _b1 ) ; } setFreq ( fc ) { this . _freq = fc = clamp05 ( fc ) ; if ( this . _type === "lp" ) { this . _b1 = Math . exp ( - TAU * fc ) ; this . _a0 = 1 - this . _b1 ; } else { this . _b1 = - Math . exp ( - TAU * ( 0.5 - fc ) ) ; this . _a0 = 1 + this . _b1 ; } } filterCoeffs ( ) { return { zeroes : [ this . _a0 ] , poles : [ 1 , this . _type === "lp" ? this . _b1 : - this . _b1 ] , } ; } }