[英]Librosa's fft and Scipy's fft are different?
Both Librosa and Scipy have the fft
function, however, they give me a different spectrogram output even with the same signal input. Librosa和Scipy都具有
fft
功能,但是,即使在相同的信号输入下,它们也为我提供了不同的频谱图输出。
I am trying to get the spectrogram with the following code 我正在尝试使用以下代码获取频谱图
import numpy as np # fast vectors and matrices
import matplotlib.pyplot as plt # plotting
from scipy import fft
X = np.sin(np.linspace(0,1e10,5*44100))
fs = 44100 # assumed sample frequency in Hz
window_size = 2048 # 2048-sample fourier windows
stride = 512 # 512 samples between windows
wps = fs/float(512) # ~86 windows/second
Xs = np.empty([int(2*wps),2048])
for i in range(Xs.shape[0]):
Xs[i] = np.abs(fft(X[i*stride:i*stride+window_size]))
fig = plt.figure(figsize=(20,7))
plt.imshow(Xs.T[0:150],aspect='auto')
plt.gca().invert_yaxis()
fig.axes[0].set_xlabel('windows (~86Hz)')
fig.axes[0].set_ylabel('frequency')
plt.show()
Then I get the following spectrogram 然后我得到以下频谱图
Now I try to get the same spectrogram with Librosa 现在,我尝试使用Librosa获得相同的频谱图
from librosa import stft
X_libs = stft(X, n_fft=window_size, hop_length=stride)
X_libs = np.abs(X_libs)[:,:int(2*wps)]
fig = plt.figure(figsize=(20,7))
plt.imshow(X_libs[0:150],aspect='auto')
plt.gca().invert_yaxis()
fig.axes[0].set_xlabel('windows (~86Hz)')
fig.axes[0].set_ylabel('frequency')
plt.show()
The two spectrogram are obviously different, specifically, the Librosa version has an attack at the very beginning. 两种频谱图明显不同,特别是Librosa版本在一开始就受到了攻击。 What causes the difference?
是什么导致差异? I don't see many parameters that I can tune in the documentation for Scipy and Librosa.
我在Scipy和Librosa的文档中看不到许多可以调整的参数。
The reason for this is the argument center
for librosa's stft . 原因是librosa的stft的论点
center
。 By default it's True
(along with pad_mode = 'reflect'
). 默认情况下为
True
(以及pad_mode = 'reflect'
)。
From the docs: 从文档:
librosa.core.stft(y, n_fft=2048, hop_length=None, win_length=None, window='hann', center=True, dtype=, pad_mode='reflect')
librosa.core.stft(y,n_fft = 2048,hop_length = None,win_length = None,window ='hann',center = True,dtype =,pad_mode ='reflect')
center:boolean
中心:布尔
If True, the signal y is padded so that frame D[:, t] is centered at y[t * hop_length].
如果为True,则填充信号y,以使帧D [:, t]以y [t * hop_length]为中心。
If False, then D[:, t] begins at y[t * hop_length]
如果为False,则D [:, t]从y [t * hop_length]开始
pad_mode:string
pad_mode:字符串
If center=True, the padding mode to use at the edges of the signal.
如果center = True,则为在信号边缘使用的填充模式。 By default, STFT uses reflection padding.
默认情况下,STFT使用反射填充。
Calling the STFT like this 像这样调用STFT
X_libs = stft(X, n_fft=window_size, hop_length=stride,
center=False)
does lead to a straight line: 确实导致一条直线:
Note that librosa's stft also uses the Hann window function by default. 请注意,默认情况下,librosa的stft也使用Hann窗口函数 。 If you want to avoid this and make it more like your Scipy stft implementation, call the stft with a window consisting only of ones:
如果要避免这种情况,并使它更类似于Scipy stft实现,请使用仅包含一个的窗口来调用stft:
X_libs = stft(X, n_fft=window_size, hop_length=stride,
window=np.ones(window_size),
center=False)
You'll notice that the line is thinner. 您会注意到该行较细。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.