Algorithm 正频率)。如果DFT长度为32,则空值将在每个箱子处对齐,提示出现无泄漏。但这种误导性的外观只是DFT长度的函数。如果用零填充加窗信号(如上所述),您将看到在零位之间的频率处的类似sinc的响应

Algorithm 正频率)。如果DFT长度为32,则空值将在每个箱子处对齐,提示出现无泄漏。但这种误导性的外观只是DFT长度的函数。如果用零填充加窗信号(如上所述),您将看到在零位之间的频率处的类似sinc的响应,algorithm,signal-processing,fft,Algorithm,Signal Processing,Fft,现在让我们看一个窗口长度不是正弦周期整数倍的情况,例如角频率为7.5π/16的余弦(周期为64个采样): 中心箱位置不再是32的整数倍,而是向下移动了一半至箱240。让我们看看相应的32点DFT是什么样子(推断出一个32点矩形窗口)。我将计算并绘制x2[n]的32点DFT,并叠加1024点DFT的32倍抽取副本: X2_32 = rfft(x2, 32) X2_sample = X2[::32] stem(r_[:17],abs(X2_32)) plot(abs(X2_sample), 'rs

现在让我们看一个窗口长度不是正弦周期整数倍的情况,例如角频率为7.5π/16的余弦(周期为64个采样):

中心箱位置不再是32的整数倍,而是向下移动了一半至箱240。让我们看看相应的32点DFT是什么样子(推断出一个32点矩形窗口)。我将计算并绘制x2[n]的32点DFT,并叠加1024点DFT的32倍抽取副本:

X2_32 = rfft(x2, 32)
X2_sample = X2[::32]
stem(r_[:17],abs(X2_32))
plot(abs(X2_sample), 'rs')    # red squares
grid(); axis([0,16,0,11])

正如您在上一个图中所看到的,空值不再以32的倍数对齐,因此32点DFT的大小在每个箱子上都不是零。在32点DFT中,窗口的空值仍然是每隔N/M=32/32=1个bin隔开的,但由于ω0=7.5π/16,中心位于“bin”7.5,这使得空值位于0.5、1.5等,因此它们不存在于32点DFT中

一般信息是,加窗信号的频谱泄漏始终存在,但如果信号规格、窗口长度和DFT长度以正确的方式排列为零,则可以在DFT中屏蔽。除此之外,您应该忽略这些DFT伪影,专注于信号的DTFT(即,用零填充以更高分辨率对DTFT进行采样,以便可以清楚地检查泄漏)

由于与窗口的光谱进行卷积而导致的光谱泄漏将始终存在,这就是为什么制作特殊形状窗口的艺术如此重要的原因。每种窗口类型的频谱都是针对特定任务定制的,例如动态范围或灵敏度

下面是一个比较矩形窗口和汉明窗口输出的示例:

from pylab import *
import wave

fs = 44100
M = 4096
N = 16384
# load a sample of guitar playing an open string 6
# with a fundamental frequency of 82.4 Hz
g = fromstring(wave.open('dist_gtr_6.wav').readframes(-1),
               dtype='int16')
L = len(g)/4
g_t = g[L:L+M]
g_t = g_t / float64(max(abs(g_t)))
# compute the response with rectangular vs Hamming window
g_rect = rfft(g_t, N)
g_hamm = rfft(g_t * hamming(M), N)

def make_plot():
    fmax = int(82.4 * 4.5 / fs * N)  # 4 harmonics
    subplot(211); title('Rectangular Window')
    plot(abs(g_rect[:fmax])); grid(); axis('tight')
    subplot(212); title('Hamming Window')
    plot(abs(g_hamm[:fmax])); grid(); axis('tight')

if __name__ == "__main__":
    make_plot()

啊,我明白了。因此,基本上,加窗函数只是“修改”或改进样本中的数据,以改进FFT算法的结果。我说得对吗?谢谢@user488792:是的,差不多就是这样-窗口函数平滑了采样窗口边缘的瞬变。是的,我明白了。非常感谢您的澄清和提供了一个很好的答案@埃里克森:?再读一遍我的答案。FFT一次又一次地重复采样帧。对于非整数数量的样本,你会得到一个跳跃不连续性,这意味着它不是一个纯正弦波,因此一定有谐波。为什么周期积分的正弦波会有泄漏?这是一个更长的FFT,它产生更高的频率分辨率,而不仅仅是对相同长度的FFT进行零填充,这不会改变分辨率,而是会改变“平滑度”。FFT的长度和零填充量是两个不同的参数,或“旋钮”,您可以单独使用。这是什么程序?(看起来像python,但它在什么环境中?)我一直在寻找MATLAB的替代品。
x2 = cos(2*pi*15*r_[:32]/64)    # ω0 = 7.5π/16, bin 15/64 * 1024 = 240
X2 = rfft(x2 * w, 1024)
plot(abs(X2))
xticks(r_[-16:513:64])
grid(); axis('tight')
X2_32 = rfft(x2, 32)
X2_sample = X2[::32]
stem(r_[:17],abs(X2_32))
plot(abs(X2_sample), 'rs')    # red squares
grid(); axis([0,16,0,11])
from pylab import *
import wave

fs = 44100
M = 4096
N = 16384
# load a sample of guitar playing an open string 6
# with a fundamental frequency of 82.4 Hz
g = fromstring(wave.open('dist_gtr_6.wav').readframes(-1),
               dtype='int16')
L = len(g)/4
g_t = g[L:L+M]
g_t = g_t / float64(max(abs(g_t)))
# compute the response with rectangular vs Hamming window
g_rect = rfft(g_t, N)
g_hamm = rfft(g_t * hamming(M), N)

def make_plot():
    fmax = int(82.4 * 4.5 / fs * N)  # 4 harmonics
    subplot(211); title('Rectangular Window')
    plot(abs(g_rect[:fmax])); grid(); axis('tight')
    subplot(212); title('Hamming Window')
    plot(abs(g_hamm[:fmax])); grid(); axis('tight')

if __name__ == "__main__":
    make_plot()