FFT频谱无法正确显示

时间:2017-04-15 01:58:22

标签: c++ audio fft spectrum

我目前正在尝试使用FFTW3和SFML显示音频频谱。我按照here找到的指示,查看了有关FFT和频谱以及FFTW的大量参考资料,但我的条形图几乎全部与左边对齐,如下所示。我遇到的另一个问题是我无法找到有关FFT输出范围的信息。目前我将它除以64,但它仍然偶尔超过它。而且我还没有找到关于为什么来自FFTW的输出必须与输入大小相同的信息。所以我的问题是:

  1. 为什么我的大部分光谱与左边的图像不同?
  2. 为什么输出介于0.0和1.0之间?
  3. 为什么输入样本计数与fft输出计数有关?
  4. 我得到了什么:

    enter image description here

    我在寻找:

    enter image description here

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

2 个答案:

答案 0 :(得分:0)

您的所有问题都与FFT理论有关。从任何标准文本/参考书中研究FFT的属性,您只能自己回答问题。

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

答案 1 :(得分:0)

  1. 许多FFT实现都是能量保留。这意味着输出的比例与输入的比例和/或大小线性相关。

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