struct.error: 解包需要长度为4的字符串参数 - 音频文件
我刚开始学习编程,正在使用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 个回答
使用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
中的名字都复制到当前模块的全局命名空间里。虽然这样可以少打点字,但当你的脚本变得复杂时,你可能会搞不清楚变量是从哪里来的(更糟糕的是,导入的变量可能会覆盖其他同名变量的值)。
提供给 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)