【问题标题】:How to plot spectrum or frequency vs amplitude of entire audio file using python?如何使用 python 绘制整个音频文件的频谱或频率与幅度的关系?
【发布时间】:2019-04-25 05:19:29
【问题描述】:

我有一些音频文件,我想绘制音频文件的平均频谱,例如使用 PYTHON(librosa 库)的“大胆”软件。我可以看到他们正在绘制整个音频的平均频率与幅度图。

之后,我想应用 CNN 对两类样本进行分类。寻找建议。

谢谢。

【问题讨论】:

    标签: python audio spectrum librosa


    【解决方案1】:

    通常您使用librosa.display.specshow 绘制随时间变化的频谱图,而不是整个文件。事实上,作为 CNN 的输入,您可能更愿意使用 librosa.stft 生成的频谱图或一些 Mel 频谱图,具体取决于您的分类目标。

    例如,如果您想对流派进行分类,梅尔谱图可能是最合适的。如果您想找出键或和弦,则需要恒定 Q 谱图 (CQT) 等。

    也就是说,这里有一些代码可以回答您的问题:

    import librosa
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    file = YOUR_FILE
    # load the file
    y, sr = librosa.load(file, sr=44100)
    # short time fourier transform
    # (n_fft and hop length determine frequency/time resolution)
    n_fft = 2048
    S = librosa.stft(y, n_fft=n_fft, hop_length=n_fft//2)
    # convert to db
    # (for your CNN you might want to skip this and rather ensure zero mean and unit variance)
    D = librosa.amplitude_to_db(np.abs(S), ref=np.max)
    # average over file
    D_AVG = np.mean(D, axis=1)
    
    plt.bar(np.arange(D_AVG.shape[0]), D_AVG)
    x_ticks_positions = [n for n in range(0, n_fft // 2, n_fft // 16)]
    x_ticks_labels = [str(sr / 2048 * n) + 'Hz' for n in x_ticks_positions]
    plt.xticks(x_ticks_positions, x_ticks_labels)
    plt.xlabel('Frequency')
    plt.ylabel('dB')
    plt.show()
    

    这导致了这个输出:

    【讨论】:

    • 非常感谢您的回答。实际上,我必须使用我的数据集进行一些二进制分类,其中有两种类型的声音常规环境声音被视为背景。还有一些无人机的声音有时会一直持续(每个声音大约 20 秒)或经过麦克风。你能详细建议如何设计这个模型吗?需要什么类型的特征提取?并且可能提供一些可以使用 CNN 轻松完成的示例代码。
    • 简短的回答是,我会使用梅尔谱图并遵循类似于arxiv.org/abs/1606.00298 的方法。但是由于这与原始问题无关,请提出一个新问题。另外,如果您认为我已经回答了您的原始问题,请接受我的回答。谢谢。
    • @hendrik , 如何绘制幅度与时间的关系?
    • 要么简单地绘制 y,要么使用波图。见librosa.github.io/librosa/generated/…
    • 请阅读decibelWikipedia 或其他地方,或在dsp.stackexchange.com 上提出新问题。简短的回答是:分贝不是单位。它(在这种情况下)描述了日志。最大可表示能量(例如1)与实际能量之间的关系。因此,如果您的样本在 -1 到 1 的范围内,则任何带有 |v|=1v 是样本值)的样本都有 0 分贝。
    【解决方案2】:
    import matplotlib.pyplot as plt
    from scipy import signal
    from scipy.io import wavfile
    
    sample_rate, samples = wavfile.read('h1.wav')
    samples=samples[:,0]
    frequencies, times, spectrogram = signal.spectrogram(samples, sample_rate)
    
    plt.imshow(spectrogram)
    plt.pcolormesh(times, frequencies, spectrogram)
    
    plt.ylabel('Frequency [Hz]')
    plt.xlabel('Time [sec]')
    plt.show()
    

    【讨论】:

    • 您好,感谢您的回答。但我想绘制整个时间序列的平均频率与幅度。图的轴将是频率与幅度,而不是时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多