为什么librosa图与matplotlib和audacity不同

时间:2019-07-29 19:10:04

标签: python matplotlib librosa audacity

我正在从文件中读取pcm数据,然后将其绘制出来。我注意到,情节在librosa.display.waveplot,情节和大胆之间变化。

这是代码和图片

%matplotlib inline
import matplotlib.pyplot as plt
import librosa.display
import numpy as np
import IPython.display as ipd
import matplotlib.pyplot as plt
import numpy, pylab

# the pcm file is 32le integer with a sampling rate of 16KHz
pcm_data = np.fromfile('someaudio.pcm', dtype=np.int32)

# the sample has the same sound as audacity
ipd.Audio(data=pcm_data, rate=16000) 

# all of these give the same resulting plot
plt.figure()
plt.subplot(3, 1, 1)
#librosa.display.waveplot(pcm_data, sr=16000)
#librosa.display.waveplot(pcm_data.astype('double'), sr=16000)
librosa.display.waveplot(pcm_data.astype('float'), max_points=None, sr=16000, max_sr=16000)

此结果看起来像 enter image description here

# alternatively plot via matplotlib
pylab.plot(pcm_data)
pylab.show()

此结果看起来像 enter image description here

matplotlib的结果看起来有点胆怯 enter image description here

2 个答案:

答案 0 :(得分:2)

matplotlib Audacity 显示了实际的信号样本,显然在记录的后半段全部为负。

另一方面,

librosa 显示了绝对信号的包络,如其documentation中所述:

  

绘制波形的幅度包络线。

     

如果y是单音,则会在[-abs(y), abs(y)]之间绘制一条填充曲线。

在这种情况下,

y是信号。

这有效地导致了沿x轴的镜像效果,这就是 librosa 图对称的原因。 matplotlib Audacity 显然没有这样做。

有人可能会说, librosa的行为有效地隐藏了不对称波形(即,正样本和负样本的幅度不相似),这在野外是可能的。来自soundonsound.com

  

这种不对称主要是由于两件事,第一是谐波复信号中基波分量和不同谐波分量之间的相对相位关系。在组合具有不同相位关系的不同频率信号时,结果通常是明显不对称的波形,而且波形的不对称性也经常随时间变化和发展。这就是叠加复杂的相关信号时发生的情况。

也许还会有人争辩说,不对称性中没有很多有用的信息,因为人类通常无法感知它。

如果您认为 librosa的行为是意外的或错误的,我建议您填写错误报告,并寻求解释。

答案 1 :(得分:0)

我通过librosa论坛收到了一些答案。这是Brian McFee的一个答案:

在文森特(Vincent)发表的内容之后,librosa的波动图没有直接显示样本,原因有两个:

  • 通过将点保持在较高位置会炸毁内存使用量 分辨率超过可视化所需的分辨率

  • 它会被高频噪声掩盖。

相反,librosa的绘图仪的工作方式更像典型的DAW,其中音频信号出于可视化目的而被下采样,并且包络而不是信号本身被可视化。这些步骤是通过显示max(abs(y [i:i + k]))而不是样本y [i],y [i + 1],... y [i + k]完成的。下采样窗口的长度由波形图的参数控制。

由于上轴和下轴的信息是通过吸收而被丢弃的,因此我们使用该轴来分离立体声信号中的左右声道(左上,右下)。在单声道信号中,包络线沿y轴反射,从而产生您报告的对称图形。

不同的DAW在执行这些步骤时会稍有不同,一旦放大到一定范围,可行的实现将还原为样本绘图。 Matplotlib并不容易做到这一点,因此我们在这里选择了这种折衷方案。如果您想要样本精确的绘图,我们建议改用pyplot.plt()。