(bind-func cerberus_create_lfos
(lambda (lfos:|4,|8,[SAMPLE,i64,i64]*||* i:i64 frequency:SAMPLE onecycleinhz:SAMPLE mod_amp:|4,SAMPLE|* mod_frq:|4,SAMPLE|* mod_phase:|4,SAMPLE|* mod_options:|4,i32|* mod_attack:|4,SAMPLE|* mod_decay:|4,SAMPLE|* mod_attack_slope:|4,SAMPLE|* mod_decay_slope:|4,SAMPLE|*)
(let ((opts (aref mod_options i))
(notedur:SAMPLE (if (> (& opts LFO_OPT_NOTEDUR) 0) onecycleinhz 1.0))
(amod:SAMPLE (if (> (& opts LFO_OPT_FRQ_TO_AMP) 0) frequency 1.0))
(fmod:SAMPLE (* notedur (if (> (& opts LFO_OPT_FRQ_TO_FRQ) 0) frequency 1.0))))
(aset! lfos i
(array (let ((osc (osc_c (aref mod_phase i))))
(lambda (chan:i64 idx:i64)
(osc (* amod (aref mod_amp idx))
(* fmod (aref mod_frq idx)))))
(let ((osc (saw_c (aref mod_phase i))))
(lambda (chan:i64 idx:i64)
(osc (* amod (aref mod_amp idx))
(* fmod (aref mod_frq idx)))))
(let ((osc (pulse_c (aref mod_phase i))))
(lambda (chan:i64 idx:i64)
(osc (* amod (aref mod_amp idx))
(* fmod (aref mod_frq idx))
0.5)))
(let ((osc (tri_c (aref mod_phase i))))
(lambda (chan:i64 idx:i64)
(osc (* amod (aref mod_amp idx))
(* fmod (aref mod_frq idx)))))
(let ((osc (ad_c)))
(cset! osc cycle #t i1)
(lambda (chan:i64 idx:i64)
(osc chan 1.0
(aref mod_attack idx)
(aref mod_decay idx)
(aref mod_attack_slope idx)
(aref mod_decay_slope idx))))
(lambda (chan:i64 idx:i64) (aref mod_amp idx)) ;; constant instead of WT
(lambda (chan:i64 idx:i64) (aref mod_amp idx)) ;; constant
(let ((cnt 0)
(rem:SAMPLE (* (aref mod_amp i) (random)))) ;; random S & H
(lambda (chan:i64 idx:i64)
(if (and (= chan 0 )
(= (% cnt (ftoi64 (/ SRf (aref mod_frq idx)))) 0))
(begin
(set! cnt (+ cnt 1))
(set! rem (* (aref mod_amp idx) (random)))))
rem)) ;; random S & H
)))
void))