为什么来自Librosa库的频谱图与实际音频轨道具有不同的时间持续性?

3
我正在尝试绘制16000Hz 16位.wav语音音频的波形图和频谱图。我已成功获得以下绘图:word 'about'的波形图和频谱图然而,频谱图上的时间值不正确。我确定程序中采样率始终为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轴上的时间值不一致。请帮忙。
1个回答

6

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

当你计算STFT时,你指定了hop_length=64, win_length=256。请注意,这些信息不包含在DS_db中——librosa更倾向于功能性方法,而不是面向对象的方法。

因此,当你使用librosa.display.specshow显示频谱图时,你必须指定hop_length,而这一点你忽略了。因此,默认值hop_length=512被使用,这导致了一个因子为512 / 64 = 8的误差。也就是说,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])

to

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

应该修复这个问题。


1
清晰的解释。添加 hop_length 修复了错误。谢谢 Hendrik。 - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接