2010-11-21 97 views
2

我正在使用fft製作音高檢測程序。爲了獲得球場,我需要找到明顯高於噪底的最低頻率。所有結果都在數組中。每個位置都是一個頻率。我不知道如何找到高峯。如何在數組中找到峯值?

我使用C#編程。

下面是大膽的頻率分析截圖。 alt text

+0

我假設你的意思是「高峯」,而不是「挑」? – 2010-11-21 17:41:35

回答

2

而不是試圖找到峯值,我會尋找一個基本的頻率,使其前5個整數倍所捕獲的光譜能量最大化。請注意,每個峯值是最低峯值的整數倍。這是倒譜法的一種破解。不要評判:)。

N.B.從你的情節,我假設一個1024採樣窗口和44.1kHZ採樣率。這產生了僅44.1kHz/1024 = 43Hz的頻率粒度。鑑於44.1kHz音頻,我建議使用更長的〜50 ms或2048個採樣的分析窗口。這會產生更精細的〜21 Hz的頻率粒度。

假設PSD值爲2048的Matlab矢量'psd'。

% 50 Hz (Dude) -> 50Hz/44100Hz * 2048 -> ~2 Lower Lim 
% 300 Hz (Baby) -> 300Hz/44100Hz * 2048 -> ~14 Upper Lim 
lower_lim = 2; 
upper_lim = 14 
for fund_cand = lower_lim:1:upper_lim 
    i_first_five_multiples = [1:1:5]*fund_cand; 
    sum_energy = sum(psd(i_first_five_multiples)); 
end 

我會找到最大化sum_energy值的頻率。

2

,如果你有絕對值的一些概念,以期望它會更容易些,但我建議:

  • 先找到最低(最弱)值。這是你的噪音水平。
  • 計算平均水平,它是你的信號強度
  • 定義一些函數來決定噪聲閾值。這是棘手的部分,它可能需要一些實驗。

在不好的情況下,信號可能只有噪聲等級的2或3倍。如果信號更好,你可以使用2xnoise的閾值。


編輯,看圖片後:

你或許應該剛開始在左邊,找到當地的最大值。看起來你可以使用30分貝閾值和一個10格窗口或其他東西。

2

找到最低峯值將無法可靠地估計音高,因爲此頻率有時完全缺失,或在本底噪聲中下降。爲了獲得更好的可靠性,請嘗試使用神經網絡,遺傳算法或決策矩陣來確定替代基音假設之間的其他算法:自相關(AMDF,ASDF滯後),倒譜(FFT log FFT),諧波積譜,狀態空間密度及其變化(RAPT,YAAPT,et.al.)。

補充:

這就是說,你可以猜測的頻率,計算頻譜幅度的平均值和標準偏差,比如說,在你的猜測2:1的頻率範圍,看是否存在峯值明顯高於平均水平(2西格瑪?)。沖洗並重復一定次數的猜測,並查看哪一個或幾個中的哪一個具有從平均值中突出最多的峯值。使用該峯值。