转:Python处理⾳频信号实战:⼿把⼿教你实现⾳乐流派分类特征提取
1986年出版的《⾳乐⼼理学》⼀书中说到“⼈类和⾳乐遵循共同的规律”。研究发现,⼈类⼤脑的⽣理信号具有带直线区域的线性规律,在⽣理上具有普遍性,产⽣公式:S(f) 1 / f ɑ。
⼆⼗世纪⼋⼗年代,有专家研究巴赫《第⼀勃兰登堡协奏曲》的⾳乐信号时发现,⾳乐信号的功率谱与⼈类⼤脑⽣理信号的功率谱相似,符合1/f信号公式。还发现,⾳乐信号α越靠近数值1越好听,从科学上到⼀个近似参数来判定⾳乐的悦⽿度。2012年加拿⼤麦吉尔⼤学⾳乐系主任分析发现,⾳乐节奏也满⾜这个规律,α值为0.8。不同⾳乐体裁的α值不⼀样,所以也可以⽤这个数值反推⾳乐的风格体裁。不同作曲家风格⾳乐的α值不⼀样,但是作曲家们所作出来的各种风格体裁的⾳乐的参数是相似的。
lemon tree 刘伟男现在的公司使⽤⾳乐分类,既可以向客户提供推荐,也可以仅仅作为产品。确定⾳乐类型是朝这个⽅向迈出的第⼀步。事实证明,机器学习技术在从⼤量数据库中提取趋势和模式⽅⾯⾮常成功。同样的原则也适⽤于⾳乐分析。
在本⽂中,我们将研究如何⽤Python处理⾳频/⾳乐信号,再利⽤所学的技能将⾳乐⽚段分类为不同的类型。
使⽤Python进⾏⾳频处理
声⾳以具有诸如频率、带宽、分贝等参数的⾳频信号的形式表⽰,典型的⾳频信号可以表⽰为幅度和时间的函数。
这些声⾳有多种格式,使计算机可以读取和分析它们。例如:
mp3格式
WMA(Windows Media Audio)格式
wav(波形⾳频⽂件)格式
⾳频库
Python有⼀些很棒的⾳频处理库,⽐如Librosa和PyAudio。还有⼀些内置的模块⽤于⼀些基本的⾳频功能。
我们将主要使⽤两个库进⾏⾳频采集和回放:
1. 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')
纵轴表⽰频率(从0到10kHz),横轴表⽰剪辑的时间。由于我们看到所有动作都发⽣在频谱的底部,我们可以将频率轴转换为对数轴。
librosa.display.specshow(Xdb, sr=sr, x_axis='time', y_axis='log')
王大治父母
写⾳频
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])
王映山id()
似乎有6个过零点,让我们⽤librosa验证。
zero_crossings = _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)
an(axis=1))
林宥嘉突然想起你mv
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个声⾳⽚段。
预处理数据
sox input.au output.wav
特征提取
然后,我们需要从⾳频⽂件中提取有意义的功能。为了对我们的⾳频⽚段进⾏分类,我们将选择5个特征,即过零率、光谱质⼼、光谱衰减、梅尔频率倒谱系数和⾊度频率。然后将所有功能附加到.csv⽂件中,以便可以使⽤分类算法。
分类
⼀旦提取了特征,我们就可以使⽤现有的分类算法将歌曲分类为不同的类型。您可以直接使⽤频谱图像进⾏分类,也可以提取特征并在其上使⽤分类模型。
⽆论哪种⽅式,都可以在模型⽅⾯进⾏⼤量实验。您可以⾃由地尝试并改善结果。使⽤CNN模型(在频谱图像上)可以提供更好的准确度,值得⼀试。
⾳乐类型分类是⾳乐信息检索的众多分⽀之⼀。从这⾥你可以执⾏⾳乐数据的其他任务,如节拍跟踪、⾳乐⽣成、推荐系统、⾳轨分离和乐器识别等。⾳乐分析是⼀个多样化的领域,也是⼀个有趣的领域。⾳乐会话以某种⽅式代表⽤户的时刻,到这些时刻并描述它们是数据科学领域的⼀个有趣挑战。show me your panty