mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Code optimization and a bit of tidying by Paul Licameli.
No changes to UI or algorithm.
This commit is contained in:
parent
b7c5a6c271
commit
3b13b78c02
@ -9,6 +9,9 @@
|
||||
;; vocoder.ny by Edgar-RFT
|
||||
;; a bit of code added by David R. Sky
|
||||
;; GUI update by Steve Daulton July 2012.
|
||||
;; Performance improvement, error message for mono, code cleanup
|
||||
;; by Paul Licameli and Steve Daulton October 2014
|
||||
|
||||
;; Released under terms of the GNU General Public License version 2:
|
||||
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
;;
|
||||
@ -27,93 +30,107 @@
|
||||
; if you have lots of nyquist "[gc:" messages try this:
|
||||
; (expand 100) ; gives Xlisp more memory but I have noticed no speed difference
|
||||
|
||||
; number of octaves between 20hz and 20khz
|
||||
;; number of octaves between 20hz and 20khz
|
||||
(setf octaves (/ (log 1000.0) (log 2.0)))
|
||||
|
||||
; convert octaves to number of steps (semitones)
|
||||
;; convert octaves to number of steps (semitones)
|
||||
(setf steps (* octaves 12.0))
|
||||
|
||||
; interval - number of steps per vocoder band
|
||||
;; interval - number of steps per vocoder band
|
||||
(setf interval (/ steps bands))
|
||||
|
||||
; Some useful calculations but not used in this plugin
|
||||
;;; Some useful calculations but not used in this plugin
|
||||
|
||||
; half tone distance in linear
|
||||
;; half tone distance in linear
|
||||
; (print (exp (/ (log 2.0) 12)))
|
||||
|
||||
; octave distance in linear
|
||||
;; octave distance in linear
|
||||
; (print (exp (/ (log 1000.0) 40)))
|
||||
|
||||
; The Radar Wavetable
|
||||
;;; The Radar Wavetable
|
||||
|
||||
; make *radar-table* a global variable.
|
||||
;; make *radar-table* a global variable.
|
||||
(setf contol-dummy *control-srate*) ; save old *control-srate*
|
||||
(set-control-srate *sound-srate*)
|
||||
(setf *radar-table* (pwl (/ 1.0 *control-srate*) 1.0 ; 1.0 after 1 sample
|
||||
(/ 2.0 *control-srate*) 0.0 ; 0.0 after 2 samples
|
||||
(/ 1.0 radar-f))) ; stay 0.0 until end of the period
|
||||
(set-control-srate contol-dummy) ; restore *control-srate*
|
||||
; make *radar-table* become a nyquist wavetable of frequency radar-f
|
||||
;; make *radar-table* become a nyquist wavetable of frequency radar-f
|
||||
(setf *radar-table* (list *radar-table* (hz-to-step radar-f) T))
|
||||
|
||||
; increase the volume of the audacity track in the middle of the slider
|
||||
; the sqrt trick is something like an artifical db scaling
|
||||
;; increase the volume of the audacity track in the middle of the slider
|
||||
;; the sqrt trick is something like an artifical db scaling
|
||||
(setf track-vol (sqrt (/ track-vl 100.0)))
|
||||
; decrease the volume of the white noise in the middle of the slider
|
||||
; the expt trick is an inverse db scaling
|
||||
;; decrease the volume of the white noise in the middle of the slider
|
||||
;; the expt trick is an inverse db scaling
|
||||
(setf noise-vol (expt (/ noise-vl 100.0) 2.0))
|
||||
; also increase the volume of the needles in the middle of the slider
|
||||
;; also increase the volume of the needles in the middle of the slider
|
||||
(setf radar-vol (sqrt (/ radar-vl 100.0)))
|
||||
|
||||
; here you can switch the tracks on and off for bug tracking
|
||||
;;; here you can switch the tracks on and off for bug tracking
|
||||
|
||||
; (setf radar-vol 0)
|
||||
; (setf noise-vol 0)
|
||||
; (setf track-vol 0)
|
||||
|
||||
; The Mixer
|
||||
;;; The Mixer
|
||||
|
||||
; calculate duration of audacity selection
|
||||
;; calculate duration of audacity selection
|
||||
(setf duration (/ len *sound-srate*))
|
||||
|
||||
; if track volume slider is less than 100 percent decrease track volume
|
||||
(if (< track-vl 100) (setf s (vector (aref s 0) (scale track-vol (aref s 1)))))
|
||||
(defun mix ()
|
||||
;; if track volume slider is less than 100 percent decrease track volume
|
||||
(if (< track-vl 100)
|
||||
(setf s
|
||||
(vector (aref s 0) (scale track-vol (aref s 1)))))
|
||||
|
||||
; if radar volume slider is more than 0 percent add some radar needles
|
||||
(if (> radar-vl 0) (setf s (vector (aref s 0) (sim (aref s 1)
|
||||
(scale radar-vol (osc (hz-to-step radar-f) duration *radar-table*))))))
|
||||
;; if radar volume slider is more than 0 percent add some radar needles
|
||||
(if (> radar-vl 0)
|
||||
(setf s
|
||||
(vector (aref s 0)
|
||||
(sim (aref s 1)
|
||||
(scale radar-vol (osc (hz-to-step radar-f)
|
||||
duration *radar-table*))))))
|
||||
|
||||
; if noise volume slider is more than 0 percent add some white noise
|
||||
(if (> noise-vl 0) (setf s (vector (aref s 0) (sim (aref s 1)
|
||||
(scale noise-vol (noise duration))))))
|
||||
;; if noise volume slider is more than 0 percent add some white noise
|
||||
(if (> noise-vl 0)
|
||||
(setf s
|
||||
(vector (aref s 0)
|
||||
(sim (aref s 1) (scale noise-vol (noise duration)))))))
|
||||
|
||||
; The Vocoder
|
||||
;;; The Vocoder
|
||||
|
||||
(defun vocoder ()
|
||||
(let ((p (+ (hz-to-step 20) (/ interval 2.0))) ; midi step of 20 Hz + offset
|
||||
f ; we can leave f initialized to NIL
|
||||
(q (/ (sqrt 2.0) (/ octaves bands))) ; explanation still missing
|
||||
(result 0)) ; must be initialized to 0 because you cannot sum to NIL
|
||||
(dotimes (i bands)
|
||||
(setf f (step-to-hz p))
|
||||
(setf result (sum result
|
||||
(bandpass2 (mult (lowpass8
|
||||
(s-max (bandpass2 (aref s 0) f q)
|
||||
(scale -1 (bandpass2 (aref s 0) f q))) (/ f dst))
|
||||
(bandpass2 (aref s 1) f q)) f q)))
|
||||
(setf p (+ p interval)))
|
||||
result))
|
||||
(do* ((i 0 (1+ i))
|
||||
mod-envelope ; local variable for filtered envelope of left channel.
|
||||
band ; local variable for band-passed audio.
|
||||
(result 0) ; result must be initialized because you cannot sum to NIL.
|
||||
(q (/ (sqrt 2.0) (/ octaves bands))) ; quick approximation of q
|
||||
; for given bandwidth.
|
||||
(p (+ (hz-to-step 20) (/ interval 2.0)) ; midi step of 20 Hz + offset.
|
||||
(+ p interval))
|
||||
(f (step-to-hz p) (step-to-hz p)))
|
||||
((= i bands) result) ; DO for each band then return 'result'.
|
||||
(setf band (bandpass2 s f q)) ; intermediate results (2 channels)
|
||||
(setf mod-envelope (lowpass8 (s-abs (aref band 0)) (/ f dst)))
|
||||
(setf result
|
||||
(sum result
|
||||
(bandpass2
|
||||
(mult mod-envelope (aref band 1))
|
||||
f q)))))
|
||||
|
||||
; The Program
|
||||
|
||||
(if (arrayp s) (let ()
|
||||
(cond ((= mst 1) (vector (aref s 0) (setf (aref s 1) (vocoder))))
|
||||
((= mst 0) (setf s (vocoder))))
|
||||
(cond ((= mst 1) (setq peakamp (peak (aref s 1) ny:all)))
|
||||
((= mst 0) (setq peakamp (peak s ny:all))))
|
||||
(cond ((= mst 1) (vector (aref s 0) (setf (aref s 1)
|
||||
(scale (/ 1.0 peakamp) (aref s 1)))))
|
||||
((= mst 0) (setf s (scale (/ 1.0 peakamp) s))))
|
||||
s)
|
||||
"Error.\nStereo track required.")
|
||||
;;; The Program
|
||||
|
||||
(cond
|
||||
((arrayp s)
|
||||
(mix) ; changes s
|
||||
(let ((original (or (= mst 0) (aref s 0))))
|
||||
(setf s (vocoder))
|
||||
;; Now normalize s to 0 db peak
|
||||
(setf s (scale (/ (peak s ny:all)) s))
|
||||
(case mst
|
||||
(0 s) ; let Audacity coerce back to stereo
|
||||
(1 (vector original s)))))
|
||||
(t ; this effect isn't meant for mono
|
||||
"Error.\nStereo track required."))
|
||||
|
Loading…
x
Reference in New Issue
Block a user