2010-06-01 55 views
4

我正在查看iPhone SDK的aurioTouch sample application。當你選擇「FFT」選項時,它實現了一個基本的spectrum analyzer。該應用缺乏的一件事是X軸標籤(即頻率標籤)。確定aurioTouch示例應用程序中x軸對應的頻率

aurioTouchAppDelegate.mm文件,在線路652的功能- (void)drawOscilloscope,它具有以下代碼:

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(); 

    } 

} 

從我的理解中,這部分代碼是什麼來決定繪製其幅度UI中的每個頻率。我的問題是如何確定for循環內每次迭代的頻率(或y值)。

例如,如果我想知道的大小什麼6kHz的,我想加入類似下面的一行:

if (yValueRepresentskHz(y, 6)) 
    NSLog(@"The magnitude for 6kHz is %f", (interpVal * 120)); 

請注意,儘管他們選擇使用變量名稱y,據我所知,它實際上代表頻譜分析儀的視覺圖中的x軸,而drawBuffers[0][y]的值代表y軸。

回答

6

我相信,它使用被賦予每個容器由

yFract * hwSampleRate * .5 

頻率我相當肯定,你需要.5因爲yFract是總fftLength的一小部分,最後斌的FFT對應於採樣率的一半。因此,你可以做類似

NSLog(@"The magnitude for %f Hz is %f.", (yFract * hwSampleRate * .5), (interpVal * 120)); 

希望這有助於指出你在正確的方向至少。