10个必学的Essentia Python示例:快速上手音乐分析
10个必学的Essentia Python示例:快速上手音乐分析
Essentia是一个强大的C++音频分析库,提供了丰富的Python绑定,让音乐和音频分析变得简单高效。本文将通过10个实用示例,帮助你快速掌握Essentia的核心功能,从基础的音频加载到高级的音乐特征提取,开启你的音频分析之旅。
1. 音频文件加载与基本信息获取 🎵
Essentia提供了简单的音频加载接口,让你轻松读取各种格式的音频文件并获取基本信息。
import essentia.standard as es
# 加载音频文件
audio = es.MonoLoader(filename='input.wav')()
sample_rate = 44100
# 获取音频基本信息
duration = len(audio) / sample_rate
print(f"音频时长: {duration:.2f}秒")
print(f"采样率: {sample_rate}Hz")
print(f"音频数据点数: {len(audio)}")
这段代码使用MonoLoader加载音频文件,并计算了音频的时长、采样率等基本信息。Essentia支持多种音频格式,包括WAV、MP3等。
音频波形可视化
2. 节奏分析:检测音乐BPM 🎶
BPM(每分钟节拍数)是音乐的重要特征,Essentia提供了强大的节奏分析工具。
import essentia.standard as es
import numpy as np
# 加载音频
audio = es.MonoLoader(filename='input.wav')()
# 配置参数
frame_size = 2048
hop_size = 128
# 计算频谱和频率带能量
w = es.Windowing(type='hann')
s = es.Spectrum()
freq_bands = es.FrequencyBands()
bands_energies = []
for frame in es.FrameGenerator(audio, frameSize=frame_size, hopSize=hop_size):
bands_energies.append(freq_bands(s(w(frame))))
# 计算 novelty curve 和 BPM
novelty = es.NoveltyCurve(frameRate=44100./hop_size)(np.array(bands_energies))
bpm, _, _, _, _, _, _, _ = es.BpmHistogram(frameRate=44100./hop_size)(novelty)
print(f"检测到的BPM: {bpm:.1f}")
这段代码通过分析音频的频谱能量变化,计算出音乐的节拍信息。你可以调整frame_size和hop_size参数来优化检测结果。
3. 频谱特征:提取MFCC 🎧
MFCC(梅尔频率倒谱系数)是音频信号的重要特征,广泛应用于语音识别和音乐信息检索。
import essentia.standard as ess
def extract_mfcc(filename):
# 配置参数
frame_size = 1102
hop_size = 441
fft_size = 2048
spectrum_size = fft_size // 2 + 1
# 加载音频
audio = ess.MonoLoader(filename=filename, sampleRate=44100)()
# 初始化算法
w = ess.Windowing(type='hamming', size=frame_size, zeroPadding=fft_size - frame_size)
spectrum = ess.Spectrum(size=fft_size)
mfcc = ess.MFCC(inputSize=spectrum_size, numberBands=26, numberCoefficients=13,
warpingFormula='htkMel', highFrequencyBound=8000)
# 提取MFCC
mfccs = []
for frame in ess.FrameGenerator(audio, frameSize=frame_size, hopSize=hop_size):
spect = spectrum(w(frame))
_, mfcc_coeffs = mfcc(spect)
mfccs.append(mfcc_coeffs)
return ess.array(mfccs).T
这个示例实现了类似HTK风格的MFCC提取,适用于需要与语音识别系统兼容的场景。
4. 音调分析:检测音乐调式 🔑
Essentia可以分析音乐的调性特征,包括调式和调性强度。
import essentia
from essentia.streaming import *
def detect_key(audio_file, output_file):
# 初始化算法
loader = MonoLoader(filename=audio_file)
framecutter = FrameCutter()
windowing = Windowing(type="blackmanharris62")
spectrum = Spectrum()
spectralpeaks = SpectralPeaks(orderBy="magnitude", magnitudeThreshold=1e-05,
minFrequency=40, maxFrequency=5000, maxPeaks=10000)
hpcp = HPCP()
key = Key()
# 创建数据池
pool = essentia.Pool()
# 连接算法网络
loader.audio >> framecutter.signal
framecutter.frame >> windowing.frame >> spectrum.frame
spectrum.spectrum >> spectralpeaks.spectrum
spectralpeaks.magnitudes >> hpcp.magnitudes
spectralpeaks.frequencies >> hpcp.frequencies
hpcp.hpcp >> key.pcp
key.key >> (pool, 'tonal.key_key')
key.scale >> (pool, 'tonal.key_scale')
key.strength >> (pool, 'tonal.key_strength')
# 运行分析
essentia.run(loader)
# 输出结果
print(f"音乐调式: {pool['tonal.key_key']} {pool['tonal.key_scale']}")
print(f"调性强度: {pool['tonal.key_strength']:.3f}")
# 保存结果
essentia.standard.YamlOutput(filename=output_file, format="json")(pool)
这个示例展示了Essentia的流式处理能力,通过构建算法网络来分析音频的调性特征。
调性提取流程
5. 傅里叶变换:STFT分析与合成 🔄
短时傅里叶变换(STFT)是音频分析的基础工具,Essentia提供了高效的STFT实现。
import essentia
import essentia.streaming as es
from pathlib import Path
def stft_analysis_synthesis(input_file, output_file):
# 参数配置
frame_size = 1024
hop_size = 256
# 初始化算法
loader = es.MonoLoader(filename=input_file, sampleRate=44100)
fcut = es.FrameCutter(frameSize=frame_size, hopSize=hop_size)
w = es.Windowing(type="hann")
fft = es.FFT(size=frame_size)
ifft = es.IFFT(size=frame_size)
overl = es.OverlapAdd(frameSize=frame_size, hopSize=hop_size, gain=1.0/frame_size)
awrite = es.MonoWriter(filename=output_file, sampleRate=44100)
# 构建处理网络
loader.audio >> fcut.signal
fcut.frame >> w.frame
w.frame >> fft.frame
fft.fft >> ifft.fft
ifft.frame >> overl.frame
overl.signal >> awrite.audio
# 执行处理
essentia.run(loader)
这段代码实现了一个简单的STFT分析和合成系统,可以用于音频的频谱分析和各种音频效果处理。
6. 正弦模型:音频分析与合成 🎛️
正弦模型是一种强大的音频分析合成技术,可以将音频分解为一系列正弦波分量。
import essentia
import essentia.streaming as es
from pathlib import Path
def sine_model_analysis_synthesis(input_file, output_file):
# 参数配置
params = {
"frameSize": 2048,
"hopSize": 512,
"sampleRate": 44100,
"maxnSines": 100,
"magnitudeThreshold": -74,
"freqDevOffset": 10,
"freqDevSlope": 0.001,
}
# 初始化算法
loader = es.MonoLoader(filename=input_file, sampleRate=params["sampleRate"])
fcut = es.FrameCutter(frameSize=params["frameSize"], hopSize=params["hopSize"])
w = es.Windowing(type="blackmanharris92")
fft = es.FFT(size=params["frameSize"])
smanal = es.SineModelAnal(**params)
smsyn = es.SineModelSynth(sampleRate=params["sampleRate"],
fftSize=params["frameSize"],
hopSize=params["hopSize"])
ifft = es.IFFT(size=params["frameSize"])
overl = es.OverlapAdd(frameSize=params["frameSize"], hopSize=params["hopSize"])
awrite = es.MonoWriter(filename=output_file, sampleRate=params["sampleRate"])
# 构建处理网络
loader.audio >> fcut.signal
fcut.frame >> w.frame >> fft.frame >> smanal.fft
smanal.magnitudes >> smsyn.magnitudes
smanal.frequencies >> smsyn.frequencies
smanal.phases >> smsyn.phases
smsyn.fft >> ifft.fft >> overl.frame >> awrite.audio
# 执行处理
essentia.run(loader)
这个示例实现了基于正弦模型的音频分析与合成,可以用于音频分离、声音转换等高级应用。
7. 音频分离:正弦波减法 🎸
通过正弦模型,我们可以分离音频中的正弦分量和残差分量。
import essentia
import essentia.streaming as es
import numpy as np
from pathlib import Path
def sine_subtraction(input_file, output_file):
# 参数配置
params = {
"frameSize": 2048,
"hopSize": 128,
"sampleRate": 44100,
"maxnSines": 100,
"magnitudeThreshold": -74,
"freqDevOffset": 10,
"freqDevSlope": 0.001,
}
# 初始化算法
loader = es.MonoLoader(filename=input_file, sampleRate=params["sampleRate"])
pool = essentia.Pool()
fcut = es.FrameCutter(frameSize=params["frameSize"], hopSize=params["hopSize"])
w = es.Windowing(type="blackmanharris92")
fft = es.FFT(size=params["frameSize"])
smanal = es.SineModelAnal(**params)
subtrFFTSize = int(min(params["frameSize"] / 4, 4 * params["hopSize"]))
smsub = es.SineSubtraction(sampleRate=params["sampleRate"],
fftSize=subtrFFTSize,
hopSize=params["hopSize"])
# 构建分析网络
loader.audio >> fcut.signal
fcut.frame >> w.frame >> fft.frame >> smanal.fft
smanal.magnitudes >> (pool, "magnitudes")
smanal.frequencies >> (pool, "frequencies")
smanal.phases >> (pool, "phases")
fcut.frame >> smsub.frame
smanal.magnitudes >> smsub.magnitudes
smanal.frequencies >> smsub.frequencies
smanal.phases >> smsub.phases
smsub.frame >> (pool, "frames")
# 执行分析
essentia.run(loader)
# 保存残差分量
outaudio = pool["frames"].flatten()
awrite = es.MonoWriter(filename=output_file, sampleRate=params["sampleRate"])
outvector = es.VectorInput(outaudio)
outvector.data >> awrite.audio
essentia.run(outvector)
这个示例展示了如何使用正弦减法从音频中分离出非正弦分量(残差),这在音乐分离和音频修复中非常有用。
8. 谱图模型:SPR分析与合成 🎹
SPR(Sinusoidal plus Residual)模型是一种更完整的音频分析合成方法。
import essentia
import essentia.streaming as es
from pathlib import Path
def spr_model_analysis_synthesis(input_file, output_file):
# 参数配置
params = {
"frameSize": 2048,
"hopSize": 128,
"sampleRate": 44100,
"maxnSines": 100,
"magnitudeThreshold": -74,
"freqDevOffset": 10,
"freqDevSlope": 0.001,
}
# 初始化算法
loader = es.MonoLoader(filename=input_file, sampleRate=params["sampleRate"])
fcut = es.FrameCutter(frameSize=params["frameSize"], hopSize=params["hopSize"])
smanal = es.SprModelAnal(**params)
synFFTSize = int(min(params["frameSize"] / 4, 4 * params["hopSize"]))
smsyn = es.SprModelSynth(sampleRate=params["sampleRate"],
fftSize=synFFTSize,
hopSize=params["hopSize"])
# 创建数据池
pool = essentia.Pool()
# 构建处理网络
loader.audio >> fcut.signal
fcut.frame >> smanal.frame
smanal.magnitudes >> (pool, "magnitudes")
smanal.frequencies >> (pool, "frequencies")
smanal.phases >> (pool, "phases")
smanal.magnitudes >> smsyn.magnitudes
smanal.frequencies >> smsyn.frequencies
smanal.phases >> smsyn.phases
smanal.res >> smsyn.res
smsyn.frame >> (pool, "frames")
# 执行分析
essentia.run(loader)
# 合成并保存结果
outaudio = pool["frames"].flatten()
awrite = es.MonoWriter(filename=output_file, sampleRate=params["sampleRate"])
outvector = es.VectorInput(outaudio)
outvector.data >> awrite.audio
essentia.run(outvector)
SPR模型同时考虑了音频的正弦分量和残差分量,能够更完整地表示音频信号,适用于高质量的音频合成和转换。
9. 音高跟踪:提取主音高 🎤
音高跟踪是音乐分析的重要任务,可以用于旋律提取、歌声分离等应用。
import essentia.standard as es
import numpy as np
import matplotlib.pyplot as plt
def extract_pitch(input_file):
# 参数配置
frame_size = 2048
hop_size = 128
sample_rate = 44100
# 加载音频
audio = es.MonoLoader(filename=input_file, sampleRate=sample_rate)()
# 提取主音高
pitch_extractor = es.PredominantPitchMelodia(frameSize=frame_size,
hopSize=hop_size,
sampleRate=sample_rate)
pitch, pitch_confidence = pitch_extractor(audio)
# 可视化结果
time = np.arange(len(pitch)) * hop_size / sample_rate
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(time, pitch, 'b-')
plt.ylabel('Frequency (Hz)')
plt.title('Estimated Pitch')
plt.subplot(2, 1, 2)
plt.plot(time, pitch_confidence, 'g-')
plt.xlabel('Time (s)')
plt.ylabel('Confidence')
plt.tight_layout()
plt.show()
return pitch, pitch_confidence
音高跟踪结果
这个示例使用Melodia算法提取音频中的主音高,适用于歌声和旋律乐器的音高分析。
10. 谐波 masking:音频分离与增强 🔍
谐波masking技术可以用于分离音频中的谐波成分,实现音频增强或分离。
import essentia.standard as es
import numpy as np
def harmonic_mask(input_file, output_file):
# 参数配置
frame_size = 2048
hop_size = 128
sample_rate = 44100.0
attenuation_dB = 100
mask_bin_width = 2
# 加载音频
audio = es.MonoLoader(filename=input_file, sampleRate=sample_rate)()
# 提取主音高
pitch_extractor = es.PredominantPitchMelodia(frameSize=frame_size,
hopSize=hop_size,
sampleRate=sample_rate)
pitch, _ = pitch_extractor(audio)
# 初始化算法
fcut = es.FrameCutter(frameSize=frame_size, hopSize=hop_size)
w = es.Windowing(type="hann")
fft = es.FFT(size=frame_size)
hmask = es.HarmonicMask(sampleRate=sample_rate,
binWidth=mask_bin_width,
attenuation=attenuation_dB)
ifft = es.IFFT(size=frame_size)
overl = es.OverlapAdd(frameSize=frame_size, hopSize=hop_size)
# 处理每一帧
audio_out = np.array(0)
for idx, frame in enumerate(es.FrameGenerator(audio, frameSize=frame_size, hopSize=hop_size)):
# STFT分析
in_fft = fft(w(frame))
# 应用谐波mask
out_fft = hmask(in_fft, pitch[idx])
# STFT合成
out_frame = overl(ifft(out_fft))
audio_out = np.append(audio_out, out_frame)
# 保存结果
es.MonoWriter(filename=output_file, sampleRate=sample_rate)(audio_out.astype(np.float32))
这个示例展示了如何使用谐波masking技术来增强或分离音频中的谐波成分,可应用于语音增强、音乐分离等场景。
总结与进阶学习
通过以上10个示例,你已经掌握了Essentia的核心功能。要深入学习,可以参考以下资源:
- 官方文档:doc/sphinxdoc/index.html
- 更多Python示例:src/examples/python/
- 算法实现:src/algorithms/
Essentia提供了丰富的音频分析功能,从基础的特征提取到高级的音乐分析,都可以通过简洁的Python接口实现。无论是音乐信息检索、音频信号处理还是音乐生成,Essentia都是一个强大而灵活的工具。
要开始使用Essentia,首先需要克隆仓库:
git clone https://gitcode.com/gh_mirrors/es/essentia
然后按照官方文档的指引进行安装和配置。祝你在音频分析的旅程中取得成功!
更多推荐






所有评论(0)