【问题标题】:How to calculate log-frequency spectrogram efficiently?如何有效地计算对数频谱图?
【发布时间】:2022-01-12 03:51:43
【问题描述】:

我正在尝试使用 matplotlib 绘制频谱图,其中频率以对数方式间隔,因此我可以可视化音乐/钢琴音符。从我在网上找到的信息来看,这是做到这一点的“最佳方式”:

data, samplerate = librosa.load("demo.wav")

S = np.abs(librosa.stft(data))
S = librosa.amplitude_to_db(S, ref=np.max)


fig, ax = plt.subplots()

img = librosa.display.specshow(S, y_axis='log', x_axis='time',
                               sr=samplerate, ax=ax)
ax.set(title='Linear-frequency power spectrogram')
ax.label_outer()
plt.show()

这很好用,但问题是它需要一段时间而且效率很低,因为 librosa.stft() 计算所有等距的频率箱,而 specshow(yaxis="log") 显然只是映射重要的频率,所以它显示时看起来是对数的。这会导致大量未使用的频率。有什么方法可以让笔记一开始就适合垃圾箱,以便更快更有效地计算?它不必使用 librosa。

【问题讨论】:

  • 这是一个信号处理或统计问题,会在这些论坛中得到更好的回应
  • 要优化,可以尝试:downsample,增加hop size,改成float32。编写自己的 stft 使用更快的 fft,使用一些多处理
  • librosa.load(...., sr=None) - 如果您的文件还不是 22kHz(稀有),它将使其更快
  • 另一个缓慢的部分通常是绘图。选择较小的 n_fft 是最简单的解决方法。或者计算一个色谱图 - 它在内部使用 STFT,但输出是一组较小的 bin,绘制起来会更快

标签: python matplotlib signal-processing librosa spectrogram


【解决方案1】:

FFT 是 O(NLogN),具有非常高效和优化的实现。因此,计算对数缩放频率变换将需要更少的内存,但如果没有像简单地重新缩放 FFT 结果那样高效的可用实现,可能仍然是 O(NLogN)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 2019-12-18
    相关资源
    最近更新 更多