123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384(* 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 Dx_envelope.mli *)letlevel_table=[|0;5;9;13;17;20;23;25;27;29;31;33;35;37;39;41;42;43;45;46|]letscale_output_level(level:int):int=iflevel>=20then28+levelelselevel_table.(max0level)letfloor=16.letfull=3840.letgain(steps:float):float=Float.pow2.((steps/.256.)-.14.)letdecibels(steps:float):float=20.*.log10(gainsteps/.gainfull)typet={rates:intarray;levels:intarray;output_level:int;rate_scaling:int;mutablestage:int;mutablelevel:float;mutabletarget:float;mutablerising:bool;mutablespeed:float;(* steps a sample *)mutabledown:bool;}(* the next stage: its target in steps, its speed from its rate *)letadvance(t:t)(stage:int):unit=t.stage<-stage;ifstage<4thenbeginletsteps=((scale_output_levelt.levels.(stage)lsr1)lsl6)+t.output_level-4256int.target<-float_of_int(max16steps);t.rising<-t.target>t.level;letqrate=min63(((t.rates.(stage)*41)lsr6)+t.rate_scaling)in(* Dexed's increment is for a block of 64 samples, in steps times
* 65536: per sample, 2^6 less, and 2^16 *)t.speed<-float_of_int((4+(qrateland3))lsl(2+(qratelsr2)))/.65536.endletcreate~(rates:intarray)~(levels:intarray)?(output_level=4064)?(rate_scaling=0)():t=lett={rates;levels;output_level;rate_scaling;stage=0;level=0.;target=0.;rising=false;speed=0.;down=true}inadvancet0;tletkey_up(t:t):unit=ift.downthenbegint.down<-false;advancet3end(* [samples] samples on in one step, the speed times as much *)letstep(t:t)(samples:float):float=(* L3 held while the key is *)ift.stage<3||(t.stage=3&¬t.down)thenbeginift.risingthenbeginift.level<1716.thent.level<-1716.;(* the whole doublings left below 17 *)t.level<-t.level+.(Float.of_int(Float.to_int((4352.-.t.level)/.256.))*.t.speed*.samples);ift.level>=t.targetthenbegint.level<-t.target;advancet(t.stage+1)endendelsebegint.level<-t.level-.(t.speed*.samples);ift.level<=t.targetthenbegint.level<-t.target;advancet(t.stage+1)endendend;t.levelletnext(t:t):float=stept1.letrun(t:t)(samples:int):float=stept(float_of_intsamples)letstage(t:t):int=t.stage