在 python 中使用 scipy 和 librosa 读取 wav 文件
回答问题 我正在尝试使用 scipy 文件夹在 Python 中加载.wav文件。我的最终目标是创建该音频文件的频谱图。读取文件的代码可以总结如下: import scipy.io.wavfile as wav (sig, rate) = wav.read(_wav_file_) 对于某些.wav文件,我收到以下错误: WavFileWarning:块(非数据)不理解,跳过它。 WavFileWa
回答问题
我正在尝试使用 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
,c
和b
仅等于大约 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
更多推荐
所有评论(0)