我正在尝试使用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的信号最大值之间的比例。尽管信号速率不同。
这听起来像是一个量化问题。如果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])
c
和b
由于量化为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
如果您自己不想进行量化,则可以使用pylab
功能使用pylab.specgram
为您完成。您可以查看函数内部,并查看其如何使用vmin
和vmax
。
要补充说,Librosa有一个实用程序可以将整数数组转换为浮点数。