You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用librosa在循环中计算并绘制多段音频语谱图

解决方案

步骤1:确保音频正确分割(若未完成)

如果还没将16秒音频分割为16段1秒信号,可通过以下代码实现:

import librosa
import numpy as np
import matplotlib.pyplot as plt

# 加载音频,保留原始采样率
y, sr = librosa.load("your_audio_file.wav", sr=None)

# 按1秒长度分割音频(每段样本数=采样率sr)
segment_length = sr
segment = [y[i*segment_length : (i+1)*segment_length] for i in range(16)]

步骤2:绘制分段语谱图(适配目标布局)

基于你提供的原始信号绘图代码,修改为绘制语谱图的版本,完全匹配4×4的子图布局:

ncols = 4
nrows = 4  # 16段刚好4行4列,无需额外计算

fig = plt.figure(figsize=(22, 19))
plt.subplots_adjust(hspace=0.5, wspace=0.4)
plt.suptitle('Spectrograms of Segmented Audio', fontweight='bold', size=20)

for i in range(16):
    # 获取当前分段音频
    current_segment = segment[i]
    
    # 计算短时傅里叶变换并转换为分贝刻度的语谱图
    stft_result = librosa.stft(current_segment)
    spec_db = librosa.amplitude_to_db(np.abs(stft_result), ref=np.max)
    
    # 创建子图
    ax = plt.subplot(nrows, ncols, i+1)
    # 绘制语谱图,自动映射时间和频率轴
    img = librosa.display.specshow(spec_db, sr=sr, x_axis='time', y_axis='hz', ax=ax)
    
    # 设置子图标题和坐标轴标签
    ax.set_title(f'Segment: {i+1}', fontweight='bold', size=15)
    ax.set_xlabel('Time (s)', fontweight='bold')
    ax.set_ylabel('Frequency (Hz)', fontweight='bold')

# 调整布局,避免标题被截断
fig.tight_layout(rect=[0, 0, 1, 0.96])
# 添加全局颜色条,统一表示分贝幅度
fig.colorbar(img, ax=fig.axes, shrink=0.8, label='Amplitude (dB)')

plt.show()

关键细节说明

  • librosa.stft:对单段音频做短时傅里叶变换,得到频率-时间维度的幅度矩阵。
  • librosa.amplitude_to_db:将线性幅度转换为分贝刻度,更符合人耳对声音的感知特性。
  • librosa.display.specshow:专门用于绘制频谱类可视化,自动根据采样率生成时间和频率轴的刻度,无需手动计算。
  • 全局颜色条:避免每个子图单独添加颜色条导致布局拥挤,让所有子图共享同一个幅度参考。

内容的提问来源于stack exchange,提问作者Malahat Mehraban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:06:26