【问题标题】:Pattern Recognition Algorithm/Technique模式识别算法/技术
【发布时间】:2017-07-26 16:31:06
【问题描述】:

背景

对于基于音乐的问题,我深表歉意,但细节并没有那么重要。我正在依次浏览一个 midi 文件,我正在寻找一种有效的方法来查找数据中的模式以找到称为连音的东西。见下图:

连音符的顶部有数字(3 或 6)。我需要知道它们在数据文件中的哪个位置开始。注释下方的数字是您将在数据文件中按顺序看到的值。以防万一您无法破译下面的数据,这里是:

1、2、2.3333、2.6666、3、3.5、3.6666、3.83333、4、4.1666、4.3333、4.5、4.6666、4.8333、
5、6.3333、6.6666、7.1666、7.3333、7.5、7.6666、7.8333、8、8.1666、8.333、8.5、8.6666。

  • 第一个连音符从位置 2 开始,音符位置之间的差异为 0.3333(重复)
  • 第二个连音符从位置 3.5 开始,音符位置之间的差异为 0.1666(重复)

主要问题是,在注释中,与下图不同,位置 7 不会在数据文件中注明,因为仅数据文件仅列出了注释位置。您在该位置看到的图标称为休息,在数据文件中没有注明。

问题

如何找到找到每个连音符开头的有效方法?是否有某种递归方法?

【问题讨论】:

  • MIDI 文件不包括音符的持续时间(与音符的开头结合起来可以检测其余部分)吗?
  • 它确实包括音符的持续时间,但与符号中固定长度的音符不同,midi 音符长度并不总是可预测的。因此,很难确切知道休息多长时间。

标签: algorithm iteration


【解决方案1】:

我认为您不需要为此进行任何递归。

正常的音符值只能由a / 2^b 类型的节拍的分数表示。连音可以是任意分数,但大多数情况下我见过三连音、五连音或(在您的情况下为六连音)。

所以最简单的方法是计算每个音符的长度(可能是两个 MIDI 事件之间的时间差?或者长度明确存储在 MIDI 中?我对格式不太熟悉)并计算有理表示这个长度。

分母不是 2 的幂的每组音符都属于这样的连音。要将音符组合在一起,我建议采用以下方法(假设一个连音的所有音符都具有相同的值):

  • 将分母分解为两个a 的幂,其余为b(例如a * b = 4 * 5
  • 初始化一个大小为b的空连音组
  • 对于每个音符,计算到连音符开头的距离并将音符存储在相应的位置,必要时插入休止符。连音符的长度可以通过取连音符中所有音符的最小长度l来计算,因此贪婪地添加它们直到这些音符的结尾超过连音符开头的距离l * b
    这样,您就可以根据最小音符长度来创建连音符,然后添加适合它的所有音符。

【讨论】:

  • 这并不完全有效:连音不必等长。例如,您可以将一个三连音绑在“八度”和“四分之一”上,而不是三个“八度”音符。否则,这是一个合理的起点,只需要调整其余部分(也可以绑定到连音中)。
  • 我在这方面确定了答案,但我不确定这是否是计算连音所基于的音符长度的最佳方法。
  • 感谢@TobiasRibizel 的回复。我的应用目前仅阅读位置,而不是持续时间。我保持音符的持续时间相同,因为这是一个击鼓应用程序,所以长度无关紧要。看起来你和 Prune 在同一个波长上,但我对你的符号有点迷茫。您能否根据我发布的职位提供 a 和 b 代表的示例?抱歉这么慢。
  • 实际上我以两种不同的方式使用 ab 。如果你指的是第一个例子:你可以写成 2,333... = 7/3,因为 3 不是 2 的幂,它属于一个连音。如果您指的是第二个示例:7,1666... = 43/6,将 6 分解为 2 * 3 = a * b 告诉您您有一个三元组 (b = 3) 我猜您可以接受六连音由两个三连音表示,否则会更复杂。
  • 哦,好吧。我得到它。是的,我绝对可以将六胞胎作为两个三胞胎。我知道 2.3333 是 7/3,但是 7 是从哪里来的呢?您是否对正在发生的其他事情进行了某种运行计数?此外,在您的回复开头您提到了持续时间,这在职位方面是否有效,因为这确实是我需要的。
猜你喜欢
  • 2012-07-02
  • 2010-09-07
  • 2010-10-13
  • 1970-01-01
  • 2011-02-23
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
相关资源
最近更新 更多