; follower.ins
; simple (stupid!) amplitude envelope following
; last updated lcb 02.06.2001

(definstrument follower (source-filename target-filename
				      &key (source-srate 1.0)
				           (target-srate 1.0)
					   (start 0.0)
				           (duration nil)
					   (decay 0.00001))
  (let* ((source-file (open-input* source-filename))
	 (source-file-duration (/ (sound-duration source-filename) 
				  (abs source-srate)))
	 (target-file (open-input* target-filename))
	 (target-file-duration (/ (sound-duration target-filename) 
				  (abs target-srate)))
	 (minimum-duration (if (null duration)
			       (min source-file-duration target-file-duration)
			       (min duration source-file-duration target-file-duration)))
	 (source-src (make-src :input source-file
			       :srate source-srate))
	 (target-src (make-src :input target-file
			       :srate target-srate))
	 (current-amp 0.0)
	 (test-amp 0.0))
    (multiple-value-bind (beg end) (times->samples start minimum-duration)
      (run
       (loop for i from beg to end do
	 (setf test-amp (src source-src))
	 (if (> test-amp current-amp)
	     (setf current-amp test-amp)
	   (setf current-amp (- current-amp decay)))
	 (outa i (* current-amp (src target-src)))))
      (close-input source-file)
      (close-input target-file))))
