假装自己知道自己在做什么,就可以对音乐进行指纹识别

更新:我将使用一些开源替代方法进行相同的练习。 还有更多…

TL; DR:音频识别有时有效,有时无效。

因为我是个白痴,已经缺了一个月的睡眠,啤酒,冬日寒冷,下雨并杀死了两架ESP-12F。

在我父母的房子里,有一个博斯卡壁炉,使房子温暖而模糊。 为此,您需要一些干木! (免费咨询)。 在一些空闲的下午,VH-1的某些部分(录像)?运行70-80-90年代的旧视频剪辑,持续一两个小时。 我爸爸不愿意看那些。

仅作记录:该家伙只是听古典音乐放松了几个小时。 妈妈在开始的15分钟内入睡,我可以忍受两个小时。 这不是他妈的莫扎特效应[阅读:不存在]。 他最喜欢的Tune in电台是古典音乐类型和智利的贝多芬广播电台。

70年代-80年代-90年代是我童年和成年前的一部分。 是的,我还没说完就说了。 为了使事情变得简单,我出生在AC / DC的“ TNT”专辑发行的同一个月。 Aaand他观看了那段时间的所有视频片段。

我开始打赌我的父亲,我可以识别任何歌曲,乐队甚至发行年份,而不必蒙上眼睛。 使用任何在线服务(再次是Shazam),该百分比为98%,只是由于背景噪音过高而丢失了。

嗯 有什么“智能”功能吗?

我对自己的第一个问题是:“ 我们(人类)如何识别歌曲? ”。


首先 ,人类是模式识别机器 。 一些研究表明,它有助于理解两个特定事件之间的差异,尽管它们之间可能存在某种联系,但它们之间的相关性尚不清楚。 对于好奇的人,有一些非常好的阅读材料,所以这里是:

  • 专家怎么看?
  • 史蒂芬·沃尔夫拉姆(Stephen Wolfram)的新科学
  • 数据声化中的人类模式识别(论文)

第二 :我们可以听懂歌曲中的口语

全球大约有6200种语言,其中汉语占主导地位(12亿)。 其次是……西班牙语? (无法找到其他确认数据)。 来源在这里。

即使我们听不懂说什么,歌曲也能奏效。 我们需要讲回去学习它。 这是“反馈学习过程”。 在此示例中,可以安全地跳过它。 如果您需要一些示例,可以考虑在youtube中使用“ despacito”。 它的缩写是“如果我们大部分时间都能听到,就可以说出来”。

最初的问题仍然存在: 机器可以识别歌曲吗? 答案是“是,但有困难”

从“计算机如何听到”开始,这是Gorgle的第一个结果。

音频从模拟源进行数字转换。 你有一波,它会共振成“某物”(麦克风),这会产生电磁脉冲,并可以通过模数转换器读取。 声卡的Layman条款。

然后,数据以二进制形式存储,以后可以处理。

首先是波形。 这是时域显示,幅度与时间的显示。

声谱图是声音强度随时间变化的视觉表示。

据我所记得,“查看”计算机比“听”要容易得多。

要实现检测,我们首先需要创建音乐的存储方式。 完成创建歌曲的哈希。 准备好了,这已经进入JSON域了……

片段“代码”是歌曲的存储方式。 为此,将歌曲编码为字符串。 为此,它使用Ffmpeg (whattha ?!)并将结果编码为base64字符串。 您需要将其存储在某个地方。

信息存储后,即可自由搜索。 怎么样? 使用相同的方法:创建样本的哈希,将其用作样本,然后使用模糊逻辑进行搜索。 搜索结果应该会吐出一些信心。 和繁荣。 你有它。

这里也有一线希望 。 识别过程应易于产生背景噪音或任何其他破坏性因素(我们称其为“恶作剧”)。 而且,它应该尽可能唯一(这几乎是灵丹妙药,但不起作用。稍后会详细介绍)。

处理是一个三步方法:代码生成(散列歌曲),提取(将要存储的结果数据送入处理)和查找(搜索和评分结果)。

在此演示中,我将使用Echoprint。 由Echo Nest最初开发,现已成为Spotify的一部分。


首先,我们需要收集一些精选音乐。 哦,我们有一些…

克隆echoprint服务器和echoprint代码源存储库,以实现更高的公正性。

编译该东西,将其安装在安全的地方(/ usr / local现在不应是蠕虫的应急池…),并确保Python库确实在工作。 之前请阅读每个项目的文档! (不要忘记setup.py进程)

现在,在命令行中使用一些非sequitur魔术:

jci @ / media / somewhere:$查找/ media / MP3 / N /-名称“ * .mp3” | echoprint-codegen -s> Fingerprint.json

文件Fingerprint.json应该包含文件的哈希值。

现在,有趣的部分。 取出内容并使用哈希创建另一个数据库文件。

jci @ / media / somewhere:$ cat Fingerprint.json | jq -r’。[]。code’| egrep -v null $> database_audio.fingerprint

将二进制搜索索引提供给:

jci @ / media / somewhere:$ cat database_audio.fingerprint | echoprint-inverted-index index.bin

并运行它!

此“回声休息服务”可作为REST服务(巨型DUH!)。 可以通过curl在以下URL上查询它:

  • / query / jaccard
  • / query / set_int
  • / query / set_int_norm_length_first

对我来说唯一具有一致数据的是第一个:Jaccard。 它使用匹配的索引值,使用统计信息并尝试计算集合与匹配结果的距离。

由于该服务正在运行,因此无法使用相同的源文件进行标识。 让我们使用一些来源,例如带有来自同一位艺术家的许可音乐的电影…

……好吧,whaddayaknow ?!

然后,使用电影中的样本。

并为此示例创建哈希:

jci @ / tmp:$ echoprint-codegen sample.mp3 | jq -r’。[0] .code’> search.txt

标识现在应该可以正常工作:

现在是无聊的部分。

我们需要找到分数较高的索引。 索引35应该是我们JSON文件的第37行。 好吧, 以前告诉过你

我们有一个虚拟行“ [”来写入整个JSON有效负载的开头,并且行号应从零行开始。 因此索引35是第37行。基本的书呆子数学。

使用set_int方法给出相对更近的数字…

第一个是最接近的一个。 我们来看第二个结果:

有用!

让我们破坏样本,只是为了好玩。

用Audacity打开它,更改采样率,并增加一些噪音。

单声道8k,重采样会带来一些失真和失真。 可能出什么问题了?

分数从205下降到120。但是,仍然在两个结果的比较值之内。

让我们对电影的另一个示例进行相同的操作。 这次有更多背景噪音。 和一个完全不同的表演者。

我们得到不同的结果。 这就是我之前所说的“诡计”。

因此,让我们增加样本量。 原来是19秒。 这是40秒。

完全不同的结果。 这不是因为背景噪声,不是因为采样率(电影未修改),也不是因为音频处理过程。 这仅仅是由于表演者的改变。 声音是相似的,但是回声打印“仍然看不见东西” 。 并且样本大小发生了变化(19秒对40秒)。


所以你有它。

在结束之前,我想介绍一些有趣的观点。

  • Spotify(有点猜测)现在拥有代码。 “令人惊讶的是”自2016年甚至更早以来没有添加任何代码。 我想知道为什么…
  • Python echoprint库缺乏很多注意事项。 实际上必须添加一些陷阱代码(并非例外),因为大型库或段错误可能会使echoprint-codegen内存不足,并偶尔吐出“ null”。 当然,在Feed CLI魔术上添加一些“ egreps”可以解决该问题,但请快来! 1996年又结束了吗?
  • 索引编制也有很多问题。 在为2444首歌曲编入索引(没有玩笑)之后,它崩溃了。 尝试了全部:在其他地方(另一台计算机)创建指纹,然后重新编制索引(不起作用)。 两次使用之间重新引导(不)。 最终放弃了,但是在让计算机着火之前,我决定运行常规的分析工作。 这也给了我另一个彻底烧掉计算机的理由。
  • 我还没有使用Shazam或其他ID服务对样本量进行任何其他结论性测试。 这些测试以19秒失败,但是40秒(平均样本时间为30秒)似乎达到了检测的最佳效果。 30秒对于4:30的歌曲来说是很多…

似乎倦怠是真实的。 Yu