void FFTEngine::findMagnitues (float* magBuf, bool onlyIfBigger)
{
    const SplitComplex& fftSplit = fft.getFFTBuffer();
    const float oneOverFFTSize = (float) getFFTProperties().oneOverFFTSize;
    const int fftSizeHalved = getFFTProperties().fftSizeHalved;
    const float oneOverWindowFactor = window.getOneOverWindowFactor();
    
    // Find magnitudes
    {
        const float newMag = FFT::magnitude (fftSplit.realp[0], 0.0f, oneOverFFTSize, oneOverWindowFactor); // imag for DC is always zero
        
        if (! onlyIfBigger || (newMag > magBuf[0]))
            magBuf[0] = newMag;
    }
    
    for (int i = 1; i < fftSizeHalved; ++i)
    {
        const float newMag = FFT::magnitude (fftSplit.realp[i], fftSplit.imagp[i], oneOverFFTSize, oneOverWindowFactor);
        
        if (! onlyIfBigger || (newMag > magBuf[i]))
            magBuf[i] = newMag;
    }

    {
        const float newMag = FFT::magnitude (fftSplit.realp[0], 0.0f, oneOverFFTSize, oneOverWindowFactor); // imag for Nyquist is always zero

        if (! onlyIfBigger || (newMag > magBuf[fftSizeHalved]))
            magBuf[fftSizeHalved] = newMag;
    }
    
    magnitutes.updateListeners();
}
void FFTEngine::updateMagnitudesIfBigger()
{
	// local copies for speed
	const SplitComplex &fftSplit = fftOperation.getFFTBuffer();
	float* magBuf = magnitutes.getData();
	const float oneOverFFTSize = (float) getFFTProperties().oneOverFFTSize;
	const int fftSizeHalved = getFFTProperties().fftSizeHalved;
	const float oneOverWindowFactor = windowProperties.getOneOverWindowFactor();
	
	// find magnitudes
	float newMag = magnitude (fftSplit.realp[0], 0.0f, oneOverFFTSize, oneOverWindowFactor); // imag for DC is always zero 
	if (newMag > magBuf[0])
		magBuf[0] = newMag;
    
	for (int i = 1; i < fftSizeHalved; i++)
	{		
		newMag = magnitude (fftSplit.realp[i], fftSplit.imagp[i], oneOverFFTSize, oneOverWindowFactor);

		if(newMag > magBuf[i])
			magBuf[i] = newMag;
	}

	newMag = magnitude (fftSplit.realp[0], 0.0f, oneOverFFTSize, oneOverWindowFactor); // imag for Nyquist is always zero 
	if (newMag > magBuf[fftSizeHalved])
		magBuf[fftSizeHalved] = newMag;
	
	magnitutes.updateListeners();
}
FFTOperation::FFTOperation (int fftSizeLog2)
    : fftProperties (fftSizeLog2)
{
	fftConfig = new ffft::FFTReal<float> (fftProperties.fftSize);

	fftBuffer.malloc (fftProperties.fftSize);
	fftBufferSplit.realp = fftBuffer.getData();
	fftBufferSplit.imagp = fftBufferSplit.realp + getFFTProperties().fftSizeHalved;	
}
void FFTEngine::findMagnitudes (Buffer* bufferToFill)
{
	// local copies for speed
	float* magBuf = magnitutes.getData();
	if (bufferToFill != nullptr)
		magBuf = bufferToFill->getData();

	const SplitComplex &fftSplit = fftOperation.getFFTBuffer();
	const float oneOverFFTSize = (float) getFFTProperties().oneOverFFTSize;
	const int fftSizeHalved = getFFTProperties().fftSizeHalved;
	const float oneOverWindowFactor = windowProperties.getOneOverWindowFactor();
	
	// find magnitudes
	magBuf[0] = magnitude (fftSplit.realp[0], 0.0f, oneOverFFTSize, oneOverWindowFactor); // imag for DC is always zero 
	for (int i = 1; i < fftSizeHalved; i++)
	{		
		magBuf[i] = magnitude (fftSplit.realp[i], fftSplit.imagp[i], oneOverFFTSize, oneOverWindowFactor);
	}
	magBuf[fftSizeHalved] = magnitude (fftSplit.realp[0], 0.0f, oneOverFFTSize, oneOverWindowFactor); // imag for Nyquist is always zero 
	
	magnitutes.updateListeners();
}
void FFTOperation::setFFTSizeLog2 (int newFFTSizeLog2)
{
	if (newFFTSizeLog2 != fftProperties.fftSizeLog2)
    {
        fftConfig = nullptr;
		
		fftProperties.setFFTSizeLog2 (newFFTSizeLog2);
		fftBuffer.malloc (fftProperties.fftSize);
		fftBufferSplit.realp = fftBuffer.getData();
		fftBufferSplit.imagp = fftBufferSplit.realp + getFFTProperties().fftSizeHalved;	
		
        fftConfig = new ffft::FFTReal<float> (fftProperties.fftSize);
	}
}
void FFTEngine::performFFT (float* samples)
{	
	// first apply the current window
	windowProperties.applyWindow (samples, getFFTProperties().fftSize);
	fftOperation.performFFT (samples);
}
//============================================================================
FFTEngine::FFTEngine (int fftSizeLog2_)
    : fftOperation (fftSizeLog2_),
      windowProperties (getFFTProperties().fftSize),
      magnitutes (getFFTProperties().fftSizeHalved + 1)
{
}