STFT 中的零填充

信息处理 fft 离散信号 信号分析 Python stft
2022-02-10 22:09:09

我最近的一个话题,据说 STFT 中的零填充可以改善它,并避免一些与循环卷积相关的事情。

这是我的 STFT Python 代码:

fftsize = 8192;  overlap = 4;  hop = fftsize / overlap  # ie hop = 2048 here
w = scipy.hamming(fftsize)       # hamming window

# x is the input signal, I assume it is already of length 2^k, ie no zero padding required for x

# STFT
x_stft = scipy.array([scipy.fft(w*x[i:i+fftsize]) for i in range(0, len(x)-fftsize, hop)])

# ISTFT
y = scipy.zeros(len(x))
for n,i in enumerate(range(0, len(x)-fftsize, hop)):
  y[i:i+fftsize] += scipy.real(scipy.ifft(x_stft[n])) * w    # overlap-add

如何使用此代码进行零填充?我应该扩大哪个阵列?

PS:为了简化代码,我没有对窗口进行归一化,所以为了完美重建,必须添加一个乘法常数等(这里不重要)

2个回答

对于线性时不变过滤,最好的方法是重叠添加(例如http://en.wikipedia.org/wiki/Overlap%E2%80%93add_method)或重叠保存。如果延迟是可以通过“块卷积器”或“分段重叠添加”改善的问题(例如http://www.cs.ust.hk/mjg_lib/bibs/DPSu/DPSu.Files/Ga95.PDF

如果处理是时变的,事情会变得复杂得多,FFT 长度、分析窗口、步长和合成窗口的正确选择实际上取决于应用程序的具体情况。

如果您不想进行任何处理而只想进行数据分析,那么零填充所做的唯一事情就是在频域中进行插值。你会得到更高分辨率的图表,但没有更多的信息。

如果您在段上有一个具有显着值的滤波器组,那么滤波后的信号将在段[0:L1][F:F][F:L+F1]

所以需要用长度进行 FFT以避免重要系数的混叠,并且为了避免回绕,需要在信号前后为零,包含原始信号,再次包含零。L+2FF[0:F1][F:L+F1][L+F:L+2F1]

但请记住,对应于给定信号开始的时间索引现在位于滤波信号中的如果您使用块大小为和重叠的重叠相加,则,所以最后一切都需要安排成是 2 的.FBDL=B+D=D+(BD)+DB+D+2F2