【问题标题】:Decoding Unknown MIDI Events解码未知 MIDI 事件
【发布时间】:2018-07-27 00:40:13
【问题描述】:

我正在用 Java 编写一个 MIDI 文件阅读器(主要是作为练习,可能用于 Android 项目,因为它不包含 javax.sound.midi 库)。我正在关注this 规范。

我在我的项目中很好地实现了规范细节,实际阅读是在逐个事件的基础上进行的。在文件上打开一个InputStream,并传递同一个对象以解析各种事件对象,这样当一个事件完成自身解析时,流定位在下一个事件上。这一切都很出色。

我的第一个测试文件只是一个带有在 Sonar 8 中创建的空数据轨道的速度图。速度轨道被完美解析。空轨道在其块标识符和轨道名称之后具有以下数据:

00 B0 07 47 00 0A 40 00 FF 2F 00

第一个字节被成功解析。 00 = 增量时间 0,B0 = 通道 0 上的控制器事件,07 = 主音量控制,47 = 音量值为 71。

接下来的字节让我感到困惑。 00 0A 40 最有可能的情况是它是一个值为 64 的 Pan 事件。0A 是一种控制器事件,我希望它前面有 B0 和音量事件。但由于它前面没有已知的事件标识符字节,我的阅读器无法解析此事件。

所以我想我的问题是如何解释这种类型的事件?在文件格式中是否可以将控制器事件与单个 B0 标识符这样串在一起?此外,如果我在文件中遇到无法识别的事件类型,如果我不知道事件应该是什么,是否真的有办法知道我可以跳过多少数据?我希望能够跳过未知事件,这样我的阅读器就不会失败,但如果我无法识别事件,我不知道如何跳过它。希望对这些具体案例有所了解。

【问题讨论】:

  • 我通过查看非空数据轨道(带有实际音符的轨道)获得了一些见解。虽然我预计会有一堆 Note-On 事件 (0x9),但我看到一个 Note-On 事件,然后是轨道中的所有音符。同样有趣的是没有 Note-Off 事件,在音符应该结束的地方有速度为 0 的 Note-On 事件。所以我开始相信一个事件标识符不仅可以识别下一个事件,而且在找到另一个事件标识符之前,事件标识符后面的所有字节都是该类型的事件。我仍然希望对此进行确认或进一步解释。

标签: java events parsing midi


【解决方案1】:

这就是所谓的运行状态。它是 MIDI 规范的一部分。你正在做的是完全正确的事情。抱歉,您必须通过对 MIDI 数据流进行逆向工程来解决这个问题。 Here is a longer explanation of running status.

而且,是的,速度为 0 的 Note On 事件是 Note Off。实际的 Note Off 事件具有关联的力度,但几乎没有设备实现 Note Off 力度,因此零力度的 Note On 更为常见。

【讨论】:

  • 这是一个更加充实的规范,太好了。非常感谢,先生。
  • 不客气。早在 MIDI 初期,我就做过很多与 MIDI 相关的编程,所以请提出您可能遇到的任何问题。
【解决方案2】:

如果有人遇到类似问题,我会回答我自己的问题。 (尽管不太可能)

我的上述评论似乎成立。读取第一个标识的事件后,如果后续事件没有事件标识符,则可以将其视为与前面相同类型的事件。

所以在我的例子中:

00 B0 07 47 00 0A 40 00 FF 2F 00

即使只存在一个事件标识符,也可以解释为两个连续的控制器事件。所以这确实是一个 Volume 事件 07,然后是一个 Pan 事件 0A,当然还有 End of Track 事件 FF 2F 00

我的代码中的解决方案是记住看到的最后一个标识符,如果流中的下一个字节不是有效标识符,则下一个字节块被解释为与前一个事件相同类型的事件。似乎有道理,更重要的是,我的读者成功完成了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多