2. Python音频处理入门:Librosa库安装与核心API、音频文件的读取与写入、波形可视化
好,咱们正式开始动手了。
上一章聊了音频的基础概念,采样率、位深、声道这些。但光有理论不行,得有个趁手的工具。Python 生态里做音频处理,Librosa 几乎是绕不开的库。我个人习惯把它叫做「音频处理的瑞士军刀」——读取、分析、特征提取、可视化,一条龙搞定。
这一章,我们就从零开始,把 Librosa 装好,然后走一遍最核心的流程:读音频、写音频、看波形。
2.1 安装Librosa:别踩这些坑
安装本身不复杂,但有几个细节我建议你注意一下。
最直接的安装方式:
pip install librosa
嗯,就这一行。但实际跑起来,你可能会遇到两个常见问题。
问题一:依赖冲突。 Librosa 底层依赖 numpy、scipy、soundfile 这些。如果你之前装过旧版本的 numpy,可能会报错。我的建议是:
pip install --upgrade numpy scipy
pip install librosa
问题二:音频解码器。 Librosa 默认用 soundfile 读写 WAV 文件。但如果你要读 MP3、FLAC 这些格式,需要额外装 ffmpeg。我在项目中遇到过好几次,明明代码没问题,就是读不了 MP3,最后发现是 ffmpeg 没装。
解决方案:
# 安装 ffmpeg(Windows 用户去官网下载,macOS 用 brew)
brew install ffmpeg # macOS
# 或者让 Librosa 使用 audioread 后端
pip install audioread
audioread + ffmpeg。如果你用的是旧版本,建议升级到最新版。
装完之后,验证一下:
import librosa
print(librosa.__version__)
能看到版本号,就说明装好了。
2.2 核心API:音频文件的读取与写入
Librosa 读取音频的核心函数就一个:librosa.load()。但别看它简单,参数里藏着不少门道。
2.2.1 读取音频:librosa.load()
基本用法:
import librosa
# 读取音频文件
audio_path = 'example.wav'
y, sr = librosa.load(audio_path)
print(f"音频数据形状: {y.shape}")
print(f"采样率: {sr} Hz")
这里返回两个东西:
- y:一维 numpy 数组,代表音频的时域信号值,范围在 [-1.0, 1.0] 之间。
- sr:采样率,默认是 22050 Hz。
等等,默认 22050?我明明录的是 44100 的 WAV 啊。没错,Librosa 默认会重采样到 22050 Hz。为什么?因为大部分音频分析任务不需要那么高的采样率,22050 已经能覆盖人耳范围(20Hz-11kHz),而且数据量减半,处理更快。
但如果你需要原始采样率,可以这样:
y, sr = librosa.load(audio_path, sr=None) # 保持原始采样率
或者指定你想要的采样率:
y, sr = librosa.load(audio_path, sr=16000) # 重采样到 16kHz
其他常用参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
sr |
22050 | 目标采样率,None 表示保持原始采样率 |
mono |
True | 是否混音为单声道。立体声会取左右声道平均 |
offset |
0.0 | 从第几秒开始读取 |
duration |
None | 读取多少秒,None 表示读到结尾 |
res_type |
'kaiser_best' | 重采样算法,'kaiser_best' 质量最高但慢,'kaiser_fast' 更快 |
举个例子,只读取音频的前 5 秒:
y, sr = librosa.load(audio_path, sr=16000, offset=0, duration=5)
2.2.2 写入音频:librosa.output 已废弃
这里有个历史遗留问题。老版本的 Librosa 有 librosa.output 模块,但新版本已经移除了。现在官方推荐用 soundfile 或 scipy.io.wavfile 来写文件。
我个人习惯用 soundfile,因为它支持更多格式:
import soundfile as sf
# 写入 WAV 文件
sf.write('output.wav', y, sr)
# 写入 FLAC 文件(无损压缩)
sf.write('output.flac', y, sr)
如果你非要用 Librosa 的风格,可以这样:
# 注意:这不是 librosa 的函数,是 soundfile 的
# 但 librosa 官方文档推荐这种方式
sf.write('output.wav', y, sr, subtype='PCM_16')
subtype='PCM_16' 可以控制位深。常见的有 'PCM_16'(16位)、'PCM_24'(24位)、'FLOAT'(32位浮点)。
2.3 波形可视化:看一眼你的音频长什么样
读进来之后,第一件事是什么?我个人习惯先看一眼波形。波形图能直观告诉你:音频有没有削波、有没有静音段、动态范围怎么样。
Librosa 提供了 librosa.display.waveshow() 来画波形。注意,它依赖 matplotlib。
import librosa.display
import matplotlib.pyplot as plt
# 读取音频
y, sr = librosa.load('example.wav', sr=None)
# 创建画布
plt.figure(figsize=(12, 4))
# 绘制波形
librosa.display.waveshow(y, sr=sr)
# 添加标签
plt.title('Waveform')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.show()
运行之后,你会看到一条上下波动的曲线。横轴是时间(秒),纵轴是振幅(归一化到 [-1, 1])。
你想想看,如果波形上下都顶到了 -1 和 1,说明音量太大,可能削波了。如果波形几乎是一条直线,那可能是静音段。
2.3.1 多段波形对比
有时候需要对比两段音频,比如原始音频和处理后的音频。可以画在同一个图上:
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
librosa.display.waveshow(y_original, sr=sr)
plt.title('Original')
plt.subplot(2, 1, 2)
librosa.display.waveshow(y_processed, sr=sr)
plt.title('Processed')
plt.tight_layout()
plt.show()
2.3.2 波形图的参数调整
waveshow 还有一些参数可以调:
| 参数 | 说明 |
|---|---|
alpha |
透明度,0-1,多个波形叠加时有用 |
color |
波形颜色,默认蓝色 |
max_points |
最大采样点数,超过时会降采样显示,提高绘图速度 |
x_axis |
横轴单位,'time' 或 'samples' |
举个例子,画一个半透明的红色波形:
librosa.display.waveshow(y, sr=sr, alpha=0.7, color='red')
2.4 本章知识体系
下面这张图总结了本章的核心流程和知识点,你可以对照着梳理一下:
这张图把本章内容分成了四个模块:安装、读取、写入、可视化。箭头表示流程方向,你可以看到,从安装开始,到读取音频,再到写入或可视化,是一个完整的链路。
2.5 完整示例:一条龙走一遍
最后,我们写一个完整的脚本,把今天学的串起来:
import librosa
import librosa.display
import soundfile as sf
import matplotlib.pyplot as plt
import numpy as np
# 1. 读取音频
audio_path = 'speech.wav'
y, sr = librosa.load(audio_path, sr=16000, duration=10)
print(f"读取完成:{len(y)/sr:.2f}秒,采样率{sr}Hz")
# 2. 查看基本信息
print(f"数据范围:{y.min():.3f} ~ {y.max():.3f}")
print(f"数据形状:{y.shape}")
# 3. 可视化
plt.figure(figsize=(12, 4))
librosa.display.waveshow(y, sr=sr, alpha=0.8, color='#2c3e50')
plt.title('Speech Waveform (16kHz)')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.savefig('waveform.png', dpi=150)
plt.show()
# 4. 写入处理后的音频(这里只是复制,实际可以加处理逻辑)
sf.write('speech_copy.wav', y, sr, subtype='PCM_16')
print("写入完成:speech_copy.wav")
这个脚本跑完之后,你会得到一张波形图和一个新的 WAV 文件。嗯,这就是最基础的音频处理流程了。
load() 和 waveshow() 是你最常用的两个函数。前者把音频变成数据,后者让你看到数据。记住采样率要明确指定,写入用 soundfile,波形图用 waveshow。这三板斧练熟了,后面的特征提取、音频增强才能玩得转。