9.3 观察音乐
要快速获得对不同体裁乐曲的印象,一个比较便捷的方式是,画出某类音乐的声谱图。声谱图是音频的一个可视化表示方式。它在特定时间段(x 轴)内显示出音频的强度(y 轴);这是说,在歌曲的某个时间窗内,颜色越深,频率越强。
Matplotlib提供了一个方便的函数specgram() ,可以处理大部分后台计算,并把它们画出来:
>>> import scipy >>> from matplotlib.pyplot import specgram >>> sample_rate, X = scipy.io.wavfile.read(wave_filename) >>> print sample_rate, X.shape 22050, (661794,) >>> specgram(X, Fs=sample_rate, xextent=(0,30))
我们刚刚读取的波形文件是以22 050 Hz的频率抽样的,一共包含了661 794个样本。
如果把各式各样的波形文件的前30秒用声谱图画出来,那么就会看到同一体裁乐曲之间的共性,见下图。
稍微浏览一下,我们立刻就可以找出金属音乐和古典音乐在声谱图里的差别。金属音乐在大多数频谱里都有一个很高的强度(有活力!),而古典音乐会随着时间显示出更加多样的模式。
这些数据应该能够训练出一个分类器,至少可以以足够高的准确率区分出金属音乐和古典音乐。而其他两两体裁之间,例如乡村和摇滚,却给我们提出了更大的挑战。对我们而言,这是一个真正的挑战,因为我们要区分的不是两个类别,而是6个。我们需要很好地区分出所有这6个类别才行。
将音乐分解成正弦波形成分
我们的计划是从原始样本中(储存在X里)提取频率强度,并把它传进分类器。这些频率强度可以通过快速傅里叶变换 (Fast Fourier Transform,FFT)得到。由于FFT背后的理论已经超出本章的讨论范围,所以我们只看一个例子,对它所做的事情有一个直观认识即可。之后,我们会把它当做一个黑盒式的特征提取器。
例如,我们生成两个波形文件:sine_a.wav 和sine_b.wav ,它们分别包含400 Hz和3000 Hz正弦波形的声音。之前提到的那个瑞士军刀sox,就是达到这个目标的一种方式:
$ sox --null -r 22050 sine_a.wav synth 0.2 sine 400 $ sox --null -r 22050 sine_b.wav synth 0.2 sine 3000
下面这个图表显示了前0.008秒的形状。同时我们也看到这个正弦波形的FFT。毫不奇怪,我们在对应的正弦波形下面可以看到400 Hz和3000Hz的峰值。
现在让我们把它们混合起来,得到具有3000 Hz声音一半音量的400 Hz声音:
$ sox --combine mix --volume 1 sine_b.wav --volume 0.5 sine_a.wav sine_mix.wav
我们可以在合成声音的FFT图形上看到两个峰值,其中3000 Hz峰值的大小几乎是400 Hz峰值的两倍:
对于真实音乐,我们很快就可以看到,FFT的形状并不像在前面那个简单例子中那样漂亮:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论