(bind-func static adsr_ratio_c
(lambda ()
(let ((calcCoef (lambda (rate:float targetRatio:float)
(exp (/ (* -1.0 (log (/ (+ 1.0 targetRatio)
targetRatio)))
rate))))
(targetRatioA 0.3)
(targetRatioDR 0.0001)
(env_idle 0) (env_attack 1) (env_decay 2) (env_sustain 3) (env_release 4)
(state env_idle)
(attackRate 0.0)
(attackCoef 0.0)
(attackBase 0.0)
(decayRate 0.0)
(decayCoef 0.0)
(decayBase 0.0)
(sustainLevel 0.0)
(releaseRate 0.0)
(releaseCoef 0.0)
(releaseBase 0.0)
(old_g 0.0)
(old_a -1.0)
(old_d -1.0)
(old_s -1.0)
(old_r -1.0)
(old_a_ratio targetRatioA)
(old_dr_ratio targetRatioDR)
(out 0.0))
(lambda (chan:i64 g:float a d s r a_ratio dr_ratio)
(if (= chan 0)
(begin
(if (<> a old_a)
(begin
(set! old_a a)
(set! attackRate (* a SRf 0.001))
(set! attackCoef (calcCoef attackRate targetRatioA))
(set! attackBase (* (+ 1.0 targetRatioA) (- 1.0 attackCoef)))))
(if (<> d old_d)
(begin
(set! old_d d)
(set! decayRate (* d SRf 0.001))
(set! decayCoef (calcCoef decayRate targetRatioDR))
(set! decayBase (* (- sustainLevel targetRatioDR) (- 1.0 decayCoef)))))
(if (<> s old_s)
(begin
(set! old_s s)
(set! sustainLevel s)
(set! decayBase (* (- sustainLevel targetRatioDR) (- 1.0 decayCoef)))))
(if (<> r old_r)
(begin
(set! old_r r)
(set! releaseRate (* r SRf 0.001))
(set! releaseCoef (calcCoef releaseRate targetRatioDR))
(set! releaseBase (* -1.0 targetRatioDR (- 1.0 releaseCoef)))))
(if (<> a_ratio old_a_ratio)
(begin
(set! old_a_ratio a_ratio)
(if (< a_ratio 0.000000001) (set! a_ratio 0.000000001)) ;; -180db
(set! targetRatioA a_ratio)
(set! attackCoef (calcCoef attackRate targetRatioA))
(set! attackBase (* (+ 1.0 targetRatioA) (- 1.0 attackCoef)))))
(if (<> dr_ratio old_dr_ratio)
(begin
(set! old_dr_ratio dr_ratio)
(if (< a_ratio 0.000000001) (set! a_ratio 0.000000001)) ;; -180db
(set! targetRatioDR dr_ratio)
(set! decayCoef (calcCoef decayRate targetRatioDR))
(set! releaseCoef (calcCoef releaseRate targetRatioDR))
(set! decayBase (* (- sustainLevel targetRatioDR) (- 1.0 decayCoef)))
(set! releaseBase (* -1.0 targetRatioDR (- 1.0 releaseCoef)))))
(if (<> g old_g)
(if (> g 0.1)
(set! state env_attack)
(set! state env_release)))
(set! old_g g)
(cond ((= state env_idle)
out)
((= state env_attack)
(set! out (+ attackBase (* out attackCoef)))
(if (>= out 1.0)
(begin (set! out 1.0)
(set! state env_decay)))
out)
((= state env_decay)
(set! out (+ decayBase (* out decayCoef)))
(if (<= out sustainLevel)
(begin (set! out sustainLevel)
(set! state env_sustain)))
out)
((= state env_sustain) out)
((= state env_release)
(set! out (+ releaseBase (* out releaseCoef)))
(if (<= out 0.0)
(begin (set! out 0.0)
(set! state env_idle)))
out)))
out)))))