Задержки MIDI

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
19.919
113
62
Киев
@PianoIst, Тимофей, чтоб хоть какой то толк от топика был -
Midi это ведь последовательный интерфейс, т.е. даже если ноты нажаты одновременно, на VSTi они прийдут последовательно.
Поиск по прежнему не работает, где то мы уже это обсуждали -
- какова скорость передачи миди сообщений (средняя)?
- какова дистанция между двумя миди сообщениями?
Ну и с какой максимальной скоростью, пусть теоретически, в состоянии играть пианист (128-е, 256-ые?)?
 
  • Like
Реакции: motley crew
Ой, тут вопросов столько — что в пору голосовым сообщением)))

Я не могу ничего сказать про пропускную способность канала — то есть я совсем не дока в том вопросе, с какой скоростью и задержкой дата течёт между платой клавиатуры и ЦПУ. Насколько я понимаю — тут всё достаточно хорошо бьётся с любыми другими COM-устройствами (то есть с мышами и клавиатурами). Возможно, учитывая ваши прорывы с iProAudio (надеюсь, не напутал с названием) — возможно этот вопрос стоит покурить отдельно.

Что же касается самого протокола — то здесь у меня компетенции больше, но она с небольшой «спецификой» того, как всё работает в Рипере. Насколько я понимаю, в Рипере оно работает так как и заявлено протоколом:
- опрос устройства идёт раз в тик. Тик привязан к темпу проекта.
- если пустить два сообщения в 1 тик — вполне может статься, что какое-то из них не дойдет.
- поэтому обычно работа идёт с миди-буфером. В целом, как я понял — буфер может быть любой длины. Всё зависит от того, какой предел длины буфера на передатчике и приёмнике. Насколько я понимаю, можно в один буфер и войну и мир впихнуть.
- потом буфер раскладывается на отдельные сообщения и скармливается движку синтезатора.

Из всего этого обычно следует вывод: задержка MIDI ничтожна по отношению к величине аудио-буффера, т.к. миди-устройство опрашивается в среднем, чаще, чем обновляется аудиобуфер. И в принципе, принято считать её нулевой.
Конечно, это не так, но в контексте цикла обработки миди-сообщений обычно аудиобуфер формируется гораздо дольше, чем требуется для опроса MIDI-устройства. Опять же, тут есть нюансы о которых я никогда не думал, и понятия не имею, как что происходит на задержках в 32 сэмпла... Может там миди и опаздывает)
 
  • Like
Реакции: motley crew
Ну и с какой максимальной скоростью, пусть теоретически, в состоянии играть пианист (128-е, 256-ые?)?
гы))) Это к биомеханикам) Но я помню 64-е играл. Где-то у Гайдна в медленной части ;)

Думаю, это где-то близко к пределу:


В принципе, в зависимости от темпа проекта он может играть быстрее тиков
 
Последнее редактирование:
Ну и с какой максимальной скоростью, пусть теоретически, в состоянии играть пианист (128-е, 256-ые?)?
барабанщик, за единицу времени, все-равно, может извлечь нот, больше чем пианист, и проблем с задержкой нет
 
  • Like
Реакции: motley crew и PianoIst
и проблем с задержкой нет
Про барабанщиков я знаю чуть больше, чем про пианистов - у меня сын хороший барабанщик.
Но заставить его играть на МИДИ барабанах ни кто не сможет! И проблема не в задержках, конечно, а совсем в другом.
Собственно и при игре на Электро фно проблемы у музыканта конечно же не в задержке, а в аутентичности того, что он ощущает и слышит.
Цифровые технологии уже очень хорошо, но они по прежнему далеки от того, чтобы обмануть тактильные и слуховые органы музыканта.

РЕЧЬ НЕ ОБ ЭТОМ.
 
  • Like
Реакции: Long
Из всего этого обычно следует вывод: задержка MIDI ничтожна по отношению к величине аудио-буффера, т.к. миди-устройство опрашивается в среднем, чаще, чем обновляется аудиобуфер. И в принципе, принято считать её нулевой.
Конечно, это не так, но в контексте цикла обработки миди-сообщений обычно аудиобуфер формируется гораздо дольше, чем требуется для опроса MIDI-устройства. Опять же, тут есть нюансы о которых я никогда не думал, и понятия не имею, как что происходит на задержках в 32 сэмпла... Может там миди и опаздывает)
Вопрос тут не в том, что кто-то опаздывает, я уверен, что миди долетит быстрее любого аудио буфера, хоть в 8 сэмплов.
Есть входной буфер и выходной, и они могут быть любыми. И каким бы маленьким не был входной буфер (а в случаи с миди входом он конечно маленький) он всё равно будет складываться с выходным аудио буфером - если нас интересует раундтрип.
И если аудио буфер мы можем померять - раундтрип, и зная схемотехника устройства посчитать какой входной, какой выходной (честные, а не те, что показывает DAW или контролер самого девайса, которые в общем не учитывают задержек на AD/DA и не только), то за какой промежуток времени нажатая нота долетит до синтезатора в DAW - померять просто не выйдет.
Сложная схема мне представляется такой -
микрофон над клавой и пишем звук удара по Клаве рядом с миди нотой на два трека и смотрим.
Зная задержку входа аудио и сравнивая расхождение пика в звуке с нотой - можем прикинуть задержку по миди.
 
  • Like
Реакции: PianoIst
Скорость МИДИ в первой версии:
MIDI messages are made up of 8-bit words (commonly called bytes) that are transmitted serially at a rate of 31.25 kbit/s.
ЕМНИП в ЮСБ скорость передачи 384 кбит/с
Ап: у Ямахи скорость передачи - 38 кбит/с
 
  • Like
Реакции: Valery
Я тут ещё ликбез у Димы прошёл (@Rst7 )
Он мне по памяти вот что сказал -
Скорость midi интерфейса - 31 кбит/с - 3100 байт/с
Одно миди сообщение занимает объём примерно 3 байта
Другими словами - одно миди сообщение летит от миди клавы до синтезатора в DAW (без учёта механики клавиш и прочего на пути) -
за 1 мс - не такое уж и маленькое время!!!!!!!
А поскольку миди это последовательный порт, то в аккорде из 10 нот (ну больше музыкант только попой нажать сможет :)) -
последняя прилетит в DAW через 10 мс - вот вам и задержка по входу 0 :(

PS: Вот - пока писал, @presly, подтвердил, что у Димы хорошая память!
 
  • Like
Реакции: Valery и presly
Многие миди-клавиатуры и клавишные инструменты сейчас напрямую к компьютеру по USB подключаются.
Возможно, там скорость передачи выше?
Или есть ограничение самой спецификации?
 
Александр рискну предположить,что счет идет относительно темпа [per quarter],т.е темп и размер завязаны непосредственно.Для передачи аккорда полимод режим есть.В секунду при такой частоте 960 отсчетов[в большинстве daw] относительно четверти при темпе 60bpm.дельта между тиками=1,04166мс.При увеличении частоты дискретизации значения дельты между тиками уменьшатся,вычислительные нагрузки скорее всего вырастут.
 
@Trasher, счёт конечно относительно темпа. Думаю, что когда @PianoIst, писал про 64-ые, он имел в виду темп по умолчанию 120.
Значит ноты играются со скоростью 30 мс.
Если кто то умеет 128-ыми, то каждая нота раз в 15 мс.
В любом случаи это на много, на много медленнее чем позволяет миди стандарт, значит проблем быть не должно.
Даже если предположить не возможное, что был нажат аккорд 10 ю пальцами и потом сразу серия 128-х нот - они все всё равно уложатся в скорость передачи миди интерфейса.
 
@Trasher, счёт конечно относительно темпа. Думаю, что когда @PianoIst, писал про 64-ые, он имел в виду темп по умолчанию 120.
Значит ноты играются со скоростью 30 мс.
Если кто то умеет 128-ыми, то каждая нота раз в 15 мс.
В любом случаи это на много, на много медленнее чем позволяет миди стандарт, значит проблем быть не должно.
Даже если предположить не возможное, что был нажат аккорд 10 ю пальцами и потом сразу серия 128-х нот - они все всё равно уложатся в скорость передачи миди интерфейса.
Александр очень наглядно можно посмотреть и прикинуть[замерить объем данных нужного вам макс/мин сообщения пакета] что к чему в рипере[midi editor].Как вариант-Принимаете(абстрактно) за чанк[пакет и т.д и т.п.] миди айтем.Создаете несколько айтемов[прям как в реалтайме,чанки начинаются когда ноте-он первой ноты, кончаются когда в определенный момент времени все ноты-офф] в каждом создаете аккорд/пассаж и т.д.Смотрите в " RAW просмотре.Звёздочками подсвечиваются начало/конец выбранной ноты"В нем указаны данные в hex ,но там(не буду сильно утверждать) свой RAW формат отличный от миди, скорее всего(что более вероятно) быстрее миди. Так как рипер может нелинейно миди с точностью до семпла[установленного samplerate] на уровне миди-айтема в аранжере,а в мидиредакторе нифига не может,т.к. привязка по ppq (версия рипера 5.9 из-за этого некоторые неприятные траблы при склейке миди-айтемов бывают,но поймать довольно сложно),за 6 рипер ничего не скажу так как не имею в наличии.Да и вверху я неправильно написал- при увеличении семплрейта т.к. ppq=960,а srate=96000=1sec=>1000ms/960ppq=1.04166 м/с,так же как и при 44100[но это тоже не точно,так как прогресс не стоит на месте)].
 
Последнее редактирование:
Думаю, что когда @PianoIst, писал про 64-ые, он имел в виду темп по умолчанию 120.
Где-то у Гайдна в медленной части
:Dle46:
А поскольку миди это последовательный порт, то в аккорде из 10 нот (ну больше музыкант только попой нажать сможет :)) -
последняя прилетит в DAW через 10 мс - вот вам и задержка по входу 0
мммм... Что-то мне подсказывает, что если взять одновременно 20 нот — они не будут рассредоточены во времени на отрезке в 20ms. Это было бы уже слышно. Соответственно, скорее всего, даже если и так — хост всё равно знает, когда они были нажаты.
192262

Теперь интересно и со звуком послушать.
192263

вот как оно звучит
рендер:

запись с выхода интерфейса:


@Trasher, концептуально вы правильно рассказываете, но реально, особенно в контексте общения с контроллером — докручиваете слишком много сущностей.
На один тик можно впихнуть сколько угодно событий — для этого достаточно их передать одним буфером, в котором будет куча событий. К началу и концу ноты это вообще не имеет отношения, т.к. MIDI — это протокол не евент-ориентированный.
Просто в относительно медленных темпах некоторые ноты могут попадать в один тик, хотя реально они может были и с разницей во времени. В этом, собственно, главная проблема спецификации.

Ну и для общего развития
скорее всего(что более вероятно) быстрее миди
нет, там свой рипероский расширенный формат, который достаточно многословный: на каждое событие тратится что-то около 30 байт, в то время, как в оригинальном midi-file что-то около 10.

Это сама структура, в которой запихано событие.
Python:
class MIDIEventDict(te.TypedDict):

    """
    Dict, represents trsferable midi event.
    Members
    -------
    ppq: float
    selected: bool
    muted: bool
    cc_shape: CCShapeFlag
    buf: ty.List[int]
    """

    ppq: float
    selected: bool
    muted: bool
    cc_shape: CCShapeFlag
    buf: ty.List[int]

А вот так оно превращается в чанк:
Python:
    def set_midi(self, midi, start=None, unit="seconds", sort=True):
        """
        Erase all midi from take and build new one from scratch.
        Parameters
        ----------
        midi : List[MIDIEventDict]
            can be taken with `Take.get_midi()` or build from scratch.
        start : float, optional
            if offset needed (for example, start from a particular time)
        unit : str, optional
            time unit: "seconds"|"beats"|"ppq"
        sort : bool, optional
            if sort is needed after insertion
        Raises
        ------
        NotImplementedError
            currently, gaps between events longer than several hours
            are not supported.
        See also
        --------
        Take.get_midi
        """
        out = b''
        start_ppq = 0
        if start is not None:
            start_ppq = self._resolve_midi_unit((start,), unit)[0]
        last_ppq = 0 - start_ppq
        for msg in midi:
            evt = b''
            ofst_i = msg['ppq'] - last_ppq
            if ofst_i > 4294967295:
                raise NotImplementedError(
                    'ofset larger than 4294967295 currently not supported'
                )
                # something done with big offset
                # it is about many-many-many hours between events
                # (1 hour is about 8000000 ppq in 120 bpm)
            ofst = struct.pack('<I', int(ofst_i))
            evt += ofst
            last_ppq = msg['ppq']

            flag = bytes(
                [
                    int(msg['selected']) | (int(msg['muted']) << 1)
                    | msg['cc_shape']
                ]
            )
            evt += flag

            len_ = struct.pack('<I', len(msg['buf']))
            evt += len_

            buf = bytes(msg['buf'])
            evt += buf
            out += evt
        packed = out.decode('latin-1')
        RPR.MIDI_SetAllEvts(self.id, packed, len(packed))
        if sort:
            self.sort_events()
 

Вложения

  • Like
Реакции: Trasher
Не знаю почему меня так бомбануло,но после задержек Багемота ака Воланд де Морта я вчера уснуть не мог...
И сегодня мне выдает что тут
"Да, бросьте Вы!
Барабан и бас играют нормально, А клавиши еле дышат. не потому, что клавишник плохой. а потому, что клавиши не отвечают ему."(c)
 
мммм... Что-то мне подсказывает, что если взять одновременно 20 нот — они не будут рассредоточены во времени на отрезке в 20ms.
Конечно не будут, в DAW всегда включен Квантайз, который сам как то определяет с какой задержкой между собой ноты считать нажатыми одновременно. И это видимо ещё один компромис и упрощение из за которого миди звучат “не живыми”.
Тимофей, но миди однозначно последовательный протокол, и сколько бы ты одновременно нот не нажал, полетят они в DAW последовательно.
А ещё, я подозреваю, что всё же есть буфер и на миди ( понятия не имею как узнать какой), хотя может его и нет, так как протокол ведь без подтверждения - не долетело, так не долетело....
 
Последнее редактирование:
ЕМНИП в ЮСБ скорость передачи 384 кбит/с
Это скорость передачи абстрактных данных, подозреваю, что с midi всё сложнее - в смысле - гдеж то миди ему возьмёт столько.... До USB, да и после, ведь всё же midi интерфейс стоит, со своим стандартным протоколом.
 
Последнее редактирование:
3 байта — это само сообщение. Мы уже вроде бы договорились, что по стандарту один пакет данных — не меньше 8 байт. А я говорю про midi-file — там сообщение ещё имеет как минимум, своё положение в тиках. Я, правда, миди-файлы никогда не парсил, так что могу ошибаться. У меня ощущение, что я и с чанком рипера приврал, но кажется, я всё-таки насчитал 30 байт (там очень с запасом взято на позицию в тиках и на форму CC)

P.S. А, нет, вру! Когда пакет идёт от инстурмента — там не 8 байт. Но и не три: ещё есть хеадер и, кажется, футер тоже. Не могу сейчас быстро спецификацию найти
 
Последнее редактирование:
  • Like
Реакции: Aleksandr Oleynik
@Aleksandr Oleynik, Да, похоже, вы всё-таки правы, и в голом поле любое первое сообщение расценивается как статус-байт. То есть, да, 3 байта на стандартное сообщение.

А вот в миди-файлах там уже больше информации, собственно это немного оффтоп, просто раз вопрос о миди-чанках возник — хотелось его прояснить.

Посмотрел на *.smf — там время по идее должно храниться в 4 байтах + сообщение, итого — 7 байт.
 
А ещё, я подозреваю, что всё же есть буфер и на миди ( понятия не имею как узнать какой), хотя может его и нет, так как протокол ведь без подтверждения - не долетело, так не долетело....

Буфер зависит от того, на чём делается. На очень древних контроллерах FIFO был 1 байт (т.е. байт пришел -- вызвал прерывание), потом 16 байт, которые можно было организовать на прерывание по достижении 1, 4, 8 или 14 байт, сейчас может быть хоть килобайт.
 
Буфер зависит от того, на чём делается. На очень древних контроллерах FIFO был 1 байт (т.е. байт пришел -- вызвал прерывание), потом 16 байт, которые можно было организовать на прерывание по достижении 1, 4, 8 или 14 байт, сейчас может быть хоть килобайт.
Это кто решает? Аппаратная часть интерфейса?
Я так понимаю, что Квантайз на лету в DAW тоже ведь через буфер происходит, нужно ведь как то подождать тех 10 нот аккорда прилетающих последовательно?
 
Последнее редактирование:

Сейчас просматривают