;; g is gate
;; a is attack in milliseconds
;; d is decay in milliseconds
;; ela is the explin for attach
;; eld is the explin for decay
;;
;; cycle is a boolean closure variable that makes the ad self oscillate
;;
;; explin is a value between [-1.0 ... 1.0] that
;; moves between logathmic (negatives) and exponential (positive)
;; curves with a centre value of 0.0 being exactly linear
(bind-func static ad_c
(lambda ()
(let ((t:SAMPLE 0.0)
(out:SAMPLE 0.0)
(time:SAMPLE 0.0)
(aa 0.0) (dd 0.0)
(cycle:i1 0)
(inc1 0.0) (inc2 0.0) (inc3 0.0))
(lambda (chan:i64 g a d ela eld)
(if (<> chan 0)
out
(begin
(if (< g 0.00001:f)
(begin (set! t 0.0)
(set! aa (+ 1.0 (* a .001 SRs)))
(set! dd (+ 1.0 (* d .001 SRs)))
(set! inc1 (/ 1.0 aa))
(set! inc2 (/ 1.0 dd))
void)
(begin (inc t 1.0)
void))
(cond ((> t (+ aa dd))
(if (and cycle (> g 0.0)) ; (< out 0.0001))
(begin (set! t 0.0)
(set! aa (+ 1.0 (* a .001 SRs)))
(set! dd (+ 1.0 (* d .001 SRs)))
(set! inc1 (/ 1.0 aa))
(set! inc2 (/ 1.0 dd))
void))
(set! time 0.0)
(set! out 0.0)) ;(clamp (- out .001) 0.0 1.0)))
((> t aa)
(dec time inc2)
(set! out (explin (clamp time 0.0 1.0) eld))) ;; decay
((> t 0.0)
(inc time inc1)
(set! out (explin time ela))) ;; attack
(else (set! out 0.0)))
out))))))