c++ - FFT 窗口导致频谱放大不均

标签 c++ window fft fftw spectrum

我正在使用 FFTW 在 C++ 中创建频谱分析仪。

在对输入信号应用任何窗函数后,输出幅度突然似乎与频率成比例。

矩形窗口

image

精确布莱克曼

image

图表以对数方式缩放,采样频率为 44100 Hz。所有谐波都在相同的水平上产生,如在矩形情况下看到的那样在 0dB 处达到峰值。 Exact-Blackman 窗口被放大 7.35dB 以尝试补偿处理增益。

这是我生成输入表的代码...

freq = 1378.125f;

for (int i = 0; i < FFT_LOGICAL_SIZE; i++)
{
    float term = 2 * PI * i / FFT_ORDER;

    for (int h = 1; freq * h < FREQ_NYQST; h+=1) // Harmonics up to Nyquist
    {
        fftInput[i] += sinf(freq * h * K_PI * i / K_SAMPLE_RATE); // Generate sine
        fftInput[i] *= (7938 / 18608.f) - ((9240 / 18608.f) * cosf(term)) + ((1430 / 18608.f) * cosf(term * 2)); // Exact-Blackman window
    }
}

fftwf_execute(fftwR2CPlan);

增加或减少窗口大小没有任何改变。我也用汉明窗测试过,同样的问题。

这是我获取输出的代码。

float val; // Used elsewhere
for (int i = 1; i < K_FFT_COMPLEX_BINS_NOLAST; i++) // Skips the DC and Nyquist bins
{
    real = fftOutput[i][0];
    complex = fftOutput[i][1];

    // Grabs the values and scales based on the window size
    val = sqrtf(real * real + complex * complex) / FFT_LOGICAL_SIZE_OVER_2;
    val *= powf(20, 7.35f / 20); // Only applied during Exact-Blackman test
}

奇怪的是,我尝试了以下尝试来平息 Exact-Blackman 案例中的响应。这种按比例缩小导致几乎但仍不完全平坦的响应。很好,但仍然没有向我解释为什么会这样。

float x = (float)(FFT_COMPLEX_BINS - i) / FFT_COMPLEX_BINS; // Linear from 0 to 1
x = log10f((x * 9) + 1.3591409f); // Now logarithmic from 0 to 1, offset by half of Euler's constant
val = sqrt(real * real + complex * complex) / (FFT_LOGICAL_SIZE_OVER_2 / x); // Division by x added to this line

最佳答案

可能是一个错误。您似乎在每个样本中多次应用窗口函数。任何窗口都应从输入合成循环中移除,并仅在 FFT 之前应用于输入 vector 一次。

关于c++ - FFT 窗口导致频谱放大不均,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45526124/

相关文章:

c++ - 将模板类型与常量数值进行比较

c++ - 限制连接 BSTR 的参数类型

c++ - Qt C++ GUI QSpinBox 存储输入?

C++ 迭代器难题

c++ - 使用FFTW将(2d)IDFT转换为DFT时,为什么频域数据为 “mirrored”?

java - Java 中的 "Math.random()"问题

c++ - ChangeDisplaySettings(NULL, 0) 移动/调整我的窗口

azure - 无法通过window azure VM使用公共(public)IP访问SSRS

python - OpenCV/Python:彩条的数量级

math - 在 C 中从笛卡尔到极坐标更快的方法?