Python:将 wav 文件写入 numpy 浮点数组

Posted

技术标签:

【中文标题】Python:将 wav 文件写入 numpy 浮点数组【英文标题】:Python: write a wav file into numpy float array 【发布时间】:2013-05-22 15:31:26 【问题描述】:
ifile = wave.open("input.wav")

我现在如何将此文件写入 numpy 浮点数组?

【问题讨论】:

@JoranBeasley 它必须是浮动的。 【参考方案1】:
>>> from scipy.io.wavfile import read
>>> a = read("adios.wav")
>>> numpy.array(a[1],dtype=float)
array([ 128.,  128.,  128., ...,  128.,  128.,  128.])

通常是字节,然后是整数......这里我们只是将它转换为浮点类型。

你可以在这里阅读:https://docs.scipy.org/doc/scipy/reference/tutorial/io.html#module-scipy.io.wavfile

【讨论】:

谢谢!还有一个问题,我怎样才能对当前工作目录中的所有 .wav 文件执行此操作?我的意思是将每个文件在一个循环中保存在一个数组中,并在每个步骤结束时将其集中到一个主数组中?【参考方案2】:

使用 librosa 包并简单地将 wav 文件加载到 numpy 数组:

y, sr = librosa.load(filename)

将音频加载和解码为时间序列 y,表示为 一维 NumPy 浮点数组。变量 sr 包含 y的采样率,即每秒的采样数 声音的。默认情况下,所有音频都混合为单声道并重新采样到 22050 加载时的赫兹。可以通过提供覆盖此行为 librosa.load() 的附加参数。

更多信息Librosa library documentation

【讨论】:

【参考方案3】:

问题提出七年后......

import wave
import numpy

# Read file to get buffer                                                                                               
ifile = wave.open("input.wav")
samples = ifile.getnframes()
audio = ifile.readframes(samples)

# Convert buffer to float32 using NumPy                                                                                 
audio_as_np_int16 = numpy.frombuffer(audio, dtype=numpy.int16)
audio_as_np_float32 = audio_as_np_int16.astype(numpy.float32)

# Normalise float32 array so that values are between -1.0 and +1.0                                                      
max_int16 = 2**15
audio_normalised = audio_as_np_float32 / max_int16

【讨论】:

我应该如何安装wave 模块? pip install wave? @Unsigned_Arduino 你刚试过吗?根据文档,wave 模块至少从 2.7 版开始就是 Python 的一部分,并且它仍然包含在 3.8 版中:docs.python.org/3.8/library/wave.html 刚试了一下,已经包含在内了。我以前从未见过这个模块,所以我质疑它是否存在于 PSL 中。 嗨,马修·沃克,谢谢你这么好的回答。我想问一下,audio_normalised的大小是samples的两倍,那么它是代表2个通道的数据,还是别的什么,请您详细说明一下吗? @avocado getsampwidth() 以字节为单位返回样本宽度,因此 2 字节 => int16,或 4 字节 => int32。我想我只是没有遇到每个样本只有 2 个字节的 WAV 文件。好点子。【参考方案4】:

在@Matthew Walker 的答案下没有足够的声誉来发表评论,所以我提出了一个新的答案,以便在 Matt 的答案中添加一个观察。 max_int16 应该是 2**15-1 而不是 2**15

更好的是,我认为规范化行应该替换为:

audio_normalised = audio_as_np_float32 / numpy.iinfo(numpy.int16).max

如果音频是立体声(即两个通道),则左右值是交错的,因此要获得立体声数组,可以使用以下方法:

channels = ifile.getnchannels()
audio_stereo = np.empty((int(len(audio_normalised)/channels), channels))
audio_stereo[:,0] = audio_normalised[range(0,len(audio_normalised),2)]
audio_stereo[:,1] = audio_normalised[range(1,len(audio_normalised),2)]

我相信这回答了 cmets 部分中的@Trees 问题。

【讨论】:

max_int16 的定义问题很有趣。 16 位整数的范围是 -32,768 到 32,767。如果我们想要从 -1 缩放到 1,那么我们想要除以最大可能值,在绝对意义上,或 32,768,即2**15。因此在我的回答中定义了max_int16

以上是关于Python:将 wav 文件写入 numpy 浮点数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 python 中读取多个 wav 文件,并转换为 numpy 数组进行绘图

Python NumPy 将 FFT 转换为文件

将.3gp文件写入.wav格式python Flask服务器

我可以从 python SpeechRecognition 中的 numpy 数组进行识别吗?

Python 3:将波形数据(字节数组)转换为浮点值的 numpy 数组

如何将wav文件转换为浮动幅度