#Noise Reduction
1 messages · Page 1 of 1 (latest)
The noise reduction is here: https://github.com/audacity/audacity/blob/master/src/effects/NoiseReduction.cpp
Written by the one and only @sharp niche
Dominic Mazzoni, Audacity’s co-founder, wrote it originally. I can’t take credit for the general algorithm. But ten years ago I did make a thorough rewrite and improved the quality of the calculations.
The general idea: “sliding windows” — a sequence of intervals of samples, overlapping — are each transformed, and then blended back together so that there are not discontinuities, little clicks, at boundaries. Each window is weighted by a raised cosine period (Hann windowing function) so its contribution to the output tapers to 0 at the boundaries, and the sum of the weights contributing to any output sample is always 1.
The transformation of each window is done by fast Fourier transform, from time domain samples to an equal number of frequency domain coefficients. For each of many frequencies, you get a pair of numbers which are sine and cosine coefficients, thus giving phase and amplitude information, but phase doesn’t matter (is unchanged) by the next step.
(Detail, actually there is a 0 Hz frequency component, and a highest, “Nyquist” frequency component which is half the sample rate, and those extremes give only one coefficient each with no phase.)
What happens next is that each frequency bin with low enough amplitude is multiplied by an attenuation factor. That factor depends on the gain slider. And “low enough” varies with the frequency and depends on the spectrum of the example of noise you give in step 1 of the effect, and also on the sensitivity slider.
After those adjustments of coefficients, there is inverse FFT which makes those output windows that are blended.
My improvements to the algorithm included multiplication of the sample by a Hann window twice — before the FFT as well as after the IFFT, needed for a different reason, which is to reduce “spectral leakage” which made the algorithm fail to lower enough of the coefficients in periods where foreground sound was mixed with noise. That is, noise reduction used to work well only in pauses between notes or words.
I also had to change the overlap, taking more frequent windows, because of that other change,
which doubled the calculations, though it was later pointed out to me by Matthieu Hodgkinson that I could take fewer than I did, trading some quality for speed. The old algorithm overlapped windows by 1/2 their length, I had to overlap by at least 1/3, in fact did by 1/4.
The reason is that now the sum of the product of two raised cosine windows (for the analysis step weighting as well as the resynthesis), offset by that fraction of window length, must add to 1 — not just one window. Do the math (using some high school trigonometric function identities) and you can show that 1/2 is not correct.
There are other details, like the frequency smoothing, also the attack and decay that isn’t mentioned in the UI (but was in the old version years ago) but you can find it in the source code. These do certain transitions of the a plied attenuation factors, so neighboring time/frequency bins, along both the time and frequency axes, influence each other a bit. This improves the quality of output sometimes in subtle ways. An artifact in noise reduction done too naively can be “birdsong” or “musical noise” and these things do some mitigation.
Enough for now.
Thank you so much!!
Oh my God!! You also made this whole explanation very beginner friendly and clear! Thank you, a lot!! I needed it ❤️
Speaking of birdsong, filtering out literal "bird sounds" would be a really cool effect to have around. I noticed someone has made a 250 dollar plugin (not audacity specific) to do just that, haha. Anyhow just something I recently had to hack myself by gross EQ manipulation (which changed a lot more of the sound than i wanted, and therefore had to apply to the entire clip).
Hm, alternately if one could drag select a rectangle within the spectrogram and audition it in isolation, and then apply filters/volume-change to it alone (well, maybe with some auto ease-in/ease-out of the modifications, along the boundaries of the rectangle) that might be a more general purpose feature.