iOS FFT Accerelate.framework draw spectrum during playback

fft, frequency, ios, spectrum

Solution

Firstly you're not applying a window function prior to the FFT - this will result in smearing of the spectrum due to spectral leakage.

Secondly, you're just using the real component of the FFT output bins to calculate dB magnitude - you need to use the complex magnitude:

magnitude_dB = 10 * log10(re * re + im * im);

Problem

UPDATE 2016-03-15 Please take a look at this project: https://github.com/ooper-shlab/aurioTouch2.0-Swift. It has been ported to Swift and contains every answer you're looking for, if you cam here. I did a lot of research and learned a lot about FFT and the Accelerate Framework. But after days of experiments I'm kind of frustrated. I want to display the frequency spectrum of an audio file during playback in a diagram. For every time interval it should show the magnitude in db on the Y-axis (displayed by a red bar) for every frequency (in my case 512 values) calculated by a FFT on the X-Axis. The output should look like this: I fill a buffer with 1024 samples extracting only the left channel for the beginning. Then I do all this FFT stuff. Here is my code so far: Setting up some variables ``` - (void)setupVars { maxSamples = 1024; log2n = log2f(maxSamples); n = 1 << log2n; stride = 1; nOver2 = maxSamples/2; A.realp = (float *) malloc(nOver2 * sizeof(float)); A.imagp = (float *) malloc(nOver2 * sizeof(float)); memset(A.imagp, 0, nOver2 * sizeof(float)); obtainedReal = (float *) malloc(n * sizeof(float)); originalReal = (float *) malloc(n * sizeof(float)); setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2); } ``` Doing the FFT. FrequencyArray is just a data structure that holds 512 float values. ``` - (FrequencyArry)performFastFourierTransformForSampleData:(SInt16*)sampleData andSampleRate:(UInt16)sampleRate { NSLog(@"log2n %i n %i, nOver2 %i", log2n, n, nOver2); // n = 1024 // log2n 10 // nOver2 = 512 for (int i = 0; i < n; i++) { originalReal[i] = (float) sampleData[i]; } vDSP_ctoz((COMPLEX *) originalReal, 2, &A, 1, nOver2); vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD); float scale = (float) 1.0 / (2 * n); vDSP_vsmul(A.realp, 1, &scale, A.realp, 1, nOver2); vDSP_vsmul(A.imagp, 1, &scale, A.imagp, 1, nOver2); vDSP_ztoc(&A, 1, (COMPLEX *) obtainedReal, 2, nOver2); FrequencyArry frequencyArray; for (int i = 0; i < nOver2; i++) { frequencyArray.frequency[i] = log10f(obtainedReal[i]); // Magnitude in db??? } return frequencyArray; } ``` The output looks always kind of weird although it some how seems to move according to the music. I'm happy that I came so far thanks to some very good posts here like this: Using the apple FFT and accelerate Framework But now I don't know what to do. What am I missing?

Original source

Related problems