;; Bandlimited Impulse Train (aka BLIT) ;; David Lowenfels, March 2003 ;; Adapted from Emanuel Landeholm's public-domain C code from music-dsp.org ;; because sum-of-cosines is kind of crappy when sweeping frequency (def-clm-struct blit (phase 0) (nyquist_attn 0.9999) (freq 0) (period 0) (partials 10) (rolloff 0.999999) (aN 0) (wrapped nil) ) (clm::def-optkey-fun make-blit-init ((frequency 440) (phase 0) (nyquist 0.9999) ) (let* ((this (gensym)) ) (setf this (make-blit :phase phase :nyquist_attn nyquist)) (set-blit-frequency this frequency) this ) ) (defmacro set-blit-frequency (blit freq) ;; if(b->phase >= 1.0 || b->curcps == 0.0) `(setf (blit-freq ,blit) (/ ,freq *srate*) (blit-period ,blit) (/ (blit-freq ,blit)) (blit-partials ,blit) (+ 1.0 (floor (/ (blit-period ,blit) 2))) (blit-rolloff ,blit) (expt (blit-nyquist_attn ,blit) (/ 2 (blit-period ,blit))) (blit-aN ,blit) (expt (blit-rolloff ,blit) (blit-partials ,blit)) ) ) (defmacro blit (b) (let* ((beta (gensym)) (Nbeta (gensym)) (cosbeta (gensym)) (num (gensym)) (den (gensym)) (aN (gensym)) (N (gensym)) (a (gensym)) (freq (gensym)) (output (gensym)) ) `(let* ((,beta (* 2 pi (blit-phase ,b))) (,a (blit-rolloff ,b)) (,N (blit-partials ,b)) (,Nbeta (* ,N ,beta)) (,cosbeta (cos ,beta)) (,aN (blit-aN ,b)) (,num (- 1 (* ,aN (cos ,Nbeta)) (* ,a (- ,cosbeta (* ,aN (cos (- ,Nbeta ,beta))))))) (,den (* (blit-period ,b) (+ 1 (* ,a (+ ,a (* ,cosbeta -2.0)))))) (,freq (blit-freq ,b)) (,output (* 2 (- (/ ,num ,den) ,freq))) ;;return this value ) (incf (blit-phase ,b) ,freq) (if (>= (blit-phase ,b) 1.0) (progn (decf (blit-phase ,b) 1.0) (setf (blit-wrapped ,b) t) ) (setf (blit-wrapped ,b) nil)) ,output ) ) )