在WAV文件中查找备注

时间:2014-03-06 13:32:14

标签: python numpy scipy

我想弄清楚如何将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,这是钢琴音阶,里面有八个音符。我想要一种方法来隔离每个音符,这样我就可以找到它的频率并找出正在播放的音符。一旦我将笔记分开,我就可以完成其余的工作。

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

编辑:所以这很复杂,就像先生们所说的那样。我现在想我只是想找到“极端”峰值,然后找到追踪这些峰值后的极端最小值,并将其作为我的注释,因为我们不需要太大的数据片来弄清楚这是频率。我遇到的问题是,有很多高峰,很难找到我想要的。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

最简单也是最有趣的事情可能是计算spectrogram数据,这基本上是数据短节的光谱图,与时间相对应。确保频率刻度对数,因为钢琴上琴键的频率是指数级的空格。在Python中,您可以使用函数specgram来计算它,它包含在matplotlib中。有关如何查找不同类型的音乐,请参阅this google image search。另外看看一些可以播放MP3 / WAV并有可视化插件的计算机程序,我记得Winamp有一种方法可以在十多年前播放现场频谱图。

这是一个有趣的练习,但如果您想使用这种技术自动转录某些音乐的音符,请告诉您:这是一个非常难的问题,科学家已经研究了很多年。例如,一个问题是大多数仪器产生大量谐波,这会使任何算法混淆以自动找到音符。忘记任何带有人声或打击乐的音乐,因为它们会产生很多宽带噪音(特别是字母'和'呐喊'),几乎不可能识别任何其他音符。

如果你想获得幻想,请看一下Q变换(参见wikipedia和那里引用的论文)。您可以将其视为频谱图,但沿着频率轴的频段以对数间隔(例如,钢琴音阶上每半音或四分音符的频段)。这种方法优于标准频谱图的优点在于它每个音符具有恒定数量的频率区间,而线性频率标度对于低音符具有很少的频段,而对于高音符具有太多的频率。我不知道这是否适用于numpy,你可能需要自己编写代码。

答案 1 :(得分:2)

你已经提到过你有一个物理背景(这有助于在原始问题中知道!)并且你已经表明你了解如何获得频率因此使用FFT从单一钢琴音调。那么缺少的是从空间和时间本地化的功能转变为随时间变化的功能。一种泛化是wavelet analysis,其中内核是

enter image description here

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

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

答案 2 :(得分:1)

要对此进行更新,以下是我们最终使用的代码。它使用在列上平均的频谱图来确定音符在哪里,并从那里使用谐波来计算音符的主要频率。然后使用abjab在一张音乐上绘制音符。不是完美的,但在单簧管的大规模上运作良好。

我们使用大胆来减少输入音频的噪音,有时还放大声音。

Here is the code. Thanks for all your help.