Beispiel #1
0
/*
 * InverseRealFFT
 *
 * This function computes the inverse of RealFFT, above.
 * The RealIn and ImagIn is assumed to be conjugate-symmetric
 * and as a result the output is purely real.
 * Only the first half of RealIn and ImagIn are used due to this
 * symmetry assumption.
 */
void InverseRealFFT(int NumSamples, float *RealIn, float *ImagIn, float *RealOut)
{
   // Remap to RealFFTf() function
   int i;
   HFFT hFFT = GetFFT(NumSamples);
   float *pFFT = new float[NumSamples];
   // Copy the data into the processing buffer
   for(i=0; i<(NumSamples/2); i++)
      pFFT[2*i  ] = RealIn[i];
   if(ImagIn == NULL) {
      for(i=0; i<(NumSamples/2); i++)
         pFFT[2*i+1] = 0;
   } else {
      for(i=0; i<(NumSamples/2); i++)
         pFFT[2*i+1] = ImagIn[i];
   }
   // Put the fs/2 component in the imaginary part of the DC bin
   pFFT[1] = RealIn[i];

   // Perform the FFT
   InverseRealFFTf(pFFT, hFFT);

   // Copy the data to the (purely real) output buffer
   ReorderToTime(hFFT, pFFT, RealOut);

   delete [] pFFT;
   ReleaseFFT(hFFT);
}
Beispiel #2
0
/*
 * InverseRealFFT
 *
 * This function computes the inverse of RealFFT, above.
 * The RealIn and ImagIn is assumed to be conjugate-symmetric
 * and as a result the output is purely real.
 * Only the first half of RealIn and ImagIn are used due to this
 * symmetry assumption.
 *
 * This is merely a wrapper of InverseRealFFTf() from RealFFTf.h.
 */
void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
		    float *RealOut)
{
   auto hFFT = GetFFT(NumSamples);
   Floats pFFT{ NumSamples };
   // Copy the data into the processing buffer
   for (size_t i = 0; i < (NumSamples / 2); i++)
      pFFT[2*i  ] = RealIn[i];
   if(ImagIn == NULL) {
      for (size_t i = 0; i < (NumSamples / 2); i++)
         pFFT[2*i+1] = 0;
   } else {
      for (size_t i = 0; i < (NumSamples / 2); i++)
         pFFT[2*i+1] = ImagIn[i];
   }
   // Put the fs/2 component in the imaginary part of the DC bin
   pFFT[1] = RealIn[NumSamples / 2];

   // Perform the FFT
   InverseRealFFTf(pFFT.get(), hFFT.get());

   // Copy the data to the (purely real) output buffer
   ReorderToTime(hFFT.get(), pFFT.get(), RealOut);
}
Beispiel #3
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 > 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;
   }
}