Multiple notches with Nyquist prompt?

Effects, Recipes, Interfacing with other software, etc.
Forum rules
If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like
daviding
Posts: 2
Joined: Sat Mar 07, 2009 6:10 pm
Operating System: Please select

Re: Multiple notches with Nyquist prompt?

Post by daviding » Sat Mar 07, 2009 6:51 pm

I have a voice recording (of a conference session) with a hum in it, and as presuming it's a 60 Hz hum. I think that it's a problem with the cable between my microphones (in a Sound Professionals Otterbox) and the recorder (Marantz PMD-620). I've haven't been able to figure out the Spectum Analyzer, but using the Notch Filter at 60 Hz does seem to make things better, so I've been proceeding up the harmonics. The commands suggested for pasting into the Nyquist Prompt haven't been working for me.
Looking at this as an iteration (in this example I will use increasingly narrow notches for higher harmonics):
You want to remove 60 Hz from the sound "s"
(notch2 s 60 25)
And you want to remove 120 Hz from the sound that has had 60 Hz removed:
(notch2 (notch2 s 60 10) 120 20)
And you want to remove 180 Hz from that:
(notch2 (notch2 (notch2 s 60 10) 120 20) 180 30)
I first tried this in Audacity 1.2.6, and see that it's not supposed to work there. I've now installed Audacity 1.3.7 .

In Effect ... Nyquist Prompt ... I pasted in ...
(notch2 (notch2 (notch2 s 60 10) 120 20) 180 30)
... and by choosing the Debug button, got the following message:
error: bad argument type - #(#<Sound: #35c23a0> #<Sound: #35c2628>)
Function: #<Subr-SND-SRATE: #2180fa8>
Arguments:
#(#<Sound: #35c23a0> #<Sound: #35c2628>)
Function: #<FSubr-LET*: #2183e48>
Arguments:
((W (* 2 PI (/ HZ (SND-SRATE X)))) (CW (COS W)) (SW (SIN W)) (ALPHA (* SW (SINH (/ 0.5 Q)))) (A0 (+ 1 ALPHA)) (A1 (* -2 CW)) (A2 (- 1 ALPHA)) (B0 1) (B1 (* -2 CW)) (B2 1))
(BIQUAD-M X B0 B1 B2 A0 A1 A2)
Function: #<Closure-NOTCH2: #36c4730>
Arguments:
#(#<Sound: #35c23a0> #<Sound: #35c2628>)
60
10
1> [ gc: total 18640, 3682 free; samples 1KB, 0KB free ]
Since doing Notch Filter manually requires a Q between 0.01 and 5, I instead tried ...
(notch2 (notch2 (notch2 s 60 5) 120 4) 180 3)
... and got the following response:
error: bad argument type - #(#<Sound: #35c23a0> #<Sound: #35c2628>)
Function: #<Subr-SND-SRATE: #2180fa8>
Arguments:
#(#<Sound: #35c23a0> #<Sound: #35c2628>)
Function: #<FSubr-LET*: #2183e48>
Arguments:
((W (* 2 PI (/ HZ (SND-SRATE X)))) (CW (COS W)) (SW (SIN W)) (ALPHA (* SW (SINH (/ 0.5 Q)))) (A0 (+ 1 ALPHA)) (A1 (* -2 CW)) (A2 (- 1 ALPHA)) (B0 1) (B1 (* -2 CW)) (B2 1))
(BIQUAD-M X B0 B1 B2 A0 A1 A2)
Function: #<Closure-NOTCH2: #36c4730>
Arguments:
#(#<Sound: #35c23a0> #<Sound: #35c2628>)
60
10
1> [ gc: total 18640, 3682 free; samples 1KB, 0KB free ]
... which could very well be the same thing. (I haven't looked closely).

So ... I'm applying the Notch Filter manually.

I first tried 60 Hz with a Q of 0.01 ... which was funny, because that's enough to remove all of the audio, so there's nothing left.

As an experiment, I reloaded the MP3 file, and iterated in the following way:
60Hz Q=0.5
120Hz Q=0.75
180Hz Q=1.00
240Hz Q=1.00
300Hz Q=1.00
360Hz Q=1.00

The first iteration (at 60 Hz) removed the most amount of hum, so "distracting" became "annoying". After five more the iterations, I can still hear hum ... and I can't detect that the sound is getting any better. I'll publish the audio as it is, because I've got other tracks to do, and should move on.

It would be easier if I didn't have to do six manual passes, though ....

daviding
Posts: 2
Joined: Sat Mar 07, 2009 6:10 pm
Operating System: Please select

Re: Multiple notches with Nyquist prompt?

Post by daviding » Sun Mar 08, 2009 12:07 am

As an experiment, I reloaded the MP3 file, and iterated in the following way:
60Hz Q=0.5
120Hz Q=0.75
180Hz Q=1.00
240Hz Q=1.00
300Hz Q=1.00
360Hz Q=1.00

The first iteration (at 60 Hz) removed the most amount of hum, so "distracting" became "annoying".
I've been doing some more experimenting in A/B comparisons. Since the notch filter should impact the sound as little as possible -- except for the hum -- I've settled on:

60Hz Q=1.0
120Hz Q=1.0
180Hz Q=2.0
240Hz Q=3.0

I tried 300Hz both at Q=4.0 and Q=5.0, and noticed that the sound turning funny. The hum is still there ... but I'm not sure that I can find a way to remove it entirely.

Trebor
Posts: 9852
Joined: Sat Dec 27, 2008 5:22 pm
Operating System: Windows 8 or 8.1

Re: Multiple notches with Nyquist prompt?

Post by Trebor » Sun Mar 08, 2009 1:13 am

Daviding, try pasting this into the Nyquist prompt to remove 60Hz mains hum harmonics

(setq a 15)
(setq v 20)
(setq freq 60); this is 60Hz USA
(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))))))

steve
Site Admin
Posts: 80752
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Multiple notches with Nyquist prompt?

Post by steve » Sun Mar 08, 2009 7:57 pm

daviding wrote:In Effect ... Nyquist Prompt ... I pasted in ...

Code: Select all

    (notch2 (notch2 (notch2 s 60 10) 120 20) 180 30)
... and by choosing the Debug button, got the following message:
error: bad argument type - #(#<Sound: #35c23a0> #<Sound: #35c2628>)
That's because the "notch2" function only works on mono tracks.

There is some information earlier in this thread about how to apply mono functions to stereo tracks, but the easiest way is to split the stereo track first (Click on the track name and select "Split Stereo Track" from the drop down menu). You can then select the two single channel (left and right) tracks and apply the notch2 function.

About the Q parameter - the higher the number, the more narrow the notch, but the more ringing you will get. Q values up to about 20 will produce pretty narrow notches with little ringing. Values over 40 will produce very narrow notches, but ringing will start to become evident.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Trebor
Posts: 9852
Joined: Sat Dec 27, 2008 5:22 pm
Operating System: Windows 8 or 8.1

Re: Multiple notches with Nyquist prompt?

Post by Trebor » Mon Mar 09, 2009 2:01 am

As promised earlier in this thread, here is a link to “50/60Hz Dehummer 2.0” dehummer plugin which can now cope with stereo tracks.
It takes a helluva long time to dehum though: about 1/3rd the actual duration of the stereo track at 48000 sample rate.
(If possible reduce your project rate from 48000 to speed up the dehumming process, e.g. reduce to 22050 for speech only recording).

If you prefer to paste code into the Nyquist prompt, rather than use the plug-in, here it is for removal of 60Hz hum harmonics…

Code: Select all

(setq  a 15)
(setq  v 20)
(setq  freq 60); 60Hz in North America, (use 50Hz in europe).
(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))

(defun dehum (mysound freq iter)
(dotimes (i iter mysound) 
(setf mysound (notch2 mysound (* freq (1+ i)) (* que (1+ (/ i d)))))))

(if (arrayp s)
(vector (dehum (aref s 0) freq iter)
(dehum (aref s 1) freq iter))
(dehum s freq iter))

[Re: Q "jumps up in steps of 69". I did try altering the code so Q went up in smaller steps, but this made no audible difference so I reverted to the original code which was slightly quicker].
Attachments
Mains dehummer 2-0.zip
My Mains dehummer 2.0 plug-in for Audacity, (zip file: "extract" to audacity plug-in folder)
(658 Bytes) Downloaded 199 times

Trebor
Posts: 9852
Joined: Sat Dec 27, 2008 5:22 pm
Operating System: Windows 8 or 8.1

Re: Multiple notches with Nyquist prompt?

Post by Trebor » Mon May 25, 2009 10:38 am

Update
I have found a way to remove the Gibbs ringing created by my multi notch mains dehummer.
I made a stereo pair of the original mono track which had mains hum, and the dehummed version which has no hum but Gibbs ringing.
Then I used the centre pan isolation of Extraboy which gave me the frequencies common to both tracks, giving me a result without hum or ringing.

unruh
Posts: 1
Joined: Wed Jun 24, 2009 7:27 am
Operating System: Please select

Re: Multiple notches with Nyquist prompt?

Post by unruh » Wed Jun 24, 2009 7:53 am

Here is an alteration of this programme which a) allows you to choose your own base frequency as well ( uselful for me since the frequency of the pwer supply for my laptop included both hum and internal transformer noise of 3015 Hz annd its harmonics)b) Makes sure that the variables are floats not integers, so the problem of the "69" steps in Q is gone, and c)allows you to limit the number of harmonics which you cancel ( by choosing the fraction of the full spectrum you want to cover). I assume that Trebor meant to release his under the GPL. Certainly all of my changes are released under the GPL assuming that I really do have permission to use his code in this way.

Code: Select all

;nyquist plug-in
;version 1
;type process
;name "50/60Hz dehummer 2.0"
;action "Removing Hum harmonics, ( this may take some time ) ..."
;info:  Unintentional reverb effect. Gibbs ringing on transients.
;info:  if you find a cure for the reverb please email me: [email protected]

;control choice "Select mains frequency" int "0=50Hz (UK)  1=60Hz (USA) 2=choice" 0 0 2
;control bfreq "Base frequency" real " 10-10000 Hz " 50.0 10.0 10000.0
;control a "Amount of hum removed" real "  1-100 base Q=(100/a)^2" 15 1 100
;control v "Anti-reverberation setting" real "1-100 " 25 1 100
;control frac "Fraction of spectr" real " 0.01 to 1 " 1.0 .01 1.0

(setf freq (cond ((= choice 0) 50.0) ((= choice 1) 60.0) ((= choice 2) bfreq)))

(setq que (/ 10000.0 (* a a)))
(setq anti (/ 10000.0 (* v v)))
(setq mysound s)
(setq r *sound-srate*)
(setq itern (truncate (* (/ (/ r freq) 4) 2)))
(setq d (/ (float itern) anti))
(setq iter (truncate (* (float itern) frac)))

(defun dehum (mysound freq iter)
(dotimes (i iter mysound )
(setf mysound (notch2 mysound (* freq (1+ i)) (* que (1+ (/ i d)))))))

(if (arrayp s)
(vector (dehum (aref s 0) freq iter)
(dehum (aref s 1) freq iter))
(dehum s freq iter))


steve
Site Admin
Posts: 80752
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Multiple notches with Nyquist prompt?

Post by steve » Wed Jun 24, 2009 8:52 am

I've just tested that out briefly but there seems to be a problem if you increase the "Amount of hum removed".
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Ctrl+N
Posts: 102
Joined: Sun Mar 14, 2010 3:13 am
Operating System: Please select

Re: Multiple notches with Nyquist prompt?

Post by Ctrl+N » Sat Aug 21, 2010 10:26 pm

I'm bumping this for two reasons.

First, the problem I had earlier in another thread amounted to the same issue of how to stick more than one line of code in the Nyquist prompt.
The dotimes function is very useful.

Second, I would like to point out that the first try worked in Audacity 1.3 but not Audacity 1.2 because the 1.3 version of the Nyquist prompt will process multiple channels with code that is written for one channel. It is no longer necessary to test for an array. I suppose this improvement is necessary in order to process multichannel audio. I notice that when using arrayp, there was no followup test the see if there were more than two channels.

Stephen

steve
Site Admin
Posts: 80752
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Multiple notches with Nyquist prompt?

Post by steve » Sun Aug 22, 2010 1:32 pm

Ctrl+N wrote:I would like to point out that the first try worked in Audacity 1.3 but not Audacity 1.2 because the 1.3 version of the Nyquist prompt will process multiple channels with code that is written for one channel. It is no longer necessary to test for an array.
That's a very good point Stephen, but worth pointing out that this does not apply to all functions. It applies to all of the biquad filter functions (highpass, lowpass, notch ....) and is very convenient.

A bit of background information.
Audio data is passed from Audacity tracks to Nyquist as the variable "s".
If the Audacity track is a mono track then "s" is a variable of type "sound".
If the Audacity track is a multi-channel track (currently that means 2 channels) then "s" is an array. The array has the same number of elements as there channels (in current versions of Audacity that will be 2). Each element is of type "sound".
So for a mono track, "s" is a sound.
For a stereo track, "s" is an array. Each element of the array is a sound. (aref s 0) contains the sound from the left channel and (aref s 1) contains the sound from the right channel.

If you look in the file .../audacity/nyquist/dspprims.lsp you can see how this has been done. For example, looking at the code for the two-pole high-pass filter:

From Audacity 1.2.6

Code: Select all

; two-pole highpass
(defun highpass2 (x hz &optional (q 0.7071))
  (let* ((w (* 2.0 Pi (/ hz (snd-srate x))))
         (cw (cos w))
         (sw (sin w))
         (alpha (* sw (sinh (/ 0.5 q))))
         (a0 (+ 1.0 alpha))
         (a1 (* -2.0 cw))
         (a2 (- 1.0 alpha))
         (b1 (- -1.0 cw))
         (b0 (* -0.5 b1))
         (b2 b0))
    (biquad-m x b0 b1 b2 a0 a1 a2)))
Without going into too much detail, we can see that this is a fairly straightforward implementation of the low level function "biquad-m".
The function biquad-m works on sounds. If we pass an array to biquad-m, then it will fail because it is the wrong argument type. If we pass an array to highpass2 (as the local variable "x"), then it will fail because the array will be passed as an argument to biquad-m and, as we have just said, it is the wrong argument type - it needs to be a sound not an array.

From Audacity 1.3.12

Code: Select all

; two-pole highpass
(defun highpass2 (x hz &optional (q 0.7071))
  (multichan-expand #'nyq:highpass2 x hz q))

(defun nyq:highpass2 (x hz q)
  (let* ((w (* 2.0 Pi (/ hz (snd-srate x))))
         (cw (cos w))
         (sw (sin w))
         (alpha (* sw (sinh (/ 0.5 q))))
         (a0 (+ 1.0 alpha))
         (a1 (* -2.0 cw))
         (a2 (- 1.0 alpha))
         (b1 (- -1.0 cw))
         (b0 (* -0.5 b1))
         (b2 b0))
    (nyq:biquad-m x b0 b1 b2 a0 a1 a2)))
Here we can see that the function nyq:highpass2 is identical to the old highpass2 function.
The difference is that the new highpass2 function uses multichan-expand.

As shown here: http://www.audacity-forum.de/download/e ... htm#stereo multichan-expand "expands" multi-channel sounds (arrays) and sends each sound from the array in turn to the function. The data that is returned from each element is mapped back into the appropriate element of the array. This works in a similar way to the function mapcar (in fact it uses the function mapcar).
So if you send an array of sounds (a multi-channel sound) to a function using multichan-expand, then each sound element is sent to the function, and the overall result is an array containing the processed sounds.

The nice thing about using multichan-expand is that if you send a mono sound to a function using multichan-expand, the the overall result is a sound (not an array).

This makes it very easy to add Audacity 1.2.x compatibility to many new filter type plug-ins.
Although (highpass2 s freq) will work with stereo sounds in Audacity 1.3.12 but not in Audacity 1.2.6, if we change that to (multichan-expand #'highpass2 s freq) then it will work in both versions.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Post Reply