- 22, Oct 2024
- #1
Фон
MIDI-файлы сильно отличаются от аудиофайлов WAV или MP3. Файлы MP3 и WAV содержат байты, представляющие «запись» звука, в то время как MIDI-файлы содержат серию MIDI-сообщений, хранящихся в MIDI-событиях, информирующих MIDI-синтезатор, на каком виртуальном инструменте играть, или MIDI-секвенсор, какой темп воспроизведения следует использовать. Эти сообщения хранятся в треках, а набор треков составляет MIDI-последовательность, события которой могут анализироваться секвенсором и передаваться сообщения от секвенсора к приемнику синтезатора.
Большую часть времени MIDI-сообщения, хранящиеся в MIDI-событиях, представляют собой сообщения Note On, которые сообщают синтезатору воспроизвести определенную ноту, или сообщения Note Off, которые сообщают синтезатору прекратить воспроизведение ноты. Эти сообщения содержат два байта данных, первый из которых сообщает синтезатору скорость ноты (более высокая скорость приводит к более громкой ноте), а второй из которых сообщает синтезатору, какую ноту нужно сыграть (т. е. среднюю до). Сами события также содержат метки, которые сообщают секвенсору, когда отправлять сообщения.
Вызов
Задача состоит в том, чтобы написать полную программу или функцию, которая анализирует серию MIDI-сообщений Note On и Note Off в однодорожечной MIDI-последовательности и выводит на STDOUT диаграмму, показывающую, когда определенные ноты включены, когда они выключены и скорость этих нот. Вертикальная ось диаграммы представляет значение ноты и должна быть помечена, как описано ниже, а горизонтальная ось представляет время в тактах MIDI (хотя она не должна быть помечена, чтобы уменьшить сложность и проблемы с интервалами).
Ваши входные данные могут представлять собой четыре отдельных массива или списка, каждый из которых содержит серию целочисленных значений; двумерный массив или список, содержащий четыре подмассива/подсписка с серией целочисленных значений; или любым другим удобным способом; это представляет коллекцию MIDI-событий с сообщениями Note On и Note Off на треке. Значения в первом из этих массивов определяют ноту, второй — скорость, третий — ноту при тике события, а четвертый — тик события при выключении ноты. Например, даны четыре таких массива:
{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 |
Анализ первого элемента каждого массива дает два события: событие на тике 0 с сообщением, имеющим команду Note On, ноту 60 (средняя C) и скорость ноты 20; и событие на тике 2 с сообщением, содержащим команду Note Off с той же нотой и скоростью.
Правила
На диаграмме должны быть показаны числа от 0 до 127, отображаемые в порядке убывания слева (представляющие значение ноты), время начала ноты, продолжительность каждой ноты (галочка «Нота выключена» минус галочка «Нота включена») и скорость ноты. Символы, обозначающие ноты, зависят от их скорости:
- 0-15:
{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 |
- 16-31:
*
- 32-47:
0
- 48-63:
+
- 64-79:
@
- 80-95:
-
- 96-111:
#
- 112-127:
=
Вы можете предположить следующее:
- Значения ноты и скорости будут находиться в диапазоне [0, 127].
- Длины каждого из четырех массивов всегда будут равны друг другу.
Вот несколько примеров:
O
Вот пример, отображающий первые несколько нот «Оды к радости»:
{60, 62, 64, 65, 67}
{20, 40, 60, 80, 100}
{ 0, 4, 8, 12, 16}
{ 2, 6, 10, 14, 18}
Ты можешь уменьшить свой счет на 25% если ваша заявка принимает фактическую последовательность MIDI в качестве входных данных, анализирует сообщения Note On и Note Off любой дорожки по вашему выбору, при условии, что она содержит как минимум четыре события с сообщениями Note On и Note Off, и выводит диаграмму, как описано выше.
Это кодовый гольф, поэтому выигрывает самый короткий код. Удачи!
#code-golf #ascii-art #music