我只是在编写自己的MIDI解析器,我想知道如何区分0xFF
指定完整的实时类别消息Reset
从某些Meta-event
的开头也编码使用0xFF
然后使用一些字节(例如FF 2F 00
- > End of track
)。
答案 0 :(得分:1)
正如@Brad暗示的那样,无论是解析流式MIDI数据还是从文件中读取数据都存在差异。无论如何,当你从文件中读取它时,你只需要跟踪你所处的状态。你可以在文件中遇到0xff很多地方,但你需要总是知道你是在解析事件还是可变长度的时间戳或别的什么。
例如,如果您刚刚解析了时间戳并遇到0xff,那么它将是一个元事件。
另外,我发现MIDI文件格式的最佳参考是:
答案 1 :(得分:1)
在 MIDI电缆上,MIDI 消息会在它们发生的瞬间传输。 MIDI文件实际上是对带时间戳的MIDI信息的录制,以便以后播放。时间戳和MIDI消息的组合称为事件。 MIDI电缆上显示的信息与MIDI文件中出现的事件之间存在一些差异。
您是正确的,在MIDI电缆上,单字节实时消息可以发生在其他消息的字节中间。但是,在MIDI文件中,跟踪每个事件的确切字节数很重要,因此实时消息不能在其他事件中存储在MIDI文件中。
系统独占事件对于存储在MIDI文件中很有用,但一般来说,将任何其他系统公共消息或系统实时消息存储在MIDI文件中是没有意义的。
$ FF重置:在MIDI线缆中,状态字节$ FF表示重置。但是,当您播放MIDI文件时,在播放期间重置接收MIDI设备通常没有意义。因此,在MIDI文件中,重新定义$ FF的状态字节以指示元事件。
$ F6 Tune Request:如果设备响应此消息,我认为它会进行一些内部调整校准,会中断正在进行的任何播放。与重置消息类似,中断MIDI文件内的播放没有意义。
时钟,位置和开始/停止信息($ F1 MIDI时间码四分之一帧,$ F2歌曲位置指针,$ F3歌曲选择,$ F8时钟,$ FA开始, $ FB继续,$ FC停止):记录MIDI文件的设备或软件通常不会将这些传入的消息记录到MIDI文件中。但是,设备可以选择解释这些消息以实际重新定位,启动,停止或控制播放或录制的速度。播放MIDI文件的设备或软件可以选择将这些消息发送到MIDI输出端口,以控制除MIDI文件音符之外正在播放其自身声部的其他MIDI设备。由于这种用法,MIDI播放器负责发送这些时钟,位置和开始/停止信息,而不是MIDI文件。
$ FE Active Sensing:如果发送设备发送此消息,则将其用作空闲填充程序,以表明电缆仍然正常连接。如果接收设备开始看到Active Sensing消息然后它们停止,则可以将其解释为电缆断开连接并使静音音符静音。将空闲填充符存储在MIDI文件中是没有用的。它将是发送设备发送它的功能,而不是MIDI文件的责任。
如果您确实需要在MIDI文件中存储System Common或System Real-Time消息,我相信它们可以存储在MIDI文件中的$ F7事件中。我的理解是存储在$ F7事件中的数据字节将在MIDI电缆上逐字传输。 Sonic Spot document将$ F7的这种用法称为“授权SysEx”事件(滚动到文档的底部)。 MIDI Technical Fanatic's Brainwashing Center文档MIDI File Format将$ F7的这种用法称为“Escaped”事件(请参阅“MTrk中的事件”页面)。 MIDI音序器软件Sekaiju将$ F7称为“SysEx(任意)”事件。
一般警告:在MIDI Manufacturers Association网站上,您可以找到一些official information(标准的表格和附录)或在forum上提问。但正如您可能知道的那样,official MIDI standards cost money的主要内容。我没有购买它们,所以我上面的理解是基于第三方网站的描述和MIDI软件的一般用法。您应该始终了解第三方可能已经解释了与官方标准不同的东西。 (例如,Jeff Glatt的MIDI技术狂热者的洗脑中心文档MIDI Specification说$ F9是一条Tick信息,但是MMA说的是$F9 is undefined and reserved消息.Glatt说General MIDI program 47 is Orchestral Strings,MMA说program 47 is Orchestral Harp 3}}。)