音樂識別系統:Audio-Fingerprinting
Audio-Fingerprinting 是一個音樂指紋識別系統,使用的語言為 JAVA,同時需要用到 MySQL 數據庫(雖然不是必須的,但這個系統采用他保存指紋和音樂信息)。他包含了指紋生成,數據庫存儲,和簡易的服務器和客戶端。
他通過生成和記錄音樂指紋,能夠識別來自麥克風、文件等各個來源的音樂,并且有很高的抗噪性,同時他對文件屬性和音樂質量不敏感。你可以使用服務器給手機或者其他程序提供音樂識別服務。
你可以根據需求調節里面的參數,當前參數是為了在較短時間識別來自極大噪聲和失真的音源,1500個左右的文件將產生接近24000000個指紋數據。如果你只用于識別文件并且沒有嚴重的噪聲與失真,你可以修改參數,1個文件只需要少量指紋就可以識別,對于噪聲較低的音源10s 200個指紋已經滿足大多需求。
簡易使用方法
-
需要安裝MySQL,并執行Fingerprint. sql, 同時你可能需要修改max_allowed_packet參數,因為添加歌曲需要發送較大的包,我采用的參數是32M。
-
修改MysqlDB中的數據庫信息為你的數據庫信息,如:
private final String url = "jdbc:mysql://127.0.0.1:3306/musiclibary?user=yecheng"; private final String user = "yecheng"; private final String password = "yecheng";
-
添加文件的方法:
Ps:你可以重寫添加的方法或者制作腳本或者直接使用其他軟件實現轉碼功能,目前他能夠從%title%}}%album%}}%artist%的文件名中獲得信息。
-
將文件轉碼為WAV,采樣率為8000。
-
調用Insert,參數為文件名或者文件夾。
-
搜索音樂
-
你可以調用Search+文件名搜索。
-
在數據庫較大的情況推薦采用運行Server,使用Client+文件名搜索。
主要參數介紹
Fingerprint:
NPeaks:一個周期中每個子帶的峰值點的個數 fftSize:FFT的窗口大小 overlap:FFT的窗口重疊大小 C:一個周期包含多少個窗口 peakRange:取峰值點時與多大范圍的鄰居比較 range_time:取點對的時候的時間范圍,單位為秒 range_freq:取點對的時候的頻率范圍,單位為頻率 Band:分成的子帶,值對應FFT產生的數組索引 minFreq:最小頻率 maxFreq:最大頻率 minPower:最小能量
修改的建議:
-
提高識別率:
-
減小minPower, 增加Band、NPeaks、range_time
-
降低數據量:
-
增大minPower,減小Band、NPeaks、rang_time
其中建議先修改Band和minPower。
Server:
port:服務器的端口
Client:
ip:服務器的ip port:服務器的端口
性能與效果
數據量:音樂庫為1500首歌,指紋數量為24000000個左右,服務器穩定后占用內存約340M。
速度:處理器i7-3632QM,添加1500首歌用時約1919秒,一首歌約用時1.3秒。使用服務器查找10s的歌曲用時約0.2秒(不考慮客戶端讀取文件的時間)。
準確度:對噪聲較低的音頻有很高的識別率,對噪聲較高的也有接近商用的準確率,但是相對來說如果對于未出現在曲庫的歌曲,也有一定的誤報率。
抗噪性:能夠抵抗較強的失真和噪聲,可以參考我給的測試音頻。
工作原理
參考文檔:
本算法實現類似Shazam,首先我計算出音頻的頻譜圖,將頻譜根據頻率分成若干子帶,對每個子帶查找若干個峰值點,本算法子帶劃分基于Mel頻率。
將獲得的峰值點根據頻率、時間范圍組成點對。
本算法的取點對頻率范圍為在子帶內,其目的在于減少點對的數目并且提高分布式能力。取點對的時間范圍為1s-4s。你可以根據需要修改這些參數。