;; bandlimited pulse wave
;; use sum of saws method
;; highcpu #t (default is lowcpu #f)
(bind-func blpulse_c
(lambda (mod:float highcpu:i1)
(let ((out 0.0) (inc 0.0) (mod2:float 0.0)
(blep 0.0:f) (absinc 0.0) (t 0.0)
(saw1 0.0) (saw2 0.0) (dcorr 0.0))
(lambda (amp:float frq:float pw:float)
(set! pw (clamp (fabs pw) 0.05 0.95))
(set! inc (/ frq SRs))
;; positive frequencies
(if (and (> inc 0.0) (>= mod 1.0))
(set! mod (- mod 1.0)))
;; negative frequencies
(if (and (< inc 0.0) (<= mod 0.0))
(set! mod (+ mod 1.0)))
;; saw 1
(set! blep (if highcpu
(blep_n (cast fBLEPTable_8_BLKHAR SAMPLE*) 4096.0 mod (fabs inc) 1.0 0 4.0 0)
(poly_blep mod (fabs inc) 1.0 0)))
(set! saw1 (+ blep (- (* mod 2.0) 1.0)))
;; saw 2
;; first calc offset for saw2 based on pw
(if (> inc 0.0)
(set! mod2 (+ mod pw))
(set! mod2 (- mod pw)))
;; positive frequencies
(if (and (> inc 0.0) (>= mod2 1.0))
(set! mod2 (- mod2 1.0)))
;; negative frequencies
(if (and (< inc 0.0) (<= mod2 0.0))
(set! mod2 (+ mod2 1.0)))
;; now calc saw 2
(set! blep (if highcpu
(blep_n (cast fBLEPTable_8_BLKHAR SAMPLE*) 4096.0 mod2 (fabs inc) 1.0 0 4.0 0)
(poly_blep mod2 (fabs inc) 1.0 0)))
(set! saw2 (+ blep (- (* mod2 2.0) 1.0)))
;; subtract 180 out of phase
(set! out (- (* 0.5 saw1) (* 0.5 saw2)))
;; dc correction
(set! dcorr (/ 1.0 pw))
(if (< pw 0.5)
(set! dcorr (/ 1.0 (- 1.0 pw))))
(set! out (* out dcorr))
(set! mod (+ mod inc)) ;; update mod
(* amp out)))))