1$nyquist plug-in
2$version 4
3$type process
4$preview linear
5$preview selection
6$name (_ "Adjustable Fade")
7$manpage "Adjustable_Fade"
8$debugbutton false
9$action (_ "Applying Fade...")
10$author (_ "Steve Daulton")
11$release 3.0.4
12$copyright (_ "GNU General Public License v2.0 or later")
13
14;; Released under terms of the GNU General Public License v2.0 or later:
15;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
16;;
17;; For information about writing and modifying Nyquist plug-ins:
18;; https://wiki.audacityteam.org/wiki/Nyquist_Plug-ins_Reference
19
20
21$control type (_ "Fade Type") choice (("Up" (_ "Fade Up"))
22                                      ("Down" (_ "Fade Down"))
23                                      ("SCurveUp" (_ "S-Curve Up"))
24                                      ("SCurveDown" (_ "S-Curve Down"))) 0
25$control curve (_ "Mid-fade Adjust (%)") real "" 0 -100 100
26$control units (_ "Start/End as") choice (("Percent" (_ "% of Original"))
27                                          ("dB" (_ "dB Gain"))) 0
28$control gain0 (_ "Start (or end)") float-text "" 0 nil nil
29$control gain1 (_ "End (or start)") float-text "" 100 nil nil
30$control preset (_ "Handy Presets (override controls)") choice (("None" (_ "None Selected"))
31                                                                ("LinearIn" (_ "Linear In"))
32                                                                ("LinearOut" (_ "Linear Out"))
33                                                                ("ExponentialIn" (_ "Exponential In"))
34                                                                ("ExponentialOut" (_ "Exponential Out"))
35                                                                ("LogarithmicIn" (_ "Logarithmic In"))
36                                                                ("LogarithmicOut" (_ "Logarithmic Out"))
37                                                                ("RoundedIn" (_ "Rounded In"))
38                                                                ("RoundedOut" (_ "Rounded Out"))
39                                                                ("CosineIn" (_ "Cosine In"))
40                                                                ("CosineOut" (_ "Cosine Out"))
41                                                                ("SCurveIn" (_ "S-Curve In"))
42                                                                ("SCurveOut" (_ "S-Curve Out"))) 0
43
44;;; Preview takes the entire selection so that we know the correct
45;;; selection length, but preview only needs to process preview length."
46(defun get-input (sig)
47  (if *previewp*
48      (multichan-expand #'trim-input sig)
49      sig))
50
51
52;;; Trim input when previewing."
53(defun trim-input (sig)
54  (let ((dur (min (get-duration 1)
55                  (get '*project* 'preview-duration))))
56    (setf sig (extract-abs 0 dur sig))))
57
58;;; invalid values
59(defun check-values (x y)
60  (setf err (format nil (_ "Error~%~%")))
61  (if (= units 0)  ;percentage values
62    (cond
63      ((or (< x 0)(< y 0))
64        (throw 'err (format nil (_ "~aPercentage values cannot be negative.") err)))
65      ((or (> x 1000)(> y 1000))
66        (throw 'err (format nil (_ "~aPercentage values cannot be more than 1000 %.") err))))
67    (cond   ;dB values
68      ((or (> x 100)(> y 100))
69        (throw 'err (format nil (_ "~adB values cannot be more than +100 dB.~%~%~
70                                 Hint: 6 dB doubles the amplitude~%~
71                                 -6 dB halves the amplitude.") err))))))
72
73;;; Select and apply fade
74(defun fade (sig type curve g0 g1)
75  (when (= preset 0)
76    ; Can't use widget validation for gain. Range depends on units.
77    (check-values g0 g1))
78  (psetq curve (/ curve 100.0)
79         g0    (gainscale g0 units)
80         g1    (gainscale g1 units))
81  (mult (get-input sig)
82    (case preset
83      (0  (case type                  ; Custom fade
84            (0 (simple (min g0 g1) (max g0 g1) curve))
85            (1 (simple (max g0 g1) (min g0 g1) curve))
86            (2 (raised-cos (min g0 g1)(max g0 g1) curve))
87            (T (raised-cos (max g0 g1) (min g0 g1) curve))))
88      (1  (linear 0 1))               ; Linear In
89      (2  (linear 1 0))               ; Linear Out
90      (3  (log-exp-curve -60 0))      ; Exponential In
91      (4  (log-exp-curve -60 1))      ; ExponentialOut
92      (5  (log-exp-curve 15.311 0))   ; Logarithmic In
93      (6  (log-exp-curve 15.311 1))   ; Logarithmic Out
94      (7  (simple-curve 0 1 0.5))     ; Rounded In
95      (8  (simple-curve 1 0 0.5))     ; Rounded Out
96      (9  (cosine-curve 0 1))         ; Cosine In
97      (10 (cosine-curve 1 0))         ; Cosine Out
98      (11 (raised-cos 0 1 0.0))       ; S-Curve In
99      (t  (raised-cos 1 0 0.0)))))    ; S-Curve Out
100
101;;; Simple Curve:
102;;; Use cosine for + values and linear for -ve.
103(defun simple (g0 g1 curve)
104  (cond
105    ((= g0 g1) g0)                    ; amplify
106    ((and (> curve 0)(< curve 0.5))   ; +ve curve less than 0.5, lin to cosine
107      (let ((curve (* curve 2)))
108        (sim
109          (mult (- 1 curve)
110            (scale-curve g0 g1 (linear g0 g1)))           ; linear
111          (mult curve
112            (scale-curve g0 g1 (cosine-curve g0 g1))))))  ; cosine curve
113    ((> curve 0)
114      (cos-curve g0 g1 (- 1.5 curve)))                    ; +ve curve > 0.5
115    (t (simple-curve g0 g1 (- 1 (* 2 curve))))))          ; -ve curve
116
117;;; Linear fade to the power of 'pow'.
118(defun simple-curve (g0 g1 pow)
119  (curve-adjust g0 g1 pow
120    (linear g0 g1)))
121
122;;; Cosine fade to the power of 'pow'.
123(defun cos-curve (g0 g1 pow)
124  (curve-adjust g0 g1 pow
125    (cosine-curve g0 g1)))
126
127(defun curve-adjust (g0 g1 pow env)
128  (scale-curve g0 g1
129    (if (= pow 1)
130        env
131        (snd-exp
132          (mult pow
133            (snd-log env))))))
134
135;;; Scale curves to min, max.
136(defun scale-curve (g0 g1 env)
137  (sum (min g0 g1)
138    (mult (abs (- g0 g1)) env)))
139
140;;; Cosine curve.
141(defun cosine-curve (g0 g1)
142  (let ((step (hz-to-step (/ 0.25 (get-duration 1))))
143        (phase (if (> g0 g1) 90 0)))
144    (osc step 1 *sine-table* phase)))
145
146;;; Linear fade in, out.
147(defun linear (g0 g1)
148  (control-srate-abs *sound-srate*
149    (if (> g0 g1)                         ; g0 = g1 does not occur here.
150        (pwlv 1 1 0)                      ; fade out
151        (pwlv 0 1 1))))                   ; else fade in
152
153;;; Raised cosine fades.
154(defun raised-cos (g0 g1 curve)
155  (setq curve
156    (if (> curve 0)
157        (exp-scale-mid (* 2 curve))       ; mid-point -3dB @ Adjust = 50%
158        (exp-scale-mid (* 1.63 curve))))  ; mid-point -12dB @ Adjust = -50%
159  (setf env
160    (control-srate-abs *sound-srate*      ; sound srate required for accuracy.
161      (cond
162        ((= g0 g1) g0)    ; amplify
163        ((> g0 g1)        ; fade down
164          (snd-exp
165            (mult (pwlv (- 1 curve) 1 1)
166              (snd-log (raised-cosin 90)))))
167        (t (snd-exp                       ; fade up
168             (mult (pwlv 1 1 (- 1 curve))
169               (snd-log (raised-cosin -90))))))))
170  (sum (min g0 g1)
171    (mult (abs (- g0 g1)) env)))
172
173;;; Raised cosine curve.
174(defun raised-cosin (phase)
175  (let ((hz (hz-to-step (/ (get-duration 2)))))
176    (mult 0.5
177      (sum 1
178        (osc hz 1 *sine-table* phase)))))
179
180;;; log or exponential curve scaled 0 to 1
181;;; x is the minimum level in dB before scaling.
182(defun log-exp-curve (x direction)
183  (control-srate-abs *sound-srate*
184    (let ((x (db-to-linear x)))
185      ;; If direction=0 fade-in else fade-out
186      (if (= direction 0)
187        (setf env (pwev x 1 1))
188        (setf env (pwev 1 1 x)))
189      (mult (/ (- 1 x))     ; normalize to 0 dB
190        (diff env x)))))    ; drop down to silence
191
192;;; Curve scaling for S-curve.
193(defun exp-scale-mid (x)
194  (let ((e (exp 1.0)))
195    (/ (- (exp (- 1 x)) e)
196      (- 1 e))))
197
198(defmacro gainscale (gain type)
199  `(setf ,gain
200      (if (= ,type 0)  ; percent
201          (/ ,gain 100.0)
202          (db-to-linear ,gain))))
203
204
205(catch 'err (fade *track* type curve gain0 gain1))
206