2015-04-01 69 views
0

我正在寫一個腳本來處理在Python中的波形文件,並顯示一個頻譜分析儀,只是爲了良好的音頻文件的可視化。在閱讀了一些文檔和論壇後,我認爲我需要使用rfft。頻譜分析儀波形文件與numpy.rfft

我正在處理2048個值的樣本,在rfft的輸出中創建1024個波段。事情是,爲了我的需要,我需要將樂隊的數量大幅減少到12個樂隊(1個八度)。由於我正在處理音頻文件並且樂隊數量有限,因此我想知道是否有一種巧妙的方法來組合頻率,以便90%的歌曲在左側低音節拍和高調的聲音/留言/正確的說明。

有了這個初步的代碼,我有更多的樂隊,我需要的,但也大多數峯值集中在低頻率與大多數歌曲,除了20至20K的測試範圍。有了這個範圍,我也意識到,音高越高,幅度越低。

def fft(self, sample_range): 
    # sample_range is a sample of 2048 ints read from the self.file wave file 
    fft_data = abs(numpy.fft.rfft(sample_range)) # real fft gives samplewidth/2 bands 
    fft_freq = numpy.fft.rfftfreq(len(sample_range)) 
    freq_hz = [abs(fft_freq[i])*self.file.getframerate() for i, fft in enumerate(fft_data)] 

    print len(zip(freq_hz, fft_data)), len(freq_hz), len(fft_data), zip(freq_hz, fft_data) 

下面是RAMPE的第一樣品(〜20Hz的)打印輸出:

1025 1025 1025 [(0.0, 1850501.0), (21.533203125, 2779524.1730200453), (43.06640625, 15469093.29481476), ... (22028.466796875, 3538.1225240980043), (22050.0, 3553.0)] 

所以我的問題是:

  • 我做的東西,我不該在上面的代碼中? =)

  • 大多數音樂播放器中的頻譜分析儀通常代表什麼單位,範圍是多少?我應該將幅度轉換爲dB嗎?

  • 有沒有一種簡單的方法將頻帶數減少到12個?我猜這個帶寬對於音高來說是指數級的嗎?我會說我需要手動實現這個指數和。

編輯:我使用參考數比例,我生成用於與帶任意數量現在求和FFT頻率:

In [22]: num_bands = 10 
In [23]: [44100*2**(b-num_bands) for b in range(num_bands)] 
Out[23]: [43.06640625, 86.1328125, 172.265625, 344.53125, 689.0625, 1378.125, 2756.25, 5512.5, 11025.0, 22050.0] 

In [24]: num_bands = 12 
In [25]: [44100*2**(b-num_bands) for b in range(num_bands)] 
Out[25]: [10.7666015625, 21.533203125, 43.06640625, 86.1328125, 172.265625, 344.53125, 689.0625, 1378.125, 2756.25, 5512.5, 11025.0, 22050.0] 

我使用這些作爲各頻帶中的最大頻率。它一直運行到num_bands = 10的最大值。從11歲起,我開始在可聽範圍內獲得非常低的頻率。任何想法縮小範圍比這更好?無論如何,第一頻段的最大頻率應至少爲40 Hz。

回答

1

是的,頻譜顯示通常轉換爲dB(或其他對數標度)。

減少頻帶數量的最簡單方法就是將每個八度音程(或者每半音階或12個八度音程等)中的相鄰FFT結果分組加在一起,其中每個音階表示的最高頻率和最低頻率之間的比例大致相等波段或一組FFT結果倉。使比例大小的組足夠大或小,以便最終獲得所需的總帶數。

+0

「上下」是指正面還是負面?如果我理解的很好,*真實* fft已經爲我做了。 – myoan 2015-04-01 20:09:42

+0

改進的答案是說每個頻段或一組FFT結果箱的最高和最低頻率。每倍頻程,頂部bin的索引大約是每個組中底部bin的兩倍(可能是-1)。 – hotpaw2 2015-04-02 00:46:08

+0

我明白了,這就是我實際做的。如果你看看我上面編輯的問題,我會生成一個列表,它是每個組的最高頻率。因此,使用'[43.06640625,86.1328125,172.265625,...]'列表'我將創建'[(0Hz,43Hz),(43Hz,86Hz),(86Hz,172Hz),(172,...)]'頻帶''。但是我不能設法生成這個列表,以便它適用於任何給定的n個頻段。我增加得越多,就越能聽到非常低的頻率(例如,頻帶11到22Hz以下)。所以我有兩個新問題:我應該如何處理<20Hz頻率?以及如何生成清單來消除它們? – myoan 2015-04-02 19:48:33