TL;DR 答案
是的,这是正确的。
长答案
您正在使用时间序列作为输入(signal
), 意思就是librosa首先使用以下计算梅尔谱图梅尔谱图功能。它需要一堆参数,其中您已经指定了一个(n_fft
)。重要的是要注意梅尔谱图还提供了两个参数center
and pad_mode
使用默认值True
and "reflect"
分别。
来自文档:
pad_mode:字符串:如果 center=True,则在信号边缘使用的填充模式。
默认情况下,STFT 使用反射填充。
中心:布尔值:如果为 True,则填充信号 y,以便帧 t 以 y[t * hop_length] 为中心。
如果为 False,则帧 t 从 y[t * hop_length] 开始
换句话说,默认情况下,librosa使信号更长(垫)以支持居中。
如果您想避免这种行为,您应该通过center=False
给你的mfcc
call.
综上所述,设置时center
to False
,请记住,使用n_fft
长度为 2048,跳长度为400
,你不一定得到(time*sr/hop_length)=40
框架,因为你还必须考虑window而不仅仅是hop长度(除非你以某种方式填充)。跳跃长度仅指定您移动该窗口的样本数量。
举一个极端的例子,考虑一个非常大的窗口和非常短的跳跃长度:假设 10 个样本(例如time=1s
, sr=10Hz
),窗口长度为n_fft=9
and hop_length=1
with center=False
。现在想象一下在 10 个样本上滑动窗口。
◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◻︎
◻︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎
t 0123456789
◻︎ sample not covered by window
◼︎ sample covered by window
首先窗口开始于t=0
并结束于t=8
。我们可以将其移动多少次hop_length
仍然期望它不会用完样品?恰好一次,直到开始于t=1
并结束于t=9
。添加第一个未移动的帧,您将得到 2 帧。这显然与错误的不同(time*sr/hop_length)=1*10/1=10
.
正确的是:(time*sr-n_fft)//hop_length+1=(1*10-9)//1+1=2
with //
表示 Python 风格的整数除法。
当使用默认值时,即center=True
,信号被填充n_fft // 2
两端都有样本,所以n_fft
不属于这个等式。