为什么来自 librosa 库的频谱图与实际音轨的持续时间不同?

Why spectrogram from librosa library have different time duration of the actual audio track?

我正在尝试绘制 16000Hz 16 位 .wav 语音音频的波形图和频谱图。我已成功获得以下地块:

但是,频谱图上的时间值不正确。我确定我的采样率在整个程序中是一致的 (16000Hz),但我仍然无法获得正确的频谱图时间值。

下面是我的 python 脚本:

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

y, sr = librosa.load('about_TTS_0792.wav', sr=16000)
print("Current audio sampling rate: ", sr)

print("Audio Duration:", librosa.get_duration(y=y, sr=sr))

D = librosa.stft(y, hop_length=64, win_length=256)  # STFT of y
S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)

fig, ax = plt.subplots(nrows=2)

librosa.display.waveplot(y, sr=sr, ax=ax[0])
img = librosa.display.specshow(S_db, sr=sr, x_axis='s', y_axis='linear',ax=ax[1])
ax[1].set(title='Linear spectrogram')
fig.colorbar(img, ax=ax[1], format="%+2.f dB")
fig.tight_layout()

plt.show()

此代码的输出:

Current audio sampling rate:  16000

Audio Duration: 0.792

我不知道我错过了什么会导致 x 轴上的时间值不一致。请帮忙。

STFT 频谱图的时间轴取决于两个因素:采样率和跳跃长度。

计算 STFT 时,指定 hop_length=64, win_length=256。请注意,此信息未包含在 DS_db 中——librosa 更倾向于函数式方法,而不是面向对象的方法。

因此,当您继续使用 librosa.display.specshow 显示频谱图时,您必须指定您错过的 hop_length。因此使用默认值 hop_length=512,这会导致 512 / 64 = 8 因素错误。 IE。 0.792 * 8 = 6.336,与您在频谱图中看到的相匹配。

此外,我认为 x_axis='s' 应该是 x_axis='time'

如此变化

img = librosa.display.specshow(S_db, sr=sr, x_axis='s', y_axis='linear',ax=ax[1])

img = librosa.display.specshow(S_db, sr=sr, hop_length=64, x_axis='time', y_axis='linear', ax=ax[1])

应该可以解决这个问题。