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

时间:2014-05-13 12:41:29

标签: python audio struct wav

我是编程的初学者,我使用的是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需要长度为4的字符串参数

拜托,有人可以帮我解决这个问题吗?有人建议使用其他策略来解释声音文件吗?

2 个答案:

答案 0 :(得分:2)

提供给struct的格式字符串必须告诉它完全第二个参数的格式。例如,"有一百三十个无符号短裤"。你编写它的方式,格式字符串说" 只有一个 float"。但是你为它提供了一个字符串,其数据比那个更多,并且它是barfs。

问题是,您需要在字节字符串中指定精确数量的压缩c类型。在这种情况下,512(帧数)乘以通道数(可能为2,但您的代码并未将此考虑在内)。

第二个问题是你的.wav文件根本不包含浮点数。如果它是8位,则它包含未签名的char,如果它是16位,则它包含签名的short等。您可以检查您的实际样本宽度。 wav做fp.getsampwidth()

那么:让我们假设您有512帧双声道16位音频;您可以将调用写为struct,如:

channels = fp.getnchannels()
...

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

答案 1 :(得分:2)

使用SciPy,您可以使用以下命令将.wav文件加载到NumPy数组中:

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

NumPy / SciPy对computing the FFT也很有用。


提示:

  • 在Ubuntu上,您可以使用

    安装NumPy / SciPy
    sudo apt-get install python-scipy
    

    这也将安装NumPy,因为NumPy是SciPy的依赖。

  • 避免使用*导入,例如from struct import *。这份副本 从struct命名空间到当前模块的全局名称 命名空间。虽然它可以为您节省一些打字,但您支付的费用非常糟糕 价格稍后当剧本变得更加复杂而你输了 跟踪变量的来源(或更糟糕的是,导入的变量 使用相同的名称屏蔽其他变量的值。