Разница временных шагов в спектрограмме

#python #matplotlib #signal-processing #fft #librosa

#python #matplotlib #обработка сигналов #бпф #librosa

Вопрос:

У меня есть аудиофайл длиной 10 секунд. Если я создаю spectrogram using matplotlib , то я получаю другое количество временных шагов по сравнению со спектрограммой, сгенерированной librosa .

Вот код:

 fs = 8000
nfft = 200
noverlap = 120
hop_length = 120

audio = librosa.core.load(path, sr=fs)

# Spectogram generated using matplotlib
spec, freqs, bins, _ = plt.specgram(audio, nfft, fs, noverlap = noverlap)

print(spec.shape) # (101, 5511)


# Using librosa
spectrogram_librosa = np.abs(librosa.stft(audio,
                                              n_fft=n_fft,
                                              hop_length=hop_length,
                                              win_length=nfft,
                                              window='hann')) ** 2
spectrogram_librosa_db = librosa.power_to_db(spectrogram_librosa, ref=np.max)

print(spectrogram_librosa_db.shape) # (101, 3676)
  

Может кто-нибудь объяснить мне, почему существует огромная разница во временных шагах и как убедиться, что оба генерируют одинаковый результат?

Ответ №1:

Это связано с тем, что noverlap из plt.specgram учитывают количество точек для перекрытия сегментов звука, тогда hop_length как учитывают шаг между сегментами.

При этом между двумя результатами по-прежнему существует разница в 2 балла, но, скорее всего, это связано с границами.

 import numpy as np
import librosa
import matplotlib.pyplot as plt

path = librosa.util.example_audio_file()
fs = 8000
nfft = 200
noverlap = 120  # overlap
hop_length = 80  # step

audio, fs = librosa.core.load(path, sr=fs)

# Spectogram generated using matplotlib
spec, freqs, bins, _ = plt.specgram(
    audio, NFFT=nfft, Fs=fs, noverlap=noverlap,
)
spec = np.log10(spec   1e-14)

print(spec.shape)  # (101, 6144)


# Using librosa
spectrogram_librosa = (
    np.abs(
        librosa.stft(
            audio,
            n_fft=nfft,
            hop_length=hop_length,
            win_length=nfft,
            window="hann",
        )
    )
    ** 2
)
spectrogram_librosa_db = librosa.power_to_db(spectrogram_librosa, ref=np.max)

print(spectrogram_librosa_db.shape)  # (101, 6146)

fig, ax = plt.subplots(2)
ax[0].pcolorfast(spec)
ax[1].pcolorfast(spectrogram_librosa_db)
plt.show()
  

Это выводит следующую картинку:

спекграммы