Почему librosa STFT показывает неправильные частоты?

Я сгенерировал синусоидальную волну 200 Гц с помощью numpy, а затем использовал функции librosas stft() и specshow(), чтобы показать спектрограмму. Однако частота, которую он показывает, не 200 Гц. Когда я использую функцию matplotlibs magnitude_spectrum(), она показывает ровно 200 Гц. Кто-нибудь знает, почему это может быть? Я делаю что-то неправильно? Любая помощь будет очень приветствоваться.

Результаты спектрограммы librosas и частотного спектра 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()

Спектрограмма Librosas и частотный спектр Matplotlibs


person sladekm    schedule 12.04.2020    source источник


Ответы (1)


Просто передать результаты specshow недостаточно. Вам также необходимо сказать, в каком масштабе находятся эти результаты. Вы делаете это, передавая параметр частоты дискретизации sr следующим образом:

librosa.display.specshow(D, y_axis='linear', sr=sr)

Если вы этого не сделаете, по умолчанию будет sr=22050, hop_length=512, что в вашем случае это, конечно, неверно.

Это похоже на ответ, данный здесь.

person Hendrik    schedule 13.04.2020
comment
Ох, даже спустя столько времени мне удалось упустить эти параметры. Большое тебе спасибо! - person sladekm; 14.04.2020
comment
Пожалуйста. Честно говоря, это простой упущение, поскольку не совсем интуитивно понятно, что D не описывает все, включая метаданные, как это (возможно) было бы в объектно-ориентированном мире. - person Hendrik; 14.04.2020
comment
Я хотел бы получить эти метаданные (если это означает данные о частоте). Что-то вроде numpy's fft.fftfreq(), которое довольно громоздко и интуитивно понятно в использовании. - person rocksNwaves; 11.08.2020