Типы событий
SysEx-события выделены в особую категорию, поскольку эксклюзивные сообщения имеют произвольную длину. Чтобы не заставлять программу искать окончание сообщения по байту 0xF7 (EOX), спецификация SMF требует сохранять SysEx-сообщения с явным указанием их длины. Сначала сохраняется статус-байт 0xF0 (признак начала SysEx), затем — длина сообщения в формате величины переменной длины (то есть число байтов, следующих за 0xF0, кроме самих байт, содержащих длину), затем — тело сообщения вместе с байтом EOX, рис. 15. Например, сообщение 0xF0 0x41 0x14 0x00 0x07 0xF7 будет сохранено в SMF как 0xF0 0x05 0x41 0x14 0x00 0x07 0xF7.
Бедный секвенсор не знает, что делать — получается, что каждому принятому кусочку нужно назначить свое дельта-время, хотя кусочек этот не является самостоятельным сообщением MIDI, а только частью большой синтаксической конструкции. Но выход нашли, поощрив тем самым нерадивых разработчиков устройств. Первая порция имеет статус-байт 0xF0, она сохраняется как обычное событие. В начало второй порции (и всех остальных) дописывается статус-байт 0xF7 (EOX), чтобы сделать порцию полноценным сообщением с собственным статус-байтом. Хоть этот байт и зарезервирован как признак конца SysEx, в данном случае секвенсор понимает, что он отмечает начало очередной порции. Байт EOX в конце последней порции завершает сообщение SysEx. Между порциями не должно храниться никаких других MIDI-событий. Вот пример хранения многопакетного сообщения SysEx. Предположим, были переданы байты 0xF0 0x41 0x12 0x00, затем последовала задержка в 200 тиков, затем последовали байты 0x36 0x15 0x03 0x51 0x20 0x00, затем — задержка в 100 тиков, затем — байты 0x41 0x02 0x00 0xF7. В MIDI-файле это будет сохранено так, как показано на рис. 16.
Вся эта история с пакетами порождает интересное следствие. Если статус-байт 0xF7 использовать вне контекста передачи сообщений SysEx (то есть без предшествующего 0xF0), то вслед за ним можно сохранять такие сообщения, которые вообще-то сохранению в SMF не подлежат (общесистемные сообщения и сообщения реального времени: MTC Quarter Frame, MIDI Clock, Song Position Pointer, Song Select и т. д.). Если байт 0xF7 используется подобным образом, то вся конструкция (рис. 17) называется ESCAPE-событием.
|