2013-07-16 32 views
3

我正在嘗試在python中處理音頻文件並應用低通濾波器來移除一些背景噪音。目前我能夠成功地加載文件,併產生一個陣列,它的數據值:解釋.WAV文件[Python]

class AudioModule: 

    def __init__(self, fname=""): 
     self.stream = wave.open(fname, 'r') 
     self.frames = [] 

    def build(self): 
     self.stream.rewind() 
     for x in range(self.stream.getnframes()): 
      self.frames.append(struct.unpack('B',self.stream.readframes(1))) 

我用struct.unpack(「B」 ..)對於該特定文件。加載音頻文件輸出以下規格:

nchannels: 1 
sampwidth: 1 
framerate: 6000 

我知道sampwidth指定由每個readframes(1)調用返回的字節的寬度。在加載它包含如圖值的陣列(範圍從128至180遍佈):

>>> r.frames[6000:6025] 
[(127,), (127,), (127,), (127,), (128,), (128,), (128,), (128,), (128,), (128,),  (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,), (128,)] 

問題: 什麼這些數字代表什麼?其他具有較大采樣寬度的音頻文件會提供完全不同的數字。我的目標是修剪音頻文件中的某些頻率,不幸的是我對這一點知之甚少,並不知道這些值如何與頻率相關。

刪除某個頻率閾值以上的所有值的最佳方法是什麼?

def store(self, fout=""): 
     out = wave.open(fout, 'w') 
     nchannels = self.stream.getnchannels() 
     sampwidth = self.stream.getsampwidth() 
     framerate = self.stream.getframerate() 
     nframes = len(self.frames) 
     comptype = "NONE" 
     compname = "not compressed" 

     out.setparams((nchannels, sampwidth, framerate, nframes, 
      comptype, compname)) 

     if nchannels == 1: 
      for f in self.frames: 
       data = struct.pack('B', f[0]) 
       out.writeframes(data) 
     elif nchannels == 2: 
      for f in self.frames: 
       data = struct.pack('BB', f[0], f[1]) 
       out.writeframes(data) 
     out.close()  
+0

這些值是時域中的壓力幅度值。您應該使用FFT將信號轉換爲頻域,執行濾波器,然後再將FFT轉換爲時域。 – OregonTrail

回答

1

我認爲數字是抽象的膜或該卷的振動的延伸:

另外,該值如下被包裝回到不同的文件。較高的值意味着膜的大振動。您可以閱讀更多here

而樣本寬度是音量的範圍。對於不同類型的採樣,樣本寬度不同。例如,如果樣本寬度是1位,那麼我們只能將音頻描述爲有聲或無聲。所以,通常樣品寬度越高,音頻質量越高。有關樣本寬度的更多信息,請參閱Sample Rate and Bitrate: The Guts of Digital Audio

存儲在音頻文件中的singnals在時域中。它不代表頻率。如果你想獲得頻域的值,你可以在你得到的陣列上執行FFT

我推薦使用numpy來做音頻表演。例如,要獲得你想要的數組,你只需要使用np.fromstring。而相關的功能如FFT已經被定義。 Google上可以找到許多樣本和論文。

+0

使用np.tostring時如何確定傳遞給字符串的dtype參數?我已經嘗試過一對夫婦,返回的值都不一樣,我假設這個case'int8'會被使用?謝謝你的時間,你的文章非常豐富。編輯:其實它可能只是要匹配我假設的樣本寬度。 – diverges

+0

我想你可以通過sampwidth來確定dtype。如果是1,則可以將int8,2用於int16。我需要在一個月前做一些關於音頻處理的事情,所以谷歌的一些信息。現在我正在閱讀理解數字信號處理第3版。這是有幫助的。@ diverges – zhangyangyu

+0

第一個程序我幾天前試圖用音頻和Python學到東西,所以我仍然不熟悉這些庫。我確實設法將過濾器應用於音頻文件,再次感謝。最終目標是從麥克風錄音中刪除所有背景音,因此我必須進一步閱讀。 – diverges