Протокол MIDI Time Code состоит из двух основных частей: сообщений, отвечающих за передачу таймкода SMPTE, и сообщений управления событиями (MIDI Cueing). Передача таймкода — процесс очевидный: текущее время SMPTE упаковывается в обычные сообщения MIDI, которые распространяются по MIDI-кабелю к потребителям. Источником MTC могут быть синхронизаторы — специальные приборы, преобразующие LTC- или VITC-вариант сигнала SMPTE, поступающего от мастера, в сигналы разных типов, в том числе и в сообщения MIDI Time Code. Второй вариант — прямое генерирование MTC секвенсором на основе размера и темпа произведения, либо цифровым магнитофоном или компьютерной рабочей станцией на основе частоты дискретизации и порядкового номера семпла.
Вторая составляющая MTC, MIDI Cueing — это нечто особенное, не имеющее аналогов в SMPTE: способ автоматизации работы MIDI-системы на основе запрограммированного списка событий.
Далее речь пойдет о структуре MTC, без обсуждения практических аспектов, а также оборудования для синхронизации и управления. Поэтому, если вы не сталкивались с этой темой ранее, приведенный материал может показаться довольно абстрактным. Однако таков замысел цикла: сначала мы рассматриваем язык общения устройств, после чего — физическую реализацию протокола, и только потом сами устройства с особенностями их использования.
Quarter Frame
Основное сообщение MTC для передачи таймкода называется Quarter Frame (четверть кадра), как следует из названия, оно передается четыре раза за SMPTE-кадр. В режиме синхронной работы от мастера к ведомым устройствам поступает непрерывный поток сообщений Quarter Frame, так что здесь прослеживается аналогия с сообщением MIDI Clock. Однако между этими сообщениями есть принципиальная разница: частота потока Quarter Frame не зависит от текущего темпа, а определяется выбранным форматом кадров SMPTE. Так, при 30 fps один "тик" Quarter Frame будет происходить каждые 8,3 мс. Однако только "тиками" в системе синхронизации по абсолютному времени не обойтись. Нужно передавать само время, как это и происходит в SMPTE.
Правда, здесь возникает сложность — как передать 80-битный кадр в одном сообщении Quarter Frame? Решение нашлось простое. Во-первых, не всю информацию из этих 80 бит нужно передавать с каждым тиком, достаточно будет текущего времени, а пользовательские данные и биты состояния можно передать дополнительно, с другими сообщениями. Во-вторых, время можно передавать поэтапно: в первом сообщении Quarter Frame передать кадры, во втором — секунды, и так далее. В результате получилась структура, приведенная на рис. 3.
Сообщение Quarter Frame относится к категории общесистемных и состоит из статус-байта 0xF1 и одного байта данных. Этот байт делится на две части: первая (биты 4, 5 и 6) содержит тип данных, а сами данные хранятся во второй части (младшие четыре бита, рис. 3). Тип данных — это не что иное, как часы, минуты, секунды или кадры. Правда, с помощью четырех оставшихся бит много информации не передашь, поэтому значение величины (например, номера кадра) формируется из двух последовательных сообщений Quarter Frame. Четыре бита данных первого сообщения объединяются с четырьмя битами второго, образуя байт данных, который затем и принимается к обработке. Так что первое сообщение будет иметь тип, скажем, "номер кадра, младшая половина значения", а второе — "номер кадра, старшая половина".
Простой пример: получены два сообщения Quarter Frame, байт данных первого равен 00000011, второго — 00010001. Тип данных первого (биты 4, 5, 6) имеет номер 0, то есть "номер кадра, младшая половина", второго — "номер кадра, старшая половина". Объединяя биты данных, получаем 00010011, то есть номер кадра равен 19. С секундами, минутами и часами все аналогично. Правда, итоговый байт расшифровывается по-разному (рис. 4).
Для номеров кадров используются только пять младших битов (старшие три бита должны быть нулевые и приемником игнорироваться). Диапазон номеров — от 0 до 29, первый кадр имеет номер 0. Для секунд и минут — шесть младших битов (диапазон от 0 до 59). Для часов итоговый байт содержит две величины: собственно номер часа (младшие пять бит) и частоту кадров (биты 5 и 6). Старший бит игнорируется. Расшифровка частот кадров приведена на рис. 4. Стоит заметить, что в стандарте SMPTE частота кадров в самом кадре не кодируется, а определяется приемником самостоятельно.
Если тайм-код передается в прямом направлении (то есть время идет вперед), то устройство, генерирующее MTC, посылает восемь сообщений Quarter Frame в показанном на рис. 5 порядке с интервалом в четверть кадра между каждым сообщением, после чего процесс повторяется. Если отсчет времени идет назад, то сообщения передаются в обратном порядке, начиная с 0xF1 0x7n и заканчивая 0xF1 0x1n. В любом случае передаются все восемь сообщений, иначе приемник не получит полного значения времени.
Таким образом, на передачу информации об одном кадре SMPTE затрачивается время, равное двум кадрам (8 х 1/4). А значит, при преобразовании SMPTE в MTC только каждый второй кадр попадает в MIDI-таймкод. Это несколько снижает скорость реакции ведомого устройства — для того, чтобы "зацепиться", ему нужно прочитать восемь сообщений Quarter Frame в указанном на рис. 5 (или обратном) порядке. В реальном времени это может занять от двух до четырех кадров, в зависимости от момента начала считывания. С другой стороны, информация о скорости (извлекаемая по времени прихода сообщения Quarter Frame) приходит в четыре раза чаще по сравнению с SMPTE, что способствует более качественной синхронизации.
Теперь пара тонкостей. В SMPTE (в варианте LTC) приемник считает за начало кадра момент получения первого бита 80-битной посылки. В MTC за начало кадра считается момент прихода первого и пятого сообщения Quarter Frame в серии, то есть 0xF1 0x0n и 0xF1 0x4n. Но время-то можно прочитать только после того, как будут получены все восемь сообщений серии. К этому моменту полученное значение времени устареет на два кадра. Для отображения на дисплее правильного времени приемное устройство должно прибавить к считанному значению поправку в эти самые два кадра. При обратном отсчете времени поправка не нужна — время считывается после прихода сообщения 0xF1 0x0n, то есть в момент реального начала кадра.
По идее, после однократного считывания времени приемник может просто подсчитывать сообщения Quarter Frame и самостоятельно крутить стрелки на своем "циферблате", так как число кадров в секунду также содержится в считанном значении. Однако спецификация требует постоянной "сверки часов", то есть извлечения реально переданного времени после каждых восьми сообщений Quarter Frame.
На рис. 6 показан пример передачи SMPTE-времени 02:44:39:12 в виде серии из восьми сообщений Quarter Frame (частота кадров — 30 fps, non-drop). Стоит отметить, что для частот 24, 30 drop frame и 30 non-drop номера кадров в сообщениях Quarter Frame будут всегда четные, а для частоты 25 fps — четные будут меняться на нечетные каждую секунду. Связано это с тем, что половина кадров SMPTE в MIDI Time Code не попадает.
Может показаться, что сообщения Quarter Frame сильно загружают канал передачи. Давайте подсчитаем. Скорость передачи данных по MIDI-кабелю составляет 31250 Кбит/с. Реально для передачи каждого байта требуются не восемь, а десять бит (почему — поговорим в статье об аппаратной реализации интерфейса). Следовательно, время передачи одного байта составляет 320 микросекунд (10 / 31250). Возьмем самую высокую частоту кадров SMPTE — 30 fps. Каждое сообщение Quarter Frame состоит из двух байт, и эта пара будет передаваться 120 раз в секунду (30 fps х 4 сообщения на кадр). В данном случае канал будет занят 640 мкс каждую 1/120 секунды, или 7,68% времени. А это значит, что кроме MIDI Time Code по тому же кабелю спокойно может пройти еще и насыщенная аранжировка. И хотя на практике мешать синхросигнал с рабочими данными не принято (под MTC отводится отдельный порт), особых препятствий для этого нет.