为什么 librosa STFT 显示错误的频率?
Why does librosa STFT show wrong frequencies?
我使用 numpy 生成了一个 200 Hz 的正弦波,然后使用 librosas stft()
和 specshow()
函数来显示频谱图。但是,它显示的频率不是 200 Hz。当我使用 matplotlibs magnitude_spectrum()
函数时,它准确显示 200 Hz。有谁知道为什么会这样?难道我做错了什么?任何帮助将不胜感激。
librosas spectrogram 和 matplotlibs 频谱的结果如下图所示。
最小工作示例:
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()
仅仅将结果传递给 specshow
是不够的。您还需要告诉它这些结果的规模。您这样做是通过像这样传递采样率参数 sr
:
librosa.display.specshow(D, y_axis='linear', sr=sr)
如果你不这样做,它 defaults 到 sr=22050, hop_length=512
,这在你的情况下肯定是不正确的。
这与给出的答案相似 。
我使用 numpy 生成了一个 200 Hz 的正弦波,然后使用 librosas stft()
和 specshow()
函数来显示频谱图。但是,它显示的频率不是 200 Hz。当我使用 matplotlibs magnitude_spectrum()
函数时,它准确显示 200 Hz。有谁知道为什么会这样?难道我做错了什么?任何帮助将不胜感激。
librosas spectrogram 和 matplotlibs 频谱的结果如下图所示。
最小工作示例:
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()
仅仅将结果传递给 specshow
是不够的。您还需要告诉它这些结果的规模。您这样做是通过像这样传递采样率参数 sr
:
librosa.display.specshow(D, y_axis='linear', sr=sr)
如果你不这样做,它 defaults 到 sr=22050, hop_length=512
,这在你的情况下肯定是不正确的。
这与给出的答案相似