;nyquist plug-in
;version 3
;type process
;categories "http://lv2plug.in/ns/lv2core#DistortionPlugin"
;name "Kazoo..."
;action "Making it beautiful..."
;info "by Steve Daulton. (www.easyspacepro.com).\nReleased under GPL v2.\n"

;; kazoo.ny by Steve Daulton Nov 2012.
;; Released under terms of the GNU General Public License version 2:
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html

;control buzz "Buzz (%)" int "" 90 0 100
;control horn "Horn length (cm)" real "" 10 0 20
;control hcf "Brightness (kHz)" int "" 10 1 15

(setq buzz (max 0.00001 (- 1 (/ buzz 100.0))))
(setq frequency (min (* hcf 1000) (/ *sound-srate* 2)))
(setq horn-hz (- 1000 (* 40 horn)))
; force 'horn' to 'float' for backward compatibility.
(setq res (- 11 (sqrt (float horn))))

(setf s
  (highpass8
    (lowpass8 s (* res horn-hz))
    (/ horn-hz res)))

(defun clip-all (sig x)
  ; use 'truncate' rather than 'round' for backward compatibility
  (let ((step (truncate (+ 0.5 (/ (snd-srate sig) 200)))))
    (setf limit (mult x (snd-avg sig step step op-peak)))
    (mult (/ 0.9 x)
      (s-min sig limit))))

(defun kazoo (sig amount Hz)
  (setf clipped
    (sim 
      (clip-all (s-max 0 sig) amount)
      (mult -1
        (clip-all (s-max 0 (mult -1 sig)) amount))))
  (setf clipped (lowpass8 clipped hz))
  (setq gain (peak clipped 1000000))
  ; in case first million samples are silent
  (setq gain
    (if (> gain 0)(/ gain) 1))
  (mult gain clipped))

(multichan-expand #'kazoo s buzz frequency)
