# How to determine the frequency of each row in a MATLAB spectrogram

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.

– A_A
Commented Jun 11, 2018 at 5:51

The physical frequency $f$ that a given Discrete Fourier Transform (DFT) frequency bin $k$ corresponds to is $f = \frac{k}{N_{DFT}} \cdot Fs$.

For an $Fs=44100$ Hz, the middle point of a given $N_{DFT}$ point DFT would correspond to $\frac{1}{2} \cdot Fs$, also known as the Nyquist Frequency.

EXCEPT MATLAB, which maps $1$ to $\frac{Fs}{2}$.

Hope this helps.

• When you say EXCEPT MATLAB, are you talking about the FFT implementation of matlab, the spectrogram implementation or my code?
– Alon
Commented May 2, 2018 at 14:01
• @JoschKraus MATLAB, as a software package (as a whole), chooses to call $1$ the Nyquist Frequency (which is 0.5 in Normalised Frequency). This is in contrast to the standard form of the normalised frequency (the textbook definition if you like). Consequently, what you call 0.25 Normalised Frequency is not the same with what MATLAB calls 0.25. This would confuse you a lot if you were calculating digital filter cut off frequencies. So, keep that in mind when comparing against MATLAB.
– A_A
Commented May 2, 2018 at 14:31

I don't know what you're doing but MATLAB's spectrogram implementation allows you to get the power spectrum ps, and the exact frequencies f and time instants t at which the spectrogram is computed with the following syntax at the output: [~, f, t, ps], where ps is a $M\times N$ matrix with the following:

• Each $k^\rm{th}$ column is the power spectrum over all frequencies at a fixed ($k^\rm{th}$) time instant. Or $$P_k(f_i), \quad\text{where}\quad i = 1, 2\cdots, M\quad\text{and}\quad k \in \left\{1, 2, \cdots, N\right\}.$$ $P_k(f)$ is a $M$-element vector.

• Each $i^\rm{th}$ row is the power spectrum over time at a fixed ($i^\rm{th}$) frequency value. Or $$P_i(t_k), \quad\text{where}\quad k = 1, 2\cdots, N\quad\text{and}\quad i \in \left\{1, 2, \cdots, M\right\}.$$ $P_i(t)$ is a $N$-element vector.

You don't always have $0$ to $F_s/2$ by default. The frequency range is $0$ to $F_s/2$ for real signal, one side of the spectrum is sufficient because of the Hermitian symmetry of the DFT. And $0$ to $F_s$ for complex signals, where uppper-half end of the frequencies can be shifted to negative frequencies.

• Thanks for the effort! Unfortunately I'm adding my work into earlier work and the computation of the spectrogram cannot be outsourced to matlabs function "spectrogram" so I need an answer that takes the manual computation into account
– Alon
Commented May 7, 2018 at 14:32