Update of /cvsroot/audacity/audacity-src/src/effects
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv18795
Modified Files:
NoiseRemoval.cpp NoiseRemoval.h
Log Message:
Change NoiseRemoval processing to use new RealFFTf function for improved
performance
also change variable definitions from exp(log(a)+log(b)) to a*b for improved
performance
Index: NoiseRemoval.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/effects/NoiseRemoval.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- NoiseRemoval.h 14 Mar 2009 08:20:54 -0000 1.20
+++ NoiseRemoval.h 23 Jun 2009 02:08:44 -0000 1.21
@@ -24,6 +24,8 @@
class Envelope;
class WaveTrack;
+#include "../RealFFTf.h"
+
class EffectNoiseRemoval: public Effect {
public:
@@ -103,13 +105,17 @@
sampleCount mOutSampleCount;
int mInputPos;
+ HFFT hFFT;
+ float *mFFTBuffer; // mWindowSize
+ float *mWindow; // mWindowSize
+
int mFreqSmoothingBins;
int mAttackDecayBlocks;
float mOneBlockAttackDecay;
+ float mNoiseAttenFactor;
int mMinSignalBlocks;
int mHistoryLen;
float *mInWaveBuffer; // mWindowSize
- float *mOutWaveBuffer; // mWindowSize
float *mOutImagBuffer; // mWindowSize
float *mOutOverlapBuffer; // mWindowSize
float **mSpectrums; // mHistoryLen x mSpectrumSize
Index: NoiseRemoval.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/effects/NoiseRemoval.cpp,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- NoiseRemoval.cpp 18 Jun 2009 00:40:05 -0000 1.60
+++ NoiseRemoval.cpp 23 Jun 2009 02:08:44 -0000 1.61
@@ -43,7 +43,6 @@
#include "NoiseRemoval.h"
#include "../Envelope.h"
-#include "../FFT.h"
#include "../WaveTrack.h"
#include "../Prefs.h"
#include "../Project.h"
@@ -350,6 +349,7 @@
mFreqSmoothingBins = (int)(mFreqSmoothingHz * mWindowSize / mSampleRate);
mAttackDecayBlocks = 1 +
(int)(mAttackDecayTime * mSampleRate / (mWindowSize / 2));
+ mNoiseAttenFactor = pow(10.0, mNoiseGain/20.0);
mOneBlockAttackDecay = (int)(mNoiseGain / (mAttackDecayBlocks - 1));
mMinSignalBlocks =
(int)(mMinSignalTime * mSampleRate / (mWindowSize / 2));
@@ -367,18 +367,26 @@
for(i = 0; i < mHistoryLen; i++) {
mSpectrums[i] = new float[mSpectrumSize];
mGains[i] = new float[mSpectrumSize];
- mRealFFTs[i] = new float[mWindowSize];
- mImagFFTs[i] = new float[mWindowSize];
+ mRealFFTs[i] = new float[mSpectrumSize];
+ mImagFFTs[i] = new float[mSpectrumSize];
}
+ // Initialize the FFT
+ hFFT = InitializeFFT(mWindowSize);
+
+ mFFTBuffer = new float[mWindowSize];
mInWaveBuffer = new float[mWindowSize];
- mOutWaveBuffer = new float[mWindowSize];
+ mWindow = new float[mWindowSize];
mOutImagBuffer = new float[mWindowSize];
mOutOverlapBuffer = new float[mWindowSize];
+ // Create a Hanning window function
+ for(i=0; i<mWindowSize; i++)
+ mWindow[i] = 0.5 - 0.5 * cos((2.0*M_PI*i) / mWindowSize);
+
if (mDoProfile) {
for (i = 0; i < mSpectrumSize; i++)
- mNoiseThreshold[i] = -999.0;
+ mNoiseThreshold[i] = float(0);
}
}
@@ -386,6 +394,8 @@
{
int i;
+ EndFFT(hFFT);
+
if (mDoProfile) {
ApplyFreqSmoothing(mNoiseThreshold);
}
@@ -401,8 +411,9 @@
delete[] mRealFFTs;
delete[] mImagFFTs;
+ delete[] mFFTBuffer;
delete[] mInWaveBuffer;
- delete[] mOutWaveBuffer;
+ delete[] mWindow;
delete[] mOutImagBuffer;
delete[] mOutOverlapBuffer;
}
@@ -413,10 +424,8 @@
for(i = 0; i < mHistoryLen; i++) {
for(j = 0; j < mSpectrumSize; j++) {
- mSpectrums[i][j] = -999.0;
- mGains[i][j] = mNoiseGain;
- }
- for(j = 0; j < mWindowSize; j++) {
+ mSpectrums[i][j] = 0;
+ mGains[i][j] = mNoiseAttenFactor;
mRealFFTs[i][j] = 0.0;
mImagFFTs[i][j] = 0.0;
}
@@ -463,15 +472,20 @@
{
int i;
- FFT(mWindowSize, false, mInWaveBuffer, NULL,
- mRealFFTs[0], mImagFFTs[0]);
- for(i = 0; i < mSpectrumSize; i++) {
- double power =
- mRealFFTs[0][i] * mRealFFTs[0][i] +
- mImagFFTs[0][i] * mImagFFTs[0][i];
- mSpectrums[0][i] = (float)(10.0 * log10(power));
- mGains[0][i] = mNoiseGain;
+ for(i=0; i < mWindowSize; i++)
+ mFFTBuffer[i] = mInWaveBuffer[i];
+ RealFFTf(mFFTBuffer, hFFT);
+ for(i = 1; i < (mSpectrumSize-1); i++) {
+ mRealFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[i] ];
+ mImagFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[i]+1];
+ mSpectrums[0][i] = mRealFFTs[0][i]*mRealFFTs[0][i] +
mImagFFTs[0][i]*mImagFFTs[0][i];
+ mGains[0][i] = mNoiseAttenFactor;
}
+ // DC and Fs/2 bins need to be handled specially
+ mSpectrums[0][0] = mFFTBuffer[0]*mFFTBuffer[0];
+ mSpectrums[0][mSpectrumSize-1] = mFFTBuffer[1]*mFFTBuffer[1];
+ mGains[0][0] = mNoiseAttenFactor;
+ mGains[0][mSpectrumSize-1] = mNoiseAttenFactor;
}
void EffectNoiseRemoval::RotateHistoryWindows()
@@ -479,11 +493,11 @@
int last = mHistoryLen - 1;
int i;
- // Delete last window
- delete[] mSpectrums[last];
- delete[] mGains[last];
- delete[] mRealFFTs[last];
- delete[] mImagFFTs[last];
+ // Remember the last window so we can reuse it
+ float *lastSpectrum = mSpectrums[last];
+ float *lastGain = mGains[last];
+ float *lastRealFFT = mRealFFTs[last];
+ float *lastImagFFT = mImagFFTs[last];
// Rotate each window forward
for(i = last; i >= 1; i--) {
@@ -493,11 +507,11 @@
mImagFFTs[i] = mImagFFTs[i-1];
}
- // Create new first window
- mSpectrums[0] = new float[mSpectrumSize];
- mGains[0] = new float[mSpectrumSize];
- mRealFFTs[0] = new float[mWindowSize];
- mImagFFTs[0] = new float[mWindowSize];
+ // Reuse the last buffers as the new first window
+ mSpectrums[0] = lastSpectrum;
+ mGains[0] = lastGain;
+ mRealFFTs[0] = lastRealFFT;
+ mImagFFTs[0] = lastImagFFT;
}
void EffectNoiseRemoval::FinishTrack()
@@ -557,25 +571,25 @@
if (mSpectrums[i][j] < min)
min = mSpectrums[i][j];
}
- if (min > mNoiseThreshold[j] && mGains[center][j] < 0.0)
- mGains[center][j] = 0.0;
+ if (min > mNoiseThreshold[j] && mGains[center][j] < 1.0)
+ mGains[center][j] = 1.0;
}
// Decay the gain in both directions;
- // note that mOneBlockAttackDecay is a negative number, like -1.0
+ // note that mOneBlockAttackDecay is less than 1.0
// dB of attenuation per block
for (j = 0; j < mSpectrumSize; j++) {
for (i = center + 1; i < mHistoryLen; i++) {
- if (mGains[i][j] < mGains[i - 1][j] + mOneBlockAttackDecay)
- mGains[i][j] = mGains[i - 1][j] + mOneBlockAttackDecay;
- if (mGains[i][j] < mNoiseGain)
- mGains[i][j] = mNoiseGain;
+ if (mGains[i][j] < mGains[i - 1][j] * mOneBlockAttackDecay)
+ mGains[i][j] = mGains[i - 1][j] * mOneBlockAttackDecay;
+ if (mGains[i][j] < mNoiseAttenFactor)
+ mGains[i][j] = mNoiseAttenFactor;
}
for (i = center - 1; i >= 0; i--) {
- if (mGains[i][j] < mGains[i + 1][j] + mOneBlockAttackDecay)
- mGains[i][j] = mGains[i + 1][j] + mOneBlockAttackDecay;
- if (mGains[i][j] < mNoiseGain)
- mGains[i][j] = mNoiseGain;
+ if (mGains[i][j] < mGains[i + 1][j] * mOneBlockAttackDecay)
+ mGains[i][j] = mGains[i + 1][j] * mOneBlockAttackDecay;
+ if (mGains[i][j] < mNoiseAttenFactor)
+ mGains[i][j] = mNoiseAttenFactor;
}
}
@@ -585,27 +599,21 @@
ApplyFreqSmoothing(mGains[out]);
// Apply gain to FFT
- for (j = 0; j < mSpectrumSize; j++) {
- float mult = pow(10.0, mGains[out][j] / 20.0);
-
- mRealFFTs[out][j] *= mult;
- mImagFFTs[out][j] *= mult;
- if (j > 0 && j < mSpectrumSize - 1) {
- mRealFFTs[out][mWindowSize - j] *= mult;
- mImagFFTs[out][mWindowSize - j] *= mult;
- }
+ for (j = 0; j < (mSpectrumSize-1); j++) {
+ mFFTBuffer[j*2 ] = mRealFFTs[out][j] * mGains[out][j];
+ mFFTBuffer[j*2+1] = mImagFFTs[out][j] * mGains[out][j];
}
+ // The Fs/2 component is stored as the imaginary part of the DC component
+ mFFTBuffer[1] = mRealFFTs[out][mSpectrumSize-1] *
mGains[out][mSpectrumSize-1];
// Invert the FFT into the output buffer
- FFT(mWindowSize, true, mRealFFTs[out], mImagFFTs[out],
- mOutWaveBuffer, mOutImagBuffer);
-
- // Hanning window
- WindowFunc(3, mWindowSize, mOutWaveBuffer);
+ InverseRealFFTf(mFFTBuffer, hFFT);
// Overlap-add
- for(j = 0; j < mWindowSize; j++)
- mOutOverlapBuffer[j] += mOutWaveBuffer[j];
+ for(j = 0; j < (mSpectrumSize-1); j++) {
+ mOutOverlapBuffer[j*2 ] += mFFTBuffer[hFFT->BitReversed[j] ] *
mWindow[j*2 ];
+ mOutOverlapBuffer[j*2+1] += mFFTBuffer[hFFT->BitReversed[j]+1] *
mWindow[j*2+1];
+ }
// Output the first half of the overlap buffer, they're done -
// and then shift the next half over.
------------------------------------------------------------------------------
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs