1986年出版的《音樂心理學》一書中說到「人類和音樂遵循共同的規律」。研究發現,人類大腦的生理信號具有帶直線區域的線性規律,在生理上具有普遍性,產生公式:S(f) 1 / f ɑ。

二十世紀八十年代,有專家研究巴赫《第一勃蘭登堡協奏曲》的音樂信號時發現,音樂信號的功率譜與人類大腦生理信號的功率譜相似,符合1/f信號公式。還發現,音樂信號α越靠近數值1越好聽,從科學上找到一個近似參數來判定音樂的悅耳度。2012年加拿大麥吉爾大學音樂系主任分析發現,音樂節奏也滿足這個規律,α值為0.8。不同音樂體裁的α值不一樣,所以也可以用這個數值反推音樂的風格體裁。不同作曲家風格音樂的α值不一樣,但是作曲家們所作出來的各種風格體裁的音樂的參數是相似的。

現在的公司使用音樂分類,既可以向客戶提供推薦,也可以僅僅作為產品。確定音樂類型是朝這個方向邁出的第一步。事實證明,機器學習技術在從大量資料庫中提取趨勢和模式方面非常成功。同樣的原則也適用於音樂分析。

在本文中,我們將研究如何用Python處理音頻/音樂信號,再利用所學的技能將音樂片段分類為不同的類型。

使用Python進行音頻處理

聲音以具有諸如頻率、帶寬、分貝等參數的音頻信號的形式表示,典型的音頻信號可以表示為幅度和時間的函數。

這些聲音有多種格式,使計算機可以讀取和分析它們。例如:

  • mp3格式
  • WMA(Windows Media Audio)格式
  • wav(波形音頻文件)格式

音頻庫

Python有一些很棒的音頻處理庫,比如Librosa和PyAudio。還有一些內置的模塊用於一些基本的音頻功能。

我們將主要使用兩個庫進行音頻採集和回放:

1. Librosa

它是一個Python模塊,通常用於分析音頻信號,但更傾向於音樂。它包括用於構建MIR(音樂信息檢索)系統的nuts 和 bolts。示例和教程:librosa.github.io/libro

安裝

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模塊進行轉換sox.sourceforge.net/

sox input.au output.wav

特徵提取

然後,我們需要從音頻文件中提取有意義的功能。為了對我們的音頻片段進行分類,我們將選擇5個特徵,即過零率、光譜質心、光譜衰減、梅爾頻率倒譜係數和色度頻率。然後將所有功能附加到.csv文件中,以便可以使用分類演算法。

分類

一旦提取了特徵,我們就可以使用現有的分類演算法將歌曲分類為不同的類型。您可以直接使用頻譜圖像進行分類,也可以提取特徵並在其上使用分類模型。

無論哪種方式,都可以在模型方面進行大量實驗。您可以自由地嘗試並改善結果。使用CNN模型(在頻譜圖像上)可以提供更好的準確度,值得一試。

網址:gist.github.com/parulni

音樂類型分類是音樂信息檢索的眾多分支之一。從這裡你可以執行音樂數據的其他任務,如節拍跟蹤、音樂生成、推薦系統、音軌分離和樂器識別等。音樂分析是一個多樣化的領域,也是一個有趣的領域。音樂會話以某種方式代表用戶的時刻,找到這些時刻並描述它們是數據科學領域的一個有趣挑戰。

參考資料:towardsdatascience.com/

[關於轉載]:本文為「學術頭條」原創文章。轉載僅限全文轉載並保留文章標題及內容,不得刪改、添加內容繞開原創保護,且文章開頭必須註明:轉自「SciTouTiao」微信公眾號。謝謝您的合作。

歡迎關注微信公眾號「學術頭條」

推薦閱讀:
相關文章