欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python通過(guò)90行代碼搭建一個(gè)音樂(lè)搜索工具

 更新時(shí)間:2015年07月29日 11:32:56   投稿:mrr  
這篇文章主要介紹了Python通過(guò)90行代碼搭建一個(gè)音樂(lè)搜索工具,需要的朋友可以參考下

下面小編把具體實(shí)現(xiàn)代碼給大家分享如下:

之前一段時(shí)間讀到了這篇博客,其中描述了作者如何用java實(shí)現(xiàn)國(guó)外著名音樂(lè)搜索工具shazam的基本功能。其中所提到的文章又將我引向了關(guān)于shazam的一篇論文及另外一篇博客。讀完之后發(fā)現(xiàn)其中的原理并不十分復(fù)雜,但是方法對(duì)噪音的健壯性卻非常好,出于好奇決定自己用python自己實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的音樂(lè)搜索工具—— Song Finder, 它的核心功能被封裝在SFEngine 中,第三方依賴方面只使用到了 scipy。

工具demo
這個(gè)demo在ipython下展示工具的使用,本項(xiàng)目名稱為Song Finder,我把索引、搜索的功能全部封裝在Song Finder中的SFEngine中。首先是簡(jiǎn)單的準(zhǔn)備工作:

復(fù)制代碼 代碼如下:

In [1]: from SFEngine import *

In [2]: engine = SFEngine()


在這之后我們對(duì)現(xiàn)有歌曲進(jìn)行索引,我在original目錄下準(zhǔn)備了幾十首歌曲(.wav文件)作為曲庫(kù):

復(fù)制代碼 代碼如下:

In [3]: engine.index('original') # 索引該目錄下的所有歌曲

在完成索引之后我們向Song Finder提交一段有背景噪音的歌曲錄音進(jìn)行搜索。對(duì)于這段《楓》在1分15秒左右的錄音:

工具的返回結(jié)果是:

復(fù)制代碼 代碼如下:

In [4]: engine.search('record/record0.wav')
original/周杰倫-楓 73
original/周杰倫-楓 31
original/周杰倫-楓 10
original/周杰倫-楓 28
original/我要快樂(lè) - 張惠妹 28

其中展示的分別是歌曲名稱及片段在歌曲中出現(xiàn)的位置(以秒計(jì)),可以看到工具正確找回了歌曲的曲名,也找到了其在歌曲中的正確位置。

而對(duì)于這段《童話》在1分05秒左右的背景噪音更加嘈雜的錄音:

工具的返回結(jié)果是:

復(fù)制代碼 代碼如下:

In [5]: engine.search('record/record8.wav')
original/光良 - 童話 67
original/光良 - 童話 39
original/光良 - 童話 33
original/光良 - 童話 135
original/光良 - 童話 69

可以看到盡管噪音非常嘈雜,但是工具仍然能成功識(shí)別所對(duì)應(yīng)的歌曲并對(duì)應(yīng)到歌曲的正確位置,說(shuō)明工具在噪音較大的環(huán)境下有良好的健壯性!

項(xiàng)目主頁(yè): Github

Song Finder原理
給定曲庫(kù)對(duì)一個(gè)錄音片段進(jìn)行檢索是一個(gè)不折不扣的搜索問(wèn)題,但是對(duì)音頻的搜索并不像對(duì)文檔、數(shù)據(jù)的搜索那么直接。為了完成對(duì)音樂(lè)的搜索,工具需要完成下列3個(gè)任務(wù):

對(duì)曲庫(kù)中的所有歌曲抽取特征
以相同的方式對(duì)錄音片段提取特征
根據(jù)錄音片段的特征對(duì)曲庫(kù)進(jìn)行搜索,返回最相似的歌曲及其在歌曲中的位置
特征提?。侩x散傅立葉變換!
為了對(duì)音樂(lè)(音頻)提取特征,一個(gè)很直接的想法是得到音樂(lè)的音高的信息,而音高在物理上對(duì)應(yīng)的則又是波的頻率信息。為了獲取這類信息,一個(gè)非常直接的額做法是使用離散傅葉變化對(duì)聲音進(jìn)行分析,即使用一個(gè)滑動(dòng)窗口對(duì)聲音進(jìn)行采樣,對(duì)窗口內(nèi)的數(shù)據(jù)進(jìn)行離散傅立葉變化,將時(shí)間域上的信息變換為頻率域上的信息,使用scipy的接口可以很輕松的完成。在這之后我們將頻率分段,提取每頻率中振幅最大的頻率:

復(fù)制代碼 代碼如下:

def extract_feature(self, scaled, start, interval):
    end = start + interval
    dst = fft(scaled[start: end])
    length = len(dst)/2 
    normalized = abs(dst[:(length-1)])
    feature = [ normalized[:50].argmax(), \
                50 +  normalized[50:100].argmax(), \
                100 + normalized[100:200].argmax(), \
                200 + normalized[200:300].argmax(), \
                300 + normalized[300:400].argmax(), \
                400 + normalized[400:].argmax()]
    return feature

這樣,對(duì)于一個(gè)滑動(dòng)窗口,我提取到了6個(gè)頻率作為其特征。對(duì)于整段音頻,我們重復(fù)調(diào)用這個(gè)函數(shù)進(jìn)行特征抽取:

def sample(self, filename, start_second, duration = 5, callback = None):

 start = start_second * 44100
 if duration == 0:
  end = 1e15
 else:
  end = start + 44100 * duration
 interval = 8192
 scaled = self.read_and_scale(filename)
 length = scaled.size
 while start < min(length, end):
  feature = self.extract_feature(scaled, start, interval)
  if callback != None:
   callback(filename, start, feature)
  start += interval

其中44100為音頻文件自身的采樣頻率,8192是我設(shè)定的取樣窗口(對(duì),這樣hardcode是很不對(duì)的),callback是一個(gè)傳入的函數(shù),需要這個(gè)參數(shù)是因?yàn)樵诓煌瑘?chǎng)景下對(duì)于所得到的特征會(huì)有不同的后續(xù)操作。

匹配曲庫(kù)
在得到歌曲、錄音的大量特征后,如何進(jìn)行高效搜索是一個(gè)問(wèn)題。一個(gè)有效的做法是建立一個(gè)特殊的哈希表,其中的key是頻率,其對(duì)應(yīng)的value是一系列(曲名,時(shí)間)的tuple,其記錄的是某一歌曲在某一時(shí)間出現(xiàn)了某一特征頻率,但是以頻率為key而非以曲名或時(shí)間為key。

表格。。

這樣做的好處是,當(dāng)在錄音中提取到某一個(gè)特征頻率時(shí),我們可以從這個(gè)哈希表中找出與該特征頻率相關(guān)的歌曲及時(shí)間!

當(dāng)然有了這個(gè)哈希表還不夠用,我們不可能把所有與特征頻率相關(guān)的歌曲都抽出來(lái),看看誰(shuí)命中的次數(shù)多,因?yàn)檫@樣會(huì)完全無(wú)視歌曲的時(shí)序信息,并引入一些錯(cuò)誤的匹配。

我們的做法是,對(duì)于錄音中在t時(shí)間點(diǎn)的一個(gè)特征頻率f,從曲庫(kù)找出所有與f相關(guān)的(曲名,時(shí)間)tuple,例如我們得到了

復(fù)制代碼 代碼如下:

[(s1, t1), (s2, t2), (s3, t3)]

我們使用時(shí)間進(jìn)行對(duì)齊,得到這個(gè)列表

復(fù)制代碼 代碼如下:

[(s1, t1-t), (s2, t2-t), (s3, t3-t)]

記為

復(fù)制代碼 代碼如下:

[(s1, t1`), (s2, t2`), (s3, t3`)]

我們對(duì)所有時(shí)間點(diǎn)的所有特征頻率均做上述操作,得到了一個(gè)大列表:

復(fù)制代碼 代碼如下:

[(s1, t1`), (s2, t2`), (s3, t3`), ..., (sn, tn`)]

對(duì)這個(gè)列表進(jìn)行計(jì)數(shù),可以看到哪首歌曲的哪個(gè)時(shí)間點(diǎn)命中的次數(shù)最多,并將命中次數(shù)最多的(曲名,時(shí)間)對(duì)返回給用戶。

不足
這個(gè)小工具是一個(gè)幾個(gè)小時(shí)寫成的hack,有許都地方需要改進(jìn),例如:

目前只支持了wav格式的曲庫(kù)及錄音
所有數(shù)據(jù)都放在內(nèi)存中,曲庫(kù)體積增大時(shí)需要引入更好的后端存儲(chǔ)
索引應(yīng)該并行化,匹配也應(yīng)該并行化,匹配的模型其實(shí)是典型的map-reduce。

以上就是Python通過(guò)90行代碼搭建音樂(lè)搜索工具,希望大家喜歡。

相關(guān)文章

  • Python 解析pymysql模塊操作數(shù)據(jù)庫(kù)的方法

    Python 解析pymysql模塊操作數(shù)據(jù)庫(kù)的方法

    這篇文章主要介紹了Python 解析pymysql模塊操作數(shù)據(jù)庫(kù)的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • python實(shí)現(xiàn)控制電腦鼠標(biāo)和鍵盤,登錄QQ的方法示例

    python實(shí)現(xiàn)控制電腦鼠標(biāo)和鍵盤,登錄QQ的方法示例

    這篇文章主要介紹了python實(shí)現(xiàn)控制電腦鼠標(biāo)和鍵盤,登錄QQ的方法,涉及Python基于Button,Controller,Key模塊針對(duì)鍵盤、鼠標(biāo)的控制相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • opencv實(shí)現(xiàn)文檔矯正

    opencv實(shí)現(xiàn)文檔矯正

    這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)文檔矯正功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Python使用Pycrypto庫(kù)進(jìn)行RSA加密的方法詳解

    Python使用Pycrypto庫(kù)進(jìn)行RSA加密的方法詳解

    RSA加密算法是一種強(qiáng)大的公鑰加密算法,安全性很高,這里我們來(lái)看一下Python使用Pycrypto庫(kù)進(jìn)行RSA加密的方法詳解,需要的朋友可以參考下
    2016-06-06
  • python實(shí)現(xiàn)圖片九宮格分割

    python實(shí)現(xiàn)圖片九宮格分割

    一張圖片分成的九宮圖,大家知道是怎么做到嗎?這篇文章就為大家詳細(xì)介紹了python實(shí)現(xiàn)圖片九宮格分割功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • selenium+python自動(dòng)化測(cè)試之頁(yè)面元素定位

    selenium+python自動(dòng)化測(cè)試之頁(yè)面元素定位

    這篇文章主要介紹了selenium+python自動(dòng)化測(cè)試之頁(yè)面元素定位,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Linux下把Python3設(shè)為默認(rèn)Python版本的三種方法

    Linux下把Python3設(shè)為默認(rèn)Python版本的三種方法

    這篇文章主要給大家介紹了關(guān)于Linux下把Python3設(shè)為默認(rèn)Python版本的三種方法,在大部分開(kāi)發(fā)過(guò)程中,我們需要使用到python3進(jìn)行測(cè)試,于是下載安裝python3,近乎是一種剛需,至于設(shè)置默認(rèn)python指向python3可以參考本文
    2023-09-09
  • OpenCV2.3.1+Python2.7.3+Numpy等的配置解析

    OpenCV2.3.1+Python2.7.3+Numpy等的配置解析

    這篇文章主要介紹了OpenCV2.3.1+Python2.7.3+Numpy等的配置解析,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Python讀寫mat文件操作指南(使用scipy.io)

    Python讀寫mat文件操作指南(使用scipy.io)

    Matlab是一個(gè)非常好用的矩陣計(jì)算分析軟件,然而隨著深度學(xué)習(xí)的發(fā)展,Python語(yǔ)言也逐漸成為人們的常用編程語(yǔ)言,這篇文章主要給大家介紹了關(guān)于Python使用scipy.io讀寫mat文件的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • Python3.9.1中使用split()的處理方法(推薦)

    Python3.9.1中使用split()的處理方法(推薦)

    這篇文章主要介紹了Python3.9.1中使用split()的處理方法(推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02

最新評(píng)論