I a recent topic, it has been told that zero-padding in the STFT can improve it, and avoid some circular convolution related things.

Here is my Python code for STFT :

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


How can I do the zero padding with this code ? Which array should I enlarge ?

PS : in order to simplify the code, I haven't normalized the window, so for perfect reconstruction, one has to add a multiplying constant, etc. (it's not important here)

• What "recent topic"? What "circular convolution related things"? What are you trying to accomplish? Windowing already fixes the circular effects of the FFT. – endolith Dec 4 '13 at 17:36
• This topic dsp.stackexchange.com/questions/12979/filtering-with-stft @endolith – Basj Dec 4 '13 at 20:03
• Oh, I see. You are trying to filter in the frequency domain by multiplying each chunk by a filter's frequency response. While it's possible to do this correctly, I would suggest just doing the high-pass filter in the time domain as a separate step from your noise reduction. – endolith Dec 4 '13 at 20:35
• Yes it may be a better idea to the hipass filtering in the time domain as a separate step. BUT when my noise reduction algorithm (based on spectrum subtraction) "masks" some coefficients , it DOES zero some bins... that's why I found it interesting to analyze what is the effect of zeroing bins in STFT – Basj Dec 4 '13 at 20:53
• @robertbristow-johnson: Hey, rbj is finally on here! Welcome! :) I'm not sure what you're saying is wrong, but I'm happy to be corrected. I was talking about windowing to fix the edge effects of FFTs while plotting STFTs. I didn't realize Basj was talking about FFT filtering. – endolith Feb 2 '14 at 15:41

For linear time invariant filtering, the best methods are overlap add (e.g. http://en.wikipedia.org/wiki/Overlap%E2%80%93add_method) or overlap save. If latency is an issue that can be improved with "block convolvers" or "segmented overlap add" (e.g. http://www.cs.ust.hk/mjg_lib/bibs/DPSu/DPSu.Files/Ga95.PDF)

If the processing is time variant, things get a lot more complicated and the right choice of FFT length, analysis window, step size & synthesis window really depends on the specific of the application.

If you don't want to do any processing but just data analysis, the only thing that zero padding does is interpolation in the frequency domain. You get graphs with higher resolution but not more information.

• thanks for these informations, but the question was more about how should I do zero padding in my code ? Should I replace fft(w * x[i:i+fftsize]) with something involving a larger window ? (If so, it won't be zero padding, but it will just be "larger FFT size"....) So how should I zero pad ? – Basj Dec 4 '13 at 17:23

If you have a signal over the segment $[0:L-1]$ and a filter bank with noticeable values over the segment $[-F:F]$, then the filtered signal will have important values over the segment $[-F:L+F-1]$.

So the FFT needs to be carried out with length $L+2F$ to avoid aliasing of important coefficients, and to avoid the wrap-around the signal needs to be padded by a block of $F$ zeros before and after, so that $[0:F-1]$ is zero, $[F:L+F-1]$ contains the original signal and $[L+F:L+2F-1]$ again contains zeros.

But remember that the time index corresponding to the start of the given signal is now at position $F$ in the filtered signal. If you use overlap-add with block size of $B$ and overlap $D$, then $L=B+D=D+(B-D)+D$, so in the end everything needs to be arranged such that $B+D+2F$ is a power of $2$.