【问题标题】:Finding notes in a WAV file在 WAV 文件中查找笔记
【发布时间】:2015-12-16 22:18:12
【问题描述】:

我正在寻找如何将 WAV 文件中的数据分成其组成注释的方法。 我加载 WAV 文件:

import scipy.io.wavfile as wavfile
rate, data = wavfile.read('scale.wav')
time = np.arange(len(data[:,0]))*1.0/rate

和绘图

plt.plot(time, data[:,0])
plt.show()

这给了我this picture,这是一个有八个音符的钢琴音阶。我想要一种方法来隔离每个音符,这样我就可以找到它的频率并找出正在播放的音符。隔离笔记后,我就可以处理其余的事情了。

我已经尝试找到最大值,但是需要多次迭代才能将其降至我想要的最大值,这是一种不可靠的方法,因为进行太多迭代会消除一些较低幅度的峰值.及时获得笔记的长度也很好。

编辑:所以这很复杂,就像各位先生所说的那样。我现在想我只想找到“极端”峰值,然后找到这些峰值之后的极端最小值,并将其用作我的笔记,因为我们不需要太大的数据片段来计算是频率。我遇到的问题是,有很多峰,很难只找到我想要的峰。有什么想法吗?

【问题讨论】:

    标签: python numpy scipy


    【解决方案1】:

    可能最简单和最有趣的事情是计算您的数据的spectrogram,它基本上是您的数据的短部分的光谱图,按时间绘制。一定要使频率刻度为对数,因为钢琴上琴键的频率是指数空间。在 Python 中,您可以使用函数 specgram 来计算它,它包含在 matplotlib 中。例如,请参阅 this google image search 了解这对于不同类型的音乐的外观。也可以看看一些可以播放 MP3/WAV 并有可视化插件的电脑程序,我记得 Winamp 在 10 多年前就有一种播放实时频谱图的方法。

    这是一个有趣的练习,但如果你想使用这种技术自动转录某些音乐的音符,让我警告你:这是一个非常困难的问题,科学家们已经研究了很多年。例如,一个问题是大多数乐器会产生大量谐波,这会使任何算法无法自动找到音符。忘记任何带有人声或打击乐的音乐,因为它们会产生大量宽带噪音(尤其是字母 's' 和踩镲),几乎无法识别任何其他音符。

    如果您想变得花哨,请查看 Q-transform(请参阅 wikipedia 以及从那里引用的论文)。您可以将其视为频谱图,但沿频率轴的 bin 以对数方式间隔(例如,钢琴音阶上每个半音或四分音符的 bin)。与标准频谱图相比,这种方法的优势在于它具有每个音符的恒定数量的频率箱,而线性频率标度对于低音符的箱数很少,而对于高音的箱数太多。我不知道这是否适用于numpy,您可能需要自己编写代码。

    【讨论】:

    • 作为一名物理学家,我理解其中的复杂性,但这是为正在研究它的学生而准备的。它不一定是完美的,只要我们掌握了要点,一切都应该适合她的成绩。使用 abjad 转录。我现在正在打电话,但我会调查一下。谢谢!
    • 这里也是物理学家和钢琴演奏家。是的,我自己也尝试过这样做,但在看到它有多困难后基本上放弃了。但我不会阻止你尝试......
    【解决方案2】:

    您提到您有物理学背景(这有助于在最初的问题中了解!)并且您表示您了解如何获取频率并因此得到注释从使用FFT 的单一钢琴音调。然后缺少的是从一个在空间和时间上都本地化的功能转移到一个随时间变化的功能。一种泛化是wavelet analysis,其中内核是

    g(t-u) 的选择会产生不同的结果,具体取决于您希望如何处理随时间变化的信号。您得到的不是频谱频率,而是频谱频率时间的二维图。这样您就可以更好地从时变信号中提取音符。

    当然,您可以简单地创建一个窗口,在其中使用 FFT 分析窗口上的每个块并提取最大频率 - 但这很脆弱,需要手动调整,并且不适用于更复杂的信号。

    【讨论】:

      【解决方案3】:

      为了对此进行更新,这是我们最终使用的代码。它使用在各列上平均的频谱图来确定音符的位置,并从那里使用谐波来确定该音符的主要频率。然后使用 abjab 在乐谱上绘制音符。不是完美的,但在单簧管的主要音阶上效果很好。

      我们使用 Audacity 来消除输入音频中的噪音,有时还会放大声音。

      Here is the code. Thanks for all your help.

      【讨论】:

      • 嗨 Wesley,我知道这是一个旧线程,但代码似乎没有运行,并且在运行 plt.specgram(...) 时在 matplotlib 内的某个地方中断。有没有机会,有一个 pip freeze 输出,所以我可以尝试你的依赖版本?
      • 嘿@SagiMann,对不起,但我没有。这已经是差不多 5 年前的事了,所以代码被破坏并不让我感到惊讶。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 2014-04-22
      • 1970-01-01
      相关资源
      最近更新 更多