audacity-plugins/RANDOMCHIRP.ny

85 lines
2.6 KiB
Common Lisp

;nyquist plug-in
;version 4
;type generate
;preview linear
;name "Random Chirps..."
;action "Chirping..."
;author "dm"
;control seed "Seed" int "" 4123 1 134456
;control duration "Duration" float "" 1 0 5
;control num-chirps "Number of Chirps" int-text "" 8 1 100
;control rand-vols "Randomize Volumes" choice "No,Yes" 0
;control rand-phase "Randomize Phases" choice "No,Yes" 0
;control freq-intervals "Frequency intervals (low high time)" string "" "(100 1000)"
;;;Globals: min-rate, max-rate and above
(setq max-rate (/ *sound-srate* 2.1))
(setq min-rate 0.1)
;;;generate pseudorandom int between 1 and 134456
(defun rnd ()
(setq seed (rem (sum (mult 8121 seed) 28411) 134456)))
;;;pseudorandom (uniform) float between lo and hi (assume hi > lo)
(defun unirand (lo hi)
(+ lo (* (- hi lo) (/ (rnd) 134456.0))))
(defun piece (inif finf crv)
(if (zerop crv)
(pwlv inif 1 finf)
(let* ((epsilon (expt 0.5 crv))
(norm (/ (- inif finf) (- 1.0 epsilon)))
(arc (scale norm (diff (pwev 1 1 epsilon) epsilon))))
(sum finf arc))))
(defun bottom (pair)
(min max-rate (max min-rate (car pair))))
(defun top (pair)
(min max-rate (max min-rate (cadr pair))))
(defun freq-curve (band-list)
(do* ((time -1 (incf time))
(cur-band (car band-list) (car band-list))
(lo (bottom cur-band) (bottom cur-band))
(hi (top cur-band) (top cur-band))
(prev-freq nil cur-freq)
(cur-freq (unirand lo hi) (unirand lo hi))
(crv-param (unirand -10.0 10.0))
(segment nil (piece prev-freq cur-freq crv-param))
(curve 0 (sim curve (at time (cue segment)))))
((= (length band-list) 1) curve)
(setf band-list (cdr band-list))))
(defun chirp (band-list phase)
(hzosc (freq-curve band-list) *table* phase))
;Stole this one from David R. Sky's Sequencer2
(defun string-to-list (string)
(read (make-string-input-stream (format nil "(~a)" string))))
(defun process-freq-intervals (string)
(let ((raw-list (string-to-list string)))
(if (= (length raw-list) 1)
(list (car raw-list) (car raw-list))
raw-list)))
(defun get-phase ()
(if (zerop rand-phase)
0
(unirand -180.0 180.0)))
(defun get-scale ()
(if (zerop rand-vols)
1.0
(unirand 0.0 1.0)))
(stretch-abs duration
(do* ((count 0 (incf count))
(bands (process-freq-intervals freq-intervals))
(phase nil (get-phase))
(vol nil (get-scale))
(cur-chirp nil (scale vol (chirp bands phase)))
(result 0 (sum result cur-chirp)))
((= count num-chirps) (scale (/ (float num-chirps)) result))))