2014-05-13 59 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名稱空間中的 名稱複製到當前模塊的全局 名稱空間中。雖然它爲您節省了一些打字費用,但當腳本變得更加複雜時,您會付出非常高的價格,並且會丟失 跟蹤變量來自哪裏(或者更糟糕的是,導入的變量 會掩蓋其他變量的值名稱)。

相關問題