;nyquist plug-in
;version 4
;type process
;name "Amplitude Tracker"
;author "Steve Daulton"
;copyright "GNU General Public License v2.0 or later."
;release 3.1.2


;control decay "Decay rate" int "dB/sec" 60 12 240

(setf decay (abs (/ decay *sound-srate*)))


(setf blocksize 10000)
; get the length in samples up to a max of blocksize.
(setf blocksize (min (truncate len) blocksize))


(defun decay (newval oldval)
  ;; Apply dB reduction to value.
  (let ((oldval (linear-to-db oldval)))
    (setf oldval (- oldval decay))
    (setf oldval (db-to-linear oldval))
    (max oldval (abs newval))))


(defun returnsound (ar)
  ;; Convert array back to a sound.
  (snd-from-array 0 *sound-srate* ar))


(defun process-array (myarray)
  (dotimes (i blocksize (returnsound myarray))
    (cond
      ((not (aref myarray i))
          (setf (aref myarray i) 0))
      ((< (abs (aref myarray i)) *prev*)
          (setf (aref myarray i) (decay (aref myarray i) *prev*)))
      (t  (setf (aref myarray i) (abs (aref myarray i)))))
    (setf *prev* (aref myarray i))))


(defun process (sig)
  (let ((loops (truncate (+ (/ (truncate len) blocksize) 0.5))))
    (seqrep (i loops)
      (cue (process-array (snd-fetch-array sig blocksize blocksize))))))


(setf *prev* 0)
(if (soundp *track*)
    (extract 0 1 (process *track*))
    "Error.\nMono track selection required.")
