;;; Building simp.ins one step at a time
;;; nando, Jan 2002

#|

;;; the smallest clm instrument ever

(definstrument simp (start-time)
  (run
   (loop for i from 0 to 44100 do
     (outa i 0.0))))

;;; add an oscillator:

(definstrument simp (start-time)
  (let* ((s (make-oscil :frequency 440)))
    (run
     (loop for i from 0 to 44100 do
       (outa i (oscil s))))))

;;; add two parameters, frequency controls the frequency of our
;;; oscillator, amplitude scales the output

(definstrument simp (start-time frequency amplitude)
  (let* ((s (make-oscil :frequency frequency)))
    (run
     (loop for i from 0 to 44100 do
       (outa i (* amplitude (oscil s)))))))

;;; add start-time and duration as parameters

(definstrument simp (start-time duration frequency amplitude)
  (let* ((start (floor (* start-time *srate*)))
	 (end (+ start (floor (* duration *srate*))))
	 (s (make-oscil :frequency frequency)))
    (run
     (loop for i from start to end do
       (outa i (* amplitude (oscil s)))))))

;;; add an amplitude envelope

(definstrument simp (start-time duration frequency amplitude amp-env)
  (let* ((start (floor (* start-time *srate*)))
	 (end (+ start (floor (* duration *srate*))))
	 (s (make-oscil :frequency frequency))
	 (e (make-env :envelope amp-env
		      :duration duration)))
    (run
     (loop for i from start to end do
       (outa i (* amplitude (env e)(oscil s)))))))

;;; make the amplitude envelope a key argument
;;; WARNING: this is the just lisp version (no run loop) so
;;; it will run very slowly...

(definstrument simp (start-time duration frequency amplitude
				&key (amp-env '(0 0 0.5 1 1 0)))
  (let* ((start (floor (* start-time *srate*)))
	 (end (+ start (floor (* duration *srate*))))
	 (s (make-oscil :frequency frequency))
	 (e (make-env :envelope amp-env
		      :duration duration)))
     (loop for i from start to end do
       (outa i (* amplitude (env e)(oscil s))))))
|#

;;; make the amplitude envelope a key argument

(definstrument simprun (start-time duration frequency amplitude
				&key (amp-env '(0 0 0.5 1 1 0)))
  (let* ((start (floor (* start-time *srate*)))
	 (end (+ start (floor (* duration *srate*))))
	 (s (make-oscil :frequency frequency))
	 (e (make-env :envelope amp-env
		      :duration duration)))
    (run
     (loop for i from start to end do
       (outa i (* amplitude (env e)(oscil s)))))))


;; some examples:
;; (with-sound (:srate 44100) (simp 1.5 2.1 640 0.4)(simp 0 1.9 370 0.2))
;; (with-sound (:srate 44100) (loop repeat 10 for time from 0 by 0.4 for freq from 200 by 100 do (simp time 0.9 freq 0.1)))

#|

(with-sound (:srate 44100)
  (loop
    repeat 10
    for time from 0 by 0.4
    for freq from 200 by 100 do
    (simp time 0.3 freq 0.1 '(0 0 0.5 1 1 0))))

(defun scribble (start-time duration notes freq spread)
  (loop
    repeat notes
    for time from start-time by 0.1
    for f from freq by spread do
    (simp time 0.2 f 0.1 '(0 0 0.1 1 0.9 1 1 0))))

(with-sound()(scribble 0 1 10 440 100)(simp 0.3 5 200 0.1 '(0 0 0.5 1 1 0))(scribble 1 1 10 740 80))

|#
