我如何知道一个字节何时是代表 MIDI 增量时间的字节序列中的第一个?

Posted

技术标签:

【中文标题】我如何知道一个字节何时是代表 MIDI 增量时间的字节序列中的第一个?【英文标题】:How do I know when a byte is the first of a sequence of bytes representing MIDI delta time? 【发布时间】:2020-06-07 21:57:52 【问题描述】:

我想以字节(和位级别)读取和编码 MIDI .mid 文件。读取 .mid 文件时,如何识别特定字节是增量时间值的第一个字节?

例如,下面是 Mandal 的 多媒体信号和系统中的图 2.12 .mid 文件的轨道块图:

我怎么知道010178000000 是增量时间字节,因为它们附加到的事件是不同的字节长度? (例如,乐器变化似乎比增量时间字节多两个字节,而第一个 Note On 事件似乎包含比增量时间字节多 3 个字节)。它是基于解释增量时间字节之后的内容吗?如果是这样,第二个 Note On 事件让我感到震惊:为什么它看起来只有两个字节跟随 delta 时间字节?

它没有出现在 Mandel 的示例中,但我希望有一个答案也能澄清多字节增量时间。

当然,我很感谢您就如何改进我的问题提出意见。

最后,我不是要求可以自​​动读取 .mid 文件的库。这些很好(耶!)但我想了解如何将文件格式读取到字节级别。

【问题讨论】:

【参考方案1】:

在知道下一个增量时间从哪里开始之前,您确实必须解码 MIDI 消息。

实际的Standard MIDI Files specification 说:

<MTrk event> = <delta-time> <event>

&lt;delta-time&gt; 存储为可变长度的数量。它表示之前的时间量 以下事件。如果轨道中的第一个事件发生在轨道的最开头,或者如果 两个事件同时发生,使用零增量时间。增量时间始终存在。 […]

<event> = <MIDI event> | <sysex event> | <meta-event>

&lt;MIDI event&gt; 是任何 MIDI 通道消息。运行状态使用:MIDI的状态字节 如果前面的事件是带有 相同的状态。每个 MTrk 块中的第一个事件必须指定状态。 Delta-time 不是 视为事件本身:它是 MTrk 事件语法的组成部分。请注意 运行状态发生在 个增量时间。

【讨论】:

感谢CL的回答。我已经在规范中阅读了您第一句话之后的所有内容。如果您将注意力集中在第二个 Note On 事件上。我不明白我怎么会知道它后面的00 是增量时间事件,而不是第一个 Note Off 事件中间的43。第二个Note On有错误吗? (它是否缺少 9n 字节?第一个 Note On 中的 93 字节是否只是隐含在第二个 Note On 中?如何解码第二个 Note On 事件以知道 00 是下一个增量时间字节?) 每条note-on消息都有两个参数字节。缺少的状态字节就是规范所说的“运行状态”。 谢谢!这很有帮助。

以上是关于我如何知道一个字节何时是代表 MIDI 增量时间的字节序列中的第一个?的主要内容,如果未能解决你的问题,请参考以下文章

MIDI:将 BPM 转换为 FPS 增量时间?

代表困惑.. 我如何知道几个代表何时完成了他们的任务?

MIDI 蓝牙 LE、SYSEX 消息不完整

MIDINoteMessage 何时在 MusicTrack 中播放? iOS

midi.Sequencer 的序列何时结束?

在 iOS 中解析 Midi 数据包