struct.error: 解包需要长度为4的字符串参数 - 音频文件

3 投票
2 回答
9788 浏览
提问于 2025-04-18 06:24

我刚开始学习编程,正在使用Ubuntu系统。

现在我想用Python来进行声音分析。

在下面的代码中,我使用了wav这个包来打开wav文件,并用struct来转换里面的信息:

from wav import *
from struct import *
fp = wave.open(sound.wav, "rb")
total_num_samps = fp.getnframes()
num_fft = (total_num_samps / 512) - 2 #for a fft lenght of 512
for i in range(num_fft):
  tempb = fp.readframes(512);
  tempb2 = struct.unpack('f', tempb)
print (tempb2)

但是在终端中出现了这样的错误信息:

struct.error: unpack requires a string argument of length 4

请问,有人能帮我解决这个问题吗?有没有其他的方法可以用来解析声音文件?

2 个回答

2

使用SciPy,你可以通过以下方式将.wav文件加载到NumPy数组中:

import scipy.io.wavfile as wavfile
sample_rate, data = wavfile.read(FILENAME)

NumPy/SciPy还可以用来计算FFT(快速傅里叶变换)。


小贴士:

  • 在Ubuntu系统上,你可以通过以下命令安装NumPy/SciPy:

    sudo apt-get install python-scipy
    

    这个命令也会同时安装NumPy,因为NumPy是SciPy的一个依赖项。

  • 尽量避免使用*这样的导入方式,比如from struct import *。这样做会把struct中的名字都复制到当前模块的全局命名空间里。虽然这样可以少打点字,但当你的脚本变得复杂时,你可能会搞不清楚变量是从哪里来的(更糟糕的是,导入的变量可能会覆盖其他同名变量的值)。

2

提供给 struct 的格式字符串必须准确地告诉它第二个参数的格式。举个例子,“有一百零三个无符号短整型”。你写的格式字符串是“有正好一个浮点数”。但是你给它的字符串数据远远超过这个数量,所以它就出错了。

所以第一个问题是,你需要在字节字符串中指定确切的打包C类型的数量。在这个例子中,就是512(帧数)乘以通道数(可能是2,但你的代码没有考虑到这一点)。

第二个问题是,你的 .wav 文件根本不包含浮点数。如果是8位的,它包含的是无符号的 char,如果是16位的,它包含的是有符号的 short,等等。你可以通过 fp.getsampwidth() 来检查你的 .wav 文件的实际采样宽度。

那么:假设你有512帧的双通道16位音频;你应该这样调用 struct

channels = fp.getnchannels()
...

tempb = fp.readframes(512);
tempb2 = struct.unpack('{}h'.format(512*channels), tempb)

撰写回答