Compare commits

...

2 Commits

Author SHA1 Message Date
wan-may 0d457b9834 add readme and licence 2024-05-02 23:12:07 -03:00
wan-may ac8860be5f make a repo 2024-05-02 23:10:55 -03:00
18 changed files with 994 additions and 3 deletions

133
ADDITIVE3.ny Normal file
View File

@ -0,0 +1,133 @@
;nyquist plug-in
;version 4
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;preview linear
;name "Additive Tone..."
;action "Generating Tones..."
;author "dm"
;copyright "Released under terms of the GNU General Public License version 2"
;release 1.1
;control coefs-string "Decay Coefficients" string "" "(2.25 3 2.0 5 3) (3.3 2.7) (5.4 2 7.5 (3.2 5) (4 2)) (7.8 9.2) (13.3)"
;control pch "Pitch (Steps)" float-text "" 60 1 96
;control vib-rate "Vibrato Speed (Hz)" float-text "" 36 0 1102.4
;control vib-depth "Vibrato Depth (Hz)" float-text "" 3 0 nil
;control dur "Duration" time "" 3 nil nil
;;;WHAT IT DO
;Generates a tone with pitch pch and duration dur, with vibrato.
;coefs-string determines the timbre, by specifying how quickly harmonics should ;attenuate according to their frequency.
;coefs-string consists of terms delimited by parentheses (), whose elements may be ;either positive numbers or further sub-terms delimited by parentheses.
;If there are n terms, the first term gives the timbre at the start time, the second at ;dur/n, the third at 2*dur/n, and so on. Timbre is smoothly interpolated between these ;points.
;In a term with k elements, the rth element determines the amplitude of
;the r-1 mod k harmonics.
;If the rth element is a number x, then the ith harmonic (where i is r-1 modulo k) has ;amplitude i^(-x). That is, higher numbers make the harmonics attenuate faster.
;If the rth element is a subterm with l elements, then the sth element of that subterm
;determines the amplitude of the (r+k*(s-1)) mod k*l harmonics.
;As an example, here are the harmonics and relative amplitudes when
;coefs-string is "((5 (4 2)) 3)" and pch is 69:
;Harmonic Frequency Amplitude Amplitude
;1 440 1^-5 1.000000
;2 880 2^-3 0.125000
;3 1320 3^-4 0.012345
;4 1760 4^-3 0.015625
;5 2200 5^-5 0.000320
;6 2640 6^-3 0.004630
;7 3080 7^-2 0.020408
;8 3520 8^-3 0.001953
;;;ACKNOWLEDGEMENT
;Shout out to steve for a very thorough code review and loads of coding tips, and the ;rewritten gen-tables which I nicked verbatim from a post of his.
;Thank you David R. Sky for the handy string-to-list function.
;;;ADDITIONAL GLOBAL VARIABLES
;;Don't compute harmonics if their frequencies are too high.
(setq hi-freq (min (/ *sound-srate* 2) 17000.0))
(setq top-overtone (min
1000 ;magic number to avoid argument stack overflow when calling simrep.
(+ 1 (truncate (/ hi-freq (step-to-hz pch))))))
(defun get-coefficient (overtone lst divis)
;;;recursively search coefficient list for exponent
(let* ((len (length lst))
(branches (mult divis len))
(term (nth (rem (/ overtone divis) len) lst)))
(if (numberp term)
term
(get-coefficient overtone term branches))))
(defun get-amplitude (overtone coef-list)
(expt (+ 1.0 overtone)
(- (get-coefficient overtone coef-list 1))))
;2022-07-06, I fucked up my backup and started from this old version
;which still had stack overflow errors from simrep.
;(defun gen-table (coef-list)
; (simrep (current-overtone top-overtone)
; (scale (get-amplitude current-overtone coef-list)
; (build-harmonic (+ 1 current-overtone) 2048))))
;2022-07-06, this one should work better.
(defun gen-table (coef-list)
(do ((table 0)
(current-overtone 0))
((> current-overtone top-overtone) table)
(setq current-overtone (+ 1 current-overtone))
(setq table
(sum table (scale (get-amplitude current-overtone coef-list)
(build-harmonic (+ 1 current-overtone) 2048))))))
(defun normalize (sig)
;;;assume signal has 2048 samples
(scale (/ 0.75 (peak sig 2048)) sig))
(defun gen-tables (coef-lists pitch interval)
;;; Push wavetable and breakpoint onto a list 'tables'.
;;; Discard the final breakpoint, then return 'tables' for siosc.
(let ((count 1) tables)
(dolist (coef-list coef-lists (reverse (cdr tables)))
(push (normalize (gen-table coef-list)) tables)
(push (* interval count) tables)
(incf count))))
(defun modulation (vib-rate vib-depth duration)
(if (= vib-rate 0)
(s-rest duration)
(scale vib-depth (lfo vib-rate duration))))
(defun gen-tone (pitch duration coef-lists)
;;;get wavetables and mod. env., pass to built-in Nyquist oscillators.
(validate-coefs coef-lists)
(let* ((mod (modulation vib-rate vib-depth duration))
(interval (/ duration (length coef-lists)))
(tables (gen-tables coef-lists pitch interval)))
(if (= (length coef-lists) 1)
(fmosc pitch mod (maketable (car tables)) 0)
(siosc pitch mod tables))))
(defun validate-coefs (lst)
;;; All items in top level list must be lists.
(dolist (coef lst)
(when (not (listp coef))
(throw 'err (format nil "Coefficient ~s is invalid (not a list)." coef)))
(validate-items lst)))
(defun validate-items (item)
;;; Items must be lists or numbers. Test recursively.
(cond
((and (numberp item) (>= item 0))) ;valid
((listp item) (mapc 'validate-items item)) ;recurse
(t (throw 'err (format nil "Coefficient ~s is invalid." item)))))
;;;Took this one-liner from David R. Sky's Sequencer 2, released under GPLv2.
;;;Replace this with eval-string when 2.3.1 releases.
(defun string-to-list (string)
(read (make-string-input-stream (format nil "(~a)" string))))
;;read string, then generate tone (or throw error)
(setf coefs (string-to-list coefs-string))
(catch 'err (gen-tone pch dur coefs))

31
CONVOLVE.ny Normal file
View File

@ -0,0 +1,31 @@
;nyquist plug-in
;version 4
;type process
;preview linear
;name "Convolve Tracks"
;action "Convolving..."
;author "dm"
(defun get-storage ()
(get '*SCRATCH* 'DM-CONVOLVE-STORAGE))
(defun clear-storage ()
(remprop '*SCRATCH* 'DM-CONVOLVE-STORAGE))
(defun store (signal)
(putprop '*SCRATCH* signal 'DM-CONVOLVE-STORAGE)
(sum (s-rest 0) signal))
(defun conv-stored (signal)
(convolve signal (get-storage)))
(setq index (get '*TRACK* 'INDEX))
(setq tracks (length (get '*SELECTION* 'TRACKS)))
;(print (symbol-plist '*SCRATCH*))
(if (= index 1)
(if (< tracks 2)
(print "Select two or more tracks")
(store *TRACK*))
(if (= index tracks)
(prog1 (conv-stored *TRACK*) (clear-storage))
(store (conv-stored *TRACK*))))

34
FILTERSWEEP.ny Normal file
View File

@ -0,0 +1,34 @@
;nyquist plug-in
;version 4
;type process
;preview linear
;name "Filter Sweep..."
;action "Filtering..."
;author "dm"
;control type "Filter Type" choice "Low-Pass,High-Pass,Band-Pass" 0
;control start-freq "Start Frequency (Hz)" float-text "" 7000 0 20000
;control end-freq "End Frequency (Hz)" float-text "" 1000 0 20000
;control shape-num "Curve Parameter" float-text "" 5 nil nil
;control intensity "Intensity" int-text "" 1 1 50
(defun curve (inif finf crv)
(if (zerop crv)
(pwlv inif 1 finf)
(let* ((crv (expt 0.5 crv))
(norm (/ (- inif finf) (- 1.0 crv)))
(arc (scale norm (diff (pwev 1 1 crv) crv))))
(sim finf arc))))
(defun iter-lp (signal cutoff iter)
(dotimes (n iter signal) (setf signal (lp signal cutoff))))
(defun iter-hp (signal cutoff iter)
(dotimes (n iter signal) (setf signal (hp signal cutoff))))
(let* ((cutoff (curve start-freq end-freq shape-num))
(bandwidth (/ *sound-srate* (float intensity) 5.0)))
(case type
(0 (iter-lp *TRACK* cutoff intensity))
(1 (iter-hp *TRACK* cutoff intensity))
(2 (reson *TRACK* cutoff bandwidth 1))))

52
FILTERSWEEPTRACK.ny Normal file
View File

@ -0,0 +1,52 @@
;nyquist plug-in
;version 4
;type process
;preview linear
;name "Filter Sweep (Track Input)..."
;action "Filtering..."
;author "dm"
;control type "Filter Type" choice "Low-Pass,High-Pass,Band-Pass" 0
;control intensity "Intensity" int-text "" 1 1 50
;control max-cu-freq "Maximum Cutoff Frequency" float "" 15000 1 22030
;clip to halfwave, scale to max cutoff freq, downsample to control rate, store,
;compute
(defun store-as-cutoff (signal)
(setf to-store
(sim (s-rest 0)
(force-srate *control-srate*
(scale max-cu-freq
(s-min (const 1)
(s-max (s-rest 1) signal))))))
(putprop '*SCRATCH* (sim (s-rest 0) to-store) 'DM-FSWEEP-CUTOFF)
*TRACK*)
(defun clear-storage ()
(remprop '*SCRATCH* 'DM-SWEEP-CUTOFF))
(defun iter-lp (signal cutoff iter)
(print (snd-length cutoff ny:all))
(dotimes (n iter signal)
(setf signal (lp signal cutoff))))
(defun iter-hp (signal cutoff iter)
(dotimes (n iter signal)
(setf signal (hp signal cutoff))))
(defun apply-filter (cutoff)
(let* ((bandwidth (/ *sound-srate* (float intensity) 5.0)))
(case type
(0 (iter-lp *TRACK* cutoff intensity))
(1 (iter-hp *TRACK* cutoff intensity))
(2 (reson *TRACK* cutoff bandwidth 1)))))
(setq index (get '*TRACK* 'INDEX))
(setq tracks (length (get '*SELECTION* 'TRACKS)))
(if (< tracks 2)
(print "Select 2 tracks")
(if (< index tracks)
(store-as-cutoff *TRACK*)
(let ((cutoff (get '*SCRATCH* 'DM-FSWEEP-CUTOFF)))
(if (= index tracks) (clear-storage))
(multichan-expand #'apply-filter cutoff))))

44
FMCHIRP.ny Normal file
View File

@ -0,0 +1,44 @@
;nyquist plug-in
;version 4
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;preview linear
;name "FM Chirp..."
;action "Generating Chirp..."
;author "dm"
;copyright "Released under terms of the GNU General Public License version 2"
;control carri-params "Carrier (Start End Curve)" string "" "800 200 -1.5"
;control modul-params "Modulator (Start End Curve)" string "" "450 -1.0 5.7"
;control modul-scale "Modulation Index" float-text "" 50 0 nil
;control dur "Duration" float "" 1 0.01 5
;;;curve going from inf to finf with curve parameter crv.
(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))))
;;;stole this one from David R. Sky's Sequencer 2.
(defun string-to-list (string)
(read (make-string-input-stream (format nil "(~a)" string))))
(defun list-to-floats (input-list)
(mapcar #'float input-list))
(defun string-to-curve (string)
(apply #'piece (list-to-floats (string-to-list string))))
(defun three-numbersp (input-list)
(eq (mapcar #'numberp input-list) (list (= 0 0) (= 0 0) (= 0 0))))
(stretch-abs dur
(let* ((modul-freq (string-to-curve modul-params))
(carri-freq (string-to-curve carri-params)))
(hzosc
(sum carri-freq
(scale modul-scale
(hzosc modul-freq))))))

192
GRAINIMOGRIFIER.ny Normal file
View File

@ -0,0 +1,192 @@
;nyquist plug-in
;version 4
;type process
;name "Grainimogrifier..."
;action "Milling..."
;author "dm"
;preview disabled
;release 1.3.1
;copyright "Released under terms of the GNU General Public License version 2"
;control grain-number "Number of Grains" int "" 50 2 1750
;control min-grain-gap "Minimum Grain Separation (ms)" float "" 1 0 50
;control grain-length "Grain Length (ms)" float "" 500 0 1000
;control grain-type "Grain Envelope" choice "Triangle,Sine,Exponential,Rectangular" 0
;control normal-places "Normalize Sample Start Control Envelope" choice "No,Yes" 0
; 'input' raw sample to granulate
; 'gaps-env' t: grain number x: absolute time in seconds until next grain
; 'starts' processed gaps - list of absolute start times of grains
; 'place-env' t: relative time in output x: relative input time where grain starts
; 'places' processed places - list of relative input times where grains start
; where gaps-env or place-env is negative, grains are reversed.
(defun scratch-cleanup ()
(remprop '*SCRATCH* '*DM-GRAN-STARTS*)
(remprop '*SCRATCH* '*DM-GRAN-PLACES*)
(remprop '*SCRATCH* '*DM-GRAN-SIGN*))
(defun get-r-grain-length ()
(/ grain-length (get-duration 1) 1000.0))
;;;FUNCTIONS CALLED BY FIRST RUN
(defun array-to-list (arr)
(do (lst
(ind 0 (1+ ind))
(end (- (length arr) 1)))
((> ind end) (reverse lst))
(push (aref arr ind) lst)))
(defun downsample-and-list (sig)
(array-to-list (snd-fetch-array
(force-srate (/ grain-number (get-duration 1)) sig)
grain-number 1)))
(defun gaps-to-starts (lst)
(do ((rslt (list 0)))
((null lst) (cdr (reverse rslt)))
(push
(+ (car rslt)
(max min-grain-gap (abs (pop lst))))
rslt)))
(defun first-invocation ()
;;;resample first track so that we have one sample per grain
;;;cast sound to list, take cumulative sum and store for future invocations
;;;also record when list is negative so we know when to reverse grains
;;mono error
(if (arrayp *TRACK*)
(throw 'err (format nil "First two tracks should be mono.")))
(let ((gaps-list (downsample-and-list *TRACK*)))
(putprop '*SCRATCH*
(gaps-to-starts gaps-list)
'*DM-GRAN-STARTS*)
(putprop '*SCRATCH*
(mapcar #'minusp gaps-list)
'*DM-GRAN-SIGN*)))
;;;FUNCTIONS CALLED BY SECOND RUN
(defun rev-time (len tim)
;;;grain starts at local time tim, local duration is len.
;;;find local start time such that reversing track plays same grain up to reversal.
(- 1.0 tim len))
(defun normalize-places (lst)
;;;ensure elements span from 0 to 1 (or if it's constant, 0)
(if (and lst normal-places)
(let* ((hi (apply #'max lst))
(lo (apply #'min lst))
(spread (- hi lo)))
(if (= spread 0)
(mapc (lambda (y) 0) lst)
(mapc (lambda (y) (/ (- y lo) spread)) lst)))
lst))
(defun get-final-duration (starts)
;;;duration of processed track
(+ (/ grain-length 1000.0) (car (last starts))))
(defun process-place-env (starts reverses)
;;;convert times to relative start times, look up values of track
;;;reverse grains whenever first or second track is negative
(do ((dur-out (get-final-duration starts))
rev reverses-out
place places)
((null starts)
(cons
(reverse (normalize-places places))
(reverse reverses-out)))
(setf place (sref *TRACK* (/ (pop starts) dur-out)))
(setf rev (or (pop reverses) (minusp place)))
;;Reversing grains is accomplished by graining a reversed copy of the whole track.
;;Thus we need to adjust the start times.
(push
(if rev
(rev-time (get-r-grain-length) (abs place))
place) places)
(push rev reverses-out)))
(defun second-invocation ()
;;;get list of absolute start times of grains from previous invocation
;;;convert to relative start times
;;;look up values of current (i.e. second) track at rel. times, store for later
(if (arrayp *TRACK*)
(throw 'err (format nil "First two tracks should be mono."
(scratch-cleanup))))
(let ((results (process-place-env
(get '*SCRATCH* '*DM-GRAN-STARTS*)
(get '*SCRATCH* '*DM-GRAN-SIGN*))))
(putprop '*SCRATCH* (car results) '*DM-GRAN-PLACES*)
(putprop '*SCRATCH* (cdr results) '*DM-GRAN-SIGN*)))
;;;FUNCTIONS CALLED BY THIRD RUN
(defun array-reverse (a length)
(do ((left 0 (1+ left))
(right (- length 1) (1- right))
(middle (/ length 2))
temp)
((= left middle) a)
(setf temp (aref a left))
(setf (aref a left) (aref a right))
(setf (aref a right) temp)))
(defun snd-reverse (sig)
(let* ((len (snd-length sig NY:ALL))
(arr (snd-samples sig len)))
(snd-from-array
(snd-t0 sig)
*sound-srate*
(array-reverse arr len))))
(defun grain-envelope (len)
(case grain-type
(0 (pwl (/ len 2.0) 1 len 0)) ;triangle
(1 (lfo (/ 0.5 (get-duration 1) len) len)) ;sine
(2 (scale (/ (- 1 len)) (diff (pwev 1 len len) len))) ;exp
(3 1))) ;rect
(defun any (lst)
(do ((rslt nil (pop lst)))
((or rslt (null lst)) rslt)))
(defun granulate (sample)
;;;extract grains from sample at relative times specified by places
;;;apply envelope to each grain, cue grains at absolute times specified by starts
(do* ((starts (get '*SCRATCH* '*DM-GRAN-STARTS*))
(places (get '*SCRATCH* '*DM-GRAN-PLACES*))
(revers (get '*SCRATCH* '*DM-GRAN-SIGN*))
;;optimization - only reverse the sample if we need to.
(rev-sample (if (any revers) (snd-reverse sample) nil))
(throw 'err (format nil "AAA"))
place
r-grain-length
(grain (s-rest 1))
(out (s-rest 0)))
((null starts) out)
(setq place (pop places))
(setq r-grain-length (get-r-grain-length))
(setf grain (mult (grain-envelope r-grain-length)
(extract place (+ place r-grain-length)
(if (pop revers) rev-sample sample))))
(setf out (sim (at 0 (cue out))
(at-abs (pop starts) (cue grain))))))
(defun process-sample-track ()
(prog1
(multichan-expand #'granulate *TRACK*)
(if (= index tracks) (scratch-cleanup))))
;;;GLOBALS
(setq index (get '*TRACK* 'INDEX))
(setq tracks (length (get '*SELECTION* 'TRACKS)))
(setq min-grain-gap (/ min-grain-gap 1000.0))
;;;MAIN
(catch 'err
(if (< tracks 3)
(throw 'err (format nil
"Select three or more audio tracks. The top two should be mono."))
(cond
((= index 1) (first-invocation) *TRACK*)
((= index 2) (second-invocation) *TRACK*)
(T (process-sample-track)))))

34
HARMONIZER.ny Normal file
View File

@ -0,0 +1,34 @@
;nyquist plug-in
;version 4
;type process
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;preview linear
;name "Harmonize..."
;action "Harmonizing..."
;author "dm"
;control decay "Decay" float "" 0.5 0 1
;control harmonics "Harmonics" int "" 2 1 10
(setq minor-third (/ 6.0 5.0))
(setq major-third (/ 5.0 4.0))
(defun get-ratio (index)
(if (evenp index)
(/
(* (expt minor-third (float (/ index 4)))
(expt major-third (float (/ (+ 2 index) 4)))))
(*
(expt minor-third (float (+ 1 (/ index 4))))
(expt major-third (float (/ (+ 1 index) 4))))))
(defun normalize (signal)
(let ((x (* (peak signal ny:all) 0.95)))
(setq signal (scale (/ x) signal))))
(do* ((index 0 (incf index))
(ratio nil (get-ratio index))
(vol 1.0 (* vol decay))
(result *TRACK*
(sum result (scale vol (pitshift *TRACK* ratio 1.0)))))
((>= index harmonics) (normalize result)))

25
INHARMONIC.ny Normal file
View File

@ -0,0 +1,25 @@
;nyquist plug-in
;version 4
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;preview linear
;name "Inharmonic..."
;action "Generating Tone..."
;author "dm"
;control decay "Decay" float "" 0.5 0 1
;control ratio "Ratio" float "" 1.005 1 1.05
;control fund-freq "Frequency (Hz)" float "" 420 1 600
;control duration "Length (Seconds)" float "" 3 0 6
(setq loop-number 500)
(do* ((cur-ind 1 (incf cur-ind))
(cur-pch (hz-to-step fund-freq) (hz-to-step (* (/ (+ cur-ind 1) 1.0 cur-ind) ratio (step-to-hz cur-pch))))
(cur-vol decay (* decay cur-vol))
(result (scale cur-vol (sine cur-pch duration))
(sum result (scale cur-vol (sine cur-pch duration)))))
(
(or (> cur-pch 120) (>= cur-ind loop-number)) result)
(print cur-pch)
(print cur-vol))

66
NOISEMODULATION.ny Normal file
View File

@ -0,0 +1,66 @@
;nyquist plug-in
;version 4
;type process
;preview linear
;name "Noise Modulation..."
;action "Modulating..."
;author "dm"
;control mixes-str "Wet-Dry Mix List" string "" "0.5 0 1"
;control width-str "Passband Width" string "" "100 300 0"
;control lp-iterations "Stopband Attenuation" int "" 5 0 15
;--- GLOBAL VARIABLES
;--- PREPARE INPUT
(defun cast-nonnegative-float (element)
(cond
((floatp element) (abs element))
((integerp element) (float (abs element)))
(T 0.0)))
(defun list-to-floats (input-list)
(mapcar #'cast-nonnegative-float input-list))
;;;stole this one from David R. Sky's Sequencer 2.
(defun string-to-list (string)
(read (make-string-input-stream (format nil "(~a)" string))))
;;;add some validation to these functions at some point
(defun process-string (string)
(list-to-floats (string-to-list string)))
;;; COMPUTE SOUND
;;;this should be written better
(defun gen-envelope (inlist &optional (cutoff (/ *control-srate* 2.1)))
(if (= 1 (length inlist))
(const (car inlist) 1.0)
(lowpass6 (pwlvr-list (reverse (cdr
(do* ((ylist inlist (cdr ylist))
(height (car ylist) (car ylist))
(interval (/ (- (length ylist) 1.0)))
(bp-list (list interval height)
(cons interval (cons height bp-list))))
((null (cdr ylist)) bp-list)))))
cutoff)))
(defun iterate-lp (signal cutoff iterations)
(if (zerop iterations) signal
(iterate-lp (lp signal cutoff) cutoff (- iterations 1))))
(defun gen-noise (widths)
(let ((cutoff (gen-envelope widths)))
(iterate-lp (noise 1) cutoff lp-iterations)))
(defun normalize (signal)
(let ((x (/ 0.95 (peak signal ny:all))))
(setq signal (scale x signal))))
(let* ((modulator (gen-noise (process-string width-str)))
(wet-env (gen-envelope (process-string mixes-str)))
(dry-env (diff 1.0 wet-env))
(raw (normalize *TRACK*))
(dry (mult dry-env raw))
(wet (mult wet-env modulator raw)))
(normalize (sum dry wet)))

39
RANDOM-TONES.ny Normal file
View File

@ -0,0 +1,39 @@
;nyquist plug-in
;name "Random Tones..."
;type generate
;version 4
;author "dm"
;action "Generating Random Tones..."
;control seed "Random Seed" int "" 12532 1 134455
;control duration "Length (Seconds)" float "" 3 0 10
;control num-tones "Number of tones" int "" 15 1 100
;control middle "Center Frequency (Hz)" float-text "" 1000 0 20000
;control width "Width" float-text "" 1 0 20000
;control table-type "Table" choice "Sine,Saw,Square,Triangle" 0
;;;generate pseudorandom int between 1 and 134456
(defun rnd ()
(setq seed (rem (sum (mult 8121 seed) 28411) 134456)))
;;;generate pseudrandom float between 0 and 1
(defun rnd-scale ()
(/ (float (rnd)) 134456.0))
;;;generate pseudorandom (uniformly distributed) frequency within width of middle
(defun rnd-freq ()
(print (min (/ *sound-srate* 2.1)
(+ middle (* (- (rnd-scale) 0.5) width 2.0)))))
(defun gen-tone (hz-freq tbl)
(case tbl
(0 (sine (hz-to-step hz-freq)))
(1 (osc-saw hz-freq))
(2 (osc-pulse hz-freq 0.0))
(3 (osc-tri hz-freq))))
(stretch-abs duration
(do* ((tone 0 (incf tone))
(pch 1.0 (rnd-freq))
(result 0 (sum result (scale (rnd-scale) (gen-tone pch table-type)))))
((= tone num-tones) (scale (/ (float num-tones)) result))))

117
RANDOM-WAVES.ny Normal file
View File

@ -0,0 +1,117 @@
;nyquist plug-in
;version 4
;type generate
;name "Random Piecewise Linear..."
;action "Generating..."
;author "dm"
;copyright "Released under terms of the GNU General Public License version 2"
;release 1.1
;control duration "Duration" time "" 3 0 nil
;control fund-freq "Frequency (Hz)" float "" 50 1 300
;control locks "Parameter Lock (Table Duration)" string "" "(5 3.5) (7 1.1)"
;control text "Timbral Parameters:"
;control seed "Random Seed" int "" 12532 1 134455
;control num-tables "Number of Key Tables" int "" 5 1 50
;control num-breakpoints "Max. Segments Per Key Table" int "" 5 1 15
;control vary-breakpoints "Vary Segments Per Key Table" choice "No,Yes" 0
;control table-type "Table In" choice "Sine,Saw,Fifth,Triangle,Random" 0
(defun rnd ()
;;;pseudorandom number between -1 and 1
(setq seed (rem (sum (mult 8121 seed) 28411) 134456))
(- (/ (float seed) 134456 0.5) 1))
;;;GENERATE LIST OF WAVETABLES AND BREAKPOINTS FOR SIOSC
(defun build-shaper (num-breaks)
;;;pseudorandom piecewise linear function on [0,2] with num-breaks pieces
(if (zerop num-breaks)
(pwlv -1 2.01 1)
(do* ((i 1 (+ i 1))
(new-time 0 (sum (rnd) 1 new-time))
(point-list (list (rnd)) (cons (rnd) (cons new-time point-list))))
((> i num-breaks)
(stretch-abs (/ 2.01 new-time) (pwlv-list (reverse point-list)))))))
(defun get-num-breaks (max-breaks)
;;;decide how many breakpoints build-shaper should create
(case vary-breakpoints
(0 max-breaks)
(1 (truncate (* max-breaks (+ 1 (rnd)))))))
(defun gen-table (raw-table max-breaks)
(shape raw-table (build-shaper (get-num-breaks max-breaks)) 1))
(defun get-raw-table ()
;;;decide which raw table to use
(case table-type
(0 (build-harmonic 1 2048))
(1 (pwlv -1 1 1))
(2 (scale 0.49 (sum (build-harmonic 2 2048) (build-harmonic 3 2048))))
(3 (pwlv -1 1 1 2 -1))
(4 (scale 0.49 (build-shaper num-breakpoints)))))
(defun wav-list (duration num-tables breaks-per-table slock-list)
(if (= num-tables 1)
(let ((cur-table (gen-table (get-raw-table) breaks-per-table)))
(list cur-table duration cur-table))
(let ((interval (/ duration num-tables))
(raw-table (get-raw-table)))
(do* ((ind 1 (+ 1 ind))
(cur-time interval (sum interval cur-time))
(cur-table (gen-table raw-table breaks-per-table)
(gen-table raw-table breaks-per-table))
(breakpoints-list (list cur-table)
(cons cur-table (cons cur-time breakpoints-list))))
((= ind num-tables) (reverse breakpoints-list))
;;locks: continue to use current wavetable for specified time
(if (and slock-list (= ind (caar slock-list)))
(progn
(setf cur-time (sum (cadar slock-list) cur-time))
(setf breakpoints-list (cons cur-table (cons cur-time breakpoints-list)))
(setf slock-list (cdr slock-list))))))))
;;;VALIDATE AND PROCESS USER INPUT
(defun sort-by-car (lst)
(sort lst
(lambda (x y) (< (car x) (car y)))))
(defun validate-pairs (pair)
(if (and (listp pair) (= 2 (length pair)))
(if (and (integerp (car pair))
(> (car pair) 0)
(<= (car pair) num-tables))
(if (and (numberp (cadr pair)) (plusp (cadr pair)))
pair
(throw 'err
(format nil "Lock duration ~s not a positive number."
(cadr pair))))
(throw 'err (format nil
"Lock table ~s not between 1 and ~s inclusive." (car pair) num-tables)))
(throw 'err (format nil
"Lock ~s not a pair of the form (Table Duration)." pair))))
;;;When 2.3.1 is out, replace with eval-string
(defun string-to-list (string)
(read (make-string-input-stream (format nil "(~a)" string))))
(defun process-locks (str)
(sort-by-car (mapcar #'validate-pairs (string-to-list str))))
;;;PROCESS OUTPUT
(defun pch-mod (dur)
;;placeholder
(s-rest dur))
(defun normalize (sig)
(let ((ac (highpass8 sig 25)))
(scale (/ 0.95 (peak ac ny:all)) ac)))
;;;main
(catch 'err (normalize (siosc
(hz-to-step fund-freq)
(pch-mod duration)
(wav-list duration num-tables num-breakpoints (process-locks locks)))))

85
RANDOMCHIRP.ny Normal file
View File

@ -0,0 +1,85 @@
;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))))

View File

@ -1,3 +0,0 @@
# audacity-plugins
My Nyquist plugins for Audacity

3
README.txt Normal file
View File

@ -0,0 +1,3 @@
A bunch of old Nyquist plugins I wrote for use in Audacity.
To install, see: https://support.audacityteam.org/basics/customizing-audacity/installing-plugins

28
REVERSECHIRP.ny Normal file
View File

@ -0,0 +1,28 @@
;nyquist plug-in
;version 4
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;preview linear
;name "Reverse Chirp..."
;action "Generating Chirp..."
;author "dm"
;control crv-param "Curve" float "" 5 0 10
;control top-freq "Top Frequency (Hz)" float "" 6000 1 22050
;control duration "Length (Seconds)" float-text "" 0.05 0 5
;control tbl-choice "Waveform" choice "Sine,Sawtooth,Triangle,Square" 0
;tone which lingers at high frequencies before chirping downward to zero
;bandpass filter is applied to emphasize frequency halfway down
(let* ((passq 5.0)
(epsilon (expt 0.5 crv-param))
(tbl-form (case tbl-choice
(0 *sine-table*)
(1 *saw-table*)
(2 (maketable (pwlv -1 0.5 -1 0.501 1 1.0 1)))
(3 *tri-table*))))
(stretch-abs duration
(bandpass2
(hzosc (scale (- top-freq) (diff (pwev epsilon 1 1) 1))
tbl-form 0.0)
(/ top-freq 2.0) passq)))

70
ReverbImpulseDrum.ny Normal file
View File

@ -0,0 +1,70 @@
;nyquist plug-in
;version 4
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;author "dm"
;name "Reverb Impulse Drum..."
;action "Generating..."
;info ""
;control band-list "List: (center amplitude &optional bandwith)" string "" "(420 0.5 250) (1500 0.3 150) (4300 0.01) (7500 0.02 2000) (12345 0.01 3000) (3500 0.05 300)"
;control impulse-type "Kind of Impulse" choice "chirp, noise, spike" 0
;control impulse-volume "Volume of Impulse" float "" 0.5 0 1
;control impulse-length "Length of Impulse (ms)" float "" 10 1 50
;control decay "Decay" float "" 0.5 0.01 1
(setq impulse-length (mult 0.001 impulse-length))
;Stolen from David R. Sky's Sequencer2, I don't know how this works.
(defun string-to-list (string)
(read (make-string-input-stream (format nil "(~a)" string))))
(defun normalize (signal &optional (amplitude 1))
(setf factor (/ amplitude (peak signal ny:all)))
(scale factor signal)
);end normalize
(defun gen-noiseband (center &optional (amplitude 1) (bandwidth 1000))
(partial (hz-to-step center) (lowpass8 (normalize (noise 1) amplitude) bandwidth))
);end gen-noiseband
(defun gen-response (band-list dur)
(setf bands ())
(dolist (band-params (string-to-list band-list))
(setf bands (cons (apply #'gen-noiseband band-params) bands))
);end dolist
(mult (normalize (apply #'sim bands) impulse-volume)
(pwlv 1 (* dur 0.25) 0.1 dur 0))
);end response
(defun chirp-impulse (dur)
(mult (hzosc (sum
(pwlv (/ *sound-srate* 2.1) (* dur 0.3) 100 dur 1) ;frequency of hzosc
(scale 100 (noise dur)) ;noise to vary frequency of chirp randomly
));end of hzosc
(pwlv 1 dur 0)) ;envelope to get rid of click at and of impulse
);end gen-impulse
(defun noise-impulse (dur)
(noise dur)
)
(defun spike-impulse (dur)
(pwl (/ dur 5.0) 1 dur 0)
)
(defun gen-impulse (dur)
(cond ;chooses which kind of impulse
((= impulse-type 0) (chirp-impulse dur))
((= impulse-type 1) (noise-impulse dur))
((= impulse-type 2) (spike-impulse dur))
);end cond
)
(setf impulse (normalize (gen-impulse impulse-length) impulse-volume))
(setf response (gen-response band-list decay))
(lowpass8 (sum
impulse
(convolve impulse response))
15000)

25
TONERATIO.ny Normal file
View File

@ -0,0 +1,25 @@
;nyquist plug-in
;version 4
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;preview linear
;name "Common Ratio Tone..."
;action "Generating Tone..."
;author "dm"
;control decay "Decay" float "" 0.5 0 1
;control ratio "Ratio" float "" 2 1 5
;control fund-freq "Frequency (Hz)" float "" 420 1 600
;control duration "Length (Seconds)" float "" 3 0 6
(setq loop-number (truncate
(/ (log (/ *sound-srate* fund-freq)) (log ratio))))
(do* ((cur-ind 1 (incf cur-ind))
(cur-pch (hz-to-step fund-freq) (hz-to-step (* ratio (step-to-hz cur-pch))))
(cur-vol decay (* decay cur-vol))
(result (scale cur-vol (sine cur-pch duration))
(sum result (scale cur-vol (sine cur-pch duration)))))
((>= cur-ind loop-number) result)
(print cur-pch)
(print cur-vol))

16
WINDOW.ny Normal file
View File

@ -0,0 +1,16 @@
;nyquist plug-in
;version 4
;type process
;name "Apply Window"
;action "Windowing..."
;author "dm"
(defun lump (width)
(lfo (/ 0.5 (get-duration 1) width) width))
(setq index (float (get '*TRACK* 'INDEX)))
(setq tracks (float (length (get '*SELECTION* 'TRACKS))))
(setq start-time (/ (- index 1.0) tracks))
(mult *TRACK*
(seq (s-rest start-time)
(cue (lump (/ 2.0 tracks)))))