在python中使用scipy和librosa读取wav文件

问题描述 投票:2回答:3

我正在尝试使用scipy文件夹在Python中加载.wav文件。我的最终目标是创建该音频文件的频谱图。读取文件的代码可以总结如下:

import scipy.io.wavfile as wav
(sig, rate) = wav.read(_wav_file_)

对于某些.wav文件,我收到以下错误:

WavFileWarning:不理解块(非数据),请跳过它。WavFileWarning)** ValueError:不完整的wav块。

因此,我决定使用librosa通过以下方式读取文件:

import librosa
(sig, rate) = librosa.load(_wav_file_, sr=None)

这在所有情况下均正常运行,但是,我注意到频谱图的颜色有所不同。虽然它是相同的确切数字,但是颜色却是相反的。更具体地说,我注意到,当保持相同的功能来计算规格时,仅更改我读取.wav的方式时,会有这种差异。知道会产生什么东西吗?两种方法读取.wav文件的方式之间有默认区别吗?

编辑:

(rate1, sig1) = wav.read(spec_file) # rate1 = 16000
sig, rate = librosa.load(spec_file) # rate 22050
sig = np.array(α*sig, dtype = "int16") 

[几乎可行的方法是将sig的结果乘以恒定的α alpha,该alpha为scipy wavread的信号最大值与librosa的信号最大值之间的比例。尽管信号速率不同。

python audio signal-processing
3个回答
3
投票

这听起来像是一个量化问题。如果wave文件中的样本存储为float,而librosa只是将其直接转换为int,则小于1的值将被截断为0。这很有可能是sig是数组的原因所有零。必须缩放float才能将其映射到int的范围内。例如,

>>> a = sp.randn(10)
>>> a
array([-0.04250369,  0.244113  ,  0.64479281, -0.3665814 , -0.2836227 ,
       -0.27808428, -0.07668698, -1.3104602 ,  0.95253315, -0.56778205])

将a转换为不缩放的int类型>

>>> a.astype(int)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

以16位整数的比例将a转换为int

>>> b = (a* 32767).astype(int)
>>> b
array([ -1392,   7998,  21127, -12011,  -9293,  -9111,  -2512, -42939,
        31211, -18604])

将换算后的int转换回float

>>> c = b/32767.0
>>> c
array([-0.04248177,  0.24408704,  0.64476455, -0.36655782, -0.28360851,
       -0.27805414, -0.0766625 , -1.31043428,  0.9525132 , -0.56776635])

cb由于量化为int而仅等于约3或4个小数位。

如果librosa返回float,则可以按2**15对其进行缩放并将其转换为int,以获得与scipy Wave阅读器所返回的值相同的范围。由于librosa返回的是float,因此这些值很可能位于比[-1, +1]中的16位整数小得多的范围内,例如[-32768, +32767]。因此,您需要缩放一个以匹配范围。例如,

sig, rate = librosa.load(spec_file, mono=True)
sig = sig × 32767

1
投票
  • 如果您自己不想进行量化,则可以使用pylab功能使用pylab.specgram为您完成。您可以查看函数内部,并查看其如何使用vminvmax


0
投票

要补充说,Librosa有一个实用程序可以将整数数组转换为浮点数。

© www.soinside.com 2019 - 2024. All rights reserved.