开发者

Auriotouch, get musical note from frequency FFT

I'm developing a kind of guitar tuner.

I have a function that gives me the FFT, and the values of the FFt for each frequency.

How do I get the musical note from there? Do I have to chose the highest peak?

 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);
    //NSLog(@"The magnitude for %f Hz is %f.", (yFract * hwSampleRate * .5), (interpVal * 120));

}

Thanks a lot if you can help.

Julien.


This is a non-trivial problem, for several reasons:

  • The peak may not correspond to the fundamental harmonic (it may even be missing).
  • The fundamental harmonic will probably not land precisely on the centre of an FFT bin, so its energy will be spread across multiple bins. You would need to do interpolation to estimate the actual frequency.
  • Unless you perform some kind of windowing, you will get "spectral leakage" effects, which will smear your spectrum all over the place, making it hard to discern details.

I appreciate that this doesn't really answer your question, but it should highlight the fact that this is actually a pretty tricky thing to do well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜