コード例 #1
0
ファイル: NoiseRemoval.cpp プロジェクト: GYGit/Audacity
void EffectNoiseRemoval::Cleanup()
{
   int i;

   EndFFT(hFFT);

   if (mDoProfile) {
      ApplyFreqSmoothing(mNoiseThreshold);
   }

   for(i = 0; i < mHistoryLen; i++) {
      delete[] mSpectrums[i];
      delete[] mGains[i];
      delete[] mRealFFTs[i];
      delete[] mImagFFTs[i];
   }
   delete[] mSpectrums;
   delete[] mGains;
   delete[] mRealFFTs;
   delete[] mImagFFTs;

   delete[] mFFTBuffer;
   delete[] mInWaveBuffer;
   delete[] mWindow;
   delete[] mOutImagBuffer;
   delete[] mOutOverlapBuffer;
}
コード例 #2
0
void EffectNoiseRemoval::RemoveNoise()
{
   int center = mHistoryLen / 2;
   int start = center - mMinSignalBlocks/2;
   int finish = start + mMinSignalBlocks;
   int i, j;

   // Raise the gain for elements in the center of the sliding history
   for (j = 0; j < mSpectrumSize; j++) {
      float min = mSpectrums[start][j];
      for (i = start+1; i < finish; i++) {
         if (mSpectrums[i][j] < min)
            min = mSpectrums[i][j];
      }
      if (min > mNoiseThreshold[j] && mGains[center][j] < 0.0)
         mGains[center][j] = 0.0;
   }

   // Decay the gain in both directions;
   // note that mOneBlockAttackDecay is a negative number, like -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;
      }
      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;
      }
   }

   // Apply frequency smoothing to output gain
   int out = mHistoryLen - 1;  // end of the queue

   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;
      }
   }

   // Invert the FFT into the output buffer
   FFT(mWindowSize, true, mRealFFTs[out], mImagFFTs[out],
       mOutWaveBuffer, mOutImagBuffer);

   // Hanning window
   WindowFunc(3, mWindowSize, mOutWaveBuffer);

   // Overlap-add
   for(j = 0; j < mWindowSize; j++)
      mOutOverlapBuffer[j] += mOutWaveBuffer[j];

   // Output the first half of the overlap buffer, they're done -
   // and then shift the next half over.
   if (mOutSampleCount >= 0) {   // ...but not if it's the first half-window
      mOutputTrack->Append((samplePtr)mOutOverlapBuffer, floatSample,
                           mWindowSize / 2);
   }
   mOutSampleCount += mWindowSize / 2;
   for(j = 0; j < mWindowSize / 2; j++) {
      mOutOverlapBuffer[j] = mOutOverlapBuffer[j + (mWindowSize / 2)];
      mOutOverlapBuffer[j + (mWindowSize / 2)] = 0.0;
   }
}
コード例 #3
0
ファイル: NoiseRemoval.cpp プロジェクト: GYGit/Audacity
void EffectNoiseRemoval::RemoveNoise()
{
   int center = mHistoryLen / 2;
   int start = center - mMinSignalBlocks/2;
   int finish = start + mMinSignalBlocks;
   int i, j;

   // Raise the gain for elements in the center of the sliding history
   for (j = 0; j < mSpectrumSize; j++) {
      float min = mSpectrums[start][j];
      for (i = start+1; i < finish; i++) {
         if (mSpectrums[i][j] < min)
            min = mSpectrums[i][j];
      }
      if (min > mSensitivityFactor * mNoiseThreshold[j] && mGains[center][j] < 1.0) {
         if (mbLeaveNoise) mGains[center][j] = 0.0;
         else mGains[center][j] = 1.0;
      } else {
         if (mbLeaveNoise) mGains[center][j] = 1.0;
      }
   }

   // Decay the gain in both directions;
   // note that mOneBlockAttackDecay is less than 1.0
   // of linear 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] < 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] < mNoiseAttenFactor)
            mGains[i][j] = mNoiseAttenFactor;
      }
   }


   // Apply frequency smoothing to output gain
   int out = mHistoryLen - 1;  // end of the queue

   ApplyFreqSmoothing(mGains[out]);

   // Apply gain to FFT
   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
   InverseRealFFTf(mFFTBuffer, hFFT);

   // Overlap-add
   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.
   if (mOutSampleCount >= 0) {   // ...but not if it's the first half-window
      mOutputTrack->Append((samplePtr)mOutOverlapBuffer, floatSample,
                           mWindowSize / 2);
   }
   mOutSampleCount += mWindowSize / 2;
   for(j = 0; j < mWindowSize / 2; j++) {
      mOutOverlapBuffer[j] = mOutOverlapBuffer[j + (mWindowSize / 2)];
      mOutOverlapBuffer[j + (mWindowSize / 2)] = 0.0;
   }
}