如何在php中检测歌曲的BPM

一首歌曲的节奏/ BPM如何以编程方式确定? 通常使用哪些algorithm,以及必须考虑什么?

在一个单独的StackOverflow文章中解释这是有难度的。 一般而言,最简单的拍子检测algorithm通过定位声能中的峰值来工作,这很容易检测。 更复杂的方法使用梳状滤波器和其他统计/波形方法。 有关代码示例的详细说明,请查看此GameDev文章

要search的关键词是“节拍检测”,“节拍跟踪”和“音乐信息检索”。 这里有很多信息: http : //www.music-ir.org/

有一个(也许)年度竞赛称为MIREX不同的algorithm进行testing其节拍检测性能。

http://nema.lis.illinois.edu/nema_out/mirex2010/results/abt/mck/

这应该给你一个testingalgorithm的列表。

一个经典的algorithm是Beatroot (谷歌它),这是很好,很容易理解。 它是这样工作的:

  1. 短时间快速FFT音乐获取声谱图。
  2. 将每个时间步长的所有频率的幅度增加相加(忽略减less)。 这给你一个称为“光谱通量”的一维时变函数。
  3. 使用任何旧的峰值检测algorithmfind峰值。 这些被称为“开始”,并且对应于音乐中的声音开始(音符开始,鼓点击等)。
  4. 构build起始间隔(IOI)的直方图。 这可以用来find可能的节奏。
  5. 为节拍跟踪结果初始化一组“代理”或“假设”。 依次向这些代理提供一个起始点。 每个代理都会跟踪也是节拍的起始列表,以及当前的速度估计。 如果代理人能够接受最初跟踪的节拍和速度,可以接受这些发起人,如果他们是完全不同的,就忽略它们,或者如果他们介于两者之间,则产生新的代理人。 不是每个节拍都需要一个起始点 – 代理可以插入。
  6. 每个经纪人根据其假设的整洁程度给予一个分数 – 如果所有的节奏开始都很响,则得分较高。 如果他们都是经常性的,就会得到更高的分数。
  7. 得分最高的代理人就是答案。

根据我的经验,下面是这个algorithm:

  • 峰值检测相当特别且对阈值参数敏感。
  • 有些音乐没有明显的节奏。 显然它不会与这些工作。
  • 很难知道如何解决60bpm-vs-120bpm的问题,尤其是现场跟踪!
  • 通过仅使用一维光谱通量丢弃大量的信息。 我认为你可以做很多有限的频谱通量(也许一个宽带鼓)。

下面是该algorithm的实时版本演示,展示了光谱通量(底部的黑线)和起始点(绿色圆圈)。 这是值得考虑的事实,节拍是从绿色圆圈中提取。 我已经像点击一样回放了起始点,说实话,我不认为我能听到他们的节拍,所以在某些方面,这个algorithm比在节拍检测的人更好。 我认为减less这样一个低维度的信号是其薄弱的一步。

令人讨厌的是,我几年前find了一个很好的网站,提供了许多algorithm和编码检测。 我完全没有把它改回来。

编辑:find它!

这里有一些很棒的链接可以帮助你开始:

http://marsyasweb.appspot.com/

http://www.vamp-plugins.org/download.html

节拍提取涉及音乐中认知度量结构的识别。 很多时候,这些不符合物理声音的能量 – 例如,在大多数音乐中存在一定程度的切分,这意味着我们所感知到的“脚踏”敲击与物理声音的存在不符。 这意味着这是一个非常不同的领域, 发病检测 ,这是检测的物理声音,并以不同的方式执行。

你可以试试Aubio库,它是一个简单的C库,提供开始和节拍提取工具。

还有在线Echonest API ,虽然这涉及上传MP3到网站和检索XML,所以可能不太适合。

编辑:我遇到了这个昨晚 – 一个非常有前途的C / C + +库,虽然我没有使用它自己。 鞋面插件

您感兴趣的研究领域称为“音乐信息检索”(MUSIC INFORMATION RETRIEVAL)

有许多不同的algorithm可以做到这一点,但是它们都是从根本上围绕着起始点检测。

开始检测测量事件的开始,在这种情况下的事件是正在播放的音符。 您可以查看加权傅立叶变换(高频率内容)中的更改,您可以查找特定内容中的较大变化。 (Spectrial差异)。 (有几篇文章,我build议你仔细观察一下)一旦你应用了一个发病检测algorithm,你可以通过阈值选取节拍的位置。

一旦获得了节拍的本地化,就可以使用各种algorithm。 你可以把它变成一个脉冲序列(创build一个所有时间都为零的信号,而且只有当你的节奏发生的时候为1),然后对这个和BAM应用一个FFT,现在你在最大的峰值处有一个发生频率。

这里有一些文件可以引导你朝着正确的方向发展:

http://www.elec.qmul.ac.uk/people/juan/Documents/Bello-TSAP-2005.pdf

http://bingweb.binghamton.edu/~ahess2/Onset_Detection_Nov302011.pdf

以下是有些人正在讨论的内容的扩展:

有人提到了应用机器学习algorithm:从基本上收集起始检测function(上面提到的)中的一大堆特征,并将它们与neural network/逻辑回归中的原始信号结合起来,并了解是什么使得一个节拍成为一拍。

看看安德鲁博士,他在斯坦福大学网上有免费的机器学习讲座(不是漫长的video讲座,实际上是一个在线的远程课程)

如果您可以设法与您的项目中的python代码接口, Echo Nest Remix API是一个相当漂亮的Python for API:

有一个方法analysis.tempo会给你的BPM。 它可以做更多的事情比简单的BPM,你可以从API文档或教程中看到

执行傅里叶变换 ,并find功率谱中的峰值。 您正在寻找人耳低于20 Hz截止频率的峰值。 我通常猜测在0.1-5赫兹范围内是慷慨的。

SO问题可能有所帮助: Bpmaudio检测库

此外,这里还有几个关于SO的“峰值发现”问题之一: 测量信号的峰值检测


编辑:不,我做audio处理。 这只是一个猜测,基于你正在寻找文件的频域属性的事实…


另一个编辑:值得注意的是有损压缩格式如mp3,存储傅里叶域数据而不是时间域数据。 有一点聪明,你可以节省自己一些沉重的计算…但看到cobbal的深思熟虑的评论。

准确的BPM检测非常困难。 看到这个stackoverflow的问题 ,我的回复。

要重新发布我的答案:简单的方法是让用户用节拍点击一个节奏的button,然后计算点击数除以时间。

其他人已经描述了一些节拍检测方法。 我想补充一点,有些库提供了这类任务的技术和algorithm。

Aubio就是其中之一,它具有良好的声誉,并且用C ++包装器编写,所以你可以很容易地将它与一个cocoa应用程序(苹果公司的框架中的所有audio资料也用C / C ++编写)集成在一起。

有几种方法可以获得BPM,但我发现最有效的方法是“拍频谱”( 这里描述)。 该algorithm通过比较每个音乐的短样本来计算相似度matrix。 一旦计算出相似度matrix,就有可能得到每个时间间隔T的每个样本对{S(T); S(T + 1)}之间的平均相似度:这是拍频谱。 拍频谱中的第一个高峰大部分时间是拍子的持续时间。 最好的部分是你也可以做音乐结构或者节奏分析。

这里有一个免费的程序将分析和写入BPM到ID3V2标签。 不知道有多好

我可以想象在4-4个舞曲中这是最简单的,因为每秒钟应该会有一次低频震动。