;; FX
(bind-func analogue_fx
(let ((MILLISEC (* .001 SRf))
(CHANSF (i32tof CHANNELS)))
(lambda ()
(let ((notekernel:NOTE_KERNEL null)
(name 'Analogue')
(mod_amp:|4,SAMPLE|* (array_ref 1.0 1.0 1.0 1.0))
(mod_phase:|4,SAMPLE|* (array_ref 0.0 0.0 0.0 0.0))
(mod_options:|4,i32|* (array_ref 0 0 0 0))
(mod_frq:|4,SAMPLE|* (array_ref 1.0 1.0 1.0 1.0))
(mod_attack:|4,SAMPLE|* (array_ref 10.0 10.0 10.0 10.0)) ;; in millis
(mod_decay:|4,SAMPLE|* (array_ref 10.0 10.0 10.0 10.0))
(mod_attack_slope:|4,SAMPLE|* (array_ref 0.0 0.0 0.0 0.0)) ;; between -1.0 log and 1.0 exp (0.0 is linear)
(mod_decay_slope:|4,SAMPLE|* (array_ref 0.0 0.0 0.0 0.0))
(mods:|32,SAMPLE|* null) ;(alloc))
(mod_matrix:|4,|32,SAMPLE||* (alloc))
(tmpmod:|32,SAMPLE|* null)
(lfos:|4,|8,[SAMPLE,i64,i64]*||* (alloc))
(lfo_types:|4,i32|* (alloc))
(hpf (hpf_c))
(hpfR (hpf_c))
(hpf_frq 20001.0)
(dly (comb_mc_c (i32toi64 CHANNELS) (* SR 120))) ;; max 120 sec delay
(delay_time_left 50.0) ;; in ms
(delay_time_right 50.0) ;; in ms
(delay_in 1.0)
(delay_mix 0.0)
(delay_fb 0.5)
(delay_frq:SAMPLE 12000.0)
(delay_res:SAMPLE 0.0)
(rev (reverb_st_c))
(reverb_mix 0.0)
(reverb_predelay 40.0) ;; in ms
(reverb_size 0.3)
(reverb_absorb 0.45)
(pan (pan_c (i32toi64 CHANNELS)))
(pan_pos 0.5)
(pan_width 1.0)
(flanger (flanger_st_c))
(flanger_low 0.1) ;; in ms
(flanger_high 4.0) ;; in ms
(flanger_rate 0.127287)
(flanger_fb 0.25)
(flanger_mix 0.0)
(overdrive (overdrive_c))
(overdrive_amt 0.5) ;; always use some overdrive
(out:SAMPLE 0.0)
(i:i64 0) (j:i64 0)
(tmp 0.0)
(fxout 0.0)
(gain 2.0))
(dotimes (i 4)
(aset! lfo_types i PARAM_SINE)
(aset! lfos i
(array (let ((osc (osc_c 0.0)))
(lambda (chan:i64 idx:i64)
(osc (aref mod_amp idx)
(aref mod_frq idx))))
(let ((osc (saw_c 0.0)))
(lambda (chan:i64 idx:i64)
(osc (aref mod_amp idx)
(aref mod_frq idx))))
(let ((osc (pulse_c 0.0)))
(lambda (chan:i64 idx:i64)
(osc (aref mod_amp idx)
(aref mod_frq idx)
0.5)))
(let ((osc (tri_c 0.0)))
(lambda (chan:i64 idx:i64)
(osc (aref mod_amp idx)
(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:float (* (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
))) ;; constant
(lambda (in:SAMPLE time:i64 chan:i64 dat:SAMPLE*)
;; calc mod matrix changes
(begin
(if (= mods null) (set! mods (notekernel.mods:|32,SAMPLE|*)))
(memset (cast mods i8*) 0 128) ;(size_of mods))
(dotimes (i 4)
(set! tmp ((aref (aref-ptr lfos i) (aref lfo_types i)) chan i))
(set! tmpmod (aref-ptr mod_matrix i))
(dotimes (j 32) (aset! mods j (+ (aref mods j) (* tmp (aref tmpmod j)))))
void))
(set! out in)
(set! out (overdrive out overdrive_amt))
(if (< hpf_frq 20000.0)
(set! out (hpf out hpf_frq 0.0)))
;; apply FX to both channels 1 and 2
(set! tmp (+ pan_pos (aref mods PARAM_PAN_POS)))
(if (> tmp CHANSF) (set! tmp (- tmp CHANSF)))
;; always with the panning!
(set! fxout (pan chan out
(+ pan_width (aref mods PARAM_PAN_WIDTH))
tmp))
(if (> flanger_mix 0.001)
(set! fxout (flanger chan fxout
1.0 flanger_mix
(+ flanger_low 0.0) ;(aref mods PARAM_FLANGER_LOW)))
(+ flanger_high 0.0) ;(aref mods PARAM_FLANGER_HIGH)))
(+ flanger_rate 0.0) ;(aref mods PARAM_FLANGER_RATE))
(+ flanger_fb 0.0)))) ;;(aref mods PARAM_FLANGER_FB)))))
(if (> delay_mix 0.001)
(set! fxout (dly chan fxout
(if (= chan 0)
(* MILLISEC (+ delay_time_left (aref mods PARAM_DELAY_TIME_LEFT)))
(* MILLISEC (+ delay_time_right (aref mods PARAM_DELAY_TIME_RIGHT))))
delay_in
delay_mix
(+ delay_fb (aref mods PARAM_DELAY_FB)))))
(if (> reverb_mix 0.001)
(set! fxout (rev chan fxout
(+ reverb_size (aref mods PARAM_REVERB_SIZE))
(+ reverb_predelay (aref mods PARAM_REVERB_PREDELAY))
(+ reverb_absorb (aref mods PARAM_REVERB_ABSORB))
(+ reverb_mix (aref mods PARAM_REVERB_MIX)))))
(* gain fxout))))))