Как замедлить MIDI-файл (в идеале на Python)?

У меня есть фоновая музыка для некоторых песен в форматах .MID и .KAR, но в каждом случае она проигрывается несколько быстрее, чем мне бы хотелось. Как проще всего создать файлы .MID или .KAR с тем же содержимым, но в более медленном темпе — скажем, один замедлился примерно на 20%, другой — на 15%, третий — на 25% и т. д.?

В идеале я бы предпочел кроссплатформенный скрипт Python (поскольку это позволило бы мне легко экспериментально настроить исходный код, чтобы получить нужный мне эффект;-), но я возьму любое бесплатное решение, работающее в Linux (Ubuntu 8.04, если это имеет значение) и Mac (Mac OS X 10.5, но предпочтительна совместимость с 10.6).


person Alex Martelli    schedule 06.09.2009    source источник
comment
Вы смотрели на формат OSC? en.wikipedia.org/wiki/Open_Sound_Control   -  person magnetar    schedule 29.09.2010


Ответы (5)


Вы можете отредактировать файл в соответствии с http://www.sonicspot.com/guide/midifiles.html

Хотя, вероятно, уже есть библиотека для чтения/записи MIDI. Фактически, нужно было увидеть связанные вопросы: Простой кросс-платформенный MIDI Библиотека для Python

Установить темп

Это метасобытие устанавливает темп последовательности в микросекундах на четверть, который кодируется тремя байтами. Обычно он находится в первом фрагменте трека, выровнен по времени, чтобы возникать одновременно с сообщением часов MIDI, чтобы обеспечить более точную синхронизацию. Если событие заданного темпа отсутствует, предполагается 120 ударов в минуту. Следующая формула может быть использована для перевода темпа из микросекунд на четвертную ноту в удары в минуту и ​​обратно.

MICROSECONDS_PER_MINUTE = 60000000

BPM = MICROSECONDS_PER_MINUTE / MPQN
MPQN = MICROSECONDS_PER_MINUTE / BPM
Meta Event  Type    Length  Microseconds/Quarter-Note
255 (0xFF)  81 (0x51)   3   0-8355711
person Vinko Vrsalovic    schedule 06.09.2009
comment
Что ж, не похоже, что я получу более прямую технику, так что спасибо за это, @Vinko. - person Alex Martelli; 08.09.2009
comment
Так много для того, чтобы ТАК быть превосходным, а? :-) Когда вам это ДЕЙСТВИТЕЛЬНО нужно, оно всегда терпит неудачу. - person Vinko Vrsalovic; 08.09.2009

Как говорит Винко, вы можете редактировать миди-файл, но, поскольку это двоичный формат, сжатый до наименьшего возможного количества битов, вам может помочь помощь.

Это конвертер midi-to-text (и наоборот):
http://midicomp.opensrc.org/
В последнее время я использую его довольно часто. довольно просто выполнять обработку текста (например, поиск строки с «Tempo») для простых операций, когда у вас есть мидифайл в виде текста. не пробовал на Mac (без проблем скомпилирован на Ubuntu 8.04).

Что касается конкретно темпа мидифайла, очень легко замедлить или ускорить воспроизведение, поскольку время событий указывается в терминах «тиков», реальная продолжительность которых в секундах определяется параметром темпа, описанным в цитате Винко. Я считаю, что тактовый размер не так важен и в основном предназначен для правильного отображения тактов/долей при открытии в миди-секвенсоре.

Кроме того, помимо pyPortMidi, есть несколько других миди-модулей Python.

[хммм... кажется, я могу публиковать только по ссылке в посте, будучи новым пользователем. я постараюсь опубликовать ссылки на модули python в паре комментариев или в другой паре ответов...]

person alex rae    schedule 19.09.2009
comment
Модуль Python для чтения, записи, создания/редактирования миди-файлов и т. д.: ‹mxm.dk/products/public /pythonmidi - person alex rae; 20.09.2009
comment
Класс для чтения и записи миди-файлов (эта публикация кажется единственным источником): ‹groups.google.com/group/alt.sources/msg/0c5fc523e050c35e - person alex rae; 20.09.2009
comment
Я также нашел это, хотя и не пробовал: ‹groups.google.com/group/comp.lang.python/browse_thread/thread/ - person alex rae; 20.09.2009

Для этого вы можете использовать music21, хотя я тестировал его только на OSX 10.10. .1.

import music21

fctr = 1.25 # scale (in this case stretch) the overall tempo by this factor
score = music21.converter.parse('song.mid')
newscore = score.scaleOffsets(fctr).scaleDurations(fctr)

newscore.write('midi','song_slow.mid') 

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

Если вы похожи на меня, то вы слушаете те же песни 7 лет спустя и можете попробовать! В противном случае, я надеюсь, что это поможет кому-то еще, кто проснулся сегодня, как я, и чесал голову, пытаясь легко решить эту проблему.

person dermen    schedule 07.01.2017
comment
fastScore = score.augmentOrDiminish(1.25) -- будет масштабировать продолжительность и смещения, а также некоторые другие параметры, чтобы результат выводился корректно. - person Michael Scott Cuthbert; 25.08.2017

протестировал версию @dermen на Windows, Python 3.8. Пришлось немного доработать, но все равно работает!

import music21

fctr = 1.5 # scale (in this case stretch) the overall tempo by this factor
score = music21.converter.Converter()
score.parseFile('home.mid')
newscore = score.stream.augmentOrDiminish(fctr)
newscore.write('midi','song_slow.mid')
person janjilecek    schedule 10.04.2020

У меня такой же интерес, как и у вашего поста. Я только что наткнулся на эту библиотеку, которая выглядит очень многообещающе:

http://web.mit.edu/music21/

person Mike    schedule 15.12.2013
comment
Обратите внимание, что ответы только по ссылкам не рекомендуются, ответы SO должны быть конечной точкой поиска. для решения (по сравнению с еще одной остановкой ссылок, которые со временем устаревают). Пожалуйста, рассмотрите возможность добавления здесь отдельного синопсиса, оставив ссылку в качестве ссылки. - person kleopatra; 15.12.2013
comment
Замена объекта tempo.MetronomeMark в начале каждого нотоносца новым должна помочь. Обратите внимание, что в настоящее время music21 квантует любой MIDI-файл. Просто добавили в наш список дел, чтобы сделать это необязательным. - person Michael Scott Cuthbert; 07.04.2014