Nice one Trebor, good to see some interest in Nyquist.
A few comments on the code - looking at the business end of it (I've replaced the controls with your default values):
Code: Select all
(setq choice 0)
(setq a 12)
(setq v 20)
(setf freq (cond((= choice 0) 50) ((= choice 1) 60)))
(setq que (/ 10000 (* a a)))
(setq anti (/ 10000 (* v v)))
(setq mysound s)
(setq r *sound-srate*)
(setq iter (truncate (/ (/ r freq) 2)))
(setq d (/ iter anti))
(dotimes (i iter mysound)
(setf mysound (notch2 mysound (* freq (1+ i)) (* que (1+ (/ i d))))))
That's a really complicated equation for calculating "Q"
(with a sample rate of 48kHz...)
Did you realise that since "que", "i" and "d" are all integers, "(* que (1+ (/ i d)))" jumps up in steps of 69?
Also, 480 iterations seems rather excessive and takes the harmonics right up to 24kHz. I can see the logic in going up to the Nyquist frequency, but I would argue that in practice the last few hundred iterations are removing a much greater percentage of the "music" than the "noise". Also, reducing the number of frequency bands will speed up processing and reduce ringing. (and yes, the removal of all of those harmonics is audible - if you process a section of audio that does not have hum, then listen through good speakers or headphones you can hear the difference between the processed and unprocessed sections)
The other thing that leads to ringing is that you are using such high Q values. While it is desirable to keep the notch filter tight, high Q values cause ringing, so there is a trade off to be made. You probably notice that if you test the plug-in with the default values on "pure hum", it takes a while before the filter "kicks in". Lower Q values will cause less ringing, but the notches will be wider, but if you limit the effect to lower frequencies where the hum is likely to be more noticeable, then lower Q values should not present a problem.
To make the plug-in work with stereo...
Stereo tracks in Audacity consist of an array with two elements (the left and right channels).
You can test for an array with (arrayp sound
The two elements (left and right) are accessed with (aref sound
0) and (aref sound
To return a stereo sound to Audacity, use "vector"
You will commonly see code like this:
(if (arrayp sound
) ;; if sound is an array
(vector (aref function()
0) (aref function()
1)) ;; create an array
) ;; else
If you turn your code into a function, then it can be called once for a mono track, or twice for a stereo track.
(One more thought - mains hum can often cause some amount of DC off-set, so adding a low frequency high pass filter could be a good idea)
Something like this:
Code: Select all
(setq setfreq 50)
(setq iter 40)
(defun dehum (mysound freq itr)
(dotimes (i itr mysound)
(setf mysound (notch2 (hp mysound 20) (* freq (1+ i)) (* 2 (1+ i))))))
(if (arrayp s)
(dehum (aref s 0) setfreq iter)
(dehum (aref s 1) setfreq iter))
(dehum s setfreq iter))