AudioFFT

June 21, 2017 ยท View on GitHub

AudioFFT provides real-to-complex/complex-to-real FFT routines.

Features

  • Real-complex FFT and complex-real inverse FFT for power-of-2-sized real data.

  • Uniform interface to different FFT implementations (currently Ooura, FFTW3, Apple Accelerate and Intel IPP).

  • Complex data is handled in "split-complex" format, i.e. there are separate arrays for the real and imaginary parts which can be useful for SIMD optimizations (split-complex arrays have to be of length (size/2+1) representing bins from DC to Nyquist frequency).

  • Output is "ready to use" (all scaling etc. is already handled internally).

  • No allocations/deallocations after the initialization which makes it usable for real-time audio applications (that's what I wrote it for and using it).

How to use it in your project

  • Add the .h and .cpp file to your project - that's all.

  • To get extra speed, you can link FFTW3 to your project and define AUDIOFFT_FFTW3 (however, please check whether your project suits the according license).

  • To get the best speed on Apple platforms, you can link the Apple Accelerate framework to your project and define AUDIOFFT_APPLE_ACCELERATE.

  • On any supported platform you can use Intel IPP's FFT's by linking to IPP and defining AUDIOFFT_INTEL_IPP.

Remarks

  • AudioFFT is not intended to be the fastest FFT, but to be a fast-enough FFT suitable for most audio applications.

  • AudioFFT uses the quite liberal MIT license.

Example usage

#include "AudioFFT.h"

void Example()
{
  const size_t fftSize = 1024; // Needs to be power of 2!
  
  std::vector<float> input(fftSize, 0.0f);
  std::vector<float> re(fftaudio::AudioFFT::ComplexSize(fftSize)); 
  std::vector<float> im(fftaudio::AudioFFT::ComplexSize(fftSize)); 
  std::vector<float> output(fftSize);
  
  audiofft::AudioFFT fft;
  fft.init(1024);
  fft.fft(input.data(), re.data(), im.data());
  fft.ifft(output.data(), re.data(), im.data());
}

Benchmarks

The following tables show time measurements for forward/backward "FFTing" 512MB of real data using the FFT input size as listed in the tables.

AudioFFT was run using internally Ooura, FFTW3 and vDSP (Apple Accelerate).

For comparison and reference, the same setup also was used with the great KissFFT, which is a quite popular FFT implementation, and which is also able to handle non-power-of-2 sizes. :-)

CPU: Intel Core i5 (2,4 GHz)

  • Mac OS X Lion 10.7.5
  • Compiler: Apple LLVM 3.0 (/Os (fastest, smallest), SSE enabled)
SizeOouraFFTW3AppleKissFFT
648.805s6.914s3.420s12.496s
12810.047s6.473s2.992s11.457s
51211.895s6.473s3.025s13.737s
102412.956s6.932s3.139s17.050s
409614.840s7.517s3.661s19.379s

CPU: Intel Xeon (2.93 GHz)

  • Windows 7
  • Compiler: VC10 (/O2 /arch:SSE2 /fp:precise)
SizeOouraFFTW3KissFFT
647.267s4.625s20.819s
1287.583s5.494s20.822s
5128.608s5.346s24.812s
10249.546s5.604s28.936s
409611.026s6.265s33.160s