2010-06-01 3 views
4

iPhone SDK의 경우 aurioTouch sample application입니다. "FFT"옵션을 선택하면 기본 spectrum analyzer이 구현됩니다. 앱에 부족한 요소 중 하나는 X 축 라벨 (예 : 빈도 라벨)입니다. aurioTouchAppDelegate.mm 파일에서aurioTouch 샘플 응용 프로그램에서 x 축에 해당하는 주파수 결정

는, 라인 (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의 각 빈도 내 질문은 각 주파수 (또는 y 값)가 for 루프 내에서 어떤 빈도를 나타내는지를 어떻게 결정할 수 있는지입니다. 나는 크기가 6kHz를 위해 무엇인지 알고 싶다면

예를 들어, 나는 다음과 같은 라인을 추가 생각 해요 :

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

주의 사항을 그들이 변수를 사용하기로 결정하지만, 이름 y, 내가 이해 한 바로는 실제로 스펙트럼 분석기의 시각적 그래프에서 x 축을 나타내고 drawBuffers[0][y]의 값은 y 축을 나타냅니다.

답변

6

나는 yFract이 전체 fftLength의 일부분 마지막 빈이기 때문에

yFract * hwSampleRate * .5 

로가 주어진다 사용하여 각 빈의 주파수가 난 당신이 0.5이 필요하다는 것을 확신한다 믿습니다 의 FFT는 샘플링 속도의 절반에 해당합니다. 따라서 당신은 다음과 같은 것을 할 수 있습니다

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

바라건대 올바른 방향으로 당신을 가리키는 데 도움이되기를 바랍니다.

관련 문제