【问题标题】:Scipy.signal.spectrogram output lengthsScipy.signal.spectrogram 输出长度
【发布时间】:2018-09-17 11:44:59
【问题描述】:

我正在尝试分析一首歌曲在数组中特定时间点的频率。

我正在使用 scipy.signal.spectrogram 函数来生成这些频率。歌曲长度为2:44,即164秒,读取的scipy.wav文件的采样率为44100。

当我使用频谱图时:

f, t, Sxx= signal.spectrogram(data[:, 1], sr)

f 的长度真的很小,129 个元素。 t 更长,为 32322,但距离原始 wavfile.read 中的 7240320 个采样窗口仍有很长的距离。

(data[:, 1]为音频数据的右声道)

【问题讨论】:

    标签: python audio scipy signal-processing spectrogram


    【解决方案1】:

    stft的默认nperseg的长度为256除以2(仅频率标度的正侧)+1(频率0)。 时间上的样本数是通过

    来实现的
    t.size = len(data[:, 1]) / nperseg * (1 + noverlap) 
    

    其中noverlap256/8=32

    【讨论】:

    • 我在 3 周前就知道了,但感谢您的回答!
    • 这个答案似乎很错误。当我使用f, t, Sxx = spectrogram(np.ones(1000)) 创建一个测试频谱图时,形状应该是(129,4),基于nperseg = 256noverlap = 32 这是默认值,上面使用的时间维度的计算形状是128.90625 -> 128,而实际时间形状为 4。使用下面的等式,我得到正确答案 4。
    • 我指的是他的问题。显然,这不是最普遍的情况。请注意,您的示例也不是通常的情况,因为您的信号不是 2 的幂。
    • 您的方程式甚至不适用于他的问题。我可以使用data = np.zeros(7240320) 创建一个虚拟数组,这是他在问题中所拥有的向量的大小。使用他的相同代码,我得到t.shape = (32322, )f.shape = (129, 0),这与他的问题中的形状相匹配。现在,如果我使用你的等式,我会得到len(data) / 256 * (1 + 32) = 933322.5。如果我使用上面答案中的方程式,我会得到int((len(data) - 32) / (256 - 32)) = 32322,它与频谱图的输出相匹配。我强烈建议您实际运行代码来检查您的答案。
    【解决方案2】:

    频率数组f被采样频率的一半加上零频率限制,所以

    f.size = int(1 + sampling_frequency / 2)
    

    虽然时间数组受到您可以从基于 nperseg 和 noverlap 的数据数组中提取的段数量的限制,就像这样

    t.size = int(len(data[:, 1]) - noverlap) / (nperseg - noverlap))
    

    如果您想象有两个分段,nperseg=8 和 noverlap=1,您需要一个至少具有 15 个样本的信号。

    【讨论】:

    • 这是考虑return_onesided=True,这是默认值。
    • 请注意,频率向量的大小应该是int(1 + nperseg / 2),就像 Gideon Kogan 的回答一样。在给定的答案中,频率大小与采样频率有关,但采样频率对向量的大小没有影响,只是向量到频率的映射。您可以使用sr = 44100sr = 1 运行示例f, t, Sxx= signal.spectrogram(np.ones(7240320) , sr),并看到f 的大小没有改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 2016-08-13
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多