如何检测重复的音乐?

信息处理 声音的 音乐
2022-02-09 11:38:55

假设您有一个带有单个音频流的音乐数据文件(例如 mp3),其中包含 3 小时的音频时间序列,但您想知道该音频文件(可能是一些编译)是否会在一段时间后重复。也许它只包含一段 1 小时的音乐,重复两次。

如何确定音频文件中是否重复播放相同的音乐?有这方面的工具吗?也许是一个python工具?或者也许我可以自己创建一个?

3个回答

您可以对整个文件进行自相关,但这对于 3 小时的音乐来说将是相当昂贵的。您可以尝试将其分割成单独的歌曲,然后将每首歌曲与其他歌曲进行交叉关联。这将更加实用,但首先需要分段。

另一种方法是对每首歌曲进行特征提取并基于特征集创建“指纹”,然后您可以简单地比较指纹。这就是像https://www.shazam.com/这样的歌曲识别通行证。但是,这样做相当复杂。

作为一个简单的解决方案,提取要测试重复的歌曲的开头(或任何部分)(您不需要太多来检测重复),然后执行流相关,这在 python 中使用 scipy.signal 很容易做到python中的.lfilter,将歌曲片段时间反转作为滤波器的系数,并作为被滤波的波形流过序列。阈值检测可以确定重复点,因为相关性的大小与所使用的滤波器系数的长度成正比(它是标准偏差,匹配的结果为Nσ)。您可以将其扩展到 pandas csvread 非常支持的文件的块处理。

您可以进一步加快使用 FFT 进行相关所需的处理,但只要要相关的初始序列不太长,上述使用 lfilter 将是一种简单、直接且稳健的检测重复方法。只需使过滤器足够长,以满足您的误报概率与检测概率标准。

对我来说,Shazam 算法的基本思想非常容易编码,10 年前我在 python 中用不到 250 行代码就完成了它,它真的很好用……

你可以从基本的开始测试这个想法:

  • 首先,您需要为所有需要的歌曲生成指纹,为此您需要为每个块音频构建一个 Spectogram(您将来可能会测试重叠),这里的关键是将您的 Spectogram 拆分为某些范围带,以保持简单而基本的尝试将您的垃圾箱分成4带状(当然这是一个基本示例),例如。我从 bin 50-200, 200-400, 400-700,中选择700-2048,如果它是最好的拆分 ?? 可能不是大声笑(这里有一个大问题,所有歌曲的采样率都需要相同),如果所有歌曲都被采样44100hz并且您使用 FFT 大小4096,那么第一个频段 bin 将覆盖:

    44100*50/4096 = 538.33hz

    44100*200/4096 = 2.153hz

    哇,它是一个大范围的频率,哈哈,但只是测试你理解,现在对于这个块音频/频谱,你需要从这个频段获取高频段/频率并存储,对接下来的 3 个频段/频段做同样的事情,最后你可以说你已经为这个块/段生成了一个指纹......例如,你可以为每个频段生成一个峰值并生成你的指纹 33-301-450-1031 (333014501031),你将为整个音频,逐块,在最后你会有很多指纹,为这首歌存储所有指纹......啊哈这是我 10 年前生成指纹的测试David Guetta Feat. Rihanna - Who's That Chick,Shazam 称之为所有指纹Constelation Map

    在此处输入图像描述

  • 现在我想你会想要通过提交一些未知音频来测试算法,看看它是否有效并在你的基础中找到,这里的过程是相同的(记住这首未知歌曲需要以相同的采样率从你构建的歌曲中采样您的指纹数据库),但是现在对于每个块指纹,您将比较您的数据库中是否存在,例如,如果在此块 unkow 歌曲中您获得此指纹33-301-450-1031 (333014501031),并且如果您的数据库中存在相同的指纹,我可以说您有一个(1)匹配这首歌的指纹,如果你的匹配在线性时间内继续增加,这就是同一首歌:-) ...

我使用 5 秒的样本对其进行测试,以尝试匹配音频并像魅力一样工作,当然你可以使用相同的原理来找到重复的点!

在此处输入图像描述