Фон
MIDI-файлы сильно отличаются от аудиофайлов WAV или MP3. Файлы MP3 и WAV содержат байты, представляющие «запись» аудио, в то время как файлы MIDI содержат серию MIDI-сообщений, сохраняемых в событиях MIDI, информирующих синтезатор MIDI, какой виртуальный инструмент следует воспроизводить, или MIDI-секвенсор, темп воспроизведения, который следует использовать. Эти сообщения хранятся в дорожках, и коллекция дорожек составляет MIDI-последовательность, события которой могут быть проанализированы секвенсором, а его сообщения переданы из секвенсора в приемник синтезатора.
В большинстве случаев MIDI-сообщения, хранящиеся в событиях MIDI, представляют собой сообщения Note On, которые говорят синтезатору воспроизводить конкретную ноту, или сообщения Note Off, которые сообщают синтезатору о прекращении воспроизведения ноты. Эти сообщения содержат два байта данных, первый из которых информирует синтезатор о скорости ноты (более высокая скорость приводит к более громкой ноте), а второй из них сообщает синтезатору ноту для воспроизведения (то есть Middle C). Сами события также содержат галочки, которые служат для того, чтобы сообщить секвенсору, когда отправлять сообщения.
Соревнование
Задача состоит в том, чтобы написать полную программу или функцию, которая анализирует серию MIDI-сообщений Note On и Note Off в MIDI-последовательности из одной дорожки и выводит на STDOUT диаграмму, показывающую, когда конкретные ноты включены, когда они выключены, и Скорость этих нот. Вертикальная ось диаграммы представляет значение ноты и должна быть помечена, как описано ниже, а горизонтальная ось представляет время в тиках MIDI (хотя она должна оставаться без метки, чтобы уменьшить сложность и проблемы с пробелами).
Ваш ввод может быть четырьмя отдельными массивами или списками, каждый из которых содержит серию целочисленных значений; двумерный массив или список, содержащий четыре подмассива / подсписка с серией целочисленных значений; или любым другим удобным способом; Это представляет собой набор MIDI-событий с сообщениями Note On и Note Off на дорожке. Значения в первом из этих массивов указывают ноту, вторую скорость, третью отметку о событии и четвертую отметку о событии. Например, с учетом четырех массивов, таких как эти:
{60, 62, 64, 65, 67}
{20, 40, 60, 80, 100}
{ 0, 4, 8, 12, 16}
{ 2, 6, 10, 14, 18}
Анализ первого элемента каждого массива дает два события: событие на отметке 0 с сообщением, содержащим команду Note On, note 60 (Middle C) и скорость ноты 20; и событие на отметке 2 с сообщением, которое имеет команду «Отключить ноту» с той же нотой и скоростью.
правила
Диаграмма должна содержать цифры от 0 до 127, отображаемые в порядке убывания слева (представляющие значение заметки), когда начинается заметка, продолжительность каждой заметки (отметка «Откл. Нота» минус отметка «Примечание на пометке») и скорость заметки. Символы, представляющие ноты, зависят от их скорости:
- 0-15:
O
- 16-31:
=
- 32-47:
#
- 48-63:
-
- 64-79:
@
- 80-95:
+
- 96-111:
0
- 112-127:
*
Вы можете предположить следующее:
- Значения для ноты и скорости будут в пределах диапазона [0, 127].
- Длины каждого из четырех массивов всегда будут равны друг другу.
Вот несколько примеров:
{60, 62, 64, 65, 67}
{20, 40, 60, 80, 100}
{ 0, 4, 8, 12, 16}
{ 2, 6, 10, 14, 18}
127|
126|
125|
...
67 | 00
66 |
65 | ++
64 | --
63 |
62 | ##
61 |
60 |==
59 |
...
2 |
1 |
0 |
{60, 48, 62, 47, 64, 45, 65, 43, 67, 41, 65, 43, 64, 45, 62, 47, 60, 48}
{63, 31, 75, 90, 12, 23, 122, 104, 33, 19, 57, 42, 5, 82, 109, 86, 95, 71}
{0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16}
{2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18}
127|
126|
...
68 |
67 | ##
66 |
65 | ** --
64 | OO OO
63 |
62 | @@ 00
61 |
60 |-- ++
59 |
...
49 |
48 |== @@
47 | ++ ++
46 |
45 | == ++
44 |
43 | 00 ##
42 |
41 | ==
40 |
...
1 |
0 |
Вот пример, который отображает первые несколько нот «Ода радости»:
{48, 55, 64, 64, 65, 67, 55, 67, 65, 64, 62, 52, 55, 60, 60, 62, 64, 55, 64, 62, 62}
{45, 45, 63, 63, 63, 63, 89, 66, 66, 66, 66, 30, 30, 103, 103, 103, 103, 127, 55, 55, 55}
{ 0, 0, 0, 4, 8, 12, 16, 16, 20, 24, 28, 32, 32, 32, 36, 40, 44, 48, 48, 54, 56}
{16, 16, 2, 6, 10, 14, 32, 18, 22, 26, 30, 48, 48, 34, 38, 42, 46, 64, 50, 55, 64}
127|
...
67 | -- @@
66 |
65 | -- @@
64 |-- -- @@ 00 --
63 |
62 | @@ 00 - --------
61 |
60 | 00 00
59 |
58 |
57 |
56 |
55 |################++++++++++++++++================****************
54 |
53 |
52 | ================
51 |
50 |
49 |
48 |################
...
0 |
Вы можете уменьшить свой счет на 25% если ваша подача принимает фактическую MIDI-последовательность в качестве входных данных, анализирует сообщения Note On и Note Off любой дорожки по вашему выбору при условии, что она содержит как минимум четыре события с сообщениями Note On и Note Off, и выводит диаграмма, как описано выше.
Это код гольф, поэтому выигрывает самый короткий код. Удачи!
Рубин, 106 байт
Это было весело Я не уверен, почему никто не пытался это сделать.
Эта функция принимает входные данные в виде четырех аргументов массива и возвращает массив строк, по одной для каждой строки диаграммы.
Замечания: это произвольно предполагает, что будет не более 10 000 тиков. Если вы запускаете его в своем терминале, я предлагаю подключить его к трубке,
less
чтобы вы могли прокручивать его горизонтально. Вы можете изменить,1e4
если хотите больше тиков, вплоть до9e9
, но это займет терабайт или два ОЗУ.Смотрите его на repl.it: https://repl.it/Cx4I/1
источник
Python 2
163160156145 байтЭто не самый лучший способ сделать это, но он был одним из самых простых. Если бы я мог понять, как заменить части строк, не превращая их в списки, не заменяя и не превращая их обратно в строки, это было бы очень полезно здесь. Предложения по игре в гольф приветствуются.
Изменить: 18 байтов благодаря Leaky Nun. Попробуйте это на Ideone !
источник
str.sub(/(?<=.{20}).{3}/,"foo")
эквивалентноstr[20,3] = "foo"
. Конечно, это означает создание регулярного выражения путем интерполяции / конкатенации строк с переменными index / length - что дешево в байтах Ruby, но, возможно, не в Python.Japt , 65 байт
Попробуйте онлайн!
Вводит в виде списка заметок в формате
[pitch, start_tick, end_tick, velocity]
. Если ввод данных в виде отдельных списков является обязательным (т. Е. Один список, содержащий все высоты, один, содержащий все скорости и т. Д.), Это может быть достигнуто за счет 1 байта .Объяснение:
источник