1$nyquist plug-in 2$version 4 3$type process 4$name (_ "Limiter") 5$manpage "Limiter" 6$debugbutton false 7$action (_ "Limiting...") 8$preview enabled 9$author (_ "Steve Daulton") 10$release 3.0.4 11$copyright (_ "GNU General Public License v2.0 or later") 12 13;; limiter.ny by Steve Daulton November 2011, updated May 2015. 14 15;; Released under terms of the GNU General Public License v2.0 or later: 16;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 17;; 18;; For information about writing and modifying Nyquist plug-ins: 19;; https://wiki.audacityteam.org/wiki/Nyquist_Plug-ins_Reference 20 21$control type (_ "Type") choice ( 22 ("SoftLimit" (_ "Soft Limit")) 23 ("HardLimit" (_ "Hard Limit")) 24 ;i18n-hint: clipping of wave peaks and troughs, not division of a track into clips 25 ("SoftClip" (_ "Soft Clip")) 26 ("HardClip" (_ "Hard Clip")) 27) 0 28$control gain-L (_ "Input Gain (dB) 29mono/Left") real "" 0 0 10 30$control gain-R (_ "Input Gain (dB) 31Right channel") real "" 0 0 10 32$control thresh (_ "Limit to (dB)") real "" -3 -10 0 33$control hold (_ "Hold (ms)") real "" 10 1 50 34$control makeup (_ "Apply Make-up Gain") choice ( 35 (_ "No") 36 (_ "Yes") 37) 0 38 39(if (not (boundp 'type)) 40 (setf type 0)) 41 42(if (boundp 'gain-L) 43 (setf gain-L (db-to-linear gain-L)) 44 (setf gain-L 1)) 45 46(if (boundp 'gain-R) 47 (setf gain-R (db-to-linear gain-R)) 48 (setf gain-R 1)) 49 50(if (boundp 'thresh) 51 (setf thresh (db-to-linear thresh)) 52 (setf thresh (db-to-linear -3.0))) 53 54(if (not (boundp 'hold)) 55 (setf hold 10.0)) 56 57(if (boundp 'makeup) 58 (if (= makeup 1) (setf makeup T) (setf makeup nil)) 59 (setf makeup nil)) 60 61;;; brick wall limiter 62(defun hardlimit (sig limit hld) 63 (let* ((time (/ hld 3000.0)) ; lookahead time (seconds) 64 (samples (round (* time *sound-srate*))) ; lookahead in samples 65 (peak-env (get-env sig samples time limit))) 66 (mult sig 67 (snd-exp 68 (mult -1 (snd-log peak-env)))))) 69 70;;; Envelope follower for brick wall limiter 71(defun get-env (sig step lookahead limit) 72 (let* ((sig (mult (/ limit) sig)) 73 (pad-time (* 3 lookahead)) ; padding required at start (seconds) 74 (pad-s (* 3 step)) ; padding samples 75 (padding (snd-const (peak sig pad-s) 0 *sound-srate* pad-time)) 76 (peak-env (snd-avg sig (* 4 step) step OP-PEAK))) 77 (extract 0 1 78 (s-max 1 79 (sim padding 80 (at-abs pad-time (cue peak-env))))))) 81 82(defun softlimit (sig thresh hld) 83 (let* ((sig (hardlimit sig 1 hold)) 84 (step (truncate (* (/ hld 3000.0) *sound-srate*))) 85 (waveshape (snd-avg sig (* 4 step) step op-peak)) 86 (env (sum thresh (mult thresh (diff 1 waveshape)))) 87 (env (clip env 1)) 88 (offset (/ (* 3 step) *sound-srate*)) 89 (initial (peak sig (* 2 step))) 90 (pause-lev (sum thresh (mult thresh (diff 1 initial)))) 91 (pause-lev (clip pause-lev 0.9)) 92 (pause (snd-const pause-lev 0 *sound-srate* offset))) 93 (setf env 94 (sim 95 pause 96 (at-abs offset (cue env)))) 97 (mult sig env))) 98 99 100(defun soft-clip-table () 101"Lookup table for soft clipping wave-shaper" 102 (abs-env 103 (sound-srate-abs 44100 104 (Control-srate-abs 44100 105 (let* ((knee (- 1 (/ 1.0 pi))) 106 (kcurve (mult knee (osc (hz-to-step (/ (* 4 knee))) knee))) 107 (ikcurve (mult knee (osc (hz-to-step (/ (* 4 knee))) knee *sine-table* -90))) 108 (lin (pwlv -0.5 knee -0.5 109 (+ knee (/ 2.0 pi)) 0.5 110 2.0 0.5 111 2.0 (+ 0.5 knee) 112 2.1 (+ 0.5 knee)))) 113 (mult (/ 2.0 pi) 114 (sim 115 (at-abs 0 (cue ikcurve)) 116 (at-abs 0 (cue lin)) 117 (at-abs (+ knee (/ 2.0 pi)) (cue kcurve))))))))) 118 119(defun soft-clip (sig) 120 (let* ((knee (- 1 (/ 1.0 pi))) 121 (clip-level (* (+ 0.5 knee)(/ 2.0 pi))) 122 (sig (mult clip-level (/ thresh) sig))) 123 (if makeup 124 (mult 0.999 125 (/ clip-level) 126 (shape sig (soft-clip-table) 1.0)) 127 (mult thresh 128 (/ clip-level) 129 (shape sig (soft-clip-table) 1.0))))) 130 131 132(defun makupgain (sig) 133 (if makeup 134 (mult (/ 0.999 thresh) sig) ;keep below 0dB 135 sig)) 136 137;; Pre-gain 138(setf *track* 139 (if (arrayp *track*) 140 (vector (mult (aref *track* 0) gain-L) 141 (mult (aref *track* 1) gain-R)) 142 (mult *track* gain-L))) 143 144 145(case type 146 (0 (makupgain (multichan-expand #'softlimit *track* thresh hold))) 147 (1 (makupgain (multichan-expand #'hardlimit *track* thresh hold))) 148 (2 (soft-clip *track*)) 149 (T (makupgain (clip *track* thresh)))) 150