I am watching a sample aurioTouch iPhone SDK application . It has a basic spectrum analyzer , implemented when the "FFT" option is selected. One of the drawbacks of the application is the X-axis labels (e.g. frequency labels).
In the aurioTouchAppDelegate.mm file in the - (void)drawOscilloscope on line 652, it has the following code:
if (displayMode == aurioTouchDisplayModeOscilloscopeFFT) { if (fftBufferManager->HasNewAudioData()) { if (fftBufferManager->ComputeFFT(l_fftData)) [self setFFTData:l_fftData length:fftBufferManager->GetNumberFrames() / 2]; else hasNewFFTData = NO; } if (hasNewFFTData) { int y, maxY; maxY = drawBufferLen; for (y=0; y<maxY; y++) { CGFloat yFract = (CGFloat)y / (CGFloat)(maxY - 1); CGFloat fftIdx = yFract * ((CGFloat)fftLength); double fftIdx_i, fftIdx_f; fftIdx_f = modf(fftIdx, &fftIdx_i); SInt8 fft_l, fft_r; CGFloat fft_l_fl, fft_r_fl; CGFloat interpVal; fft_l = (fftData[(int)fftIdx_i] & 0xFF000000) >> 24; fft_r = (fftData[(int)fftIdx_i + 1] & 0xFF000000) >> 24; fft_l_fl = (CGFloat)(fft_l + 80) / 64.; fft_r_fl = (CGFloat)(fft_r + 80) / 64.; interpVal = fft_l_fl * (1. - fftIdx_f) + fft_r_fl * fftIdx_f; interpVal = CLAMP(0., interpVal, 1.); drawBuffers[0][y] = (interpVal * 120); } cycleOscilloscopeLines(); } }
From my point of view, this part of the code is what is used to determine what value should be used for each frequency in the user interface. My question is how to determine what frequency each iteration (or y value) represents inside the for loop.
For example, if I want to know what the value is for 6 kHz, I'm going to add a line similar to the following:
if (yValueRepresentskHz(y, 6)) NSLog(@"The magnitude for 6kHz is %f", (interpVal * 120));
Note that although they decided to use the variable name y , from what I understand, it actually represents the x axis in the visual graph of the spectrum analyzer, and the value drawBuffers[0][y] represents y Oy.
source share