我刚刚开始将 Python 与 Librosa 一起用于我将从事的 DSP 项目。我一直在尝试做的第一件事是确定 FFT 窗口大小和跳跃距离的首选参数。
领域是音乐,我的计划是尝试各种窗口大小和跳跃距离的值,对它们中的每一个,执行正向 STFT,然后执行反向 STFT,并将结果写回 wav 文件。然后,我将听取结果并根据我认为在输入中捕获信息的最佳值进行选择。
我的简单代码如下:
import librosa.core as lc
import numpy as np
import scipy
_n_fft=80
print(str(_n_fft))
_hop_length=_n_fft/4
data, sampleRate = lc.load("13_Hate_To_See_Your_Heart_Break.wav", sr=44100, duration=20, mono=True)
stftMat = lc.stft(data, n_fft=_n_fft, hop_length=_hop_length, center=True)
iStftMat = lc.istft(stftMat, hop_length=_hop_length)
scipy.io.wavfile.write("testOut.wav", 44100, iStftMat)
powerMat = np.abs(stftMat)
print("powerMat shape = " + str(powerMat.shape))
然而,我正在经历的行为并不是我所期望的。
当我使用非常短的窗口长度时(如上面的代码中所示) - 我的 FFT 长度和跳跃距离得到了正确数量的窗口帧:
powerMat shape = (41, 44101)
44101 窗口是有道理的,正如您所见,频率分辨率很低,只有 41 个频段。我希望得到的 testOut.wav 听起来很糟糕,因为频率分辨率太低了。当频率变化的细微之处被涂抹在一起时,我可以明显地看到对渲染频谱图的影响。然而,回想起来,生成的音轨听起来很棒——很像原始输入。
将此与更宽的窗口大小 44100 进行比较(1 个窗口 = 1 秒的音频,跳跃距离为 1/4*窗口大小):
powerMat shape = (22051, 81)
同样,这个输出是有意义的——在 20 秒的音频中,窗口长度为 1 秒,跳跃距离为 1/4 秒,大约有 80 个窗口帧。这是相当差的时间分辨率,但具有 22051 个频率箱的频率分辨率相当高。我再次希望得到的 testOut.wav 在时域中听起来很差。
生成的音轨再一次听起来很棒——很像原始输入。这些极值,以及介于两者之间的所有值,几乎都会产生相同的输出 testOut.wav,即使在实际功率谱上我可以在更改参数时明显看到差异。
我对 STFT 是否存在根本性的误解,并且是相反的?我只是不了解图书馆吗?