考虑以下代码

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

s = np.linspace(0,1,44100)
x = np.sin(2*np.pi*1000*s)
fmin=500

cq_lib = cqt(x,sr=44100, fmin=fmin, n_bins=40)

plt.imshow(abs(cq_lib),aspect='auto', origin='lower')
plt.xlabel('Time Steps')
plt.ylabel('Freq bins')


它会给出这样的频谱图

python-3.x - Librosa常数Q变换(CQT)在频谱图的开头和结尾处包含缺陷-LMLPHP

当您仔细观察频谱图的开始和结束时,您会发现那里存在一些缺陷。

当仅绘制第一时间步和最后一个时间步时,可以看到频率不正确。

第一帧

plt.plot(abs(cq_lib)[:,0])
plt.ylabel('Amplitude')
plt.xlabel('Freq bins')
plt.tick_params(labelsize=16)


python-3.x - Librosa常数Q变换(CQT)在频谱图的开头和结尾处包含缺陷-LMLPHP

最后和第二个最后一帧比较

plt.plot(abs(cq_lib)[:,-1])
plt.plot(abs(cq_lib)[:,-2])
plt.legend(['last step', '2nd last step'], fontsize=16)
plt.ylabel('Amplitude')
plt.xlabel('Freq bins')
plt.tick_params(labelsize=16)


python-3.x - Librosa常数Q变换(CQT)在频谱图的开头和结尾处包含缺陷-LMLPHP

我试图解决它

据我所知,这应该是由于填充和将stft窗口置于中心。但是看来cqt不支持参数center=False

cq_lib = cqt(x,sr=44100, fmin=fmin, n_bins=40,center=False)



TypeError:cqt()获得了意外的关键字参数'center'


我做错什么了吗?如何在center=False中制作cqt

最佳答案

我认为您可能想尝试cqt支持的pad_mode。如果您检出np.pad documentation,则可以看到可用的选项(或查看本文的结尾)。使用wrap选项,您会得到这样的结果,尽管我怀疑该阶段是一团糟,所以您应确保它满足您的需求。如果始终生成自己的信号,则可以尝试使用<function>而不是可用选项之一。

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

s = np.linspace(0,1,44100)
x = np.sin(2*np.pi*1000*s)
fmin=500

cq_lib = cqt(x,sr=44100, fmin=fmin, n_bins=40, pad_mode='wrap')

plt.imshow(abs(cq_lib),aspect='auto', origin='lower')
plt.xlabel('Time Steps')
plt.ylabel('Freq bins')


python-3.x - Librosa常数Q变换(CQT)在频谱图的开头和结尾处包含缺陷-LMLPHP

如果您看第一帧和最后两帧,现在看起来会好得多。我用librosa 0.6.3和0.7.0进行了尝试,结果是相同的。

python-3.x - Librosa常数Q变换(CQT)在频谱图的开头和结尾处包含缺陷-LMLPHP

python-3.x - Librosa常数Q变换(CQT)在频谱图的开头和结尾处包含缺陷-LMLPHP

尝试一些选项,希望您可以找到可以实现此目的的填充选项之一:
np.pad options
‘constant’, ‘edge’, ‘linear_ramp’, ‘maximum’, ‘mean’,‘median’,‘minimum’, ‘reflect’, ‘symmetric’, ‘wrap’, ‘empty’, <function>

09-25 17:16