(load "blit.lisp")

(defun envelope-or-number (in)
  (if (numberp in)
    (list 0 in 1 in)
    in
  ))

(definstrument super-saw (start-time duration frequency &optional (amp 1.0)
				    &key (amp-env '(0 1.0 1.0 1.0))
				    (freq-env '(0 1 1.0 1)) ;frequency envelope as a factor of original frequency
				    (leak (- 1 (/ 35 *srate*))) ; -0.5 dB at 20 Hz   0.99841
				    (limit .9) ;attenuation at Nyquist, affects sharpness of waveform, eliminates Gibb's phenomena (!! Must be less than 1.0)
				    (glide 4)  ;exponent of portamento (quartic functions approximate logarithmic behavior)
				    (phase 0) ;between 0 and 1
				    (detune 0) ;how many cents to detune the second oscillator
				    )

  
  (multiple-value-bind (beg end) (times->samples start-time duration)
    (let* (
	   (blit1 (make-blit-init :frequency frequency :phase phase :nyquist limit))
	   (blit2 (make-blit-init :frequency frequency :phase phase :nyquist limit))
	   
	   (integrator (make-one-pole :a0 1
				      :b1 (- leak)))
	   
	   (amp (make-env :envelope amp-env
			  :scaler amp
			  :duration duration))
	   (freq (make-env :envelope (envelope-exp freq-env glide)
			   :scaler frequency
			   :duration duration))
	   (detune (expt 2 (/ detune 1200)))
	   f
	   )
      (run
       (loop for i from beg below end do
	 (setf f (env freq))
	 (if (blit-wrapped blit1)
	     (set-blit-frequency blit1 f)
	   )
	 (if (blit-wrapped blit2)
	     (set-blit-frequency blit2 (* f detune))
	   )
	 
 	 (outa i (* (env amp) 1.6 ;;correction factor
		    0.5
		    (one-pole integrator (+ (blit blit1) (blit blit2)))
		    )
	       ))))
    )
  )

#|
(with-sound (:srate 44100 :statistics t :clipped t)
	    (super-saw 0 3 200 0.3 :freq-env '(0 1 1 .51) :detune 30)
	    (super-saw 0 3 101 0.3 :freq-env '(0 1 1 .51) :detune 30)) ;;"Hoover" sound

(with-sound (:srate 44100 :statistics t :clipped t)
	    (super-saw 0 2 200 0.3 :freq-env '(0 1 0.05 3 0.5 1 0.55 .51 1 .53) :detune 30)
	    (super-saw 0 2 101 0.3 :freq-env '(0 1 0.05 3 0.5 1 0.55 .50 1 .53) :detune 30))
|#