I'm looking to perform an FFT on a linear PCM audio file (with potentially more than one audio channel) on OS X. What is the best way to go about this?
Several sources have indicated that Apple's Accelerate Framework is what I need. If so, how should I extract and properly prepare the floating point data for use in those FFT functions?
Here's roughly what you want to do. Fill in your own input and output functions.
// Stick new data into inData, a (float*) array
fetchFreshData(inData);
// (You might want to window the signal here... )
doSomeWindowing(inData);
// Convert the data into a DSPSplitComplex
// Pardon the C++ here. Also, you should pre-allocate this, and NOT
// make a fresh one each time you do an FFT.
mComplexData = new DSPSplitComplex;
float *realpart = (float *)calloc(mNumFrequencies, sizeof(float));
float *imagpart = (float *)calloc(mNumFrequencies, sizeof(float));
mComplexData->realp = realpart;
mComplexData->imagp = imagpart;
vDSP_ctoz((DSPComplex *)inData, 2, mComplexData, 1, mNumFrequencies);
// Calculate the FFT
// ( I'm assuming here you've already called vDSP_create_fftsetup() )
vDSP_fft_zrip(mFFTSetup, mComplexData, 1, log2f(mNumFrequencies), FFT_FORWARD);
// Don't need that frequency
mComplexData->imagp[0] = 0.0;
// Scale the data
float scale = (float) 1.0 / (2 * (float)mSignalLength);
vDSP_vsmul(mComplexData->realp, 1, &scale, mComplexData->realp, 1, mNumFrequencies);
vDSP_vsmul(mComplexData->imagp, 1, &scale, mComplexData->imagp, 1, mNumFrequencies);
// Convert the complex data into something usable
// spectrumData is also a (float*) of size mNumFrequencies
vDSP_zvabs(mComplexData, 1, spectrumData, 1, mNumFrequencies);
// All done!
doSomethingWithYourSpectrumData(spectrumData);
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With