首页 > 解决方案 > 使用 scipy 读取 wav 时如何修复“不完整的 wav 块”错误

问题描述

我的问题

我正在尝试拟合一个(机器学习)模型,该模型接收音频文件(.wav)并从中预测情绪(多标签分类)。
我正在尝试从文件中读取采样率和信号,但是从 调用read(filename)scipy.io.wavfile,我得到了ValueError: Incomplete wav chunk.

我试过的

  1. 我试过从 切换scipy.read()librosa.read()
    它们都输出信号和采样率,但由于某种原因librosa,花费的时间比 成倍地长scipy,对我的任务来说是不切实际的。

  2. 我已经按照这里sr, y = scipi.io.wavfile.read(open(filename, 'r'))的建议尝试过,但无济于事。

  3. 我已经尝试查看我的文件并检查可能导致它的原因:
    在所有 2084 个 wav 文件中,1057 个是好的(=scipy 设法读取它们),1027 个是坏的(=引发了错误)。
    我似乎找不到任何关于是什么使文件通过或失败的东西,但尽管如此,这是一个奇怪的结果,因为所有文件都是从同一个数据集中的同一个数据集中获取

  4. 我听说有人说我可以使用某些软件将文件重新导出为 wav,它应该可以工作。
    我没有尝试这个,因为a)我没有任何音频处理软件,这似乎有点过头了,b)我想了解实际问题而不是贴上创可贴。

最小的、可重现的例子

假设filenames是我所有音频文件的一个子集,包含fn_goodfn_bad,其中fn_good是一个被处理的实际文件,并且fn_bad是一个引发错误的实际文件。

def extract_features(filenames):
    for fn in filenames:
        sr, y = scipy.io.wavfile.read(fn)
        print('Signal is: ', y)
        print('Sample rate is: ', sr)

附加信息

使用 VLC,似乎支持编解码器scipy.io.wavfile,但在任何一种情况下,两个文件都有相同的编解码器,所以很奇怪它们没有相同的效果...... GOOD 文件的编解码器: 在此处输入图像描述

BAD文件的编解码器: 在此处输入图像描述

标签: pythonmachine-learningaudioscipy

解决方案


我不知道为什么scipy.io.wavfile不能读取文件——其中可能有一个无效的块,其他读者会忽略。请注意,即使我使用 读取“好”文件,也会生成scipy.io.wavfile警告 ( ):WavFileWarning: Chunk (non-data) not understood, skipping it.

In [22]: rate, data = wavfile.read('fearful_song_strong_dogs_act10_f_1.wav')                              
/Users/warren/mc37/lib/python3.7/site-packages/scipy/io/wavfile.py:273: WavFileWarning: Chunk (non-data) not understood, skipping it.
  WavFileWarning)

我可以'fearful_song_strong_dogs_act06_f_0.wav'使用wavio(github 上的源代码:)阅读wavio,这是我创建的一个包,wave它使用理解 NumPy 数组的函数来包装 Python 的标准库:

In [13]: import wavio                                                                                     

In [14]: wav = wavio.read('fearful_song_strong_dogs_act06_f_0.wav')                                       

In [15]: wav                                                                                              
Out[15]: Wav(data.shape=(198598, 1), data.dtype=int16, rate=48000, sampwidth=2)

In [16]: plot(np.arange(wav.data.shape[0])/wav.rate, wav.data[:,0])                                       
Out[16]: [<matplotlib.lines.Line2D at 0x117cd9390>]

阴谋


推荐阅读