【问题标题】:FFT Spectrum not displaying correctlyFFT 频谱未正确显示
【发布时间】:2017-04-15 01:58:22
【问题描述】:

我目前正在尝试使用 FFTW3 和 SFML 显示音频频谱。我已经按照here 的说明进行操作,并查看了有关 FFT 和频谱以及 FFTW 的大量参考资料,但不知何故,我的条形图几乎都与左对齐,如下所示。我遇到的另一个问题是我找不到有关 FFT 输出规模的信息。目前我将其除以 64,但偶尔仍会超出此范围。此外,我还没有找到关于为什么来自 FFTW 的输出必须与输入大小相同的信息。所以我的问题是:

  1. 为什么与下图不同,我的大部分光谱都向左对齐?
  2. 为什么输出不在 0.0 和 1.0 之间?
  3. 为什么输入样本计数与 fft 输出计数相关?

我得到了什么:

我在寻找什么:

const int bufferSize = 256 * 8;

void init() {
    sampleCount = (int)buffer.getSampleCount();
    channelCount = (int)buffer.getChannelCount();
    for (int i = 0; i < bufferSize; i++) {
        window.push_back(0.54f - 0.46f * cos(2.0f * GMath::PI * (float)i / (float)bufferSize));
    }
    plan = fftwf_plan_dft_1d(bufferSize, signal, results, FFTW_FORWARD, FFTW_ESTIMATE);
}
void update() {
    int mark = (int)(sound.getPlayingOffset().asSeconds() * sampleRate);
    for (int i = 0; i < bufferSize; i++) {
        float s = 0.0f;

        if (i + mark < sampleCount) {
            s = (float)buffer.getSamples()[(i + mark) * channelCount] / (float)SHRT_MAX * window[i];
        }

        signal[i][0] = s;
        signal[i][1] = 0.0f;
    }
}
void draw() {
    int inc = bufferSize / 2 / size.x;
    int y = size.y - 1;
    int max = size.y;
    for (int i = 0; i < size.x; i ++) {
        float total = 0.0f;
        for (int j = 0; j < inc; j++) {
            int index = i * inc + j;
            total += std::sqrt(results[index][0] * results[index][0] + results[index][1] * results[index][1]);
        }
        total /= (float)(inc * 64);
        Rectangle2I rect = Rectangle2I(i, y, 1, -(int)(total * max)).absRect();
        g->setPixel(rect, Pixel(254, toColor(BLACK, GREEN)));
    }
}

【问题讨论】:

    标签: c++ audio fft spectrum


    【解决方案1】:

    您的所有问题都与 FFT 理论有关。从任何标准教科书/参考书上研究 FFT 的特性,您将只能自己回答所有问题。

    您至少可以从这里开始: https://en.wikipedia.org/wiki/Fast_Fourier_transform

    【讨论】:

    • 我浏览了 FFT、DFT 和 Spectral Density Estimation wiki 页面,但无法找到任何问题的答案,因为大部分信息超出了我的理解范围。
    • @trigger_death:那你应该把问题发到dsp.stackexchange.com
    【解决方案2】:
    1. 许多 FFT 实现都是节能的。这意味着输出的规模与输入的规模和/或大小呈线性关系。

    2. FFT 是 DFT 是方阵变换。因此,除非某些输出被丢弃,否则输出的数量将始终等于输入的数量(或通过忽略给定严格实输入的冗余复共轭的一半)。如果不是,则不是 FFT。如果您想要更少的输出,可以通过其他方式对 FFT 输出进行下采样或对其进行后处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-26
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-16
      • 2010-11-21
      相关资源
      最近更新 更多