Librosa教程

来自泡泡学习笔记
跳到导航 跳到搜索

本节涵盖了使用librosa进行开发的基础知识,包括包概述、基本和高级用法以及与scikit-learn包的集成。我们将假设对Python和NumPy/SciPy有基本的熟悉程度。


概述

librosa包的结构是由子模块组成的集合:


  • librosa.beat
    • 用于估计节奏和检测节拍事件的函数。


  • librosa.core
    • 核心功能包括从磁盘加载音频、计算各种频谱图表示以及音乐分析中常用的各种工具。为了方便起见,此子模块中的所有功能都可以直接从顶级librosa.*命名空间访问。


  • librosa.decompose
    • 用于谐波-打击声源分离(HPSS)和使用scikit-learn实现的矩阵分解方法进行通用频谱图分解的函数。


  • librosa.display
    • 使用matplotlib进行可视化和显示例程。


  • librosa.effects
    • 时域音频处理,如音高移位和时间拉伸。此子模块还为分解子模块提供时域包装器。


  • librosa.feature
    • 特征提取和操作。这包括低级特征提取,如色度图、Mel频谱图、MFCC以及各种其他频谱和节奏特征。还提供了特征操作方法,如delta特征和内存嵌入。


  • librosa.filters
    • 滤波器生成(色度、伪CQT、CQT等)。这些主要是由librosa的其他部分使用的内部函数。


  • librosa.onset
    • 检测和起始强度计算。


  • librosa.segment
    • 对于结构性分割有用的函数,例如递归矩阵构建、时间滞后表示和顺序约束聚类。


  • librosa.sequence
    • 用于顺序建模的函数。各种形式的Viterbi解码,以及构建转移矩阵的辅助函数。


  • librosa.util
    • 辅助实用程序(归一化、填充、居中等)。


快速入门

在深入了解之前,我们将通过一个简单的示例程序进行演示。

# Beat tracking example
import librosa

# 1. Get the file path to an included audio example
filename = librosa.example('nutcracker')


# 2. Load the audio as a waveform `y`
#    Store the sampling rate as `sr`
y, sr = librosa.load(filename)

# 3. Run the default beat tracker
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)

print('Estimated tempo: {:.2f} beats per minute'.format(tempo))

# 4. Convert the frame indices of beat events into timestamps
beat_times = librosa.frames_to_time(beat_frames, sr=sr)


  1. 程序的第一步:

     filename = librosa.example('nutcracker')

    获取librosa附带的音频示例文件的路径。在此步骤之后,filename将是一个包含示例音频文件路径的字符串变量。


  2. 第二步:

     y, sr = librosa.load(filename)

    加载并解码音频为表示为一维NumPy浮点数组的时间序列y。变量sr包含y的采样率,即每秒的样本数。默认情况下,所有音频都混合为单声道并在加载时重新采样为22050 Hz。这种行为可以通过向librosa.load提供额外的参数来覆盖。


  3. 接下来,我们运行节拍跟踪器:

    tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)

    节拍跟踪器的输出是对节奏(以每分钟的拍数为单位)的估计,以及与检测到的节拍事件对应的帧号数组。

    这里的帧对应于信号(y)的短窗口,每个窗口之间相隔hop_length = 512个样本。librosa使用居中帧,因此第k帧围绕样本k * hop_length居中。


  4. 下一个操作将帧号beat_frames转换为时间戳:

    beat_times = librosa.frames_to_time(beat_frames, sr=sr)

    现在,beat_times将是一个与检测到的节拍事件对应的时间戳数组(以秒为单位)。


    beat_times的内容应该如下所示:

     7.43
     8.29
     9.218
     10.124
     ...


高级用法

这里我们将介绍一个更高级的例子,整合谐波-打击声分离、多种频谱特征和节拍同步特征聚合。

# Feature extraction example
import numpy as np
import librosa

# Load the example clip
y, sr = librosa.load(librosa.ex('nutcracker'))

# Set the hop length; at 22050 Hz, 512 samples ~= 23ms
hop_length = 512

# Separate harmonics and percussives into two waveforms
y_harmonic, y_percussive = librosa.effects.hpss(y)

# Beat track on the percussive signal
tempo, beat_frames = librosa.beat.beat_track(y=y_percussive,
                                            sr=sr)

# Compute MFCC features from the raw signal
mfcc = librosa.feature.mfcc(y=y, sr=sr, hop_length=hop_length, n_mfcc=13)

# And the first-order differences (delta features)
mfcc_delta = librosa.feature.delta(mfcc)

# Stack and synchronize between beat events
# This time, we'll use the mean value (default) instead of median
beat_mfcc_delta = librosa.util.sync(np.vstack([mfcc, mfcc_delta]),
                                    beat_frames)

# Compute chroma features from the harmonic signal
chromagram = librosa.feature.chroma_cqt(y=y_harmonic,
                                        sr=sr)

# Aggregate chroma features between beat events
# We'll use the median value of each feature between beat frames
beat_chroma = librosa.util.sync(chromagram,
                                beat_frames,
                                aggregate=np.median)

# Finally, stack all beat-synchronous features together
beat_features = np.vstack([beat_chroma, beat_mfcc_delta])


这个例子基于我们已经在快速入门示例中介绍过的工具,所以这里我们将专注于新的部分。


  1. 第一个区别是使用效果模块进行时间序列谐波-打击声分离:

     y_harmonic, y_percussive = librosa.effects.hpss(y)

    这一行的结果是将时间序列y分离成两个时间序列,包含信号的谐波(音调)和打击声(瞬态)部分。y_harmonic和y_percussive与y具有相同的形状和持续时间。

    进行这种操作的动机有两方面:首先,打击元素往往是节奏内容更强的指示器,可以帮助提供更稳定的节拍跟踪结果;其次,打击元素可以通过在所有频带上贡献能量来污染音调特征表示(如色度),因此没有它们会更好。


  2. 接下来,我们引入特征模块并从原始信号y中提取梅尔频率倒谱系数:

     mfcc = librosa.feature.mfcc(y=y, sr=sr, hop_length=hop_length, n_mfcc=13)

    此函数的输出是矩阵mfcc,它是一个形状为(n_mfcc, T)的numpy.ndarray(其中T表示以帧为单位的跟踪持续时间)。请注意,我们在这里使用与节拍跟踪器相同的hop_length,因此检测到的beat_frames值对应于mfcc的列。


  3. 我们引入的第一类特征操作是delta,它计算其输入列之间的(平滑)一阶差值:

     mfcc_delta = librosa.feature.delta(mfcc)

    生成的矩阵mfcc_delta与输入mfcc具有相同的形状。


  4. 第二类特征操作是sync,它在采样索引(例如,节拍帧)之间聚合其输入列:

     beat_mfcc_delta = librosa.util.sync(np.vstack([mfcc, mfcc_delta]), beat_frames)

    这里,我们将mfcc和mfcc_delta矩阵垂直堆叠在一起。此操作的结果是一个矩阵beat_mfcc_delta,其行数与输入相同,但列数取决于beat_frames。每个beat_mfcc_delta[:, k]将是从beat_frames[k]到beat_frames[k+1]之间的输入列的平均值。(beat_frames将被扩展以覆盖整个范围[0, T],以便所有数据都被考虑在内。)


  5. 接下来,我们仅使用谐波分量计算色度图:

     chromagram = librosa.feature.chroma_cqt(y=y_harmonic, sr=sr)

    在这一行之后,chromagram将是一个形状为(12, T)的numpy.ndarray,每一行对应于一个音高类别(例如,C,C#等)。chromagram的每一列都通过其峰值值进行归一化,尽管可以通过设置norm参数来覆盖这种行为。


  6. 一旦我们有了色度图和节拍帧列表,我们再次在节拍事件之间同步色度:

     beat_chroma = librosa.util.sync(chromagram, beat_frames, aggregate=np.median)

    这一次,我们将默认的聚合操作(如上文用于MFCCs的平均)替换为中位数。一般来说,可以在这里提供任何统计汇总功能,包括np.max(),np.min(),np.std()等。


  7. 最后,所有特征再次垂直堆叠:

     beat_features = np.vstack([beat_chroma, beat_mfcc_delta])

    从而得到一个形状为(12 + 13 + 13, # beat intervals)的特征矩阵beat_features。