結合Python代碼介紹音符起始點檢測 (onset detection)


本文由 meelo 原創,請務必以鏈接形式注明 本文地址

音符起始點檢測介紹

音符起始點檢測(onset detection)是音樂信號處理中非常重要的一個算法。節拍和速度(tempo)的檢測都會基於音符起始點的檢測。

音符起始點就是其字面意思,表示琴鍵🎹按下的那個時刻。

 

音符起始點檢測仍然是一個非常活躍的研究方向,MIREX的年度音樂信號處理競賽的一個題目便是音符起始點檢測

本文里,我會結合代碼,介紹一種簡單的算法。

注:代碼使用了Python的librosa庫。

 

音符起始點的一個特征是,能量的突然增加,或是頻譜能量分布的改變。

根據這一特征,我們可以設計如下算法。算法是在頻域進行的。

算法

輸入為音樂的離散時間信號,輸出為所有音符起始點的時間。

1. 計算對數梅爾時頻圖幅度

mel = np.abs(librosa.feature.melspectrogram(y, fmax=11025))
amp_db = librosa.power_to_db(mel)

2. 計算對數梅爾時頻圖幅度的一階時間差分,並計算每一幀所有頻率點幅度的均值。

diff = np.maximum(amp_db[:,1:] - amp_db[:,:-1], 0.0)
onset_amp = np.mean(diff, axis=0)

3. 歸一化到[0,1]之間,並進行峰值檢測。

onset_my -= onset_my.min()
onset_my /= onset_my.max()
onset_peak = librosa.util.peak_pick(onset_my)

上圖中藍色實線表示算法中第二步所計算得到的結果,紅色虛線是峰值檢測后的結果。

庫函數用法示例

Python的librosa庫中已有音符起始點檢測的函數,使用的算法便是上面介紹的算法。如果希望了解算法的一些細節以及參數的選擇,可以閱讀函數的源碼。

下面是庫函數的一個示例用法:

import librosa

y, sr = librosa.load('music.mp3')
onsets_frames = librosa.onset.onset_detect(y)
D = librosa.stft(y)
librosa.display.specshow(librosa.amplitude_to_db(D))
plt.vlines(onsets_frames, 0, sr, color='r', linestyle='--')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM