简体   繁体   English

Librosa的英尺和Scipy的英尺不同?

[英]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功能,但是,即使在相同的信号输入下,它们也为我提供了不同的频谱图输出。

Scipy SciPy的

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 然后我得到以下频谱图 在此处输入图片说明

Librosa Librosa

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()

在此处输入图片说明

Question

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: 确实导致一条直线:

librosa.stft,中心= False

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)

librosa.stft,center = False,没有窗口函数

You'll notice that the line is thinner. 您会注意到该行较细。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM