使用来自 SciPy 的 wavfile.write 在 Python 中编写 wav 文件

Posted

技术标签:

【中文标题】使用来自 SciPy 的 wavfile.write 在 Python 中编写 wav 文件【英文标题】:Writing wav file in Python with wavfile.write from SciPy 【发布时间】:2013-09-09 19:58:02 【问题描述】:

我有这个代码:

import numpy as np
import scipy.io.wavfile
import math

rate, data = scipy.io.wavfile.read('xenencounter_23.wav')

data2 = []

for i in range(len(data)):
    data2.append([int(round(math.sin(data[i][0])*3000)), int(round(math.sin(data[i][1])*3000))])

data2 = np.asarray(data2)

print data2

scipy.io.wavfile.write('xenencounter_23sin3.wav',rate,data2)

打印(截断):

[[-2524  2728]
 [ -423 -2270]
 [ 2270   423]
 ..., 
 [-2524     0]
 [ 2524 -2728]
 [-2270   838]]

wav 文件在 Windows Media Player 中打开并播放,因此至少它是正确的格式。但是,当使用 Audacity 打开它并查看单个样本时,它们都是 0,并且一致地,该文件根本不会播放任何声音。

我不明白的是上面列出的 numpy 数组是如何变成全 0 的。它应该低于样本的最大值(或高于,如果它是负数)。

【问题讨论】:

如果你用 scipy 重新加载它会发生什么?是零还是您保存的值? 它返回的内容与写入之前打印的内容相同。 你能在rate, data = scipy.io.wavfile.read('xenencounter_23.wav') 行之后添加print data 语句吗?我想看看这些数据是什么样子的。 它打印这个[[-1 2] [-3 4] [-4 3] ..., [-1 0] [ 1 -2] [ 4 -6]] 但是,在它列出的数组的另一部分:[-2050 -1856] [-1814 -1621] [-1493 -1295] [-2042 -1848],非常相似 试试scipy.io.wavfile.write('xenencounter_23sin3.wav',rate,data) - 你想知道是写方法还是你对数据执行的操作有问题。 【参考方案1】:

在通过 scipy.io.wavfile.write() 创建 wav 文件时,我发现幅度非常重要。如果你创建一个幅度为 150 的正弦波,在 VLC 中播放时听起来像是无声的。如果幅度为 100,听起来像一个失真的正弦波,如果你把它设为 80,它开始听起来像一个正常的文件。

在创建波形文件时一定要注意幅度,但我现在还不清楚在开始削波或消失之前最大电平是多少。

【讨论】:

【参考方案2】:

我发现 scipy.io.wavfile.write() 以 16 位整数写入,这解释了尝试使用 32 位整数(默认值)时文件大小较大的原因。虽然我找不到在 wavfile.write 中更改它的方法,但我确实通过更改找到了:

data2 = np.asarray(data2)

data2 = np.asarray(data2, dtype=np.int16)

我可以写一个工作文件。

【讨论】:

这也解决了我的问题。 scipy 在文档中注意到这一点会很好:S 非常感谢这位分享者!你真棒。 顺便问一下其他感兴趣的人,看看下面的例子:docs.scipy.org/doc/scipy/reference/generated/…【参考方案3】:

正如您通过在不同点打印输出并重新保存最初加载的内容所发现的那样,data2.append([int(round(math.sin(data[i][0])*3000)), int(round(math.sin(data[i][1])*3000))]) 行是问题的根源。

我怀疑 3000 的幅度太大。试试 1。

【讨论】:

它做了同样的事情。我认为 -32768 和 32767 之间的样本值应该没问题。 试试data2.append([int(data[i][0]), [int(data[i][1])]) - 不幸的是,你需要不断消除东西,直到你发现破坏你的代码的功能。 那也是一样的。我了解波形文件数据存储为每个样本的二进制补码数。我不知道这是否会有所作为。它不会打印为二进制补码,所以我认为转换在 wavefile.write data1.shape == data2.shape 的输出是什么?我开始怀疑第二个数组的尺寸有误。 'xenencounter_23.wav' 绝对是未压缩的 wav 吗?

以上是关于使用来自 SciPy 的 wavfile.write 在 Python 中编写 wav 文件的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 k-means(来自 Scipy)聚类到两个片段的图像会显示两个以上不同的像素值?

来自 SciPy 的带有 QHull 的凸包体积

2 树状图 + 来自 scipy 的压缩相关矩阵的热图

带有名称的 Scipy 树状图

使用 scipy.optimize.minimize 提前停止损失函数

scipy csr_matrix 来自几个表示为集合列表的向量