Auriotouch,从频率 FFT 获取音符

发布于 2024-10-22 12:51:42 字数 939 浏览 2 评论 0原文

我正在开发一种吉他调音器。

我有一个函数可以提供 FFT 以及每个频率的 FFT 值。

我如何从那里获取音符?我必须选择最高峰吗?

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

如果您能提供帮助,非常感谢

朱利安.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

归属感 2024-10-29 12:51:42

这是一个不平凡的问题,原因如下:

  • 峰值可能与基波谐波不对应(甚至可能缺失)。
  • 基波谐波可能不会精确落在 FFT 箱的中心,因此其能量将分布在多个箱中。您需要进行插值来估计实际频率。
  • 除非您执行某种加窗操作,否则您将获得“光谱泄漏”效应,这会将您的光谱弄得到处都是,从而难以辨别细节。

我明白这并不能真正回答你的问题,但它应该强调这样一个事实:这实际上是一件很难做好的事情。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文