mel_specgram = self.MelSpectrogram(waveform)
if self.log_mels:
log_offset = 1e-6
mel_specgram = torch.log(mel_specgram + log_offset)
else:
mel_specgram = self.amplitude_to_DB(mel_specgram)
第三个问题,你可能会合理地想知道是否可以强制librosa正确运行。答案是肯定的(或者至少看起来是),可以直接使用mel频谱图并取其自然对数,将其作为输入传递给librosa mfcc函数。详情请参见下面的代码。
最后,请小心一些。如果您使用此代码,请检查查看不同特征时发生的情况。第0个特征仍然具有严重的未解释偏移,并且更高级别的特征 tend to drift away from each other.这可能是底层实现的不同或稍微不同的数值稳定常数之类的简单问题,也可以通过微调(例如,在填充方面做出选择或在分贝转换中引用参考)来解决。我真的不知道。
以下是一些示例代码:
import librosa
import python_speech_features
import matplotlib.pyplot as plt
from scipy.signal.windows import hann
import torchaudio.transforms
import torch
n_mfcc = 13
n_mels = 40
n_fft = 512
hop_length = 160
fmin = 0
fmax = None
sr = 16000
melkwargs={"n_fft" : n_fft, "n_mels" : n_mels, "hop_length":hop_length, "f_min" : fmin, "f_max" : fmax}
y, sr = librosa.load(librosa.util.example_audio_file(), sr=sr, duration=5,offset=30)
mfcc_lib_db = librosa.feature.mfcc(y=y, sr=sr, n_fft=n_fft,
n_mfcc=n_mfcc, n_mels=n_mels,
hop_length=hop_length,
fmin=fmin, fmax=fmax, htk=False)
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=n_mels, fmin=fmin,
fmax=fmax, hop_length=hop_length)
mfcc_lib_log = librosa.feature.mfcc(S=np.log(S+1e-6), n_mfcc=n_mfcc, htk=False)
mfcc_speech = python_speech_features.mfcc(signal=y, samplerate=sr, winlen=n_fft / sr, winstep=hop_length / sr,
numcep=n_mfcc, nfilt=n_mels, nfft=n_fft, lowfreq=fmin, highfreq=fmax,
preemph=0.0, ceplifter=0, appendEnergy=False, winfunc=hann)
mfcc_torch_log = torchaudio.transforms.MFCC(sample_rate=sr, n_mfcc=n_mfcc,
dct_type=2, norm='ortho', log_mels=True,
melkwargs=melkwargs)(torch.from_numpy(y))
mfcc_torch_db = torchaudio.transforms.MFCC(sample_rate=sr, n_mfcc=n_mfcc,
dct_type=2, norm='ortho', log_mels=False,
melkwargs=melkwargs)(torch.from_numpy(y))
feature = 1
plt.subplot(2, 1, 1)
plt.plot(mfcc_lib_log.T[:,feature], 'k')
plt.plot(mfcc_lib_db.T[:,feature], 'b')
plt.plot(mfcc_speech[:,feature], 'r')
plt.plot(mfcc_torch_log.T[:,feature], 'c')
plt.plot(mfcc_torch_db.T[:,feature], 'g')
plt.grid()
plt.subplot(2, 2, 3)
plt.plot(mfcc_lib_log.T[:,feature], 'k')
plt.plot(mfcc_torch_log.T[:,feature], 'c')
plt.plot(mfcc_speech[:,feature], 'r')
plt.grid()
plt.subplot(2, 2, 4)
plt.plot(mfcc_lib_db.T[:,feature], 'b')
plt.plot(mfcc_torch_db.T[:,feature], 'g')
plt.grid()
说实话,这些实现都不令人满意:
Python_speech_features采用了一种难以理解的方法,将第0个特征替换为能量而不是添加它,并且没有常用的delta实现。
Librosa默认情况下非标准化且没有警告,并且缺乏明显的用于增强能量的方法,但在库的其他地方具有高度竞争力的delta函数。
Torchaudio将模拟任何一种方法,并且具有多功能的delta函数,但仍然没有干净,明显的获取能量的方法。
![输入图像描述](https://istack.dev59.com/uW9d7.webp)
samplerate=sr
,会有什么不同吗?或者在librosa版本中更改dct_type
呢? - Hendriksr
作为输入。在dct_type
方面,当我将其设置为3时,有一些变化,但仍然与psf输出相差甚远(1和2几乎相同)。 - TYZsamplerate=sr
,会有所不同吗?我的意思是,您正在将其作为位置参数传递,但它是一个关键字参数。不确定在这里将其作为kwarg参数传递是否有所不同,但我会遵守(显式)API。 - Hendrik