使用 librosa.resample 后出现“wave.Error:未知格式:3”。 librosa 的输出有啥问题吗?

Posted

技术标签:

【中文标题】使用 librosa.resample 后出现“wave.Error:未知格式:3”。 librosa 的输出有啥问题吗?【英文标题】:"wave.Error: unknown format: 3" after using librosa.resample. Is there anything wrong with the output of librosa?使用 librosa.resample 后出现“wave.Error:未知格式:3”。 librosa 的输出有什么问题吗? 【发布时间】:2019-06-06 13:19:21 【问题描述】:

我有一个采样率为 44.1khz 的 .wav 文件,我想使用 librosa.resample 将其重新采样为 16khz。虽然 output.wav 听起来不错,而且是 16khz,但是当我尝试通过 wave.open 读取它时出现错误。

这个问题和我的很相似: Opening a wave file in python: unknown format: 49. What's going wrong?

这是我的代码:

if __name__ == "__main__":
    input_wav = '1d13eeb2febdb5fc41d3aa7db311fa33.wav'
    output_wav = 'result.wav'
    y, sr = librosa.load(input_wav, sr=None)
    print(sr)
    y = librosa.resample(y, orig_sr=sr, target_sr=16000)
    librosa.output.write_wav(output_wav, y, sr=16000)

    wave.open(output_wav)

最后一步出错wave.open(output_wav)

异常如下:

Traceback (most recent call last):
  File "/Users/range/Code/PycharmProjects/Speaker/test.py", line 204, in <module>
    wave.open(output_wav)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/wave.py", line 499, in open
    return Wave_read(f)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/wave.py", line 163, in __init__
    self.initfp(f)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/wave.py", line 143, in initfp
    self._read_fmt_chunk(chunk)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/wave.py", line 260, in _read_fmt_chunk
    raise Error('unknown format: %r' % (wFormatTag,))
wave.Error: unknown format: 3

我只是不知道为什么 wave.open 不能读取 wav_flie,我必须重新采样 wav 才能做进一步的工作。

不知道librosa.output.write是否改变了wav的类型。

所以我必须自己编写重采样函数。幸运的是,它有效。 这是我的代码:

def resample(input_wav, output_wav, tar_fs=16000):
    audio_file = wave.open(input_wav, 'rb')
    audio_data = audio_file.readframes(audio_file.getnframes())
    audio_data_short = np.fromstring(audio_data, np.short)
    src_fs = audio_file.getframerate()
    dtype = audio_data_short.dtype
    audio_len = len(audio_data_short)
    audio_time_max = 1.0*(audio_len-1) / src_fs
    src_time = 1.0 * np.linspace(0, audio_len, audio_len) / src_fs
    tar_time = 1.0 * np.linspace(0, np.int(audio_time_max*tar_fs), np.int(audio_time_max*tar_fs)) / tar_fs
    output_signal = np.interp(tar_time, src_time, audio_data_short).astype(dtype)

    with wave.open(output_wav, 'wb') as f:
        f.setnchannels(1)
        f.setsampwidth(2)
        f.setframerate(tar_fs)
        f.writeframes(output_signal)

我希望你能帮助我理解在 librosa 重新采样 wav 时出了什么问题,我很高兴看到我的代码可以帮助其他有同样问题的人。 :)

【问题讨论】:

【参考方案1】:

我正在做一个项目并且遇到了同样的错误,所以稍微挖掘了一下,发现问题是由于 librosa 在输出模块中使用 write_wav() 写入波形文件的默认方式。

问题在于编码量化是24位,因为它是“浮点PCM”。 您可以使用 SoX 轻松更改位量化。 SoX 是跨平台命令行实用程序,您可以使用它来控制编码格式等细节。

例如,你会做这样的事情来从 24 位编码到 16 位编码:

sox audio.wav -b 16 -e signed-integer modified_audio.wav

【讨论】:

【参考方案2】:

(对于 Linux 用户):sox 的替代品,因为我无法使用它。但是我在终端上使用以下命令成功地将其转换为 ffmpeg:

ffmpeg -i input_wav.wav -ar 44100 -ac 1 -acodec pcm_s16le output_wav.wav

其中“ar” = 音频速率,“ac” = 音频通道。

【讨论】:

如果您下载 ffmpeg 并将其添加到您的 PATH 中,那么它在 Windows 上的工作也像一个魅力。谢谢!

以上是关于使用 librosa.resample 后出现“wave.Error:未知格式:3”。 librosa 的输出有啥问题吗?的主要内容,如果未能解决你的问题,请参考以下文章

用 pyinstaller、-F -w等打包方式生成 exe 后,都出现错误,是怎么回事?

VMware 加载物理硬盘后出现“磁盘编码错误”一例

python常用函数 W

Luogu P1340 兽径管理

滚动关闭和打开后,视图重新出现在 UITableViewCell 中

为啥这个代码在 w.show() 调用中会出现段错误?