导致频谱不等放大的FFT窗口

问题描述:

我正在使用FFTW在C++中创建频谱分析仪。导致频谱不等放大的FFT窗口

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

Retangular窗口

image

EXACT-布莱克曼

image

图形与44100赫兹的采样频率对数缩放。所有谐波都在同一电平上产生,峰值为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之前将其应用于输入矢量。

+0

斑点!就是这样!非常感谢! – Krunklehorn

我无法重现代码,因为我手边没有图书馆。但是,这可能是频谱泄漏的结果。 https://en.wikipedia.org/wiki/Spectral_leakage

这是窗函数以及采样的不可避免性。如果你看一下这篇文章的权衡部分,窗口的类型可以适应各种各样的频率,或者专注于特定的频率。由于信号的频率正在增加,可能目标外的低频信号更容易受到频谱泄漏。