【问题标题】:struct.error: unpack requires a string argument of length 4 - audio filestruct.error: unpack 需要一个长度为 4 的字符串参数 - 音频文件
【发布时间】:2014-05-13 12:41:29
【问题描述】:

我是编程的初学者,我使用的是 Ubuntu。

但现在我正在尝试使用 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 需要一个长度为 4 的字符串参数

请问,有人可以帮我解决这个问题吗?有人对解释声音文件的其他策略有建议吗?

【问题讨论】:

    标签: python audio struct wav


    【解决方案1】:

    提供给struct 的格式字符串必须告诉它准确第二个参数的格式。例如,“有一百零三条未签名的短裤”。您编写它的方式,格式字符串说“有一个 exactly one float”。但是你给它提供了一个比这更多的数据的字符串,它就会出错。

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

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

    那么:假设您有 512 帧的两通道 16 位音频;您可以将调用写入struct,如下所示:

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

    【讨论】:

    • 我试过你的建议,它奏效了。非常感谢!但我还有一个问题。如果我想为提取分贝信息做同样的事情,我应该使用以下代码吗? db = struct.unpack('{}h'.format(512*channels), "%dB"%(512))
    【解决方案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 命名空间中的名称到当前模块的全局 命名空间。虽然它节省了你一点打字,但你付出了可怕的代价 当脚本变得更复杂并且您输了时,稍后再定价 跟踪变量的来源(或更糟糕的是,导入的变量 屏蔽其他同名变量的值)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      • 2021-10-06
      • 2015-09-15
      • 1970-01-01
      • 2012-12-08
      相关资源
      最近更新 更多