1986年出版的《音樂心理學》一書中說到「人類和音樂遵循共同的規律」。研究發現,人類大腦的生理信號具有帶直線區域的線性規律,在生理上具有普遍性,產生公式:S(f) 1 / f ɑ。
二十世紀八十年代,有專家研究巴赫《第一勃蘭登堡協奏曲》的音樂信號時發現,音樂信號的功率譜與人類大腦生理信號的功率譜相似,符合1/f信號公式。還發現,音樂信號α越靠近數值1越好聽,從科學上找到一個近似參數來判定音樂的悅耳度。2012年加拿大麥吉爾大學音樂系主任分析發現,音樂節奏也滿足這個規律,α值為0.8。不同音樂體裁的α值不一樣,所以也可以用這個數值反推音樂的風格體裁。不同作曲家風格音樂的α值不一樣,但是作曲家們所作出來的各種風格體裁的音樂的參數是相似的。
現在的公司使用音樂分類,既可以向客戶提供推薦,也可以僅僅作為產品。確定音樂類型是朝這個方向邁出的第一步。事實證明,機器學習技術在從大量資料庫中提取趨勢和模式方面非常成功。同樣的原則也適用於音樂分析。
在本文中,我們將研究如何用Python處理音頻/音樂信號,再利用所學的技能將音樂片段分類為不同的類型。
聲音以具有諸如頻率、帶寬、分貝等參數的音頻信號的形式表示,典型的音頻信號可以表示為幅度和時間的函數。
這些聲音有多種格式,使計算機可以讀取和分析它們。例如:
音頻庫
Python有一些很棒的音頻處理庫,比如Librosa和PyAudio。還有一些內置的模塊用於一些基本的音頻功能。
我們將主要使用兩個庫進行音頻採集和回放:
1. Librosa
它是一個Python模塊,通常用於分析音頻信號,但更傾向於音樂。它包括用於構建MIR(音樂信息檢索)系統的nuts 和 bolts。示例和教程:https://librosa.github.io/librosa/
安裝
pip install librosa or conda install -c conda-forge librosa
為了提供更多的音頻解碼能力,您可以安裝隨許多音頻解碼器一起提供的ffmpeg。
2. IPython.display.Audio
IPython.display.Audio 讓您直接在jupyter筆記本中播放音頻。
載入音頻文件
import librosa audio_path = ../T08-violin.wav x , sr = librosa.load(audio_path) print(type(x), type(sr)) <class numpy.ndarray> <class int> print(x.shape, sr) (396688,) 22050
這會將音頻時間序列作為numpy數組返回,默認採樣率(sr)為22KHZ mono。我們可以通過以下方式更改此行為:
librosa.load(audio_path, sr=44100)
以44.1KHz重新採樣,或禁用重新採樣。採樣率是每秒傳輸的音頻樣本數,以Hz或kHz為單位。
librosa.load(audio_path, sr=None)
使用IPython.display.Audio播放音頻。
import IPython.display as ipd ipd.Audio(audio_path)
然後返回jupyter筆記本中的音頻小部件,如下圖所示,這個小部件在這裡不起作用,但它可以在你的筆記本中使用,你甚至可以使用mp3或WMA格式作為音頻示例。
波形
我們可以繪製音頻數組librosa.display.waveplot:
%matplotlib inline import matplotlib.pyplot as plt import librosa.display plt.figure(figsize=(14, 5)) librosa.display.waveplot(x, sr=sr)
譜圖是通過視覺表示頻譜的頻率、聲音或其他信號,因為它們隨時間變化。頻譜圖有時被稱為超聲波儀,聲紋或語音圖。當數據在3D圖中表示時,它們可以稱為waterfalls。在二維陣列中,第一軸是頻率,而第二軸是時間。
我們可以使用顯示頻譜圖: librosa.display.specshow.
X = librosa.stft(x) Xdb = librosa.amplitude_to_db(abs(X)) plt.figure(figsize=(14, 5)) librosa.display.specshow(Xdb, sr=sr, x_axis=time, y_axis=hz) plt.colorbar()
縱軸表示頻率(從0到10kHz),橫軸表示剪輯的時間。由於我們看到所有動作都發生在頻譜的底部,我們可以將頻率軸轉換為對數軸。
librosa.display.specshow(Xdb, sr=sr, x_axis=time, y_axis=log) plt.colorbar()
librosa.output.write_wav 將NumPy數組保存到WAV文件。
librosa.output.write_wav(example.wav, x, sr)
現在讓我們創建一個220Hz的音頻信號,音頻信號是一個numpy數組,所以我們將創建一個並將其傳遞給音頻函數。
import numpy as np sr = 22050 # sample rate T = 5.0 # seconds t = np.linspace(0, T, int(T*sr), endpoint=False) # time variable x = 0.5*np.sin(2*np.pi*220*t)# pure sine wave at 220 Hz Playing the audio ipd.Audio(x, rate=sr) # load a NumPy array Saving the audio librosa.output.write_wav(tone_220.wav, x, sr)
每個音頻信號都包含許多特徵。但是,我們必須提取與我們試圖解決的問題相關的特徵。提取要使用它們進行分析的特徵的過程稱為特徵提取,讓我們詳細研究一些特徵。
該特徵在語音識別和音樂信息檢索中都被大量使用。對於像金屬和岩石那樣的高衝擊聲,它通常具有更高的值。讓我們計算示例音頻片段的過零率。
# Load the signal x, sr = librosa.load(../T08-violin.wav) #Plot the signal: plt.figure(figsize=(14, 5)) librosa.display.waveplot(x, sr=sr)
# Zooming in n0 = 9000 n1 = 9100 plt.figure(figsize=(14, 5)) plt.plot(x[n0:n1]) plt.grid()
似乎有6個過零點,讓我們用librosa驗證。
zero_crossings = librosa.zero_crossings(x[n0:n1], pad=False) print(sum(zero_crossings)) 6
它指示聲音的「質心」位於何處,並計算為聲音中存在的頻率的加權平均值。如果有兩首歌曲,一首來自布魯斯類型,另一首屬於金屬。與長度相同的布魯斯流派歌曲相比,金屬歌曲在最後有更多的頻率。因此,布魯斯歌曲的光譜質心將位於其光譜中間附近,而金屬歌曲的光譜質心將朝向它的末端。
librosa.feature.spectral_centroid 計算信號中每幀的光譜質心:
spectral_centroids = librosa.feature.spectral_centroid(x, sr=sr)[0] spectral_centroids.shape (775,) # Computing the time variable for visualization frames = range(len(spectral_centroids)) t = librosa.frames_to_time(frames) # Normalising the spectral centroid for visualisation def normalize(x, axis=0): return sklearn.preprocessing.minmax_scale(x, axis=axis) #Plotting the Spectral Centroid along the waveform librosa.display.waveplot(x, sr=sr, alpha=0.4) plt.plot(t, normalize(spectral_centroids), color=r)
它是信號形狀的度量。librosa.feature.spectral_rolloff 計算信號中每幀的滾降係數:
spectral_rolloff = librosa.feature.spectral_rolloff(x+0.01, sr=sr)[0] librosa.display.waveplot(x, sr=sr, alpha=0.4) plt.plot(t, normalize(spectral_rolloff), color=r)
信號的Mel頻率倒譜係數(MFCC)是一小組特徵(通常約10-20),其簡明地描述了頻譜包絡的整體形狀,它模擬了人聲的特徵。讓我們這次用一個簡單的循環波。
x, fs = librosa.load(../simple_loop.wav) librosa.display.waveplot(x, sr=sr)
librosa.feature.mfcc 通過音頻信號計算MFCC:
mfccs = librosa.feature.mfcc(x, sr=fs) print mfccs.shape (20, 97) #Displaying the MFCCs: librosa.display.specshow(mfccs, sr=sr, x_axis=time)
這裡mfcc計算了超過97幀的20個MFCC。我們還可以執行特徵縮放,使得每個係數維度具有零均值和單位方差:
import sklearn mfccs = sklearn.preprocessing.scale(mfccs, axis=1) print(mfccs.mean(axis=1)) print(mfccs.var(axis=1)) librosa.display.specshow(mfccs, sr=sr, x_axis=time)
色度頻率是音樂音頻有趣且強大的表示,其中整個頻譜被投影到12個區間,代表音樂八度音的12個不同的半音(或色度),librosa.feature.chroma_stft 用於計算。
# Loadign the file x, sr = librosa.load(../simple_piano.wav) hop_length = 512 chromagram = librosa.feature.chroma_stft(x, sr=sr, hop_length=hop_length) plt.figure(figsize=(15, 5)) librosa.display.specshow(chromagram, x_axis=time, y_axis=chroma, hop_length=hop_length, cmap=coolwarm)
在概述了聲學信號,它們的特徵和它們的特徵提取過程之後,是時候利用我們新開發的技能來處理機器學習問題了。
目的
在這個部分中,我們將嘗試對分類器進行建模,以將歌曲分類為不同的類型。讓我們假設一個場景:由於某種原因,我們在硬碟上找到一堆隨機命名的MP3文件,我們的任務是根據音樂類型將它們分類到不同的文件夾中,如爵士樂、古典樂、鄉村音樂、流行樂、搖滾樂和金屬樂。
數據集
我們將使用著名的GITZAN數據集進行案例研究,該數據集曾用於G.Tzanetakis和P.Cook在IEEE Transactions on Audio and Speech Processing 2002 中的「 音頻信號的音樂類型分類」。
數據集由每30秒長的1000個音軌組成,它包含10種類型:藍調、古典、鄉村、迪斯科、嘻哈、爵士、雷鬼、搖滾、金屬和流行音樂,每種類型包含100個聲音片段。
預處理數據
在訓練分類模型之前,我們必須將音頻樣本中的原始數據轉換為更有意義的表示,音頻片段需要從.au格式轉換為.wav格式,以使其與用於讀取音頻文件的python波形模塊兼容。可開源SoX模塊進行轉換(http://sox.sourceforge.net/)
sox input.au output.wav
特徵提取
然後,我們需要從音頻文件中提取有意義的功能。為了對我們的音頻片段進行分類,我們將選擇5個特徵,即過零率、光譜質心、光譜衰減、梅爾頻率倒譜係數和色度頻率。然後將所有功能附加到.csv文件中,以便可以使用分類演算法。
分類
一旦提取了特徵,我們就可以使用現有的分類演算法將歌曲分類為不同的類型。您可以直接使用頻譜圖像進行分類,也可以提取特徵並在其上使用分類模型。
無論哪種方式,都可以在模型方面進行大量實驗。您可以自由地嘗試並改善結果。使用CNN模型(在頻譜圖像上)可以提供更好的準確度,值得一試。
網址:https://gist.github.com/parulnith/7f8c174e6ac099e86f0495d3d9a4c01e#file-music_genre_classification-ipynb
音樂類型分類是音樂信息檢索的眾多分支之一。從這裡你可以執行音樂數據的其他任務,如節拍跟蹤、音樂生成、推薦系統、音軌分離和樂器識別等。音樂分析是一個多樣化的領域,也是一個有趣的領域。音樂會話以某種方式代表用戶的時刻,找到這些時刻並描述它們是數據科學領域的一個有趣挑戰。
參考資料:https://towardsdatascience.com/music-genre-classification-with-python-c714d032f0d8
[關於轉載]:本文為「學術頭條」原創文章。轉載僅限全文轉載並保留文章標題及內容,不得刪改、添加內容繞開原創保護,且文章開頭必須註明:轉自「SciTouTiao」微信公眾號。謝謝您的合作。