4

我正在尝试读取 C++ 中的 midi 文件,但我遇到了一个错误,这似乎是标准 midi 规范中未定义的事件(从许多网站检索,包括: http: //www.sonicspot.com/指南/midifiles.html )

我在十六进制编辑器中打开了 midi 并查明了错误。它发生在第一个“注释”事件之前。该文件是使用 Sibelius 6 软件生成的,我想知道如果我在这里发布文件部分,有人会帮助我解决这个问题。

这是第 3 首曲目的开头:

4D 54 72 6B (MTrk magic number)
00 00 1F F5 (track size in bytes - 8181)
00 FF 03 04 (4 bytes follows) (track sequence name)
00 FF 04 0B (11 bytes follows) (instrument name)
00 C0 34 (program change event)
00 B0 79 00 (controller event)
00 5B <- (what the heck is that?!)

它不能是增量滴答,因为第一个值是 00(没有 MSB 设置为 1),它也不是可识别的事件。10 个字节后,我识别出一个“注释”事件它是:

00 5B 30 00 40 00 00 07 64 00 0A 10 00 90 3E 47 <- 注意

我不知道“注释”之前的那 12 个字节代表什么,因此无法读取文件。我知道第一个音符很长,也许这就是原因。我还注意到我找不到代表“条形”暂停的事件。也许这就是条形+长度的代码?我应该把它们读成蜱虫吗?

4

1 回答 1

6

MIDI 文件的一种复杂性是运行状态。如果有相同类型和通道的消息序列(例如所有控制器或所有音符),则 MIDI 可以通过省略状态字节来节省一些字节。如果这不使用运行状态,那么您将看到的字节是:

00 B0 79 00 - controller 121: controller reset
00 B0 5B 00 - controller 91: reverb
00 B0 40 00 - controller 64: sustain
00 B0 07 64 - controller 7: volume
00 B0 0A 10 - controller 10: pan
00 90 3E 47 - note message

因为所有的控制器消息都是连续的并且用于相同的通道,所以可以省略状态字节。一旦消息类型发生变化,就必须再次添加状态字节。

如果您试图理解 MIDI 文件,那么我建议在您无法理解 MIDI 事件时使用单独的工具(例如Python-MIDIGNMidi )作为完整性检查器。这些可以将其显示为文本,以便您可以模仿它在做什么。

编辑:另一个需要注意的问题是任何带有长度或持续时间参数的 MIDI 消息(例如 PPQN 中的 MIDI 文件中的事件之间的时间,或者 sysex 消息或元事件的长度)都使用可变长度,所以不要不要假设所有长度字段总是固定长度。

免责声明:我在 Sibelius 6 中编写了 MIDI 导出代码...

于 2012-10-16T21:54:58.443 回答