如何以编程方式确定歌曲的速度/ BPM?常用的算法是什么,必须考虑哪些因素?
这在单个StackOverflow帖子中解释具有挑战性.通常,最简单的节拍检测算法通过定位声能中的峰值来工作,这很容易被检测到.更复杂的方法使用梳状滤波器和其他统计/波形方法.有关包含代码示例的详细说明,请查看此GameDev文章.
要搜索的关键字是"节拍检测","节拍跟踪"和"音乐信息检索".这里有很多信息:http://www.music-ir.org/
有一个名为MIREX的(可能)年度比赛,其中不同的算法测试其节拍检测性能.
http://nema.lis.illinois.edu/nema_out/mirex2010/results/abt/mck/
那应该给你一个要测试的算法列表.
一个经典的算法是Beatroot(google it),它很好且易于理解.它的工作原理如下:
短时FFT音乐得到超声波图.
对每个时间步长的所有频率的幅度增加求和(忽略减少).这为您提供了称为"光谱通量"的一维时变函数.
使用任何旧的峰值检测算法查找峰值.这些被称为"开始"并且对应于音乐中的声音开始(音符开始,鼓点击等).
构建起始间隔(IOI)的直方图.这可用于查找可能的节奏.
为节拍跟踪结果初始化一组"代理"或"假设".按顺序一次一个地添加这些代理.每个代理都跟踪也是节拍的开始列表,以及当前的速度估计.代理可以接受开始,如果它们与他们最后跟踪的节拍和节奏紧密相符,如果它们完全不同则忽略它们,或者如果它们介于中间则产生新的代理.不是每个节拍都需要一个发作 - 代理可以插入.
每个代理人根据其假设的整齐程度给出一个分数 - 如果其所有的节拍开始都很大,则获得更高的分数.如果它们都是常规的,它会获得更高的分数.
最高得分的代理人就是答案.
根据我的经验,这个算法的缺点是:
峰值检测非常临时且对阈值参数和诸如此类的敏感.
有些音乐对节拍没有明显的影响.显然它不适用于那些.
很难知道如何解决60bpm-vs-120bpm问题,尤其是实时跟踪!
仅使用一维光谱通量就可以丢弃大量信息.我估计你可以通过一些带限频谱通量(可能是一个宽带鼓通道)来做得更好.
这是该算法的实时版本的演示,显示了光谱通量(底部的黑线)和开始(绿色圆圈).值得考虑的是,节拍仅从绿色圆圈中提取.我已经像点击一样播放了这些内容,说实话我不认为我能听到他们的节拍,因此在某种程度上这种算法比节拍检测的人要好.我认为减少这种低维信号是它的弱点.
令人讨厌的是,几年前我确实找到了一个非常好的网站,其中包含许多用于节拍检测的算法和代码.虽然我完全没有改进它.
编辑:发现它!以下是一些很棒的链接,可以帮助您入门:
http://marsyasweb.appspot.com/
http://www.vamp-plugins.org/download.html
节拍提取涉及识别音乐中的认知度量结构.通常这些不对应于物理声能 - 例如,在大多数音乐中存在一定程度的切分音,这意味着我们感知的"脚踏"节拍与物理声音的存在不对应.这意味着这是与起始检测完全不同的领域,其是物理声音的检测,并且以不同的方式执行.
您可以尝试Aubio库,它是一个普通的C库,提供起始和节拍提取工具.
还有在线Echonest API,虽然这涉及将MP3上传到网站并检索XML,所以可能不太适合..
编辑:昨晚我遇到了这个 - 一个非常有前途的C/C++库,虽然我自己没有使用它.鞋面插件
如果您可以设法在项目中与python代码进行交互,那么Echo Nest Remix API对于python来说是一个非常灵活的API:
有一种方法analysis.tempo
可以为您提供BPM.它可以比简单的BPM做得更多,正如您可以从API文档或本教程中看到的那样
您感兴趣的一般研究领域称为MUSIC INFORMATION RETRIEVAL
有许多不同的算法可以做到这一点,但它们都基本上以ONSET DETECTION为中心.
起始检测测量事件的开始,在这种情况下的事件是正在播放的音符.您可以查看加权傅立叶变换(高频内容)中的变化,您可以查看标本内容的较大变化.(特殊差异).(有几篇论文我建议你进一步研究下来)一旦你应用了一个起始检测算法,你就可以通过阈值来挑选节拍的位置.
一旦你获得节拍的时间定位,就可以使用各种算法.您可以将其转换为脉冲序列(创建一个始终为零的信号,仅在您的节拍发生时为1)然后对此应用FFT和BAM,现在您在最大峰值处具有开始频率.
以下是一些引导您走向正确方向的论文:
http://www.elec.qmul.ac.uk/people/juan/Documents/Bello-TSAP-2005.pdf
http://bingweb.binghamton.edu/~ahess2/Onset_Detection_Nov302011.pdf
这是对一些人讨论的内容的扩展:
有人提到应用机器学习算法:基本上从起始检测功能(如上所述)收集一堆特征,并将它们与神经网络/逻辑回归中的原始信号结合起来,并了解什么使节拍成为节拍.
看看Andrew Ng博士,他在线获得了斯坦福大学的免费机器学习讲座(不是漫长的视频讲座,实际上是在线远程课程)
执行傅里叶变换,找到功率谱中的峰值.您正在寻找低于20 Hz截止值的人类听觉峰值.我猜通常在0.1-5Hz的范围内是慷慨的.
可能有帮助的问题:Bpm音频检测库
此外,这是SO上的几个"峰值发现"问题之一:测量信号的峰值检测
编辑:不是我做音频处理.基于您正在寻找文件的频域属性的事实,这只是猜测...
另一个编辑:值得注意的是有损压缩格式如mp3,首先存储傅立叶域数据而不是时域数据.有点聪明,你可以节省一些繁重的计算......但是看到cobbal的深思熟虑的评论.