将字节写入波形文件?

Posted

技术标签:

【中文标题】将字节写入波形文件?【英文标题】:Writing bytes to wave file? 【发布时间】:2015-10-08 17:18:05 【问题描述】:

我有一些 Python 数据,我想输出到 WAV 文件。现在我将所有样本生成为短裤并将它们放入缓冲区。然后,每当该缓冲区达到一定长度时,我就会打包数据并将其发送到写入帧(在写入每个样本之间进行妥协,这很慢,并且在写入之前将整个内容保存在内存中,这很昂贵)。

但它总是抛出 TypeError。

output = wave.open(fname, 'wb')
output.setparams((channels, sample_width, sample_rate, 0, 'NONE', 'not compressed'))
# ...generate the data, write to the buffer, then if the buffer is full...
cooked = []
for (ldata, rdata) in rawdata:
    cooked.append(struct.pack('<hh',ldata,rdata)) # Pack it as two signed shorts, little endian
output.writeframes(bytes.join(cooked)) # Write to the wave file

我也尝试过''.join(cooked)bytes(cooked),并从一开始就将cooked 设为bytearray,但这些似乎都不起作用。

如上

output.writeframes(bytes.join(cooked)) # Write to the wave file
TypeError: descriptor 'join' requires a 'bytes' object but received a 'list'

使用bytes()

output.writeframes(bytes(cooked)) # Write to the wave file
TypeError: 'bytes' object cannot be interpreted as an integer

使cooked 成为一个字节数组

cooked.append(struct.pack('<hh',ldata,rdata)) # Pack it as two signed shorts, little endian
TypeError: an integer is required

直接发送cooked

TypeError: memoryview: list object does not have the buffer interface

使用''.join()

output.writeframes(''.join(cooked)) # Write to the wave file
TypeError: sequence item 0: expected str instance, bytes found

这样做的正确方法是什么?我无法弄清楚 Python 到底想要什么。

编辑:如果有任何影响,请使用 Python 3.4.1。

【问题讨论】:

【参考方案1】:

你需要这样做:

output.writeframes(b''.join(cooked))

方法的第一个参数是self。如果你正常调用该方法,这个参数是自动传递的。但是,如果您通过Class.method() 调用它,则必须手动传递它。由于您传递了一个列表而不是 bytes 对象作为您的第一个参数,因此您得到了第一个 TypeError。

为了完整起见,以下是剩余的错误:

output.writeframes(bytes(cooked)) # Write to the wave file
TypeError: 'bytes' object cannot be interpreted as an integer

bytes() 接受整数序列;此外,它们一次只有一个字节。您需要使用按位运算而不是 struct.pack()(例如,cooked.extend((ldata &amp; 0xFF, ldata &gt;&gt; 8, rdata &amp; 0xFF, rdata &gt;&gt; 8)) 用于 little-endian 16 位整数,假设没有大于 0xFFFF 且不考虑负数)。

cooked.append(struct.pack('<hh',ldata,rdata)) # Pack it as two signed shorts, little endian
TypeError: an integer is required

同样,bytearray.append() 接受一个整数。

output.writeframes(cooked)
TypeError: memoryview: list object does not have the buffer interface

list 不是字节类对象,因此 writeframes() 不能接受。

output.writeframes(''.join(cooked)) # Write to the wave file
TypeError: sequence item 0: expected str instance, bytes found

您不能混合使用文本和二进制字符串。

【讨论】:

这是有道理的。但是当我尝试这个时,我得到TypeError: memoryview: str object does not have the buffer interface 这对我来说毫无意义。我们绝不会在任何地方传递字符串,假设您使用的是b'' 而不仅仅是''。我看不出那个错误可能来自哪里。 我也有些困惑。不过,关闭并重新打开 Python 似乎已经清除了它,所以我猜这是我的文件在编辑后没有正确保存。非常感谢!

以上是关于将字节写入波形文件?的主要内容,如果未能解决你的问题,请参考以下文章

将数据从缓冲区写入磁盘上的波形文件[关闭]

波形写入功能不起作用,我做错了啥?

为啥将许多小字节数组写入文件比写入一个大数组要快?

C ++将字节写入文件

C++ 将字符串写入文件 = 额外字节

将字节数组中的文件写入 zip 文件