I have recorded some audio and would like to obtain a spectrum from it. As the audio is a real valued signal, I figure that I could perform a FFT with some window and obtain a spectrum for that period. There is the scipy.signal.spectrogram function which can just do this in one go. This is the code that I have thrown together:

import numpy as np
import matplotlib.pyplot as pl
import scipy.io.wavfile
import scipy.fftpack
from scipy import signal

rate, data = scipy.io.wavfile.read('audio.wav')
N = rate // 10
f, t, Sxx = signal.spectrogram(data, rate, window=signal.blackman(N), nfft=N, mode='magnitude')
pl.pcolormesh(t, f, 10 * np.log10(Sxx), shading='auto', cmap='jet')

The sampling rate is 44100 Hz. I thought that using a window of 100 ms should give me a lower frequency of 10 Hz, which is fine for my purpose.

Looking at the resulting spectrum plots I see that the upper half of the frequency seems to be different from the lower part.

From the documentation I would have expected that I just get the real amplitude as return_onesided defaults to True. In general I would expect to have amplitudes and phases, or real and imaginary part. But with the spectrum I just want the amplitudes. Are they just the lower part?

And if so, why is the maximum frequency just around 11 kHz whereas the sampling frequency is 44 kHz and from the Nyquist–Shannon sampling theorem I'd expect to be able to resolve like 22 kHz?

Update: Other recording

Using my laptop with Audacity instead of my phone with SmartRecorder to record some audio, I have no strange upper half in the spectrum.

enter image description here

Update: Jet colormap

I was asked why I have been using Jet instead of Viridis. When using the latter for the spectrum plot, one cannot see so much of the structure.

enter image description here

I know that Jet isn't so great, but I just want to have more contrast.

  • $\begingroup$ My guess is that the signal you're analyzing was low-pass filtered to ~11 kHz. Anything above 11 kHz is just noise. $\endgroup$
    – MBaz
    Jan 30 at 19:05
  • $\begingroup$ @MBaz: That sounds like a plausible explanation! I've used an Android app called “SmartRecorder” which might process it for better speech understanding. I just tried recording with Audacity with my laptop and the spectrum seemed to make sense. $\endgroup$ Jan 30 at 19:48
  • $\begingroup$ Why are you using the jet colormap? :) They got rid of that because it's misleading. The default viridis is better $\endgroup$
    – endolith
    Jan 30 at 21:39
  • 1
    $\begingroup$ @endolith: Due to the high range, I wasn't really able to see much of the structure. I'll add this picture again, so that you can see. $\endgroup$ Jan 31 at 7:18
  • $\begingroup$ @MartinUeding Maybe turbo colormap would be better, then? $\endgroup$
    – endolith
    Jan 31 at 19:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.