回答问题

我正在尝试使用 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 相乘,这是来自 scipy wavread 的信号的最大值与来自 librosa 的信号之间的比例。尽管信号速率不同。

Answers

这听起来像是一个量化问题。如果波形文件中的样本存储为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])

将 a 转换为int,缩放为 16 位整数

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

由于量化到int,cb仅等于大约 3 或 4 位小数。

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

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

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐