频谱图中的时间步长差异

Time steps difference in spectrogram

我有一个长度为 10 秒的音频文件。如果我使用 matplotlib 生成 spectrogram,那么与 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)

有人可以向我解释一下为什么时间步长存在巨大差异以及如何确保两者生成相同的输出吗?

这是因为 plt.specgramnoverlap 考虑了与音频片段重叠的点数,而 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()

这将输出以下图片: