2014-05-13 25 views
3

我是编程的初学者,我使用Unbuntu。struct.error:解压缩需要一个长度为4的字符串参数 - 音频文件

但是现在我试图用Python来进行声音分析。

在下面的代码我用WAV包打开wav文件和结构将信息转换:

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

提供给struct的格式字符串必须告知确切地说第二个参数的格式。例如,“有一百零三个未签名的短裤”。你写的方式,格式字符串说“有只有一个浮动”。但是,然后你用比这个更多的数据来提供一个字符串,并且它是barf。

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

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

那么,我们假设你有512帧双声道16位音频;你会写调用struct,就像这样:

channels = fp.getnchannels() 
... 

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

我试过你的建议,它的工作。非常感谢!但我还有一个问题。如果我想要提取分贝信息,我应该使用下面的代码吗? 'db = struct.unpack('{} h'.format(512 * channels),“%dB”%(512))' – amonte

2

使用SciPy,你可以在.wav文件加载到使用NumPy的数组:

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

与NumPy/SciPy的还将为computing the FFT是有用的。


提示:

  • 在Ubuntu,你可以用

    sudo apt-get install python-scipy 
    

    这将安装与NumPy以及安装与NumPy/SciPy的,因为NumPy的是SciPy的的依赖。

  • 避免使用*等进口产品,如from struct import *。这会将struct名称空间中的 名称复制到当前模块的全局 名称空间中。虽然它为您节省了一些打字费用,但当脚本变得更加复杂时,您会付出非常高的价格,并且会丢失 跟踪变量来自哪里(或者更糟糕的是,导入的变量 会掩盖其他变量的值名称)。

相关问题