2011-05-28 121 views
1

我目前正在開發一個程序,用於分析演奏樂器的獨奏音樂家的wav文件並檢測其中的音符。要做到這一點,它執行FFT,然後查看生成的數據。目標是(在某個時候)通過編寫MIDI文件來製作樂譜。活頁樂譜的音頻分析

我只想就什麼可能會有困難,不管是否有人嘗試過,也許有些事情是很好的研究。目前我最大的困難是,並不是所有的音符都是純粹的一個頻率,我還不能檢測到和絃;只是單一的筆記。還有,我正在檢測的音符之間有一段暫停,所以我確定一個音樂已經結束,另一個開始。對此的任何評論也將非常歡迎!

這是我使用的代碼,當一個新的幀來自信號。它會尋找樣本中最主要的頻率:

//Get frequency vector for power match 
     double[] frequencyVectorDoubleArray = Accord.Audio.Tools.GetFrequencyVector(waveSignal.Length, waveSignal.SampleRate); 

     powerSpectrumDoubleArray[0] = 0; // zero DC 

     double[,] frequencyPowerDoubleArray = new double[powerSpectrumDoubleArray.Length, 2]; 

     for (int i = 0; i < powerSpectrumDoubleArray.Length; i++) 
     { 
      if (frequencyVectorDoubleArray[i] > 15.00) 
      { 
       frequencyPowerDoubleArray[i, 0] = frequencyVectorDoubleArray[i]; 
       frequencyPowerDoubleArray[i, 1] = powerSpectrumDoubleArray[i]; 
      } 
     } 

    //Method for finding the highest frequency in a sample of frequency domain data 
     //But I want to filter out stuff 
     pulsePowerDouble = lowestPowerAcceptedDouble;//0;//lowestPowerAccepted; 
     int frequencyIndexAtPulseInt = 0; 
     int oldFrequencyIndexAtPulse = 0; 
     for (int j = 0; j < frequencyPowerDoubleArray.Length/2; j++) 
     { 
      if (frequencyPowerDoubleArray[j, 1] > pulsePowerDouble) 
      { 
       oldPulsePowerDouble = pulsePowerDouble; 
       pulsePowerDouble = frequencyPowerDoubleArray[j, 1]; 

       oldFrequencyIndexAtPulse = frequencyIndexAtPulseInt; 
       frequencyIndexAtPulseInt = j; 
      } 
     } 
     foundFreq = frequencyPowerDoubleArray[frequencyIndexAtPulseInt, 0]; 
+0

你有任何代碼可以告訴我們嗎? – 2011-05-28 23:53:19

+0

當然。將張貼。 – Nyx 2011-05-29 00:46:59

+0

請參閱http://stackoverflow.com/questions/435533/detecting-the-fundamental-frequency – mtrw 2011-05-29 02:00:03

回答

4

1)關於頻率估計和基音估計(這是兩個不同的主題)的研究文獻有很多(幾十年的價值)。 2)峯值FFT頻率與音高不一致。一些獨奏樂器只能爲一個音符產生超過十幾個頻率峯值,更不用說和絃了,並且在音樂音調附近的任何地方都沒有最大的峯值。對於一些常用儀器,峯值甚至可能不是數學上精確的諧波。

3)使用短的未加窗FFT的峯值箱不是一個很好的頻率估計器。

4)根據儀器的不同,註釋起始檢測可能需要一些複雜的模式匹配。

+0

嗨。謝謝,我現在也在使用一個窗口(Hann),並且一直在考慮隱藏的馬爾可夫模型進行模式匹配。該窗口大大提高了我找到的頻率的準確性。 RE 2:這確實是一個問題。目前我有點解決其中的一部分,通過檢查一組樣本中最強大頻率的較低八度音和最高頻率的出現。 – Nyx 2011-06-02 04:21:34

1

您不想專注於最高頻率,而是最低頻率。任何樂器的音符都充滿了諧波。期待聽到最基本的,每個八度音階。加上所有的二次和三次諧波。

諧波是什麼讓他們都在播放相同的音符喇叭聲音不同於長號。

+0

請記住,雖然這通常會失去根本(http://en.wikipedia.org/wiki/Missing_fundamental)。 – mtrw 2011-05-29 01:59:42

+0

是的,上面的代碼只會在樣本中聲音最大。稍後我會查看是否出現較低的頻率,例如,如果II正在播放A4並將數據返回,如下所示: 440,880,880,880,880 顯示A5更可能是音符I將會認爲它是A4,因爲至少有一次出現A4。然而,音符越低,我發現越難得到任何事件,因爲它們足夠大聲。 – Nyx 2011-05-29 08:05:48

1

不幸的是,這是一個非常困難的問題,一些原因已經給出。我將從文獻搜索開始(例如谷歌學術搜索)來進行「音符識別」。

如果這不是一個閒暇時間的項目,要小心 - 我已經看到了碩士論文創始人在這個特殊的淺灘沒有得到任何有用的結果。