比较两个音频文件

9 投票
3 回答
37046 浏览
提问于 2025-04-16 00:47

基本上,我有很多音频文件,它们都是同一首歌的不同版本。不过,有些文件的质量比原版差,有些甚至经过编辑,跟原版完全不一样。我想做的是通过编程的方式,把这些音频文件和原版进行比较,看看哪些文件和原版相符,不管质量如何。直接比较显然不行,因为文件的质量差异很大。

我觉得可以通过分析歌曲的结构来和原版进行比较,但我对音频工程一窍不通,所以这对我帮助不大。所有的歌曲都是同一种格式(MP3)。另外,我在用Python,如果有适合Python的库就太好了;如果没有,JVM上的东西或者其他本地库也可以,只要能在Linux上运行,我能搞明白怎么用就行。

3 个回答

6

首先,你需要改变比较的方式。直接分析未压缩文件里的原始样本是没有意义的。你需要从音频样本中提取一个或多个特征来作为你的距离度量。维基百科列出了以下一些常用的特征,这些特征通常用于声学指纹识别

音频指纹常用的感知特征包括平均零交叉率、估计的节奏、平均频谱、频谱平坦度、一组频带中的显著音调和带宽。

我没有现成的程序解决方案给你,但这里有一个有趣的尝试,它是对YouTube音频识别系统的逆向工程。这一系统用于检测版权侵权,和你遇到的问题类似。

21

这其实不是一件简单的事情。我觉得市面上没有现成的库能做到这一点。这里有一个可能的方法:

  1. 把mp3格式的音乐解码成PCM格式。
  2. 确保PCM数据有一个特定的采样率,这个采样率你需要提前选择(比如16KHz)。如果歌曲的采样率不同,你需要重新采样。高采样率并不是必须的,因为你只需要模糊比较,但采样率太低会丢失太多细节。
  3. 对PCM数据进行归一化处理(也就是找到最大采样值,然后调整所有采样,使得最大幅度的采样值能使用整个数据格式的动态范围,比如如果采样格式是有符号的16位,那么归一化后最大幅度的采样值应该是32767或-32767)。
  4. 把音频数据分成固定数量的采样帧(比如每帧1000个采样)。
  5. 把每一帧转换到频谱域(使用快速傅里叶变换)。
  6. 计算代表两首歌曲的帧序列之间的相关性。如果相关性超过某个阈值,就认为这两首歌是相同的。

Python库推荐:

  • PyMedia(用于第一步)
  • NumPy(用于数据处理)——你也可以看看这篇文章,里面有一些入门信息。

还有一个额外的复杂情况。你的歌曲可能在开头有不同长度的静音。所以为了避免漏掉匹配,你可能需要增加一个步骤:

3.1. 从PCM数据的开头开始扫描,直到声音能量超过预设的阈值。(比如用一个10个采样的滑动窗口计算均方根,当它超过动态范围的1%时停止)。然后丢弃这一点之前的所有数据。

5

复制自那个回答:

这个问题其实是很多人在老的AudioScrobbler和现在的MusicBrainz上讨论过很久的。现在,有一个Python项目可以帮助你,就是Picard。这个工具可以给音频文件(不仅仅是MPEG 1 Layer 3文件)加上一个唯一的标识符(其实是几个),这样之后匹配这些标签就变得很简单了。

如果你想自己动手做一个项目,libofa可能会对你有帮助。关于这个Python库的文档可能会对你最有帮助。

撰写回答