/usr/share/audacity/plug-ins/vocalrediso.ny is in audacity-data 2.2.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | ;nyquist plug-in
;version 4
;type process
;categories "http://lv2plug.in/ns/lv2core#MixerPlugin"
;name "Vocal Reduction and Isolation..."
;manpage "Vocal_Reduction_and_Isolation"
;action "Applying Action..."
;author "Robert Haenggi"
;copyright "Released under terms of the GNU General Public License version 2"
;;
;; vocrediso.ny, based on rjh-stereo-tool.ny
;; Released under terms of the GNU General Public License version 2:
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
;; Plug-in version 1.56, June 2015
;; Requires Audacity 2.1.1 or later, developed under Audacity 2.1.1
;;
;control action "Action" choice "Remove Vocals,Isolate Vocals,Isolate Vocals and Invert,Remove Center,Isolate Center,Isolate Center and Invert,Remove Center Classic: Mono,Analyze" 0
(setf rotation 0.0)
;;control rotation "Rotation (Degrees)" real "" 0 -180 180
;control strength "Strength" real "" 1.0 0.0 50.0
;control low-transition "Low Cut for Vocals (Hz)" real "" 120 1 24000
;control high-transition "High Cut for Vocals (Hz)" real "" 9000 1 24000
;
;preview linear
;
;; make aref shorter
(defmacro : (array index) (backquote (aref ,array ,index)))
;;
;; input corrections
(defmacro limit (symbol lower upper)
(backquote (min ,upper (max ,lower ,symbol))))
;;;
;;; Some statistical functions
;;
;; Running Sum
(defun sigma (sig)
(snd-biquad sig 1 0 0 1 0 0 0))
;;
;; Compares two sounds (Y = A + B * X)
(defun least-squares-xy (x y &key show)
(let* ((n (float (min (snd-length x ny:all)
(snd-length y ny:all))))
(t-n (/ (1- n) (snd-srate x)))
(bar-x (* (/ n) (snd-sref (sigma x) t-n)))
(bar-y (* (/ n) (snd-sref (sigma y) t-n)))
(x (diff x bar-x))
(y (diff y bar-y))
(pos-x (max (snd-sref (sigma (s-abs x)) t-n) 1e-17))
(pos-y (max (snd-sref (sigma (s-abs y)) t-n) 1e-17))
(pos-xy (cond
((> pos-x pos-y) (- (/ pos-y pos-x) 1))
(t (- 1 (/ pos-x pos-y)))))
(s-xy (* (/ n) (snd-sref (sigma (prod x y)) t-n)))
(s-x2 (* (/ n) (snd-sref (sigma (prod x x)) t-n)))
(s-y2 (* (/ n) (snd-sref (sigma (prod y y)) t-n)))
(r (/ s-xy (max 1e-17 (sqrt (* s-x2 s-y2)))))
(r2 (expt r 2.0))
(a1 (cond
((= s-x2 0) 0)
((= s-xy 0) 0)
(t (/ s-xy s-x2))))
(a0 (- bar-y (* a1 bar-x))))
(if show (format t
"Average x: ~a, y: ~a
Covariance x y: ~a
Average variance x: ~a, y: ~a
Standard deviation x: ~a, y: ~a
Coefficient of correlation: ~a
Coefficient of determination: ~a
Variation of residuals: ~a
y equals ~a plus ~a times x~%"
bar-x bar-y s-xy s-x2 s-y2 (sqrt s-x2) (sqrt s-y2) r r2 (* s-y2 (- 1 r2)) a0 a1))
(list r r2 pos-xy a0 a1)))
;;
(defun between (val low high)
(and (> val low) (<= val high)))
;;
;; Summary for "Analyse", fed with coeff. of correlation
(defun summary (analysis &aux (corr (car analysis)) (pan-position (third analysis)))
(format nil "Pan position: ~a~%The left and right channels are correlated by about ~a %. This means:~%~a~%"
pan-position
(round (* corr 100))
(cond
((between corr 0.97 1.1)
" - The two channels are identical, i.e. dual mono.
The center can't be removed.
Any remaining difference may be caused by lossy encoding.")
((between corr 0.9 0.97)
" - The two Channels are strongly related, i.e. nearly mono or extremely panned.
Most likely, the center extraction will be poor.")
((between corr 0.5 0.9)
" - A fairly good value, at least stereo in average and not too wide spread.")
((between corr 0.2 0.5)
" - An ideal value for Stereo.
However, the center extraction depends also on the used reverb.")
((between corr -0.2 0.2)
" - The two channels are almost not related.
Either you have only noise or the piece is mastered in a unbalanced manner.
The center extraction can still be good though.")
((between corr -0.8 -0.2)
" - Although the Track is stereo, the field is obviously extra wide.
This can cause strange effects.
Especially when played by only one speaker.")
(t " - The two channels are nearly identical.
Obviously, a pseudo stereo effect has been used
to spread the signal over the physical distance between the speakers.
Don't expect good results from a center removal."))))
;;;
;;; FFT Functionality
;;
;; different windows
(defun fft-window (fs type hop zeros)
(cond
; Bartlett, but first value > 0
((= type 0)
(if (= zeros 0)
(snd-pwl 0 fs
(list 0 (/ (float hop)) (1- hop) 1.0 (1- fs) 0.0 fs))
(progn (setf cut (truncate (- fs zeros 1)))
(snd-pwl 0 fs
(list 0 (/ (float hop))(- cut hop) 1.0 cut 0.0 fs 0.0 fs)))))
; Han
((= type 1)
(seq (cue (control-srate-abs fs
(mult 0.5 (sum 1 (lfo (/ fs (* 2.0 hop)) (/ (- fs zeros) (get-duration fs)) *table* 270)))))
(cue (snd-const 0 0 fs (/ (float zeros) fs)))))
; rectangle
(t (if (= fs hop) (snd-pwl 0 fs (list 0 1.0 fs 1.0 fs))
(snd-pwl 0 fs
(list 0 1.0 (1- hop) 1.0 hop 0.0 fs 0.0 fs))))))
;;
;; objects and classes
(setf fft-class (send class :new
'(sound length skip window function argument2 wt-max) ))
(send fft-class :answer :next '() '(
(if argument2
(funcall function (snd-fft sound length skip window) argument2)
(funcall function (snd-fft sound length skip window)))))
(send fft-class :answer :isnew '(snd len skp win fn arg2) '(
(setf wt-max 0.0)
(setf sound snd)
(setf length len)
(setf skip skp)
(setf window win)
(setf function fn)
(setf argument2 arg2)))
;;
;;; Short Time Fourier Transform
(defun stft (sound length skip window
&optional (function #'(lambda (fr) fr)) (argument2 nil))
(send fft-class :new sound length skip window function argument2))
;;
;; Power spectrum calculated from fft (as sound)
(defun power-spectrum (frame size sr)
(let* ((snd (scale (/ (sqrt 8.0) *win-sigma*) (snd-from-array 0 sr frame)))
(zero (snd-from-array 0 sr #(0))))
(s-log (scale 2 (snd-avg (seq (cue zero) (cue (prod snd snd))) 2 2 op-average)))))
;;
;; Make a weighted center (mono)
;; that can be substracted from L&R
(defun steer (side obj &aux (mid (send obj :next)))
(cond ((and mid side)
(let* ((power-sum (power-spectrum mid fs 2))
(power-dif (power-spectrum side fs 2))
(wt-exp (s-exp (scale strength (diff power-dif power-sum))))
(weight (shape wt-exp *map* 0))
(weight (snd-samples weight ny:all)))
(do ((i low-transition (+ i 2))) ((>= i high-transition))
(setf (: out i) (: weight (/ (1+ i) 2)))
(setf (: out (1+ i)) (: weight (/ (1+ i) 2))))
(snd-samples (mult (snd-from-array 0 1 mid) (snd-from-array 0 1 out)) fs)))
(t nil)))
;;;
;;; Sound Pre-processing
;;
;; rotate the stereo field around the center point
;; between the two speakers
(defun transform (snd &optional ( cosine (cos (abs rotation))) (sine (sin (abs rotation))))
(let* ((direction (/ (+ 1e-15 rotation) (abs (+ 1e-15 rotation))))
(fft-offset (s-rest (if (< action 6) (/ hop (get-duration *sr*)) 0)))
(L (seq (cue fft-offset) (cue (: snd 0))))
(R (seq (cue fft-offset) (cue (: snd 1)))))
(vector (sum (mult cosine L) (mult (- direction) sine R))
(sum (mult direction sine L) (mult cosine R)))))
;;;
;;; main procedure
(defun catalog (&aux snd
(original-len (/ (+ len hop) *sr*)) (dur (get-duration 1)))
(if (soundp *track*) (return-from catalog "This plug-in works only with stereo tracks.")
(setf snd (vector (snd-copy (: *track* 0)) (snd-copy (: *track* 1)))))
(cond
((= action 7)
(return-from catalog (summary (least-squares-xy (: snd 0) (: snd 1) :show nil))))
((= action 6)
(return-from catalog (diff (: snd 0) (: snd 1))))
(t; For everything that involves center isolation
(setf snd (transform snd))
(setf analyze-win (s-sqrt (fft-window fs type hop zs)))
(setf synthesis-win analyze-win)
(unless double-win (setf analyze-win (fft-window fs type hop zs))
(setf synthesis-win nil))
(setf *win-sigma* (* fs (peak (integrate analyze-win) ny:all)))
(setf sum-fft (stft (sum (: snd 0) (: snd 1)) fs hop analyze-win))
(setf dif-fft (stft (diff (: snd 0) (: snd 1)) fs hop analyze-win 'steer sum-fft))
(setf c (snd-ifft 0 *sr* dif-fft hop synthesis-win ))
(cond
((member action '(0 3))
(setf output (vector (extract-abs (/ hop *sr*) original-len (diff (: snd 0) c))
(extract-abs (/ hop *sr*) original-len (diff (: snd 1) c)))))
((member action '(1 4))
(setf strength (recip strength))
(setf output (extract-abs (/ hop *sr*) original-len c)))
((member action '(2 5))
(setf strength (recip strength))
(setf output (extract-abs (/ hop *sr*) original-len (mult -1 c)))))))
(if (soundp output) (setf output (vector output output)))
(mult *norm* output))
;;;; Main
*track*; Return original audio if something goes wrong
;;; we start with some variable assignements
(setf *sr* *sound-srate*)
;; hard coded STFT parameters
;; Change for experimental purposes
(setf type 1); -1 = square 0 =triangle 1 = Han
(setf double-win t); t = windows before and after
(setf fs (* 16 512)); fft-frame-size
(setf hop (* 7 512)); Hop (step size to advance)
(setf zs (- fs (* 2 hop))); zero-padding
;; Some input corrections
(setf strength (expt (limit strength 0.02 50.0) 2.0))
; bins to be ignored (bass and treble)
(if (> action 2) (psetq low-transition 0.0 high-transition 24000.0))
(let* ((ltrans (logior (truncate (/ (* 2 fs (limit low-transition 1 (/ *sr* 2.0))) *sr*)) 1))
(htrans (logior (limit (truncate (/ (* 2 fs high-transition) *sr*)) 1 (1- fs)) 1)))
(psetq low-transition (min ltrans htrans)
high-transition (max ltrans htrans)))
(setf out (snd-samples (snd-const 0.0 0 fs fs) fs)); holds the left/right weights (removal)
(setf *map* (snd-pwl 0 10000 (list 0 0.5 10000 0.0 20000 -0.5 20001)))
(setf *norm* 1.0)
(expand 120); remove for lower efficiency/more conservative memory management
(catalog)
|