123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Modal.mli *)letrate=float_of_intSignal.ratetypet={w:float;mutabler:float;mutablea1:float;(* 2 r cos w *)mutablea2:float;(* r^2 *)mutabley1:float;mutabley2:float;mutablepending:float;(* the next strike's impulse *)mutablelevel:float;(* the amplitude's bound, decayed each sample *)}letcoefficients(t:t)(t60:float):unit=t.r<-Float.pow10.(-3./.(Float.max1e-4t60*.rate));t.a1<-2.*.t.r*.cost.w;t.a2<-t.r*.t.rletcreate~(frequency:float)~(t60:float):t=letw=2.*.Float.pi*.Float.minfrequency(0.49*.rate)/.rateinlett={w;r=0.;a1=0.;a2=0.;y1=0.;y2=0.;pending=0.;level=0.}incoefficientstt60;tletstrike(t:t)(a:float):unit=t.pending<-t.pending+.(a*.sint.w);t.level<-t.level+.Float.absaletdamp(t:t)~(t60:float):unit=coefficientstt60letnext(t:t):float=lety=(t.a1*.t.y1)-.(t.a2*.t.y2)+.t.pendingint.pending<-0.;t.y2<-t.y1;t.y1<-y;t.level<-t.level*.t.r;yletlevel(t:t):float=t.level