I recently learned how to manually compute a spectrogram of an audio signal, which is essentially a matrix. Each column corresponds to a time frame (e.g. 10 ms or something) but I'm asking which row corresponds to which frequency?
See my implementation below:
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
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
My theory: The topmost row must be 0.5*Fs (half of the sampling frequency) because of the sampling theorem. All other rows are linear increments to then match to 0.5*Fs. Example: 5 Rows, topmost is 5 Hz, then the first row is 1 Hz, the second is 2 Hz and so forth.