为什么 librosa plot 不同于 matplotlib 和 audacity

Why does librosa plot differ from matplotlib and audacity

我正在从文件中读取 pcm 数据然后绘制它。我注意到情节在 librosa.display.waveplot、plot 和 audacity 之间有所不同。

这是代码和图片

%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)

这个结果看起来像

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

这个结果看起来像

matplotlib 的结果看起来很大胆

matplotlibAudacity 显示实际信号样本,在记录的后半部分显然都是负数。

另一方面,

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

中所述

Plot the amplitude envelope of a waveform.

If y is monophonic, a filled curve is drawn between [-abs(y), abs(y)].

y 是这种情况下的信号。

这有效地导致了沿 x 轴的镜像效应,这就是为什么 librosa 图是对称的。 matplotlibAudacity 显然没有做这样的事情。

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

This asymmetry is due mainly to two things, the first being the relative phase relationships between the fundamental and different harmonic components in a harmonically complex signal. In combining different frequency signals with differing phase relationships, the result is often a distinctly asymmetrical waveform, and that waveform asymmetry often changes and evolves over time, too. That's just what happens when complex related signals are superimposed.

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

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

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

根据 Vincent 发布的内容,librosa 的波浪图没有直接显示样本,原因有二:

  • 它会通过保持更高的点数来增加内存使用量 比可视化所需的分辨率

  • 它可以被高频噪声遮挡。

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

由于取abs去掉了上下轴信息,所以我们用轴来分隔立体声信号中的左右声道(左上,右下)。在单声道信号中,包络在 y 轴上反射,从而产生您报告的对称图形。

不同的 DAW 在执行这些步骤时会略有不同,一旦您放大到一个范围,一个奇特的实现将恢复为样本绘图,这样这样做就变得可行了。 Matplotlib 并没有让这完全容易实现,所以我们在这里选择了这种折衷方案。如果您想要样本精确的绘图,我们建议改用 pyplot.plt()。