# How to get finer grained spectral decomposition for audio signals?

I am not a "proper" DSP guy at all, so apologies in advance if I am making any basic errors in this question. I would really appreciate it if you could point out any errors I make.

I have an audio signal sampled at (say) 44100 Hz. I want to get a spectrogram from this signal and display it. For this question, I will be using the formula as displayed in https://ccrma.stanford.edu/~jos/mdft/DFT_Definition.html .

My approach is as follows:

1. Take (say) 1024 of the frames at a time (which I will denote by $x$), and run an FFT routine over them, probably after applying a Hann window.
2. This will give me the frequency domain representation of the input window. I will denote the output of the FFT routine by $X$.

$X$ will effectively contain 512 values, with the value at index $n$ being the Fourier coefficient of the frequency $n * 22050 / 512$ Hz. Thus, say, the 300th sample of $X$ will correspond to the frequency 12919.92 Hz. (Is this understanding correct?)

Now my actual problem: I am not really interested in frequencies above 5000 Hz since my input will be human voice. Instead of $X$ covering a frequency range of 22050 Hz, I would like to "zoom in" so that it covers a range of only 5000 Hz. I.e., I want a finer grained spectral decomposition till a lower frequency of 5000 Hz. My question: how do I do this?

An approach I can think of: currently my sampling rate is 44100 Hz. If I can "reduce" the sampling rate to 11025 Hz, then the normal FFT approach will work and the output of the FFT routine will cover only frequencies till approximately 5000 Hz. I can accomplish this by either,

1. Averaging every 4 frames of my original input.
2. Taking only every 4th frame of my original input.
3. Taking the max of every 4 frames of my original input.

Will any of the above 3 approaches work? Is there any other way of getting a finer grained spectrum?

Edit: it struck me later that I could achieve the result by using a larger "bin" . I.e., 8192 frames instead of 1024 frames as input to my FFT routine. Is this the best approach available?

• You can change the sampling rate by doing "downsampling"; there are some related questions on this website. Regarding the spectral resolution, the only way to increase it is to include more signal samples (actual samples, not zero padding).
– MBaz
Mar 11 '16 at 17:16

if you are not experiencing computational limits (like you have all of the CPU speed and memory that your heart desires), what i would suggest is just do a much longer DFT or FFT. instead of 1024 points, do it with 16384 points or 65536 points or more. you will have lotsa data up in the top two octaves that you don't need and can decide to ignore.

if you do not want to have all of that data above 5512 Hz, then what i would recommend is formally downsampling by a factor of 4 and running the FFT on the downsampled data. to downsample legitimately, first you have to apply a good low-pass filter and kill all of the content above 5 kHz. after that LPF, then simply pick out every 4th sample, discarding the 3 samples in between. your data will be reduced by a factor of 4, your sample rate will be 11025 Hz and your Nyquist will be 5512.5 Hz and you can send that data into an FFT and look at those results.

• @ARV, Fourier spectral analysis has a sort of "Heisenberg uncertaintiy principle"... you can either get spectral resolution or time resolution, but not both. There are techniques to overcome this limitation, but I don't know much about them.
– MBaz
Mar 11 '16 at 17:57
• @ARV: While it is true that a longer window implies a worse time resolution, you can still shift the window by any number of points you want. In fact, if you apply a (non-rectangular) window function, you need at least some overlap anyway to prevent data loss at the boundaries. In some sense, time and frequency resolution just measure the "blurriness" of the spectrum in both directions. Mar 11 '16 at 19:37
• so ARV, you understand what @MBaz meant by overlapping so you can have a long window and a short update interval. right? and BTW, I know of no technique that overcomes the limitation of trading spectral resolution for time resolution. if you want meaningful spectral resolution of, say 2.5 Hz, you will need a window of ~0.4 seconds. Mar 12 '16 at 1:06
• there is still the tradeoff. longer wavelets (i.e. the mother wavelet scaled out to be longer) have better frequency resolution than shorter wavelets which have better time resolution. Mar 12 '16 at 1:46
• yes. you can offset even less than N/2. if you're using this to analyze and reconstruct some modified audio, then you have to worry a little about how the offset windows add. if they are "complementary". Mar 12 '16 at 18:54

If, by "finer grained", you just want a more precise estimate of some isolated spectral frequency peaks, in low enough noise, of a single (pseudo)periodic signal (a single human voice, no background accompaniment, etc.) than provided by the given FFT result bin spacing, you do not need to use a lower sampling rate, nor need to use a longer window of data that might lower time resolution.

Instead you can just interpolate a peak or peaks between DFT/FFT result bins, as long as none are closely spaced (less than several FFT bins apart). Parabolic interpolation may slightly increase frequency resolution, windowed-Sinc interpolation is better. But zero padding your short data window and using a much longer FFT is one simple very high-quality way to interpolate extra, more closely spaced, frequency points. Note that interpolation does not help increase resolution if there are nearby spectral peaks or a high surrounding noise floor, so it does not work in the general case. But in the case of a single voice in low noise, it might work reasonable well.

BTW: Lowering sample rate by directly decimating or averaging is incredibly noisy and will likely corrupt your results. Use a high quality low pass anti-aliasing filter instead. Also, trying to zoom-in by 4X by various means may well be slower than just computing the full FFT with all the "un-needed" FFT result bins, and just throwing away (not looking at) the higher frequency results.

Also, if you actually want a pitch frequency estimate rather than a spectral frequency peak estimate (two very different things, especially for voice), you can also interpolate an autocorrelation result.