void fft::inversePowerSpectrum(int start, int half, int windowSize, float *finalOut,float *magnitude,float *phase) {
	int i;
	int windowFunc = 3;
	
	/* processing variables*/
	float *in_real = new float[windowSize];
	float *in_img = new float[windowSize];
	float *out_real = new float[windowSize];
	float *out_img = new float[windowSize];
	
	/* get real and imag part */
	for (i = 0; i < half; i++) {	
		in_real[i] = magnitude[i]*cos(phase[i]);
		in_img[i]  = magnitude[i]*sin(phase[i]);
	}
	
	/* zero negative frequencies */
	for (i = half; i < windowSize; i++) {	
		in_real[i] = 0.0;
		in_img[i] = 0.0;
	}
	
	FFT(windowSize, 1, in_real, in_img, out_real, out_img); // second parameter indicates inverse transform
	WindowFunc(windowFunc, windowSize, out_real);
	
	for (i = 0; i < windowSize; i++) {
		finalOut[start + i] += out_real[i];
	}
	
	delete[]in_real;
	delete[]in_img;   
	delete[]out_real;
	delete[]out_img;
}
Beispiel #2
0
void EffectNoiseRemoval::GetProfile(sampleCount len,
                                    sampleType *buffer)
{
   float *in = new float[len];
   float *out = new float[len];
   
   int i;
   
   for(i=0; i<len; i++)
      in[i] = buffer[i]/32767.;

   // Apply window and FFT
   WindowFunc(3, len, in); // Hanning window
   PowerSpectrum(len, in, out);
   
   for(i=0; i<=len/2; i++) {
      float value = log(out[i]);
      
      if (finite(value)) {
         sum[i] += value;
         sumsq[i] += value*value;
         profileCount[i]++;
      }
   }

   delete[] in;
   delete[] out;
}
/* Calculate the power spectrum */
void fft::powerSpectrum(int start, int half, float *data, int windowSize,float *magnitude,float *phase, float *power, float *avg_power) {
	int i;
	int windowFunc = 3;
	float total_power = 0.0f;
	
	/* processing variables*/
	float *in_real = new float[windowSize];
	float *in_img = new float[windowSize];
	float *out_real = new float[windowSize];
	float *out_img = new float[windowSize];
	
	for (i = 0; i < windowSize; i++) {
		in_real[i] = data[start + i];
	}
	
	WindowFunc(windowFunc, windowSize, in_real);
	RealFFT(windowSize, in_real, out_real, out_img);
	
	for (i = 0; i < half; i++) {
		/* compute power */
		power[i] = out_real[i]*out_real[i] + out_img[i]*out_img[i];
		total_power += power[i];
		/* compute magnitude and phase */
		magnitude[i] = 2.0*sqrt(power[i]);
		phase[i] = atan2(out_img[i],out_real[i]);
	}
	/* calculate average power */
	*(avg_power) = total_power / (float) half;
	
	delete[]in_real;
	delete[]in_img;   
	delete[]out_real;
	delete[]out_img;
}
Beispiel #4
0
void EffectWaveletDenoise::RemoveNoise(sampleCount len,
        float *buffer,
        bool first)
{
    PQMF H(d20soqf, 0, 19);  // Daubechies filters
    PQMF G(d20doqf, 0, 19); 

    // Multiply by Hanning window
    float *window = new float[len];
    for (int i=0; i<len; i++) {
        window[i] = buffer[i];
    }
    WindowFunc(3, len, window);

    // Construct wave++ interval from buffer
    Interval signal(0,len-1);
    for (int i=0; i<len; i++) {
        signal[i] = window[i];
    }
    delete[] window;

    // Wavelet transform
    Interval coeff(0, len-1);
    WaveTrans(signal, coeff, H, G, ConvDecPer);

    // Thresholding
    Interval delta(0, len-1);   // initialized to 0
    for(int i=0; i<len; i++) {
        // Hard thresholding
        // if (abs(coeff[i]) > threshold)
        //     delta[i] = 1;

        // Ramaraphu/Maher soft thresholding
        // delta[i] = exp( (abs(coeff[i])/threshold - 1)/0.2 );

        // Soft thresholding
        if (coeff[i]*coeff[i] > threshold)
            delta[i] = 1.0 - threshold/(coeff[i]*coeff[i]);
    }

    for(int i=0; i<len; i++)
        coeff[i] *= delta[i];

    // Inverse transform
    Interval output(0, len-1);
    InvWaveTrans(coeff, output, H, G, AdjConvDecPer);

    // Write interval data back to buffer
    for (int i=0; i<len; i++)
        buffer[i] = output[i];
}
Beispiel #5
0
void EffectFilter::Filter(sampleCount len,
                          sampleType *buffer)
{
   float *inr = new float[len];
   float *ini = new float[len];
   float *outr = new float[len];
   float *outi = new float[len];
   
   unsigned int i;
   
   for(i=0; i<len; i++)
      inr[i] = buffer[i]/32767.;

   // Apply window and FFT
   WindowFunc(3, len, inr); // Hanning window
   FFT(len, false, inr, NULL, outr, outi);
   
   // Apply filter
   unsigned int half = len/2;
   for(i=0; i<=half; i++) {
      int j = len - i;
      
      outr[i] = outr[i]*filterFunc[i];
      outi[i] = outi[i]*filterFunc[i];
      
      if (i!=0 && i!=len/2) {
         outr[j] = outr[j]*filterFunc[i];
         outi[j] = outi[j]*filterFunc[i];
      }
   }

   // Inverse FFT and normalization
   FFT(len, true, outr, outi, inr, ini);
   
   for(i=0; i<len; i++)
      buffer[i] = sampleType(inr[i]*32767);

   delete[] inr;
   delete[] ini;
   delete[] outr;
   delete[] outi;
}
Beispiel #6
0
/* Calculate the power spectrum */
void fft::powerSpectrum (float *data, int windowSize, float *magnitude) {
	
   int windowFunc = 3;
   float total_power = 0.0f;
   
	/* processing variables*/
	float *out_real = new float[windowSize];
	float *out_img = new float[windowSize];
   
    WindowFunc(windowFunc, windowSize, data);
	RealFFT(windowSize, data, out_real, out_img);

	for (int i=0; i<windowSize/2; i++) {
		/* compute magnitude and phase */
		magnitude[i] = 1000.0*sqrt(out_real[i]*out_real[i] + out_img[i]*out_img[i])/windowSize;
		//phase[i] = atan2(out_img[i],out_real[i]);
	}
	
	delete[]out_real;
    delete[]out_img;
}
bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
                                size_t windowSize, double rate,
                                const float *data, size_t dataLen,
                                float *pYMin, float *pYMax,
                                FreqGauge *progress)
{
   // Wipe old data
   mProcessed.resize(0);
   mRate = 0.0;
   mWindowSize = 0;

   // Validate inputs
   int f = NumWindowFuncs();

   if (!(windowSize >= 32 && windowSize <= 65536 &&
         alg >= SpectrumAnalyst::Spectrum &&
         alg < SpectrumAnalyst::NumAlgorithms &&
         windowFunc >= 0 && windowFunc < f)) {
      return false;
   }

   if (dataLen < windowSize) {
      return false;
   }

   // Now repopulate
   mRate = rate;
   mWindowSize = windowSize;
   mAlg = alg;

   auto half = mWindowSize / 2;
   mProcessed.resize(mWindowSize);

   Floats in{ mWindowSize };
   Floats out{ mWindowSize };
   Floats out2{ mWindowSize };
   Floats win{ mWindowSize };

   for (size_t i = 0; i < mWindowSize; i++) {
      mProcessed[i] = 0.0f;
      win[i] = 1.0f;
   }

   WindowFunc(windowFunc, mWindowSize, win.get());

   // Scale window such that an amplitude of 1.0 in the time domain
   // shows an amplitude of 0dB in the frequency domain
   double wss = 0;
   for (size_t i = 0; i<mWindowSize; i++)
      wss += win[i];
   if(wss > 0)
      wss = 4.0 / (wss*wss);
   else
      wss = 1.0;

   if (progress) {
      progress->SetRange(dataLen);
   }

   size_t start = 0;
   int windows = 0;
   while (start + mWindowSize <= dataLen) {
      for (size_t i = 0; i < mWindowSize; i++)
         in[i] = win[i] * data[start + i];

      switch (alg) {
         case Spectrum:
            PowerSpectrum(mWindowSize, in.get(), out.get());

            for (size_t i = 0; i < half; i++)
               mProcessed[i] += out[i];
            break;

         case Autocorrelation:
         case CubeRootAutocorrelation:
         case EnhancedAutocorrelation:

            // Take FFT
            RealFFT(mWindowSize, in.get(), out.get(), out2.get());
            // Compute power
            for (size_t i = 0; i < mWindowSize; i++)
               in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);

            if (alg == Autocorrelation) {
               for (size_t i = 0; i < mWindowSize; i++)
                  in[i] = sqrt(in[i]);
            }
            if (alg == CubeRootAutocorrelation ||
                alg == EnhancedAutocorrelation) {
               // Tolonen and Karjalainen recommend taking the cube root
               // of the power, instead of the square root

               for (size_t i = 0; i < mWindowSize; i++)
                  in[i] = pow(in[i], 1.0f / 3.0f);
            }
            // Take FFT
            RealFFT(mWindowSize, in.get(), out.get(), out2.get());

            // Take real part of result
            for (size_t i = 0; i < half; i++)
               mProcessed[i] += out[i];
            break;

         case Cepstrum:
            RealFFT(mWindowSize, in.get(), out.get(), out2.get());

            // Compute log power
            // Set a sane lower limit assuming maximum time amplitude of 1.0
            {
               float power;
               float minpower = 1e-20*mWindowSize*mWindowSize;
               for (size_t i = 0; i < mWindowSize; i++)
               {
                  power = (out[i] * out[i]) + (out2[i] * out2[i]);
                  if(power < minpower)
                     in[i] = log(minpower);
                  else
                     in[i] = log(power);
               }
               // Take IFFT
               InverseRealFFT(mWindowSize, in.get(), NULL, out.get());

               // Take real part of result
               for (size_t i = 0; i < half; i++)
                  mProcessed[i] += out[i];
            }

            break;

         default:
            wxASSERT(false);
            break;
      }                         //switch

      // Update the progress bar
      if (progress) {
         progress->SetValue(start);
      }

      start += half;
      windows++;
   }

   if (progress) {
      // Reset for next time
      progress->Reset();
   }

   float mYMin = 1000000, mYMax = -1000000;
   double scale;
   switch (alg) {
   case Spectrum:
      // Convert to decibels
      mYMin = 1000000.;
      mYMax = -1000000.;
      scale = wss / (double)windows;
      for (size_t i = 0; i < half; i++)
      {
         mProcessed[i] = 10 * log10(mProcessed[i] * scale);
         if(mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if(mProcessed[i] < mYMin)
            mYMin = mProcessed[i];
      }
      break;

   case Autocorrelation:
   case CubeRootAutocorrelation:
      for (size_t i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Find min/max
      mYMin = mProcessed[0];
      mYMax = mProcessed[0];
      for (size_t i = 1; i < half; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];
      break;

   case EnhancedAutocorrelation:
      for (size_t i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Peak Pruning as described by Tolonen and Karjalainen, 2000

      // Clip at zero, copy to temp array
      for (size_t i = 0; i < half; i++) {
         if (mProcessed[i] < 0.0)
            mProcessed[i] = float(0.0);
         out[i] = mProcessed[i];
      }

      // Subtract a time-doubled signal (linearly interp.) from the original
      // (clipped) signal
      for (size_t i = 0; i < half; i++)
         if ((i % 2) == 0)
            mProcessed[i] -= out[i / 2];
         else
            mProcessed[i] -= ((out[i / 2] + out[i / 2 + 1]) / 2);

      // Clip at zero again
      for (size_t i = 0; i < half; i++)
         if (mProcessed[i] < 0.0)
            mProcessed[i] = float(0.0);

      // Find NEW min/max
      mYMin = mProcessed[0];
      mYMax = mProcessed[0];
      for (size_t i = 1; i < half; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];
      break;

   case Cepstrum:
      for (size_t i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Find min/max, ignoring first and last few values
      {
         size_t ignore = 4;
         mYMin = mProcessed[ignore];
         mYMax = mProcessed[ignore];
         for (size_t i = ignore + 1; i + ignore < half; i++)
            if (mProcessed[i] > mYMax)
               mYMax = mProcessed[i];
            else if (mProcessed[i] < mYMin)
               mYMin = mProcessed[i];
      }
      break;

   default:
      wxASSERT(false);
      break;
   }

   if (pYMin)
      *pYMin = mYMin;
   if (pYMax)
      *pYMax = mYMax;

   return true;
}
Beispiel #8
0
void PaulStretch::process(float *smps, size_t nsmps)
{
   //add NEW samples to the pool
   if ((smps != NULL) && (nsmps != 0)) {
      if (nsmps > poolsize) {
         nsmps = poolsize;
      }
      int nleft = poolsize - nsmps;

      //move left the samples from the pool to make room for NEW samples
      for (int i = 0; i < nleft; i++)
         in_pool[i] = in_pool[i + nsmps];

      //add NEW samples to the pool
      for (size_t i = 0; i < nsmps; i++)
         in_pool[i + nleft] = smps[i];
   }

   //get the samples from the pool
   for (size_t i = 0; i < poolsize; i++)
      fft_smps[i] = in_pool[i];
   WindowFunc(eWinFuncHanning, poolsize, fft_smps.get());

   RealFFT(poolsize, fft_smps.get(), fft_c.get(), fft_s.get());

   for (size_t i = 0; i < poolsize / 2; i++)
      fft_freq[i] = sqrt(fft_c[i] * fft_c[i] + fft_s[i] * fft_s[i]);
   process_spectrum(fft_freq.get());


   //put randomize phases to frequencies and do a IFFT
   float inv_2p15_2pi = 1.0 / 16384.0 * (float)M_PI;
   for (size_t i = 1; i < poolsize / 2; i++) {
      unsigned int random = (rand()) & 0x7fff;
      float phase = random * inv_2p15_2pi;
      float s = fft_freq[i] * sin(phase);
      float c = fft_freq[i] * cos(phase);

      fft_c[i] = fft_c[poolsize - i] = c;

      fft_s[i] = s; fft_s[poolsize - i] = -s;
   }
   fft_c[0] = fft_s[0] = 0.0;
   fft_c[poolsize / 2] = fft_s[poolsize / 2] = 0.0;

   FFT(poolsize, true, fft_c.get(), fft_s.get(), fft_smps.get(), fft_tmp.get());

   float max = 0.0, max2 = 0.0;
   for (size_t i = 0; i < poolsize; i++) {
      max = std::max(max, fabsf(fft_tmp[i]));
      max2 = std::max(max2, fabsf(fft_smps[i]));
   }


   //make the output buffer
   float tmp = 1.0 / (float) out_bufsize * M_PI;
   float hinv_sqrt2 = 0.853553390593f;//(1.0+1.0/sqrt(2))*0.5;

   float ampfactor = 1.0;
   if (rap < 1.0)
      ampfactor = rap * 0.707;
   else
      ampfactor = (out_bufsize / (float)poolsize) * 4.0;

   for (size_t i = 0; i < out_bufsize; i++) {
      float a = (0.5 + 0.5 * cos(i * tmp));
      float out = fft_smps[i + out_bufsize] * (1.0 - a) + old_out_smp_buf[i] * a;
      out_buf[i] =
         out * (hinv_sqrt2 - (1.0 - hinv_sqrt2) * cos(i * 2.0 * tmp)) *
         ampfactor;
   }

   //copy the current output buffer to old buffer
   for (size_t i = 0; i < out_bufsize * 2; i++)
      old_out_smp_buf[i] = fft_smps[i];
}
Beispiel #9
0
bool WaveClip::GetSpectrogram(float *freq, sampleCount *where,
                               int numPixels,
                               double t0, double pixelsPerSecond,
                               bool autocorrelation)
{
   int minFreq = gPrefs->Read(wxT("/Spectrum/MinFreq"), 0L);
   int maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
   int range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
   int gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
   int frequencygain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
   int windowType;
   int windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
   int fftSkipPoints = gPrefs->Read(wxT("/Spectrum/FFTSkipPoints"), 0L);
   int fftSkipPoints1 = fftSkipPoints+1;
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
   int half = windowSize/2;
   gPrefs->Read(wxT("/Spectrum/WindowType"), &windowType, 3);

#ifdef EXPERIMENTAL_USE_REALFFTF
   // Update the FFT and window if necessary
   if((mWindowType != windowType) || (mWindowSize != windowSize)
      || (hFFT == NULL) || (mWindow == NULL) || (mWindowSize != hFFT->Points*2) ) {
      mWindowType = windowType;
      mWindowSize = windowSize;
      if(hFFT != NULL)
         EndFFT(hFFT);
      hFFT = InitializeFFT(mWindowSize);
      if(mWindow != NULL) delete[] mWindow;
      // Create the requested window function
      mWindow = new float[mWindowSize];
      int i;
      for(i=0; i<windowSize; i++)
         mWindow[i]=1.0;
      WindowFunc(mWindowType, mWindowSize, mWindow);
      // Scale the window function to give 0dB spectrum for 0dB sine tone
      double ws=0;
      for(i=0; i<windowSize; i++)
         ws += mWindow[i];
      if(ws > 0) {
         ws = 2.0/ws;
         for(i=0; i<windowSize; i++)
            mWindow[i] *= ws;
      }
   }
#endif // EXPERIMENTAL_USE_REALFFTF

   if (mSpecCache &&
       mSpecCache->minFreqOld == minFreq &&
       mSpecCache->maxFreqOld == maxFreq &&
       mSpecCache->rangeOld == range &&
       mSpecCache->gainOld == gain &&
       mSpecCache->windowTypeOld == windowType &&
       mSpecCache->windowSizeOld == windowSize &&
       mSpecCache->frequencyGainOld == frequencygain &&
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
       mSpecCache->fftSkipPointsOld == fftSkipPoints &&
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
       mSpecCache->dirty == mDirty &&
       mSpecCache->start == t0 &&
       mSpecCache->ac == autocorrelation &&
       mSpecCache->len >= numPixels &&
       mSpecCache->pps == pixelsPerSecond) {
      memcpy(freq, mSpecCache->freq, numPixels*half*sizeof(float));
      memcpy(where, mSpecCache->where, (numPixels+1)*sizeof(sampleCount));
      return false;  //hit cache completely
   }

   SpecCache *oldCache = mSpecCache;

   mSpecCache = new SpecCache(numPixels, half, autocorrelation);
   mSpecCache->pps = pixelsPerSecond;
   mSpecCache->start = t0;

   sampleCount x;

   bool *recalc = new bool[mSpecCache->len + 1];

   for (x = 0; x < mSpecCache->len + 1; x++) {
      recalc[x] = true;
      // purposely offset the display 1/2 bin to the left (as compared
      // to waveform display to properly center response of the FFT
      mSpecCache->where[x] =
         (sampleCount)floor((t0*mRate) + (x*mRate/pixelsPerSecond) + 1.);
   }

   // Optimization: if the old cache is good and overlaps
   // with the current one, re-use as much of the cache as
   // possible
   if (oldCache->dirty == mDirty &&
       oldCache->minFreqOld == minFreq &&
       oldCache->maxFreqOld == maxFreq &&
       oldCache->rangeOld == range &&
       oldCache->gainOld == gain &&
       oldCache->windowTypeOld == windowType &&
       oldCache->windowSizeOld == windowSize &&
       oldCache->frequencyGainOld == frequencygain &&
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
       oldCache->fftSkipPointsOld == fftSkipPoints &&
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
       oldCache->pps == pixelsPerSecond &&
       oldCache->ac == autocorrelation &&
       oldCache->where[0] < mSpecCache->where[mSpecCache->len] &&
       oldCache->where[oldCache->len] > mSpecCache->where[0]) {

      for (x = 0; x < mSpecCache->len; x++)
         if (mSpecCache->where[x] >= oldCache->where[0] &&
             mSpecCache->where[x] <= oldCache->where[oldCache->len]) {

            int ox = (int) ((double (oldCache->len) *
                      (mSpecCache->where[x] - oldCache->where[0]))
                       / (oldCache->where[oldCache->len] -
                                             oldCache->where[0]) + 0.5);
            if (ox >= 0 && ox < oldCache->len &&
                mSpecCache->where[x] == oldCache->where[ox]) {

               for (sampleCount i = 0; i < (sampleCount)half; i++)
                  mSpecCache->freq[half * x + i] =
                     oldCache->freq[half * ox + i];

               recalc[x] = false;
            }
         }
   }

#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
   float *buffer = new float[windowSize*fftSkipPoints1];
   mSpecCache->fftSkipPointsOld = fftSkipPoints;
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
   float *buffer = new float[windowSize];
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
   mSpecCache->minFreqOld = minFreq;
   mSpecCache->maxFreqOld = maxFreq;
   mSpecCache->gainOld = gain;
   mSpecCache->rangeOld = range;
   mSpecCache->windowTypeOld = windowType;
   mSpecCache->windowSizeOld = windowSize;
   mSpecCache->frequencyGainOld = frequencygain;

   float *gainfactor = NULL;
   if(frequencygain > 0) {
      // Compute a frequency-dependant gain factor
      // scaled such that 1000 Hz gets a gain of 0dB
      double factor = 0.001*(double)mRate/(double)windowSize;
      gainfactor = new float[half];
      for(x = 0; x < half; x++) {
         gainfactor[x] = frequencygain*log10(factor * x);
      }
   }

   for (x = 0; x < mSpecCache->len; x++)
      if (recalc[x]) {

         sampleCount start = mSpecCache->where[x];
         sampleCount len = windowSize;
         sampleCount i;

         if (start <= 0 || start >= mSequence->GetNumSamples()) {

            for (i = 0; i < (sampleCount)half; i++)
               mSpecCache->freq[half * x + i] = 0;

         }
         else
         {
            float *adj = buffer;
            start -= windowSize >> 1;

            if (start < 0) {
               for (i = start; i < 0; i++)
                  *adj++ = 0;
               len += start;
               start = 0;
            }
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
            if (start + len*fftSkipPoints1 > mSequence->GetNumSamples()) {
               int newlen = (mSequence->GetNumSamples() - start)/fftSkipPoints1;
               for (i = newlen*fftSkipPoints1; i < (sampleCount)len*fftSkipPoints1; i++)
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
            if (start + len > mSequence->GetNumSamples()) {
               int newlen = mSequence->GetNumSamples() - start;
               for (i = newlen; i < (sampleCount)len; i++)
#endif //EXPERIMENTAL_FFT_SKIP_POINTS
                  adj[i] = 0;
               len = newlen;
            }

            if (len > 0)
#ifdef EXPERIMENTAL_FFT_SKIP_POINTS
               mSequence->Get((samplePtr)adj, floatSample, start, len*fftSkipPoints1);
            if (fftSkipPoints) {
               // TODO: (maybe) alternatively change Get to include skipping of points
               int j=0;
               for (int i=0; i < len; i++) {
                  adj[i]=adj[j];
                  j+=fftSkipPoints1;
               }
            }
#else //!EXPERIMENTAL_FFT_SKIP_POINTS
               mSequence->Get((samplePtr)adj, floatSample, start, len);
#endif //EXPERIMENTAL_FFT_SKIP_POINTS

#ifdef EXPERIMENTAL_USE_REALFFTF
            if(autocorrelation) {
               ComputeSpectrum(buffer, windowSize, windowSize,
                               mRate, &mSpecCache->freq[half * x],
                               autocorrelation, windowType);
            } else {
               ComputeSpectrumUsingRealFFTf(buffer, hFFT, mWindow, mWindowSize, &mSpecCache->freq[half * x]);
            }
#else  // EXPERIMENTAL_USE_REALFFTF
           ComputeSpectrum(buffer, windowSize, windowSize,
                           mRate, &mSpecCache->freq[half * x],
                           autocorrelation, windowType);
#endif // EXPERIMENTAL_USE_REALFFTF
           if(gainfactor) {
              // Apply a frequency-dependant gain factor
              for(i=0; i<half; i++)
                 mSpecCache->freq[half * x + i] += gainfactor[i];
           }
         }
      }

   if(gainfactor)
      delete[] gainfactor;
   delete[]buffer;
   delete[]recalc;
   delete oldCache;

   mSpecCache->dirty = mDirty;
   memcpy(freq, mSpecCache->freq, numPixels*half*sizeof(float));
   memcpy(where, mSpecCache->where, (numPixels+1)*sizeof(sampleCount));
   return true;
}

bool WaveClip::GetMinMax(float *min, float *max,
                          double t0, double t1)
{
   *min = float(0.0);
   *max = float(0.0);

   if (t0 > t1)
      return false;

   if (t0 == t1)
      return true;

   sampleCount s0, s1;

   TimeToSamplesClip(t0, &s0);
   TimeToSamplesClip(t1, &s1);

   return mSequence->GetMinMax(s0, s1-s0, min, max);
}
/* Mangle a single window. Each output sample (except the first and last
 * half-window) is the result of two distinct calls to this function, 
 * due to overlapping windows. */
static void reduce_noise(chandata_t* chan, float* window, float level)
{
    float *inr   = (float*)calloc(WINDOWSIZE, sizeof(float));
    float *ini   = (float*)calloc(WINDOWSIZE, sizeof(float));
    float *outr  = (float*)calloc(WINDOWSIZE, sizeof(float));
    float *outi  = (float*)calloc(WINDOWSIZE, sizeof(float));
    float *power = (float*)calloc(WINDOWSIZE, sizeof(float));
    float *smoothing = chan->smoothing;
    static int callnum = 0;
    int i;

    callnum ++;

    for (i = 0; i < FREQCOUNT; i ++) {
        assert(smoothing[i] >= 0 && smoothing[i] <= 1);
    }

    memcpy(inr, window, WINDOWSIZE*sizeof(float));

    FFT(WINDOWSIZE, 0, inr, NULL, outr, outi);

    memcpy(inr, window, WINDOWSIZE*sizeof(float));
    WindowFunc(HANNING, WINDOWSIZE, inr);
    PowerSpectrum(WINDOWSIZE, inr, power);

    for(i = 0; i < FREQCOUNT; i ++) {
        float smooth;
        float plog;
        plog = log(power[i]);
        if (power[i] != 0 && plog < chan->noisegate[i] + level*8.0)
            smooth = 0.0;
        else
            smooth = 1.0;

        smoothing[i] = smooth * 0.5 + smoothing[i] * 0.5;
    }

    /* Audacity says this code will eliminate tinkle bells.
     * I have no idea what that means. */
    for (i = 2; i < FREQCOUNT - 2; i ++) {
        if (smoothing[i]>=0.5 &&
            smoothing[i]<=0.55 &&
            smoothing[i-1]<0.1 &&
            smoothing[i-2]<0.1 &&
            smoothing[i+1]<0.1 &&
            smoothing[i+2]<0.1)
            smoothing[i] = 0.0;
    }

    outr[0] *= smoothing[0];
    outi[0] *= smoothing[0];
    outr[FREQCOUNT-1] *= smoothing[FREQCOUNT-1];
    outi[FREQCOUNT-1] *= smoothing[FREQCOUNT-1];
    
    for (i = 1; i < FREQCOUNT-1; i ++) {
        int j = WINDOWSIZE - i;
        float smooth = smoothing[i];

        outr[i] *= smooth;
        outi[i] *= smooth;
        outr[j] *= smooth;
        outi[j] *= smooth;
    }

    FFT(WINDOWSIZE, 1, outr, outi, inr, ini);
    WindowFunc(HANNING, WINDOWSIZE, inr);

    memcpy(window, inr, WINDOWSIZE*sizeof(float));

    free(inr);
    free(ini);
    free(outr);
    free(outi);
    free(power);

    for (i = 0; i < FREQCOUNT; i ++) {
        assert(smoothing[i] >= 0 && smoothing[i] <= 1);
    }
}
Beispiel #11
0
void EffectNoiseRemoval::RemoveNoise(sampleCount len,
                                     sampleType *buffer)
{
   float *inr = new float[len];
   float *ini = new float[len];
   float *outr = new float[len];
   float *outi = new float[len];
   float *power = new float[len];
   float *plog = new float[len];
   
   int i;
   
   for(i=0; i<len; i++)
      inr[i] = buffer[i]/32767.;

   // Apply window and FFT
   WindowFunc(3, len, inr); // Hanning window
   FFT(len, false, inr, NULL, outr, outi);

   for(i=0; i<len; i++)
      inr[i] = buffer[i]/32767.;
   WindowFunc(3, len, inr); // Hanning window
   PowerSpectrum(len, inr, power);

   for(i=0; i<=len/2; i++)
      plog[i] = log(power[i]);
    
   int half = len/2;
   for(i=0; i<=half; i++) {
      float smooth;
      
      if (plog[i] < noiseGate[i] + (level/2.0))
         smooth = 0.0;
      else
         smooth = 1.0;
      
      smoothing[i] = smooth * 0.5 + smoothing[i] * 0.5;
   }

   /* try to eliminate tinkle bells */
   for(i=2; i<=half-2; i++) {
      if (smoothing[i]>=0.5 &&
          smoothing[i]<=0.55 &&
          smoothing[i-1]<0.1 &&
          smoothing[i-2]<0.1 &&
          smoothing[i+1]<0.1 &&
          smoothing[i+2]<0.1)
         smoothing[i] = 0.0;
   }

   outr[0] *= smoothing[0];
   outi[0] *= smoothing[0];
   outr[half] *= smoothing[half];
   outi[half] *= smoothing[half];
   for(i=1; i<half; i++) {
      int j = len - i;
      float smooth = smoothing[i];

      outr[i] *= smooth;
      outi[i] *= smooth;
      outr[j] *= smooth;
      outi[j] *= smooth;
   }

   // Inverse FFT and normalization
   FFT(len, true, outr, outi, inr, ini);
   
   for(i=0; i<len; i++)
      buffer[i] = sampleType(inr[i]*32767);

   delete[] inr;
   delete[] ini;
   delete[] outr;
   delete[] outi;
   delete[] power;
   delete[] plog;
}
Beispiel #12
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;
   }
}
Beispiel #13
0
bool ComputeSpectrum(float * data, int width, int height,
                     int maxFreq, int windowSize,
                     double rate, float *grayscaleOut,
                     bool autocorrelation)
{
   int windowFunc = 3;

   if (width < windowSize)
      return false;

   if (!data || !grayscaleOut)
      return true;

   float *processed = new float[windowSize];

   int i;
   for (i = 0; i < windowSize; i++)
      processed[i] = float(0.0);
   int half = windowSize / 2;

   float *in = new float[windowSize];
   float *out = new float[windowSize];
   float *out2 = new float[windowSize];

   int start = 0;
   int windows = 0;
   while (start + windowSize <= width) {
      for (i = 0; i < windowSize; i++)
         in[i] = data[start + i];

      WindowFunc(windowFunc, windowSize, in);

      if (autocorrelation) {
         // Take FFT
         FFT(windowSize, false, in, NULL, out, out2);

         // Compute power
         for (i = 0; i < windowSize; i++)
            in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);

         // Tolonen and Karjalainen recommend taking the cube root
         // of the power, instead of the square root

         for (i = 0; i < windowSize; i++)
            in[i] = pow(in[i], 1.0f / 3.0f);

         // Take FFT
         FFT(windowSize, false, in, NULL, out, out2);

         // Take real part of result
         for (i = 0; i < half; i++)
            processed[i] += out[i];
      } else {
         PowerSpectrum(windowSize, in, out);

         for (i = 0; i < half; i++)
            processed[i] += out[i];
      }

      start += half;
      windows++;
   }

   int maxSamples = int (maxFreq * windowSize / rate + 0.5);
   if (maxSamples > half)
      maxSamples = half;

   if (autocorrelation) {
      maxSamples = half;

      // Peak Pruning as described by Tolonen and Karjalainen, 2000

      // Clip at zero, copy to temp array
      for (i = 0; i < maxSamples; i++) {
         if (processed[i] < 0.0)
            processed[i] = float(0.0);
         out[i] = processed[i];
      }

      // Subtract a time-doubled signal (linearly interp.) from the original
      // (clipped) signal
      for (i = 0; i < maxSamples; i++)
         if ((i % 2) == 0)
            processed[i] -= out[i / 2];
         else
            processed[i] -= ((out[i / 2] + out[i / 2 + 1]) / 2);

      // Clip at zero again
      for (i = 0; i < maxSamples; i++)
         if (processed[i] < 0.0)
            processed[i] = float(0.0);

      // Find new max
      float max = 0;
      for (i = 1; i < maxSamples; i++)
         if (processed[i] > max)
            max = processed[i];

      // Reverse and scale
      for (i = 0; i < maxSamples; i++)
         in[i] = processed[i] / (windowSize / 4);
      for (i = 0; i < maxSamples; i++)
         processed[maxSamples - 1 - i] = in[i];
   } else {
      // Convert to decibels
      for (i = 0; i < maxSamples; i++)
         processed[i] = 10 * log10(processed[i] / windowSize / windows);
   }

   // Finally, put it into bins in grayscaleOut[], normalized to a 0.0-1.0 scale

   for (i = 0; i < height; i++) {
      float bin0 = float (i) * maxSamples / height;
      float bin1 = float (i + 1) * maxSamples / height;

      float binwidth = bin1 - bin0;

      float value = float(0.0);

      if (int (bin1) == int (bin0))
         value = processed[int (bin0)];
      else {
         value += processed[int (bin0)] * (int (bin0) + 1 - bin0);
         bin0 = 1 + int (bin0);
         while (bin0 < int (bin1)) {
            value += processed[int (bin0)];
            bin0 += 1.0;
         }
         value += processed[int (bin1)] * (bin1 - int (bin1));

         value /= binwidth;
      }

      if (!autocorrelation) {
         // Last step converts dB to a 0.0-1.0 range     
         value = (value + 80.0) / 80.0;
      }

      if (value > 1.0)
         value = float(1.0);
      if (value < 0.0)
         value = float(0.0);

      grayscaleOut[i] = value;
   }

   delete[]in;
   delete[]out;
   delete[]out2;
   delete[]processed;

   return true;
}
Beispiel #14
0
void FreqWindow::Recalc()
{
   if (mProcessed)
      delete mProcessed;
   mProcessed = NULL;

   if (!mData) {
      mFreqPlot->Refresh(false);
      return;
   }

   int alg = mAlgChoice->GetSelection();
   int windowFunc = mFuncChoice->GetSelection();
   long windowSize = 0;
   (mSizeChoice->GetStringSelection()).ToLong(&windowSize);

   if (!(windowSize >= 32 && windowSize <= 65536 &&
         alg >= 0 && alg <= 3 && windowFunc >= 0 && windowFunc <= 3)) {
      mFreqPlot->Refresh(false);
      return;
   }

   mWindowSize = windowSize;

   if (mDataLen < mWindowSize) {
      mFreqPlot->Refresh(false);
      return;
   }

   mProcessed = new float[mWindowSize];

   int i;
   for (i = 0; i < mWindowSize; i++)
      mProcessed[i] = 0.0;
   int half = mWindowSize / 2;

   float *in = new float[mWindowSize];
   float *in2 = new float[mWindowSize];
   float *out = new float[mWindowSize];
   float *out2 = new float[mWindowSize];

   int start = 0;
   int windows = 0;
   while (start + mWindowSize <= mDataLen) {
      for (i = 0; i < mWindowSize; i++)
         in[i] = mData[start + i];

      WindowFunc(windowFunc, mWindowSize, in);

      switch (alg) {
      case 0:                  // Spectrum
         PowerSpectrum(mWindowSize, in, out);

         for (i = 0; i < half; i++)
            mProcessed[i] += out[i];
         break;

      case 1:
      case 2:
      case 3:                  // Autocorrelation, Cuberoot AC or Enhanced AC

         // Take FFT
         FFT(mWindowSize, false, in, NULL, out, out2);

         // Compute power
         for (i = 0; i < mWindowSize; i++)
            in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);

         if (alg == 1) {
            for (i = 0; i < mWindowSize; i++)
               in[i] = sqrt(in[i]);
         }
         if (alg == 2 || alg == 3) {
            // Tolonen and Karjalainen recommend taking the cube root
            // of the power, instead of the square root

            for (i = 0; i < mWindowSize; i++)
               in[i] = pow(in[i], 1.0 / 3.0);
         }
         // Take FFT
         FFT(mWindowSize, false, in, NULL, out, out2);

         // Take real part of result
         for (i = 0; i < half; i++)
            mProcessed[i] += out[i];
         break;

      case 4:                  // Cepstrum
         FFT(mWindowSize, false, in, NULL, out, out2);

         // Compute log power
         for (i = 0; i < mWindowSize; i++)
            in[i] = log((out[i] * out[i]) + (out2[i] * out2[i]));

         // Take IFFT
         FFT(mWindowSize, true, in, NULL, out, out2);

         // Take real part of result
         for (i = 0; i < half; i++)
            mProcessed[i] += out[i];

         break;
      }                         //switch

      start += half;
      windows++;
   }

   switch (alg) {
   case 0:                     // Spectrum
      // Convert to decibels
      for (i = 0; i < half; i++)
         mProcessed[i] = 10 * log10(mProcessed[i] / mWindowSize / windows);

      mProcessedSize = half;
      mYMin = -90;
      mYMax = 10;
      mYStep = 10;
      break;

   case 1:                     // Standard Autocorrelation
   case 2:                     // Cuberoot Autocorrelation
      for (i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Find min/max
      mYMin = mProcessed[0];
      mYMax = mProcessed[0];
      for (i = 1; i < half; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];

      mYStep = 1;

      mProcessedSize = half;
      break;

   case 3:                     // Enhanced Autocorrelation
      for (i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Peak Pruning as described by Tolonen and Karjalainen, 2000

      // Clip at zero, copy to temp array
      for (i = 0; i < half; i++) {
         if (mProcessed[i] < 0.0)
            mProcessed[i] = 0.0;
         out[i] = mProcessed[i];
      }

      // Subtract a time-doubled signal (linearly interp.) from the original
      // (clipped) signal
      for (i = 0; i < half; i++)
         if ((i % 2) == 0)
            mProcessed[i] -= out[i / 2];
         else
            mProcessed[i] -= ((out[i / 2] + out[i / 2 + 1]) / 2);

      // Clip at zero again
      for (i = 0; i < half; i++)
         if (mProcessed[i] < 0.0)
            mProcessed[i] = 0.0;

      // Find new min/max
      mYMin = mProcessed[0];
      mYMax = mProcessed[0];
      for (i = 1; i < half; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];

      mYStep = 1;

      mProcessedSize = half;
      break;

   case 4:                     // Cepstrum
      for (i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Find min/max, ignoring first and last few values
      int ignore = 4;
      mYMin = mProcessed[ignore];
      mYMax = mProcessed[ignore];
      for (i = ignore + 1; i < half - ignore; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];

      mYStep = 1;

      mProcessedSize = half;
      break;
   }

   delete[]in;
   delete[]in2;
   delete[]out;
   delete[]out2;

   mFreqPlot->Refresh(false);
}
Beispiel #15
0
void FreqWindow::Recalc()
{
   wxLogMessage(wxT("Starting FreqWindow::Recalc()"));
   if (mProcessed)
      delete[] mProcessed;
   mProcessed = NULL;

   if (!mData) {
      mFreqPlot->Refresh(true);
      return;
   }

   int alg = mAlgChoice->GetSelection();
   int windowFunc = mFuncChoice->GetSelection();
   long windowSize = 0;
   (mSizeChoice->GetStringSelection()).ToLong(&windowSize);

   int f = NumWindowFuncs();

   if (!(windowSize >= 32 && windowSize <= 65536 &&
         alg >= 0 && alg <= 4 && windowFunc >= 0 && windowFunc < f)) {
      mFreqPlot->Refresh(true);
      return;
   }

   mWindowSize = windowSize;

   if (mDataLen < mWindowSize) {
      mFreqPlot->Refresh(true);
      return;
   }

   mProcessed = new float[mWindowSize];

   int i;
   for (i = 0; i < mWindowSize; i++)
      mProcessed[i] = float(0.0);
   int half = mWindowSize / 2;

   float *in = new float[mWindowSize];
   float *in2 = new float[mWindowSize];
   float *out = new float[mWindowSize];
   float *out2 = new float[mWindowSize];
   float *win = new float[mWindowSize];

   // initialize the window
   for(int i=0; i<mWindowSize; i++)
      win[i] = 1.0;
   WindowFunc(windowFunc, mWindowSize, win);
   // Scale window such that an amplitude of 1.0 in the time domain
   // shows an amplitude of 0dB in the frequency domain
   double wss = 0;
   for(int i=0; i<mWindowSize; i++)
      wss += win[i];
   if(wss > 0)
      wss = 4.0 / (wss*wss);
   else
      wss = 1.0;

   //Progress dialog over FFT operation
   wxLogMessage(wxT("Starting progress dialogue in FreqWindow::Recalc()"));
   ProgressDialog *mProgress = new ProgressDialog(_("FreqWindow"),_("Drawing Spectrum"));

   int start = 0;
   int windows = 0;
   while (start + mWindowSize <= mDataLen) {
      for (i = 0; i < mWindowSize; i++)
         in[i] = win[i] * mData[start + i];

      switch (alg) {
      case 0:                  // Spectrum
         PowerSpectrum(mWindowSize, in, out);

         for (i = 0; i < half; i++)
            mProcessed[i] += out[i];
         break;

      case 1:
      case 2:
      case 3:   // Autocorrelation, Cuberoot AC or Enhanced AC

         // Take FFT
#ifdef EXPERIMENTAL_USE_REALFFTF
         RealFFT(mWindowSize, in, out, out2);
#else
         FFT(mWindowSize, false, in, NULL, out, out2);
#endif
         // Compute power
         for (i = 0; i < mWindowSize; i++)
            in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);

         if (alg == 1) {
            for (i = 0; i < mWindowSize; i++)
               in[i] = sqrt(in[i]);
         }
         if (alg == 2 || alg == 3) {
            // Tolonen and Karjalainen recommend taking the cube root
            // of the power, instead of the square root

            for (i = 0; i < mWindowSize; i++)
               in[i] = pow(in[i], 1.0f / 3.0f);
         }
         // Take FFT
#ifdef EXPERIMENTAL_USE_REALFFTF
         RealFFT(mWindowSize, in, out, out2);
#else
         FFT(mWindowSize, false, in, NULL, out, out2);
#endif

         // Take real part of result
         for (i = 0; i < half; i++)
            mProcessed[i] += out[i];
         break;

      case 4:                  // Cepstrum
#ifdef EXPERIMENTAL_USE_REALFFTF
         RealFFT(mWindowSize, in, out, out2);
#else
         FFT(mWindowSize, false, in, NULL, out, out2);
#endif

         // Compute log power
         // Set a sane lower limit assuming maximum time amplitude of 1.0
         float power;
         float minpower = 1e-20*mWindowSize*mWindowSize;
         for (i = 0; i < mWindowSize; i++)
         {
            power = (out[i] * out[i]) + (out2[i] * out2[i]);
            if(power < minpower)
               in[i] = log(minpower);
            else
               in[i] = log(power);
         }
         // Take IFFT
#ifdef EXPERIMENTAL_USE_REALFFTF
         InverseRealFFT(mWindowSize, in, NULL, out);
#else
         FFT(mWindowSize, true, in, NULL, out, out2);
#endif

         // Take real part of result
         for (i = 0; i < half; i++)
            mProcessed[i] += out[i];

         break;
      }                         //switch

      start += half;
      windows++;
      // only update the progress dialogue infrequently to reduce it's overhead
      // If we do it every time, it spends as much time updating X11 as doing
      // the calculations. 10 seems a reasonable compromise on Linux that
      // doesn't make it unresponsive, but avoids the slowdown.
      if ((windows % 10) == 0)
         mProgress->Update(1 - static_cast<float>(mDataLen - start) / mDataLen);
   }

   wxLogMessage(wxT("Finished updating progress dialogue in FreqWindow::Recalc()"));
   switch (alg) {
   double scale;
   case 0:                     // Spectrum
      // Convert to decibels
      mYMin = 1000000.;
      mYMax = -1000000.;
      scale = wss / (double)windows;
      for (i = 0; i < half; i++)
      {
         mProcessed[i] = 10 * log10(mProcessed[i] * scale);
         if(mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if(mProcessed[i] < mYMin)
            mYMin = mProcessed[i];
      }
      if(mYMin < -dBRange)
         mYMin = -dBRange;
      if(mYMax <= -dBRange)
         mYMax = -dBRange + 10.; // it's all out of range, but show a scale.
      else
         mYMax += .5;

      mProcessedSize = half;
      mYStep = 10;
      break;

   case 1:                     // Standard Autocorrelation
   case 2:                     // Cuberoot Autocorrelation
      for (i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Find min/max
      mYMin = mProcessed[0];
      mYMax = mProcessed[0];
      for (i = 1; i < half; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];

      mYStep = 1;

      mProcessedSize = half;
      break;

   case 3:                     // Enhanced Autocorrelation
      for (i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Peak Pruning as described by Tolonen and Karjalainen, 2000

      // Clip at zero, copy to temp array
      for (i = 0; i < half; i++) {
         if (mProcessed[i] < 0.0)
            mProcessed[i] = float(0.0);
         out[i] = mProcessed[i];
      }

      // Subtract a time-doubled signal (linearly interp.) from the original
      // (clipped) signal
      for (i = 0; i < half; i++)
         if ((i % 2) == 0)
            mProcessed[i] -= out[i / 2];
         else
            mProcessed[i] -= ((out[i / 2] + out[i / 2 + 1]) / 2);

      // Clip at zero again
      for (i = 0; i < half; i++)
         if (mProcessed[i] < 0.0)
            mProcessed[i] = float(0.0);

      // Find new min/max
      mYMin = mProcessed[0];
      mYMax = mProcessed[0];
      for (i = 1; i < half; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];

      mYStep = 1;

      mProcessedSize = half;
      break;

   case 4:                     // Cepstrum
      for (i = 0; i < half; i++)
         mProcessed[i] = mProcessed[i] / windows;

      // Find min/max, ignoring first and last few values
      int ignore = 4;
      mYMin = mProcessed[ignore];
      mYMax = mProcessed[ignore];
      for (i = ignore + 1; i < half - ignore; i++)
         if (mProcessed[i] > mYMax)
            mYMax = mProcessed[i];
         else if (mProcessed[i] < mYMin)
            mYMin = mProcessed[i];

      mYStep = 1;

      mProcessedSize = half;
      break;
   }

   delete[]in;
   delete[]in2;
   delete[]out;
   delete[]out2;
   delete[]win;

   wxLogMessage(wxT("About to draw plot in FreqWindow::Recalc()"));
   DrawPlot();
   mFreqPlot->Refresh(true);
   delete mProgress;
}
Beispiel #16
0
void EffectNoiseRemoval::RemoveNoise(sampleCount len, float *buffer)
{
   float *inr = new float[len];
   float *ini = new float[len];
   float *outr = new float[len];
   float *outi = new float[len];
   float *power = new float[len];
   float *plog = new float[len];
   
   int i;
   
   for(i=0; i<len; i++)
      inr[i] = buffer[i];

   // Apply window and FFT
   /* WindowFunc(3, len, inr); // Hanning window */
   FFT(len, false, inr, NULL, outr, outi);

   for(i=0; i<len; i++)
      inr[i] = buffer[i];
   WindowFunc(3, len, inr); // Hanning window
   PowerSpectrum(len, inr, power);

   for(i=0; i<=len/2; i++)
      plog[i] = log(power[i]);
    
   int half = len/2;
   for(i=0; i<=half; i++) {
      float smooth;
      
//Factor of 4 here replaces previous 2, giving a 
//finer gradation of noise removal choice.      
      if (plog[i] < mNoiseGate[i] + (mLevel / 4.0))
         smooth = float(0.0);
      else
         smooth = float(1.0);
      
      smoothing[i] = smooth * 0.5 + smoothing[i] * 0.5;
   }

   /* try to eliminate tinkle bells */
   for(i=2; i<=half-2; i++) {
      if (smoothing[i]>=0.5 &&
          smoothing[i]<=0.55 &&
          smoothing[i-1]<0.1 &&
          smoothing[i-2]<0.1 &&
          smoothing[i+1]<0.1 &&
          smoothing[i+2]<0.1)
          smoothing[i] = float(0.0);
   }

   outr[0] *= smoothing[0];
   outi[0] *= smoothing[0];
   outr[half] *= smoothing[half];
   outi[half] *= smoothing[half];
   for(i=1; i<half; i++) {
      int j = len - i;
      float smooth = smoothing[i];

      outr[i] *= smooth;
      outi[i] *= smooth;
      outr[j] *= smooth;
      outi[j] *= smooth;
   }

   // Inverse FFT and normalization
   FFT(len, true, outr, outi, inr, ini);
   WindowFunc(3, len, inr); // Hanning window */
   
   for(i=0; i<len; i++)
      buffer[i] = inr[i];

   delete[] inr;
   delete[] ini;
   delete[] outr;
   delete[] outi;
   delete[] power;
   delete[] plog;
}
Beispiel #17
0
bool ComputeSpectrum(const float * data, int width,
                     int windowSize,
                     double WXUNUSED(rate), float *output,
                     bool autocorrelation, int windowFunc)
{
   if (width < windowSize)
      return false;

   if (!data || !output)
      return true;

   float *processed = new float[windowSize];

   int i;
   for (i = 0; i < windowSize; i++)
      processed[i] = float(0.0);
   int half = windowSize / 2;

   float *in = new float[windowSize];
   float *out = new float[windowSize];
   float *out2 = new float[windowSize];

   int start = 0;
   int windows = 0;
   while (start + windowSize <= width) {
      for (i = 0; i < windowSize; i++)
         in[i] = data[start + i];

      WindowFunc(windowFunc, windowSize, in);

      if (autocorrelation) {
         // Take FFT
         RealFFT(windowSize, in, out, out2);
         // Compute power
         for (i = 0; i < windowSize; i++)
            in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);

         // Tolonen and Karjalainen recommend taking the cube root
         // of the power, instead of the square root

         for (i = 0; i < windowSize; i++)
            in[i] = powf(in[i], 1.0f / 3.0f);

         // Take FFT
         RealFFT(windowSize, in, out, out2);
      }
      else
         PowerSpectrum(windowSize, in, out);

      // Take real part of result
      for (i = 0; i < half; i++)
        processed[i] += out[i];

      start += half;
      windows++;
   }

   if (autocorrelation) {

      // Peak Pruning as described by Tolonen and Karjalainen, 2000
      /*
       Combine most of the calculations in a single for loop.
       It should be safe, as indexes refer only to current and previous elements,
       that have already been clipped, etc...
      */
      for (i = 0; i < half; i++) {
        // Clip at zero, copy to temp array
        if (processed[i] < 0.0)
            processed[i] = float(0.0);
        out[i] = processed[i];
        // Subtract a time-doubled signal (linearly interp.) from the original
        // (clipped) signal
        if ((i % 2) == 0)
           processed[i] -= out[i / 2];
        else
           processed[i] -= ((out[i / 2] + out[i / 2 + 1]) / 2);

        // Clip at zero again
        if (processed[i] < 0.0)
            processed[i] = float(0.0);
      }

      // Reverse and scale
      for (i = 0; i < half; i++)
         in[i] = processed[i] / (windowSize / 4);
      for (i = 0; i < half; i++)
         processed[half - 1 - i] = in[i];
   } else {
      // Convert to decibels
      // But do it safely; -Inf is nobody's friend
      for (i = 0; i < half; i++){
         float temp=(processed[i] / windowSize / windows);
         if (temp > 0.0)
            processed[i] = 10*log10(temp);
         else
            processed[i] = 0;
      }
   }

   for(i=0;i<half;i++)
      output[i] = processed[i];
   delete[]in;
   delete[]out;
   delete[]out2;
   delete[]processed;

   return true;
}