Reputation: 47
I generated a 200 Hz sine wave using numpy and then used librosas stft()
and specshow()
functions to show a spectrogram. However, the frequency it is showing is not 200 Hz. When I use matplotlibs magnitude_spectrum()
function, it shows exactly 200 Hz. Does anyone know why that might be? Am I doing something wrong? Any help will be much appriciated.
The results from librosas spectrogram and matplotlibs frequency spectrum can be seen in the image below.
Minimal working example:
import matplotlib.pyplot as plt
from matplotlib import mlab
%matplotlib inline
import numpy as np
import librosa
import librosa.display
sr = 20000
freq1 = 200
n_fft=2000
x = np.linspace(0, 1, sr)
y = 0.5*np.sin(freq1 * 2 * np.pi * x)
no_window = np.linspace(1, 1, n_fft)
D = np.abs(librosa.stft(y, n_fft=n_fft, hop_length=int(n_fft/2), window=no_window, center=False,))
plt.figure(figsize=(9, 4))
librosa.display.specshow(D, y_axis='linear')
plt.xlabel('Time [s]')
plt.ylabel('Frequency [Hz]')
plt.ylim(0, 250)
plt.tight_layout()
plt.show()
plt.figure(figsize=(9, 4))
plt.magnitude_spectrum(y, Fs=sr, color='C1', window=mlab.window_none)
plt.xlim(0, 250)
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [-]')
plt.tight_layout()
plt.show()
Upvotes: 1
Views: 1420
Reputation: 5310
Just passing the results to specshow
is not enough. You also need to tell it what scale these results are on. You do this be passing the sample rate parameter sr
like this:
librosa.display.specshow(D, y_axis='linear', sr=sr)
If you don't, it defaults to sr=22050, hop_length=512
, which is certainly not correct in your case.
This is similar to the answer given here.
Upvotes: 4