Steve's updated delay.ny (http://bugzilla.audacityteam.org/show_bug.cgi?id=533)
This commit is contained in:
parent
ac793683c1
commit
d8ce078a6b
|
@ -3,130 +3,126 @@
|
|||
;type process
|
||||
;categories "http://lv2plug.in/ns/lv2core#DelayPlugin"
|
||||
;name "Delay..."
|
||||
;action "Performing Delay Effect..."
|
||||
;info "by Roger Dannenberg, modified by David R. Sky\nReleased under terms of the GNU General Public License Version 2 \nDelay type: 'bouncing ball' makes the echoes occur increasingly close\ntogether (faster); 'reverse bouncing ball' makes them occur increasingly far\napart (slower). In either bouncing ball effect, delay time is not time between\nechoes but the * maximum * delay time in bounces.\nApplying delay can cause clipping (distortion), especially when reducing the\ndecay value and using more echoes. It's normally best to use Effect > Amplify\nto set the peak amplitude to -6 dB before using delay.
|
||||
;action "Applying Delay Effect..."
|
||||
;info "by Steve Daulton. Based on an effect by David R. Sky.\nReleased under GPL v2.\n"
|
||||
|
||||
;; by Steve Daulton, July 2012.
|
||||
;; based on 'Delay' by David R. Sky
|
||||
;; Released under terms of the GNU General Public License version 2:
|
||||
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
;;
|
||||
;; For information about writing and modifying Nyquist plug-ins:
|
||||
;; http://wiki.audacityteam.org/wiki/Nyquist_Plug-ins_Reference
|
||||
|
||||
;control delay-type "Delay type" choice "regular,bouncing ball,reverse bouncing ball" 0
|
||||
;control decay "Decay amount [dB; negative value increases volume]" real "" 6 -1 24
|
||||
;control delay "Delay time [seconds]" real "" 0.5 0 5
|
||||
;control shift "Pitch change per echo [semitones; negative value = lower, 0 is off]" real "" 0 -2 2
|
||||
;control count "Number of echoes" int "" 5 1 30
|
||||
|
||||
; Delay by Roger B. Dannenberg
|
||||
; modified by David R. Sky October 2007,
|
||||
; adding negative decay values, which gives delay effect
|
||||
; increasing volume with each delay; and adding
|
||||
; bouncing ball and reverse bouncing ball delay effects
|
||||
; and pitch [semitone] change with each echo.
|
||||
; modified by Richard Ash January 2008, removing all
|
||||
; normalization functions.
|
||||
|
||||
; Note by Roger Dannenberg: this effect will use up memory proportional to
|
||||
; delay * count, since that many samples must be buffered
|
||||
; before the first block is freed.
|
||||
|
||||
; initialize empty error message
|
||||
(setf error-msg "")
|
||||
;control dgain "Delay level per echo (dB)" real "" -6 -30 1
|
||||
;control delay "Delay time (seconds)" real "" 0.3 0 5
|
||||
;control pitch-type "Pitch change effect" choice "Pitch/Tempo,LQ Pitch Shift" 0
|
||||
;control shift "Pitch change per echo (semitones)" real "" 0 -2 2
|
||||
;control number "Number of echoes" int "" 5 1 30
|
||||
;control constrain "Allow duration to change" choice "Yes,No" 0
|
||||
|
||||
|
||||
; check function: returns 1 on error
|
||||
(defun check (arg min max)
|
||||
(if (and (>= arg min) (<= arg max))
|
||||
0 1))
|
||||
;; The default pitch shift effect is a simple resampling,
|
||||
;; so both pitch and tempo of the delayed audio will change
|
||||
;; [as in Audacity's Change Speed effect].
|
||||
;; LQ Pitch Shift (Low Quality) changes the pitch without
|
||||
;; changing the tempo, but the sound quality is not very good
|
||||
;; and tends to cause a short echo effect which can be quite
|
||||
;; noticeable on percussive sounds though may be acceptable
|
||||
;; on other sounds.
|
||||
|
||||
(setf err "") ; initialise error message
|
||||
|
||||
(defun err-chk (arg min max)
|
||||
(if (or (< arg min) (> arg max))
|
||||
T nil))
|
||||
|
||||
(when (err-chk number 1 50)(setq err (format nil
|
||||
"Number of echoes '~a' outside valid range 1 to 50.~%~a"
|
||||
number err)))
|
||||
|
||||
(when (err-chk shift -12 12)(setq err (format nil
|
||||
"Pitch change '~a' outside valid range -12 to +12 semitones.~%~a"
|
||||
shift err)))
|
||||
|
||||
(when (err-chk delay 0 10)(setq err (format nil
|
||||
"Delay time '~a' outside valid range 0 to 10 seconds.~%~a"
|
||||
delay err)))
|
||||
|
||||
(when (err-chk dgain -30 6)(setq err (format nil
|
||||
"Delay level '~a' outside valid range -30 to +6 dB.~%~a"
|
||||
dgain err)))
|
||||
|
||||
|
||||
; checking for erroneous user-input values:
|
||||
(setf error-msg (if (= (check decay -1 24) 0)
|
||||
error-msg
|
||||
(strcat error-msg
|
||||
(format nil "Decay value '~a' outside valid range -1.0 to 24.0 dB.
|
||||
" decay))))
|
||||
|
||||
(setf error-msg (if (= (check delay 0 5) 0)
|
||||
error-msg
|
||||
(strcat error-msg
|
||||
(format nil "Delay value '~a' outside valid range 0.0 to 5.0 seconds.
|
||||
" delay))))
|
||||
|
||||
(setf error-msg (if (= (check shift -2 2) 0)
|
||||
error-msg
|
||||
(strcat error-msg
|
||||
(format nil "Pitch change value '~a' outside valid range -2.0 to 2.0 semitones.
|
||||
" shift))))
|
||||
|
||||
(setf error-msg (if (= (check count 1 30) 0)
|
||||
error-msg
|
||||
(strcat error-msg
|
||||
(format nil "Number of echoes '~a' outside valid range 1 to 30 echoes.
|
||||
" count))))
|
||||
; finished error-checking
|
||||
|
||||
; if error-msg is longer than 0 characters,
|
||||
; prepend opening message
|
||||
(setf error-msg (if (> (length error-msg) 0)
|
||||
(strcat "Error -\n\nYou have input at least one invalid value:
|
||||
" error-msg)
|
||||
error-msg))
|
||||
|
||||
(cond ; 1
|
||||
((> (length error-msg) 0)
|
||||
(format nil "~a" error-msg))
|
||||
|
||||
(t ; no input errors, perform delay
|
||||
|
||||
; convert shift value to a value the Nyquist code understands
|
||||
(setf shift (expt 0.5 (/ shift 12.0)))
|
||||
|
||||
; for bouncing ball effects, set delay time to delay time/count
|
||||
(setf delay (if (> delay-type 0)
|
||||
(/ delay count) delay))
|
||||
;;; anti-alias low pass filter
|
||||
(defun lp-wall (sig freq)
|
||||
(do ((count 0 (1+ count))
|
||||
(freq (* 0.94 freq)))
|
||||
((= count 10) sig)
|
||||
(setf sig (lowpass8 sig freq))))
|
||||
|
||||
|
||||
|
||||
; function to stretch audio
|
||||
(defun change (sound shift)
|
||||
(if (arrayp sound)
|
||||
(vector
|
||||
(force-srate 44100 (stretch-abs shift (sound (aref sound 0))))
|
||||
(force-srate 44100 (stretch-abs shift (sound (aref sound 1)))))
|
||||
(force-srate 44100 (stretch-abs shift (sound sound)))))
|
||||
;;; Change speed
|
||||
(defun change-speed (sig shift)
|
||||
(if (= shift 0) ; no pitch shift
|
||||
sig
|
||||
(let ((ratio (expt 0.5 (/ shift 12.0)))) ; shift value as frequency ratio
|
||||
(force-srate *sound-srate*
|
||||
(stretch-abs ratio (sound sig))))))
|
||||
|
||||
|
||||
(cond ; 2
|
||||
((= delay-type 0) ; regular delay
|
||||
; delay function
|
||||
(defun delays (s decay delay count shift)
|
||||
(if (= count 0) (cue s)
|
||||
(sim (cue s)
|
||||
(loud decay (at delay (delays (change s shift)
|
||||
decay delay (- count 1) shift))))))
|
||||
;;; pitch shift audio
|
||||
(defun p-shift (sig shift)
|
||||
(if (= shift 0) ; no pitch shift
|
||||
sig
|
||||
(let ((sig (force-srate 44100 sig)) ; pitshift quality best at 44100
|
||||
; anti-alias filter frequency
|
||||
(minrate (* 0.5 (min *sound-srate* 44100)))
|
||||
(ratio (expt 0.5 (/ shift -12.0)))) ; shift value as frequency ratio
|
||||
(force-srate *sound-srate* ; convert back to correct rate
|
||||
(progv '(*sound-srate*) (list 44100) ; pitshift requires rates to match
|
||||
(cond
|
||||
((> shift 5) ; reduce aliasing
|
||||
(pitshift (lp-wall sig (/ minrate ratio)) ratio 1))
|
||||
((< shift -2)
|
||||
(pitshift (hp sig 20) ratio 1)) ; reduce sub-sonic frequencies
|
||||
(T (pitshift sig ratio 1))))))))
|
||||
|
||||
(stretch-abs 1 (delays s (- 0 decay) delay count shift)))
|
||||
;;; apply effects to echo
|
||||
(defun modify (sig num gain shift p-type)
|
||||
(let ((gain (db-to-linear (* num gain)))
|
||||
(shift (* num shift)))
|
||||
(if (= p-type 0)
|
||||
(mult gain (change-speed sig shift))
|
||||
(mult gain (p-shift sig shift)))))
|
||||
|
||||
;;; compute echoes
|
||||
(defun delays (sound gain delay shift num type mod)
|
||||
(let ((echo (s-rest 0)))
|
||||
(do ((count 1 (1+ count))
|
||||
(dly 0))
|
||||
((> count num)(sim echo sound))
|
||||
(setq dly
|
||||
(case type
|
||||
(0 (+ dly delay))
|
||||
(1 (+ dly (* delay (- (1+ num) count))))
|
||||
(2 (+ dly (* delay count)))))
|
||||
(setf echo (sim
|
||||
(at 0 (cue echo))
|
||||
(at-abs dly
|
||||
(cue (modify sound count gain shift mod))))))))
|
||||
|
||||
((= delay-type 1) ; bouncing ball delay
|
||||
; bouncing ball delay function
|
||||
(defun bounces (s decay delay count shift)
|
||||
(if (= count 0) (cue s)
|
||||
(sim (cue s)
|
||||
(loud decay (at (mult delay count)
|
||||
(bounces (change s shift) decay delay
|
||||
(- count 1) shift))))))
|
||||
(defun constrain-abs (sig dur)
|
||||
(extract-abs 0 dur (cue sig)))
|
||||
|
||||
(stretch-abs 1 (bounces s (- 0 decay) delay count shift)))
|
||||
|
||||
|
||||
((= delay-type 2) ; reverse bouncing ball delay
|
||||
; reverse bouncing ball delay function
|
||||
(defun revbounces (s decay delay count revcount shift)
|
||||
(if (= count 0) (cue s)
|
||||
(sim (cue s)
|
||||
(loud decay (at (mult delay (- revcount count))
|
||||
(revbounces (change s shift) decay delay
|
||||
(- count 1 ) revcount shift))))))
|
||||
|
||||
(setf revcount (1+ count))
|
||||
(stretch-abs 1 (revbounces s (- 0 decay) delay count revcount shift)))
|
||||
) ; end cond2, different delay effect choices
|
||||
) ; end cond1 t
|
||||
) ; end cond 1
|
||||
;;; return errors or process
|
||||
(if (> (length err) 0)
|
||||
(format nil "Error.~%~a" err) ; return error
|
||||
(let* ((delay (if (= delay-type 0) delay (/ delay number)))
|
||||
(output
|
||||
(multichan-expand #'delays
|
||||
s dgain delay shift number delay-type pitch-type)))
|
||||
(if (= constrain 1)
|
||||
(multichan-expand #'constrain-abs output (get-duration 1))
|
||||
output)))
|
||||
|
|
Loading…
Reference in New Issue
Block a user