# Apply windowing before FFT or after?

I am computing a spectrogram and I've found a code example online which goes like this:

for jj = 1:size(signal_framewise,2)
current_frame = signal_framewise(:,jj);
dtf = fft(current_frame).*gausswin(window_length_s);
%nfft is half of the fft results (since the fft is symetric)
out_buffer(:,jj) = dtf(1:nfft);
end


But I intuitively did it like this:

for jj = 1:size(signal_framewise,2)
current_frame = signal_framewise(:,jj).*gausswin(window_length_s);
dtf = fft(current_frame);
out_buffer(:,jj) = dtf(1:nfft);
end


The difference is, that the guy online applies the window to the finished FFT and I apply it to the signal frame. Question is: What's the right way to do and does it make a difference? I've attached the outputs of the spectrogram and the full code.

[![%% my implementation][1]][1]

clc; clear all; close all;
Fs = 44100;
t_max = 3;
T = 1/Fs;

time = 0:T:(t_max-T);
input = chirp(time,1500,1,8000);

window_length_t = 0.01; %10ms window length
window_length_s = round(0.01 * Fs); %window length in samples
if mod(window_length_s,2) == 0
window_length_s = window_length_s + 1; %make sure we have odd window size
end

%activate the following for a no overlap implementation
%signal_framewise = buffer(input , window_length_s);
signal_framewise = buffer(input , window_length_s , floor(window_length_s/2));
nfft =((window_length_s-1)/2)+1;

out_buffer = zeros(nfft,size(signal_framewise,2));
for jj = 1:size(signal_framewise,2)
current_frame = signal_framewise(:,jj).*gausswin(window_length_s);
dtf = fft(current_frame);
out_buffer(:,jj) = dtf(1:nfft);
end

F = linspace(0,Fs/2,nfft);
T = linspace(0,3,size(signal_framewise,2));
surf(T,F,20*log10(abs(out_buffer)), 'EdgeColor', 'none');
axis xy;
axis tight; colormap(jet); view(0, 90);
xlabel('Time');
colorbar;
ylabel('Frequency(Hz)');
set(gca, 'YTickLabel', num2cell(get(gca, 'YTick')));


• I'm not familiar with Matlab so I can't be sure but is it possible that the * operator denotes convolution (when applied in the frequency domain), rather than multiplication? Apr 25, 2018 at 12:48
• No, ".*" means element-wise multiplication. Convolution is "conv(...)". Element-wise meaning, the first element of the first vector gets multiplied with the first element of the second vector, then the second element of the first vector gets multiplied with the second element of the second vector and so forth
– Alon
Apr 25, 2018 at 12:54
• Well, multiplication in the frequency domain corresponds to convolution in the time-domain so perhaps that other guy wanted to do something else (frequency domain filtering is similar to this although he doesn't seem to be using a filter at all, unless we assume the gauss window to be that filter. Anyway, as far as I can tell, the two code snippets are not equivalent. Apr 25, 2018 at 13:17

Element-wise multiplication in the spatial/temporal domain with a windowing function serves to reduce the effect of the potentially large jump you get at the signal edge, when making the sampled signal periodic. This jump would otherwise introduce lots of frequencies that might not be present in the signal.

Element-wise multiplication in the frequency domain with a windowing function applies a low-pass filter. Multiplying by a Gaussian window is equivalent to applying a Gaussian filter in the spatial/temporal domain.

If the code you found online were to compute the inverse transform after applying the window, then whoever wrote it would be low-pass filtering. With the code as you posted, I tend to think that person doesn't know what they're doing (or maybe it's just a typo).

• de.mathworks.com/matlabcentral/answers/… have a look! It's a very short entry
– Alon
Apr 26, 2018 at 8:34
• @JoschKraus it looks like a misplaced parenthesis to me. Apr 26, 2018 at 12:55
• I cant see where there is supposed to be a misplaced parenthesis?
– Alon
Apr 27, 2018 at 12:14
• I imagine it could have looked like this: dtf = fft(current_frame.*gausswin(window_length_s));. This just moves the closing parenthesis for fft to the end of the statement. Apr 27, 2018 at 13:19
• Now I understand, thx
– Alon
May 2, 2018 at 9:02