# Improve spectrogram appearance using windowing functions MATLAB

I have a program which plots data obtained in a NI USB DAQ realtime to a spectrogram plot using the surf function. I'd like to improve the appearance of the plot using some sort of windowing function. My questions are: Which windowing function is the best to use for this? and How do I implement it? Here's a sample of my current code:

fprintf('Initializing DAQ\n');
s = daq.createSession ('ni');

s.NumberOfScans = Fs*Record_Time;
s.Rate = Fs;
s.Channels.Range = [-1 1];
s.DurationInSeconds = 5;

Spect_nFFT = 2^8;
num_overlap = 19*round(Spect_nFFT/20);
start_sample = 1;

DataRdy = true;
% Run in background session

Lh = s.addlistener('DataAvailable', @(src,event) CaptureData(event.TimeStamps, event.Data));
s.NotifyWhenDataAvailableExceeds = 100000*.1;
s.IsContinuous = true;
s.startBackground();
NFFT = 2^nextpow2(L);
P = zeros(8193,50);
F = Fs/2*linspace(0,1,NFFT/2+1);
g=0;

while g==0

while DataRdy == 0
pause(.01)
end
pause(.5)

Min_Threshold = 10^12;

start_sample = 1;
NFFT = 2^nextpow2(L); % Next power of 2 from length of myRecording
FFT_Out = fft(myRecording(start_sample:end),NFFT)/size(myRecording(start_sample:end),1);
FFT_Out = FFT_Out(1:NFFT/2+1);

A = sqrt(FFT_Out.*conj(FFT_Out));
P = [P(:,2:end), sqrt(FFT_Out.*conj(FFT_Out))];
P(P<=max(max(P))/Min_Threshold)=max(max(P))/Min_Threshold;
surf(1:size(P,2),F,10*log10(P),'edgecolor','none'); axis tight;

% Create updating spectrogram
view(0,90);

xlabel('Time');
ylabel('Hz');

drawnow;

DataRdy = 0;
uicontrol('Style', 'pushbutton', 'String', 'Exit',...
'Position', [20 20 50 20],...
'Callback', 'g=g+1');

end
delete(Lh);
stop(s);


Thanks for any help!

• Do you really need to window your time-domain data? Don't forget, the spectrum you obtain after windowing will not be the true spectrum of your original input signal. Is that really what you want? – Richard Lyons Sep 17 '15 at 11:25

Windowing is nothing more than element-wise multiplication of your signal by window function.

Let's assume that you want to apply Hanning window. In your case signal is stored inside myRecording(start_sample:end).

• Create the window values vector of your signal length: win = hann(length(myRecording(start_sample:end)))
• Multiply by your signal and store it in variable: sig = win.*size(myRecording(start_sample:end).
• Perform the FFT, but keep in mind that now you cannot simply normalize but your signal length (as you do within FFT function), but you should (very simply speaking) divide by sum of your window values: sum(win). Probably you will notice that in case of no window applied = rectangular window, that is also true.

Answering second part of your question, which window to choose? You can start from this great white paper (on figure 8 you have recomendations for different window types): Windowing: Optimizing FFTs Using Window Functions.

Just keep in mind that if you you increase side-lobe attenuation then you also make your main-lobe wider (worse frequency resolution). Hanning is a good start.

Also I've noticed in your code that you are normalizing by the number of samples and then taking only first half of your spectrum. That's perfectly ok, but you must also multiply amplitude by 2 in order to compensate for removing of half of your energy in components above $\frac{f_s}{2}$