java - 节拍匹配算法

标签 java android ios objective-c

我最近开始尝试创建一个移动应用程序 (iOS/Android),它会自动匹配 ( http://en.wikipedia.org/wiki/Beatmatching) 两首歌曲。

我知道这确实存在,而且还有其他人取得了一些成功,但我遇到了与播放器准确性相关的问题。

具体来说,我遇到了“节拍”不对齐的“同步”问题。目前使用的各种方法有:

  • 提前计算 BPM,确定一个“节拍”(使用 sonicapi.com 之类的东西),并尝试适本地排列,然后开始混音并调整其播放速率(速度调整)

  • 利用一堆元数据来触发特定的开始和停止

什么不起作用:

  • 利用 echonest 的 API(它在服务器上胜过比赛,我们想在客户端上完成)
  • 类似 pydub 的东西(不是实时的)

今天谁在使用这个算法:

  • iwebdj

  • 拖拉机

有没有人对如何解决这个问题有任何建议?我见过很多人这样做,但在移动设备上实时进行似乎是个问题。

最佳答案

有很多方法可以解决这个问题,其中一些方法比其他方法效果更好。 Matthew Davies已发表多篇关于此事的论文,等等。扫视this article似乎分解了执行此操作所需的一些步骤。我和一个同学在 Matlab 中构建了一个节拍跟踪器(不幸的是......),我们的目标是在 2 首歌曲之间创建一个结尾/开头,以便它们之间的节奏是无缝的。我们想对 BPM 变化很小的歌曲(两者之间的 BPM 为 +-7 左右)执行此操作。我们的方法有点像这样:

  1. 在我们的数据库中找到两首具有重叠“调中心”的歌曲。所以让我们说 2 首歌,都是 Am。

  2. 找到两者之间关键中心的这种特殊重叠。说第一首歌 30 秒和第二首歌 60 秒

  3. 现在使用 onset-detection algorithm 创建节拍图带峰值拾取;另外,this对我们很有帮助。

  4. 为每个轨道选择第一个“节拍”,并在该点重叠两个轨道。现在,由于它们之间的 BPM 略有不同,因此节拍不会真正对齐。

  5. 据此,我们创建了一种 map ,为我们提供了歌曲 A 的节拍和歌曲 B 的节拍之间的样本偏移。由此,我们希望能够对歌曲的淡入区域进行时间拉伸(stretch)歌曲 B 以便它的每个开始(在本例中为节拍)在正确的样本索引处与歌曲 A 的开始排列在 ITS 淡出区域上。因此,例如,如果歌曲 B 的起始点 2 显示为比歌曲 A 的起始点 2 早 5,000 个样本,我们只需拉伸(stretch)这 5,000 个样本区域,以便起始点 2 在两首歌曲之间完全匹配。

这听起来很奇怪,但实际上听起来不错。尽管这是在 Matlab 中完全离线完成的,但我也在寻找一种在移动应用程序中实时执行此操作的方法。不完全确定您可以在 Android 世界中为此使用的库,但我想它在 C++ 中最有效。

我遇到的几个库对于制作某些东西的原型(prototype)非常有用,或者至少研究源代码以更好地理解如何在移动应用程序中执行此操作:

Essentia (伟大的社区,开源) Aubio (似乎也维护得很好,开源)

在 iOS 领域做这类事情需要阅读的其他内容: vDSP Programming guide This article may also help 我遇到了this project那是在做一些节拍检测。不幸的是,虽然它看起来已经过时了,但它可能会提供一些额外的见解。

不幸的是,它不像同时“按下播放”来对齐节拍那么简单,除非您假设它们有非常具体的方面(精确的节奏等)。

如果你真的有时间,你应该看看Tristan Jehan's (founder of Echonest) thesis ;它塞满了节拍检测等算法和方法。

关于java - 节拍匹配算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20850575/

相关文章:

android - firebase API 中的 MismatchSenderID 错误

ios - 具有不同字体的 UIButton textLabel

java - 将坐标从 3D 场景转换为 2D 叠加

java - 将数据发布到 dropwizard 资源?

java - 使用 Apache Camel,如何向已经很大的文件添加一些行?

ios - IOS快捷方式:使用应用程序设置(嵌套)词典以修改EXIF数据

iphone - 横向模式下的图像封面流

java - 字符串到列表<String>的内存高效映射

android - 使用 paypal 沙箱的信用卡付款返回响应为 "state": "created"?

java - java 中的 menu.add 不会将 NONE 作为有效整数