使用浏览器的音频API检测歌曲的速度

本文介绍了一个小项目背后的一些想法,该项目使用Audio API检测歌曲的速度。 我建议您在阅读本文的其余部分之前查看一下这些链接:GitHub上的Demo和Code。

使用音频API进行节拍检测

几天前,我遇到了乔·沙利文Joe Sullivan)的博客文章“使用网络音频进行节拍检测”,他在其中解释了一种简单的算法,该算法可以使用音频API计算歌曲的速度。 看完后,我很好奇算法在其他轨道上的表现如何。

于是我坐下来,用他的算法编码了一个小项目,并添加了一个搜索框来搜索歌曲,并显示歌曲的结果。

该算法应该与歌曲的中央片段一起使用时效果更好。 这避免了具有较小音量和较少信号的节拍,我们可以用这些信号来检测节拍。

搜索歌曲并获取预览MP3

某些音乐流服务的API提供了样本中每首歌曲30秒的样本。 我们无法选择想要的曲目的30秒(即片段的起始点是什么),但是它们通常会是歌曲中最具代表性的片段,这是算法的一个很好的选择。

根据我的测试,样本的比特率相当低,约为96 kb / s。 我以前曾尝试将它们用于我的卡拉OK项目,但结果非常嘈杂。

由于我对Spotify Web API非常熟悉,因此我选择它来搜索曲目。 搜索也非常灵活,通常使用曲目名称(没有歌手姓名)就足以找到我们想要的歌曲。

Search端点返回一个轨道列表,它们的Preview_url属性指向一个MP3文件,我们可以直接将其插入AudioContext进行处理。

计算速度

我正在遵循Joe Sullivan(非常详细)描述的算法。 我对它进行了一些调整:

  1. 动态调整阈值以识别峰 :在某些情况下,阈值0.8实在太大,并且代表峰的数量返回得太低,无法进行正确的猜测。 因此,我降低了阈值,直到给定样本的峰数更多为止。
  2. 将理论速度四舍五入为最接近的整数 。 否则,几乎不可能获得具有相同值的多个间隔。 乍一看,我们会失去精度,但是节奏通常都是整数。

为了检查算法的效果,我想知道歌曲的BPM,这是由一些可靠的来源计算得出的。 幸运的是,相同的Spotify API提供了一个端点来获取轨道的音频功能。

该项目的第一个版本使用了Echo Nest API来获取歌曲的节奏。 不久前,该API不再使用,并且此端点和其他端点合并到Spotify的Web API中。 这意味着我们不需要匹配来自不同音乐服务的曲目标识符,从而使一切变得更加容易。

端点返回一个JSON对象,该对象具有轨道的一些功能,包括其速度。

渲染峰并播放曲目

从Joe的帖子中,我非常喜欢简单的图表,这些图表显示了歌曲的峰值,以此来表示算法的作用。 我决定做同样的事情,还添加了一个按钮来播放音轨以及贯穿图形的指示器,并帮助我们查看算法检测到的峰。

增强功能?

我敢肯定,必须有更好的算法来找出歌曲的速度,但是事实证明,对于大多数90至180 BPM的“可舞曲”音轨来说,这一算法非常简单有效。 我认为这是使用现代浏览器的最新API的一种有趣方式。