;nyquist plug-in
;version 3
;type analyze
;name "Waveform macro..."
;action "Calculating waveform macro..."
;info "Waveform macro tool version 2.6\nBy Kef Schecter; edited by poodlecock\nReleased under CC0 1.0 Universal\nProtip: you can type in your own values in the box for some program-crashing fun!\nBe careful with big numbers!"

;control wavesize-choice "Wave size" int "" 16 4 1024
;control maxvol-choice "Max volume" int "" 16 1 256
;control normalize-choice "Normalize result" choice "yes,no" 1

; *****************************************************************************************
; Waveform macro tool version 2.6.1.1
; By Kef Schecter; edited by poodlecock
; CC0 1.0 Universal; details at https://creativecommons.org/publicdomain/zero/1.0/legalcode
; *****************************************************************************************

(setf *gc-flag* nil)

(setf normalize-yes 0)
(setf normalize-no 1)

(setf wavesize wavesize-choice)

(setf max-volume (1- maxvol-choice))

(setf half-max-volume (/ max-volume 2.0))

(setf new-old-ratio (/ (float wavesize) len))

(setf resample-rate (truncate (* *sound-srate* new-old-ratio)))


(defmacro push (item lst)
  `(setq ,lst (cons ,item ,lst)))


(defun process ()
  (let* ((resampled (resample s resample-rate))
         (normalized (if (= normalize-choice normalize-yes)
                         (normalize resampled)
                         resampled))
         (samples-array (snd-samples normalized wavesize))
         (samples-list '()))
    (dotimes (index wavesize)
      (push (n163-adjust (aref samples-array index)) samples-list))
    (reverse samples-list)))


(defun normalize (snd)
  (let ((maximum (peak snd NY:ALL)))
    (scale (/ 1.0 maximum) snd)))


; Converts value in range from -1.0 to 1.0 into an integer from 0 to max-volume
; Does not bother range-checking input
(defun n163-adjust (value)
  (truncate (* (+ value 1.0) half-max-volume)))


(defun run ()
  (list (list 0 (string-trim "()" (format nil "~a" (process))))))


; Execution begins here
(if (arrayp s)
  "Stereo tracks are not supported. Please convert your tracks to mono before proceeding."
  (run))