如何从Librosa的chroma_stft获取以Hz为单位的音高类值
解决Librosa色度特征的频率与时间信息获取问题
一、关于色度与Hz的核心说明
Librosa的chroma_stft返回的是12个音高类的强度分布(形状(12, t)),每个音高类对应跨八度的同调式频率集合(比如C类包含65.4Hz、130.8Hz、261.6Hz等所有八度的C音),本身没有单一固定的Hz值。如果需要对应某一基准八度的参考频率,可按以下方法计算。
二、获取每个色度对应的基准频率(Hz)
可以通过Librosa的音高转换工具,直接生成12个音高类对应的基准频率(默认以A4=440Hz为基准,对应C4到B4的频率):
import librosa # 生成12个音高类对应的基准频率(C4到B4) chroma_notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] chroma_freqs = librosa.midi_to_hz(librosa.note_to_midi(chroma_notes))
得到的chroma_freqs数组中,每个元素对应色度特征索引的基准Hz值(比如索引0对应C4的261.6Hz)。若需要其他八度的频率,只需对基准值乘以/除以2的整数次幂(比如C3为261.6/2=130.8Hz,C5为261.6*2=523.2Hz)。
三、获取时间轴信息
色度特征的时间维度可通过librosa.frames_to_time函数计算,基于你设置的采样率sr和hop_length参数:
# 生成对应每一列色度的时间轴(单位:秒) times = librosa.frames_to_time(range(chroma.shape[1]), sr=44100, hop_length=3276)
times数组中的每个元素,对应色度特征每一列的起始时间点。
四、完整示例代码
import librosa import numpy as np # 加载音频信号(替换为你的音频路径) audiosignal, sr = librosa.load("your_audio.wav", sr=44100) window = np.hanning(8192) # 计算色度特征 chroma = librosa.feature.chroma_stft(y=audiosignal, sr=sr, window=window, n_fft=8192, hop_length=3276) # 获取色度对应的基准频率 chroma_notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] chroma_freqs = librosa.midi_to_hz(librosa.note_to_midi(chroma_notes)) # 获取时间轴 times = librosa.frames_to_time(range(chroma.shape[1]), sr=sr, hop_length=3276) # 示例输出:第一个时间帧的音高类、基准频率和对应强度 print(f"时间点(秒): {times[0]:.2f}") for note, freq, strength in zip(chroma_notes, chroma_freqs, chroma[:, 0]): print(f"音高类: {note}, 基准频率: {freq:.2f}Hz, 强度: {strength:.4f}")
补充提示
如果需要精确的单频点信息,而不是跨八度的调式聚合,建议直接使用librosa.stft生成频谱图,而非色度特征——色度的核心是忽略八度差异,聚焦调式分布。
内容的提问来源于stack exchange,提问作者Luckyboy. Jupiterchen
相关产品推荐
相关产品推荐

