Построение нотной диаграммы
С помощью MusicVisualizations
можно строить диаграмму на основе Notes
, похожую на «отпечатки клавиш» в таких программах DAW, как Cubase. Для этого служит функция noteplotter
, которая использует PyPlot
.
#
MusicVisualizations.noteplotter
— Function
noteplotter(notes::Notes; kwargs...)
Строит диаграмму на основе notes
в виде «отпечатков клавиш», где:
-
по оси X отмечается положение нот;
-
по оси Y отмечается «высота тона» или «значение» ноты (см. ниже);
-
цвет обозначает силу воспроизведения нот.
Затем возвращаются значения по оси Y.
Именованные аргументы
-
st = (notes[1].position ÷ notes.tpq) * notes.tpq
: время, с которого начинает строиться диаграмма. -
fi = st + 16notes.tpq
: время завершения построения диаграммы; по умолчанию 16 четвертных нот, то есть четыре такта. Если диаграмма должна строиться до последней ноты, укажитеInf
. -
ax = (PyPlot.figure(); PyPlot.gca())
: ось, по которой строится диаграмма. -
cmap = "viridis"
: цветовая карта, используемая для силы воспроизведения. -
grid = 0:0.25:1
: сетка, которая отрисовывается вместе с нотами (по умолчанию шестнадцатые ноты). Чтобы не наносить линии сетки, укажите nothing. -
names
: словарь, в котором со значениями по оси Y сопоставляются имена. По умолчанию используется функцияpitch_to_name
вместе с эвристикой, позволяющей присваивать имена только 7 нотам. -
plotnote!
Функция с аргументами вызоваplotnote!(ax, note, cmap)
(гдеcmap
— экземпляр цветовой карты, а не строка), которая фактически строит диаграмму нот. По умолчанию отрисовываются «отпечатки клавиш».
Аргумент plotnote!
позволяет настраивать тип диаграммы. Предполагается, что функция отображает ноту на заданной оси и возвращает «значение» ноты. Пример использования, например для построения диаграммы нот для ударных, см. в официальной документации.
Ноты для фортепиано
using MusicVisualizations, PyPlot
# MusicVisualizations для удобства повторно экспортирует MusicManipulations
# загружаем выступление группы (с метрономом)
midi = readMIDIFile(joinpath(@__DIR__, "mfi_grapevine_1.mid"))
grid = 0:1//4:1
piano = getnotes(midi, 4)
819 Notes with tpq=960
Note F4 | vel = 99 | pos = 8981, dur = 1217
Note A4 | vel = 99 | pos = 8981, dur = 1275
Note D5 | vel = 97 | pos = 8990, dur = 1314
Note D3 | vel = 97 | pos = 9004, dur = 1772
Note D4 | vel = 81 | pos = 9015, dur = 1287
Note F4 | vel = 84 | pos = 10496, dur = 130
Note A4 | vel = 87 | pos = 10504, dur = 175
⋮
Note E5 | vel = 87 | pos = 310837, dur = 114
Note F5 | vel = 81 | pos = 311276, dur = 233
Note G4 | vel = 82 | pos = 311284, dur = 196
Note B4 | vel = 58 | pos = 311286, dur = 197
Note G4 | vel = 92 | pos = 311739, dur = 197
Note E5 | vel = 99 | pos = 311744, dur = 181
Note B4 | vel = 56 | pos = 311782, dur = 104
noteplotter(piano; st = 15300, grid = grid)

Ноты для ударных
Преимущество функции noteplotter
в том, что ее можно полностью настраивать с помощью аргумента plotnote!
. В этом разделе мы покажем пример того, как можно использовать noteplotter
для отображения нот для ударных в барабанной нотации, как это делается в области GM Map в Cubase.
Сначала нужно определить специальную функцию для plotnote!
. Так как длительность нот в данном случае не имеет значения, мы можем просто указать их на диаграмме в виде точек. Кроме того, мы можем использовать разные символы для разных партий барабанов, например кружки для малого и большого барабанов и крестики для хай-хэта и тарелок.
function plotdrumnote!(ax, note, cmap)
p = note.pitch
if p == 0x24 # «бочка»
v, m = 1, "o"
elseif p ∈ (0x26, 0x28) # малый барабан
v, m = 3, "o"
elseif p ∈ (0x16, 0x1a) # ребро хай-хэта
v, m = 5, "X"
elseif p ∈ (0x2e, 0x2a) # мембрана хай-хэта
v, m = 5, "x"
elseif p == 0x35 # звенящая райд-тарелка
v, m = 6, "D"
elseif p == 0x33 # мембрана райд-тарелки
v, m = 6, "x"
elseif p == 0x3b # ребро райд-тарелки
v, m = 6, "X"
elseif p ∈ (0x30, 0x32) # бочка 1
v, m = 4, "s"
elseif p ∈ (0x2b, 0x3a) # бочка 3
v, m = 2, "s"
elseif p ∈ (0x31, 0x37, 0x34, 0x39)
v, m = 7, "X"
elseif p == 0x2c # педаль хай-хэта
v, m = 1, "x"
else
error("Unknown pitch $(UInt8(p))")
end
ax.scatter(note.position, v, marker = m, s = 250,
color = cmap(min(note.velocity, 127)/127))
return v
end
plotdrumnote! (generic function with 1 method)
(Обратите внимание, что указанная выше функция настроена вручную для конкретной электронной ударной установки.)
Чтобы диаграмму было удобнее читать, можно использовать собственные имена для нот:
TD50_PLOT = Dict(
1 => "kick",
3 => "snare",
5 => "hihat",
6 => "ride",
4 => "tom1",
2 => "tom3",
7 => "crash",
)
Dict{Int64, String} with 7 entries:
5 => "hihat"
4 => "tom1"
6 => "ride"
7 => "crash"
2 => "tom3"
3 => "snare"
1 => "kick"
В итоге диаграмма нот для ударных может выглядеть так:
drums = getnotes(midi, 3)
drums = translate(drums, -300) # постоянная задержка
noteplotter(drums; st = 15300, grid = grid,
names=TD50_PLOT, plotnote! = plotdrumnote!)
