Документация Engee

Вывод партитуры с помощью MuseScore

MuseScore — это замечательный профессиональный редактор музыкальных партитур с открытым исходным кодом и огромным количеством возможностей. MusicManipulations предоставляет удобный интерфейс, который позволяет мгновенно вывести любую структуру Notes или MIDIFile через MuseScore.

musescore(file, notes | midi; keywords...)

Использует программное обеспечение с открытым исходным кодом «MuseScore» для создания партитуры и сохранения заданных нот notes (или всего midi файла) в файл file, который может быть либо .pdf, либо .png. Если задан .png, то фактическое имя файла будет заканчиваться -1, -2 и т.д. для каждой страницы партитуры.

Для выполнения этого кода редактор MuseScore должен быть доступен из командной строки (добавьте путь к MuseScore.exe в переменную среды PATH; узнать, как это делается, можно в Google).

При указании именованного аргумента display = true также отображается созданный файл file. При указании именованного аргумента rmmidi = true MIDI-файл, который должен создаваться между преобразованиями партитуры, удаляется (чтобы сохранить его, используйте значение false). MuseScore по умолчанию запускается с командами -n -T 10 -r 1200, но в именованном аргументе c можно указать любую другую требуемую команду (внутри обратных апострофов). Подробные сведения см. в описании параметров командной строки MuseScore.

Помните, что для создания партитур в MuseScore требуются четко определенные ноты. Это означает, что вам следует использовать функцию quantize для квантования как положения, так и длительности нот.

Создание партитуры на основе нот

using FileIO # используется для загрузки MIDI-файлов
using MusicManipulations # инструменты для работы с нотами в Julia
using MusicVisualizations # инструменты для визуализации этих нот

Сначала загрузим тестовый MIDI-файл Doxy. Третья дорожка содержит ноты басовой партии:

midi = load(testmidi()) # считываем «тестовую» MIDI-запись Doxy.
bass = getnotes(midi, 3)
basstrim = bass[1:50]
50 Notes with tpq=960
 Note A♯2 | vel = 95  | pos = 7680, dur = 690
 Note A♯2 | vel = 71  | pos = 9280, dur = 308
 Note G♯2 | vel = 52  | pos = 9600, dur = 668
 Note G♯2 | vel = 58  | pos = 11200, dur = 338
 Note G2  | vel = 71  | pos = 11520, dur = 701
 Note G♯2 | vel = 83  | pos = 13120, dur = 281
 Note G2  | vel = 73  | pos = 13440, dur = 855
  ⋮
 Note F2  | vel = 75  | pos = 53760, dur = 885
 Note A♯2 | vel = 80  | pos = 54720, dur = 930
 Note G♯2 | vel = 97  | pos = 55680, dur = 889
 Note D♯2 | vel = 80  | pos = 56640, dur = 930
 Note G2  | vel = 80  | pos = 57600, dur = 975
 Note B1  | vel = 88  | pos = 58560, dur = 952
 Note D2  | vel = 83  | pos = 59520, dur = 941

Так как ноты басовой партии уже квантованы, их можно вывести на нотный стан с помощью MuseScore:

musescore("bass.png", basstrim)
Басовая партитура

Удивительно, но MuseScore автоматически определяет ключ и даже тональность произведения!

Создание полной партитуры на основе MIDI-файла

В musescore можно также передать полный MIDI-файл.

piano = getnotes(midi, 4)
533 Notes with tpq=960
 Note F4  | vel = 69  | pos = 7427, dur = 181
 Note A♯4 | vel = 85  | pos = 7760, dur = 450
 Note D5  | vel = 91  | pos = 8319, dur = 356
 Note D4  | vel = 88  | pos = 8323, dur = 314
 Note G♯3 | vel = 88  | pos = 8327, dur = 358
 Note A♯4 | vel = 76  | pos = 8694, dur = 575
 Note G4  | vel = 66  | pos = 9281, dur = 273
  ⋮
 Note D5  | vel = 91  | pos = 189794, dur = 227
 Note D5  | vel = 106 | pos = 190725, dur = 610
 Note A4  | vel = 99  | pos = 190729, dur = 604
 Note D♯4 | vel = 101 | pos = 190742, dur = 720
 Note A3  | vel = 106 | pos = 190746, dur = 833
 Note D4  | vel = 106 | pos = 190746, dur = 837
 Note G4  | vel = 109 | pos = 190748, dur = 590

Однако MuseScore показывает достойные результаты только с квантованными нотами. Давайте выполним квантование по триплетной сетке, используя quantize:

qpiano = quantize(piano, [0, 1//3, 2//3, 1])
533 Notes with tpq=960
 Note F4  | vel = 69  | pos = 7360, dur = 320
 Note A♯4 | vel = 85  | pos = 7680, dur = 320
 Note D5  | vel = 91  | pos = 8320, dur = 320
 Note D4  | vel = 88  | pos = 8320, dur = 320
 Note G♯3 | vel = 88  | pos = 8320, dur = 320
 Note A♯4 | vel = 76  | pos = 8640, dur = 640
 Note G4  | vel = 66  | pos = 9280, dur = 320
  ⋮
 Note D5  | vel = 91  | pos = 189760, dur = 320
 Note D5  | vel = 106 | pos = 190720, dur = 640
 Note A4  | vel = 99  | pos = 190720, dur = 640
 Note D♯4 | vel = 101 | pos = 190720, dur = 640
 Note A3  | vel = 106 | pos = 190720, dur = 960
 Note D4  | vel = 106 | pos = 190720, dur = 960
 Note G4  | vel = 109 | pos = 190720, dur = 640

И сохраним обе дорожки в MIDI-файле:

ptrack = MIDITrack()
addnotes!(ptrack, qpiano)
addtrackname!(ptrack, "Doxy")
smidi = MIDIFile(1, 960, [midi.tracks[3], ptrack])
MIDIFile (format=1, tpq=960) with tracks:
 Bass
 Doxy

А затем сохраним все как файл .pdf или .png:

musescore("doxy.pdf", smidi)

Первая страница выглядит следующим образом: Полная партитура

При наличии нескольких дорожек MuseScore отображает название дорожки (trackname), а также инструмент, который был автоматически выбран для ее воспроизведения.

Барабанная нотация

В MuseScore можно также создавать барабанную нотацию. Процесс практически идентичен описанному выше, за исключением двух отличий. Во-первых, высота тона каждой ноты должна иметь определенное значение, которое соответствует реальному ударному инструменту, а во-вторых, все ноты должны записываться в канал 9.

Функция DrumNote упрощает этот процесс:

DrumNote(pitch, position, duration = 960; velocity = 100)

Сокращенный конструктор для объекта Note, который всегда помещается в канал 9. Высоту тона можно указать в виде строки String (например, Acoustic Snare), которая будет преобразована в фактическую высоту с помощью DRUMKEY.

А это используемый нами барабанный лад:

DRUMKEY
Dict{String, String} with 15 entries:
  "Crash Cymbal 2"     => "A3"
  "Closed Hi-Hat"      => "F#2"
  "Crash Cymbal 1"     => "C#3"
  "Acoustic Bass Drum" => "B1"
  "Acoustic Snare"     => "D2"
  "Tambourine"         => "F#3"
  "Ride Bell"          => "F3"
  "Side Stick"         => "C#2"
  "Low-Mid Tom"        => "B2"
  "Pedal Hi-Hat"       => "G#2"
  "Ride Cymbal"        => "D#3"
  "Open Hi-Hat"        => "A#2"
  "Cowbell"            => "G#3"
  "High Floor Tom"     => "G2"
  "Low Floor Tom"      => "F2"

Вот пример создания «базового рокового ритма» в барабанной нотации:

tpq = 960; e = 960÷2 # восьмая нота = четвертная нота ÷ 2
bass = "Acoustic Bass Drum"
snare = "Acoustic Snare"
hihat = "Closed Hi-Hat"
"Closed Hi-Hat"

Мы создаем 8 хай-хэтовых нот:

rock = [DrumNote(hihat, i*e, e) for i in 0:7]
8-element Vector{Note}:
 Note F♯2 | vel = 100 | pos = 0, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 480, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 960, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1440, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1920, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2400, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2880, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 3360, dur = 480 | channel 9

И 2 ноты большого барабана:

push!(rock, DrumNote(bass, 0, e), DrumNote(bass, 4e, e))
10-element Vector{Note}:
 Note F♯2 | vel = 100 | pos = 0, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 480, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 960, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1440, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1920, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2400, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2880, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 3360, dur = 480 | channel 9
 Note B1  | vel = 100 | pos = 0, dur = 480 | channel 9
 Note B1  | vel = 100 | pos = 1920, dur = 480 | channel 9

Добавляем 2 ноты малого барабана:

push!(rock, DrumNote(snare, 2e, e), DrumNote(snare, 6e, e))
12-element Vector{Note}:
 Note F♯2 | vel = 100 | pos = 0, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 480, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 960, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1440, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1920, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2400, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2880, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 3360, dur = 480 | channel 9
 Note B1  | vel = 100 | pos = 0, dur = 480 | channel 9
 Note B1  | vel = 100 | pos = 1920, dur = 480 | channel 9
 Note D2  | vel = 100 | pos = 960, dur = 480 | channel 9
 Note D2  | vel = 100 | pos = 2880, dur = 480 | channel 9

Наконец, объединяем эти ноты с указанием количества импульсов на четвертную ноту:

rock = Notes(rock, tpq)
12 Notes with tpq=960
 Note F♯2 | vel = 100 | pos = 0, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 480, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 960, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1440, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 1920, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2400, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 2880, dur = 480 | channel 9
 Note F♯2 | vel = 100 | pos = 3360, dur = 480 | channel 9
 Note B1  | vel = 100 | pos = 0, dur = 480 | channel 9
 Note B1  | vel = 100 | pos = 1920, dur = 480 | channel 9
 Note D2  | vel = 100 | pos = 960, dur = 480 | channel 9
 Note D2  | vel = 100 | pos = 2880, dur = 480 | channel 9

А затем вызываем MuseScore для построения партитуры:

musescore("rock.png", rock)
rock 1