mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-02 17:09:26 +02:00
Fix for bug 849. Validates user selected frequency in Spectral Edit plugins to prevent Nyquist applying invalid frequency (greater than Nyquist frequency) parameters to filters.
This does not address the broader question of how Spectral Selection should handle multiple sample rates.
This commit is contained in:
parent
abda1166de
commit
2e562600af
@ -6,33 +6,44 @@
|
|||||||
;author "Paul Licameli"
|
;author "Paul Licameli"
|
||||||
;copyright "Released under terms of the GNU General Public License version 2"
|
;copyright "Released under terms of the GNU General Public License version 2"
|
||||||
|
|
||||||
|
|
||||||
;; SpectralEditMulti.ny by Paul Licameli, November 2014.
|
;; SpectralEditMulti.ny by Paul Licameli, November 2014.
|
||||||
;; Updated to version 4 by Steve Daulton November 2014.
|
;; Updated to version 4 by Steve Daulton November 2014.
|
||||||
;; Released under terms of the GNU General Public License version 2:
|
;; Released under terms of the GNU General Public License version 2:
|
||||||
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
|
||||||
(defun wet (sig)
|
(defun wet (sig f0 f1 fc)
|
||||||
(let ((f0 (get '*selection* 'low-hz))
|
(cond
|
||||||
(f1 (get '*selection* 'high-hz))
|
((not f0) (highpass2 sig f1))
|
||||||
(fc (get '*selection* 'center-hz)))
|
((not f1) (lowpass2 sig f0))
|
||||||
(cond
|
(T (let ((q (/ fc (- f1 f0))))
|
||||||
((not (or f0 f1)) (throw 'error-message "Please select frequencies."))
|
(notch2 sig fc q)))))
|
||||||
((not f0) (highpass2 sig f1))
|
|
||||||
((not f1) (lowpass2 sig f0))
|
|
||||||
((= f0 f1) (throw 'error-message "Bandwidth is zero.\nSelect a frequency range."))
|
|
||||||
(T (let ((q (/ fc (- f1 f0))))
|
|
||||||
(notch2 sig fc q))))))
|
|
||||||
|
|
||||||
(defun result (sig)
|
(defun result (sig)
|
||||||
(let* ((tn (truncate len))
|
(let* ((f0 (get '*selection* 'low-hz))
|
||||||
|
(f1 (get '*selection* 'high-hz))
|
||||||
|
(fc (get '*selection* 'center-hz))
|
||||||
|
(tn (truncate len))
|
||||||
(rate (snd-srate sig))
|
(rate (snd-srate sig))
|
||||||
(transition (truncate (* 0.01 rate))) ; 10 ms
|
(transition (truncate (* 0.01 rate))) ; 10 ms
|
||||||
(t1 (min transition (/ tn 2))) ; fade in length (samples)
|
(t1 (min transition (/ tn 2))) ; fade in length (samples)
|
||||||
(t2 (max (- tn transition) (/ tn 2))) ; length before fade out (samples)
|
(t2 (max (- tn transition) (/ tn 2))) ; length before fade out (samples)
|
||||||
(breakpoints (list t1 1.0 t2 1.0 tn))
|
(breakpoints (list t1 1.0 t2 1.0 tn))
|
||||||
(env (snd-pwl 0.0 rate breakpoints)))
|
(env (snd-pwl 0.0 rate breakpoints)))
|
||||||
(sum (prod env (wet sig)) (prod (diff 1.0 env) sig))))
|
(cond
|
||||||
|
((not (or f0 f1)) (throw 'error-message "Please select frequencies."))
|
||||||
|
((and f0 f1 (= f0 f1)) (throw 'error-message
|
||||||
|
"Bandwidth is zero.\nPlease select a frequency range."))
|
||||||
|
;; low pass frequency is above Nyquist so do nothing
|
||||||
|
((and (not f1) (>= f0 (/ *sound-srate* 2.0)))
|
||||||
|
nil)
|
||||||
|
;; notch frequency is above Nyquist so do nothing
|
||||||
|
((and (and f0 f1) (>= fc (/ *sound-srate* 2.0)))
|
||||||
|
nil)
|
||||||
|
;; high-pass above Nyquist so fade to silence
|
||||||
|
((and (not f0) (>= f1 (/ *sound-srate* 2.0)))
|
||||||
|
(mult sig (diff 1.0 env)))
|
||||||
|
(T (sum (prod env (wet sig f0 f1 fc))
|
||||||
|
(prod (diff 1.0 env) sig))))))
|
||||||
|
|
||||||
(if (string-not-equal (get '*TRACK* 'VIEW) "spectrogram" :end1 4 :end2 4)
|
(if (string-not-equal (get '*TRACK* 'VIEW) "spectrogram" :end1 4 :end2 4)
|
||||||
"Use this effect in the 'Spectrogram'\nor 'Spectrogram (log f)' view."
|
"Use this effect in the 'Spectrogram'\nor 'Spectrogram (log f)' view."
|
||||||
|
@ -17,43 +17,52 @@
|
|||||||
|
|
||||||
(setf control-gain (min 24 (max -24 control-gain))) ; excessive settings may crash
|
(setf control-gain (min 24 (max -24 control-gain))) ; excessive settings may crash
|
||||||
|
|
||||||
(defun wet (sig gain)
|
(defmacro validate (hz)
|
||||||
(let ((f0 (get '*selection* 'low-hz))
|
"Ensure frequency is below Nyquist"
|
||||||
(f1 (get '*selection* 'high-hz))
|
`(setf hz (min (/ *sound-srate* 2.0),hz)))
|
||||||
(fc (get '*selection* 'center-hz))
|
|
||||||
(bw (get '*selection* 'bandwidth)))
|
(defun wet (sig gain f0 f1)
|
||||||
(cond
|
;; (re)calculate bw and fc to ensure we do not exceed Nyquist frequency
|
||||||
((not (or f0 f1))
|
(let ((fc (sqrt (* f0 (validate f1))))
|
||||||
(throw 'debug-message (format nil "~aPlease select frequencies." p-err)))
|
(bw (/ (log (/ (validate f1) f0))
|
||||||
((not f0)
|
(log 2.0))))
|
||||||
(throw 'debug-message (format nil "~aLow frequency is undefined." p-err)))
|
(eq-band sig fc gain (/ bw 2))))
|
||||||
((not f1)
|
|
||||||
(throw 'debug-message (format nil "~aHigh frequency is undefined." p-err)))
|
|
||||||
((= bw 0)
|
|
||||||
(throw 'debug-message (format nil "~aBandwidth is zero.\nSelect a frequency range." p-err)))
|
|
||||||
(t (eq-band sig fc gain (/ bw 2))))))
|
|
||||||
|
|
||||||
(defun result (sig)
|
(defun result (sig)
|
||||||
(let*
|
(let*
|
||||||
((tn (truncate len))
|
((f0 (get '*selection* 'low-hz))
|
||||||
|
(f1 (get '*selection* 'high-hz))
|
||||||
|
(bw (get '*selection* 'bandwidth))
|
||||||
|
(tn (truncate len))
|
||||||
(rate (snd-srate sig))
|
(rate (snd-srate sig))
|
||||||
(transition (truncate (* 0.01 rate))) ; 10 ms
|
(transition (truncate (* 0.01 rate))) ; 10 ms
|
||||||
(t1 (min transition (/ tn 2))) ; fade in length (samples)
|
(t1 (min transition (/ tn 2))) ; fade in length (samples)
|
||||||
(t2 (max (- tn transition) (/ tn 2))) ; length before fade out (samples)
|
(t2 (max (- tn transition) (/ tn 2))) ; length before fade out (samples)
|
||||||
(breakpoints (list t1 1.0 t2 1.0 tn))
|
(breakpoints (list t1 1.0 t2 1.0 tn))
|
||||||
(env (snd-pwl 0.0 rate breakpoints)))
|
(env (snd-pwl 0.0 rate breakpoints)))
|
||||||
(sum (prod env (wet sig control-gain)) (prod (diff 1.0 env) sig))))
|
(cond
|
||||||
|
((not (or f0 f1))
|
||||||
|
(throw 'error-message (format nil "~aPlease select frequencies." p-err)))
|
||||||
|
((not f0)
|
||||||
|
(throw 'error-message (format nil "~aLow frequency is undefined." p-err)))
|
||||||
|
((not f1)
|
||||||
|
(throw 'error-message (format nil "~aHigh frequency is undefined." p-err)))
|
||||||
|
((= bw 0)
|
||||||
|
(throw 'error-message (format nil "~aBandwidth is zero.~%Select a frequency range." p-err)))
|
||||||
|
;; If seleted frequency band is above Nyquist, do nothing.
|
||||||
|
((< f0 (/ *sound-srate* 2.0))
|
||||||
|
(sum (prod env (wet sig control-gain f0 f1)) (prod (diff 1.0 env) sig))))))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
((not (get '*TRACK* 'VIEW)) ; 'View is NIL during Preview
|
((not (get '*TRACK* 'VIEW)) ; 'View is NIL during Preview
|
||||||
(setf p-err (format nil "This effect requires a frequency selection in the~%~
|
(setf p-err (format nil "This effect requires a frequency selection in the~%~
|
||||||
'Spectrogram' or 'Spectrogram (log f)' track view.~%~%"))
|
'Spectrogram' or 'Spectrogram (log f)' track view.~%~%"))
|
||||||
(catch 'debug-message
|
(catch 'error-message
|
||||||
(multichan-expand #'result *track*)))
|
(multichan-expand #'result *track*)))
|
||||||
((string-not-equal (get '*TRACK* 'VIEW) "spectrogram" :end1 4 :end2 4)
|
((string-not-equal (get '*TRACK* 'VIEW) "spectrogram" :end1 4 :end2 4)
|
||||||
"Use this effect in the 'Spectrogram'\nor 'Spectrogram (log f)' view.")
|
"Use this effect in the 'Spectrogram'\nor 'Spectrogram (log f)' view.")
|
||||||
(T (setf p-err "")
|
(T (setf p-err "")
|
||||||
(if (= control-gain 0) ; Allow dry preview
|
(if (= control-gain 0) ; Allow dry preview
|
||||||
"Gain is zero. Nothing to do."
|
"Gain is zero. Nothing to do."
|
||||||
(catch 'debug-message
|
(catch 'error-message
|
||||||
(multichan-expand #'result *track*)))))
|
(multichan-expand #'result *track*)))))
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
(setf control-gain (min 24 (max -24 control-gain))) ; excessive settings may crash
|
(setf control-gain (min 24 (max -24 control-gain))) ; excessive settings may crash
|
||||||
|
|
||||||
|
(defmacro validate (hz)
|
||||||
|
"Ensure frequency is below Nyquist"
|
||||||
|
`(setf hz (min (/ *sound-srate* 2.0),hz)))
|
||||||
|
|
||||||
(defun mid-shelf (sig lf hf gain)
|
(defun mid-shelf (sig lf hf gain)
|
||||||
"Combines high shelf and low shelf filters"
|
"Combines high shelf and low shelf filters"
|
||||||
(let* ((invg (- gain)))
|
(let* ((invg (- gain)))
|
||||||
@ -24,38 +28,47 @@
|
|||||||
(eq-highshelf (eq-lowshelf sig lf invg)
|
(eq-highshelf (eq-lowshelf sig lf invg)
|
||||||
hf invg))))
|
hf invg))))
|
||||||
|
|
||||||
(defun wet (sig gain)
|
(defun wet (sig gain f0 f1)
|
||||||
(let ((f0 (get '*selection* 'low-hz))
|
(cond
|
||||||
(f1 (get '*selection* 'high-hz)))
|
((not f0) ;low-shelf
|
||||||
(cond
|
(if (< f1 (/ *sound-srate* 2.0))
|
||||||
((not (or f0 f1))
|
(eq-lowshelf sig f1 gain)
|
||||||
(throw 'debug-message (format nil "~aPlease select frequencies." p-err)))
|
(mult sig gain))) ;frequency above Nyquist so amplify full spectrum
|
||||||
((not f0) (eq-lowshelf sig f1 gain))
|
((not f1) (eq-highshelf sig f0 gain))
|
||||||
((not f1) (eq-highshelf sig f0 gain))
|
(t (mid-shelf sig f0 (validate f1) gain))))
|
||||||
(t (mid-shelf sig f0 f1 gain)))))
|
|
||||||
|
|
||||||
(defun result (sig)
|
(defun result (sig)
|
||||||
(let*
|
(let*
|
||||||
((tn (truncate len))
|
((f0 (get '*selection* 'low-hz))
|
||||||
|
(f1 (get '*selection* 'high-hz))
|
||||||
|
(tn (truncate len))
|
||||||
(rate (snd-srate sig))
|
(rate (snd-srate sig))
|
||||||
(transition (truncate (* 0.01 rate))) ; 10 ms
|
(transition (truncate (* 0.01 rate))) ; 10 ms
|
||||||
(t1 (min transition (/ tn 2))) ; fade in length (samples)
|
(t1 (min transition (/ tn 2))) ; fade in length (samples)
|
||||||
(t2 (max (- tn transition) (/ tn 2))) ; length before fade out (samples)
|
(t2 (max (- tn transition) (/ tn 2))) ; length before fade out (samples)
|
||||||
(breakpoints (list t1 1.0 t2 1.0 tn))
|
(breakpoints (list t1 1.0 t2 1.0 tn))
|
||||||
(env (snd-pwl 0.0 rate breakpoints)))
|
(env (snd-pwl 0.0 rate breakpoints)))
|
||||||
(sum (prod env (wet sig control-gain)) (prod (diff 1.0 env) sig))))
|
(cond
|
||||||
|
((not (or f0 f1))
|
||||||
|
(throw 'error-message (format nil "~aPlease select frequencies." p-err)))
|
||||||
|
((and f0 f1 (= f0 f1)) (throw 'error-message
|
||||||
|
"Please select a frequency range."))
|
||||||
|
; shelf is above Nyquist frequency so do nothing
|
||||||
|
((and f0 (>= f0 (/ *sound-srate* 2.0))) nil)
|
||||||
|
(T (sum (prod env (wet sig control-gain f0 f1))
|
||||||
|
(prod (diff 1.0 env) sig))))))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
((not (get '*TRACK* 'VIEW)) ; 'View is NIL during Preview
|
((not (get '*TRACK* 'VIEW)) ; 'View is NIL during Preview
|
||||||
(setf p-err (format nil "This effect requires a frequency selection in the~%~
|
(setf p-err (format nil "This effect requires a frequency selection in the~%~
|
||||||
'Spectrogram' or 'Spectrogram (log f)' track view.~%~%"))
|
'Spectrogram' or 'Spectrogram (log f)' track view.~%~%"))
|
||||||
(catch 'debug-message
|
(catch 'error-message
|
||||||
(multichan-expand #'result *track*)))
|
(multichan-expand #'result *track*)))
|
||||||
((string-not-equal (get '*TRACK* 'VIEW) "spectrogram" :end1 4 :end2 4)
|
((string-not-equal (get '*TRACK* 'VIEW) "spectrogram" :end1 4 :end2 4)
|
||||||
"Use this effect in the 'Spectrogram'\nor 'Spectrogram (log f)' view.")
|
"Use this effect in the 'Spectrogram'\nor 'Spectrogram (log f)' view.")
|
||||||
(T (setf p-err "")
|
(T (setf p-err "")
|
||||||
(if (= control-gain 0) ; Allow dry preview
|
(if (= control-gain 0) ; Allow dry preview
|
||||||
"Gain is zero. Nothing to do."
|
"Gain is zero. Nothing to do."
|
||||||
(catch 'debug-message
|
(catch 'error-message
|
||||||
(multichan-expand #'result *track*)))))
|
(multichan-expand #'result *track*)))))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user