Преобразование MIDI-тиков в реальные секунды воспроизведения
Я хочу знать, как конвертировать MIDI-тики в реальные секунды воспроизведения.
Например, если MIDI PPQ (количество импульсов на четвертную ноту) равен 1120, как бы я преобразовал его в реальные секунды воспроизведения?
3 ответа
Формула 60000 / (BPM * PPQ)
(миллисекунды).
Где BPM - это темп трека (ударов в минуту).
(т.е. дорожка 120 ударов в минуту будет иметь время MIDI (60000 / (120 * 192))
или 2,604 мс за 1 тик.
Если вы не знаете BPM, сначала вам нужно будет это определить. Время MIDI полностью зависит от темпа трека.
В MIDI темп задается мета-событиями "Установить темп" в микросекундах на четвертную ноту.
В отличие от PPQ, который определяется только один раз в заголовке MIDI, темп может меняться во время музыкальной пьесы, поэтому он может быть задан несколько раз мета-событиями.
Секунды воспроизведения можно рассчитать следующим образом:
ticks_per_quarter = <PPQ, found in the header>
µs_per_quarter = <as of latest Set Tempo event>
µs_per_tick = µs_per_quarter / ticks_per_quarter
µs = ticks * µs_per_tick
seconds = µs / 1.000.000
Обратите внимание, что если бы у нас был темп в BPM, а не мкс в квартал, мы бы умножили его на PPQ, как в ответе Ааронаута. BPM и мкс на квартал являются обратными: первая частота, а вторая - период.
Обратите внимание, что в документе, указанном выше, PPQ также называется "делением" или "тиками на квартальную ноту".
60 ударов в минуту - 1 минута 1000 миллисекунд - 1 секунда 60 секунд - 1 минута или 60000 миллисекунд
поэтому, чтобы преобразовать миллисекунды в бит / мин для события тика: бит / мин (в миллисекундах) равен 60000, деленному на (BpmValue)
чтобы установить событие тика для */8 тактов (как в 7/8): ударов в минуту (в миллисекундах) равно 60000, деленное на (BpmValue), деленное на 2
Сейчас я работаю над метрономом C#. Если вы программируете, приведите его к целому числу, чтобы округлить. доли миллисекунды не должны быть проблемой. хотя, если точность - ваша сделка, удостоверьтесь, что вы устанавливаете свой результат, чтобы читать в плавающей точке.
вопрос: объект таймера C# допускает значение с плавающей запятой, назначенное в миллисекундах?
Любые комментарии или предложения, касающиеся реализации C#, с благодарностью. если моя математика неверна, пожалуйста, дайте мне знать. Спасибо!