How is Spectrogram function working?

13 visualizaciones (últimos 30 días)
Vibhor Kumar
Vibhor Kumar el 12 de Feb. de 2024
Respondida: Mathieu NOE el 13 de Feb. de 2024
Hello Matlab Community,
I am trying to understand the script of Spectrogram function which takes the short time fourier transform of a signal. IS is doing the same thing as I shown below? We can also divide the x into n segments.
For a x signal.
fftx= fft(x);
gxx= abs(fftx).^2; % doubles sided spectral density
sxx= 2*gxx(2:length(gxx)/2,:); % calculating single sided spectra
sxx= [gxx(1,:);sxx;gxx(length(gxx)/2+1,:)]; % Concatenate to get final vector

Respuestas (1)

Mathieu NOE
Mathieu NOE el 13 de Feb. de 2024
see my demo code below , which replicates the principle of spectrogram
  • split the signal (with overlap)
  • apply window
  • fft
  • average
[signal, Fs] = audioread ("test_voice_mono.wav");
nfft = 1024; % fft / frame length
overlap = 0.5; % window overlap % overlap is 50% of nfft here
[S,F,T] = myspecgram(signal, Fs, nfft, overlap);
figure(1);
imagesc(T,F,20*log10(abs(S)))
colorbar('vert');
set(gca,'YDir','Normal')
xlabel('Time (secs)')
ylabel('Freq (Hz)')
title('Short-time Fourier Transform spectrum (dB Scale)')
colormap('jet');
function [fft_specgram,freq_vector,time] = myspecgram(signal, Fs, nfft, Overlap)
% FFT peak spectrogram of signal (example sinus amplitude 1 = 0 dB after fft).
% signal - input signal,
% Fs - Sampling frequency (Hz).
% nfft - FFT window size
% Overlap - buffer overlap % (between 0 and 0.95)
signal = signal(:);
samples = length(signal);
% fill signal with zeros if its length is lower than nfft
if samples<nfft
s_tmp = zeros(nfft,1);
s_tmp((1:samples),:) = signal;
signal = s_tmp;
samples = nfft;
end
% window : hanning
window = hanning(nfft);
window = window(:);
% compute fft with overlap
offset = fix((1-Overlap)*nfft);
spectnum = 1+ fix((samples-nfft)/offset); % Number of windows
% % for info is equivalent to :
% noverlap = Overlap*nfft;
% spectnum = fix((samples-noverlap)/(nfft-noverlap)); % Number of windows
% main loop
fft_specgram = [];
for ci=1:spectnum
start = (ci-1)*offset;
sw = signal((1+start):(start+nfft)).*window;
fft_specgram = [fft_specgram abs(fft(sw))*4/nfft]; % X=fft(x.*hanning(N))*4/N; % hanning only
end
% one sidded fft spectrum % Select first half
if rem(nfft,2) % nfft odd
select = (1:(nfft+1)/2)';
else
select = (1:nfft/2+1)';
end
fft_specgram = fft_specgram(select,:);
freq_vector = (select - 1)*Fs/nfft;
% time vector
% time stamps are defined in the middle of the buffer
time = ((0:spectnum-1)*offset + round(nfft/2))/Fs;
end

Categorías

Más información sobre Time-Frequency Analysis en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by