(bind-func static bltri_c
(lambda (mod:float)
(let ((sawout:float 0.0) (sqrout 0.0) (inc 0.0)
(out:float 0.0)
(sqrmod 1.0)
(diffout 0.0) (zreg:float 0.0) (c 0.0))
(lambda (amp:float frq:float)
(set! inc (/ frq SRs))
;; positive frequencies
(if (and (> inc 0.0) (>= mod 1.0))
(begin (set! mod (- mod 1.0))
(set! sqrmod (* sqrmod -1.0))))
;; negative frequencies
(if (and (< inc 0.0) (<= mod 0.0))
(begin (set! mod (+ mod 1.0))
(set! sqrmod (* sqrmod -1.0))))
;; start with saw
(set! sawout (- (* mod 2.0) 1.0)) ;; bipolar sawtooth
(set! sawout (* sawout sawout)) ;; sqr'd sawtooth
(set! sawout (- 1.0 sawout)) ;; inverted sqr'd sawtooth
;; modulate with sqr (50 % pulse width)
(set! out (* sawout sqrmod))
;; differentiate
(set! diffout (- out zreg))
(set! zreg out)
(set! c (/ SRs (* 4.0 2.0 frq (- 1.0 inc))))
(set! mod (+ mod inc)) ;; update mod
(set! mod (+ mod inc)) ;; update mod
(* diffout c amp)))))