52700.fb2
c = note 0;
cs = note 1;
d = note 2;
ds = note 3;
...
Первая буква содержит буквенное обозначение ноты, а вторая либо s (от англ. sharp диез) или f (от англ.
flat бемоль). Все эти ноты находятся в первой октаве, но смещением высоты на 12 единиц мы легко можем
смещать эти ноты в любую другую октаву:
higher :: Int -> Score -> Score
higher n = fmap (\a -> a{ notePitch = 12*n + notePitch a })
lower :: Int -> Score -> Score
lower n = higher (-n)
high :: Score -> Score
high = higher 1
low :: Score -> Score
low = lower 1
С помощью этих функций мы легко можем смещать группы нот в любую октаву. Функция higher прини-
мает число октав, на которые необходимо сместить вверх высоту во всех нотах трека. Смещение высоты на
12 определяет смещение на одну октаву. Остальные функции определены в через функцию higher.
Длительность ноты
Пока что наши ноты длятся 1 единицу времени. Но нам бы хотелось иметь в распоряжении и другие дли-
тельности. Ноты других длительностей мы можем легко получать с помощью функции stretch, мы просто
изменим масштаб времени и длительность всех нот изменится. Определим несколько синонимов:
bn, hn, qn, en, sn :: Score -> Score
-- (brewis note)
(half note)
(quater note)
bn = stretch 2;
hn = stretch 0.5;
qn = stretch 0.25;
-- (eighth note)
(sizth note)
en = stretch 0.125;
sn = stretch 0.0625;
Эти преобразования отвечают длительностям нот в европейской музыкальной традиции.
Громкость ноты
Пока мы умеем создавать ноты средней громкости, но мы можем определить преобразователи на манер
тех, что изменяли высоту звука октавами:
louder :: Int -> Score -> Score
louder n = fmap $ \a -> a{ noteVolume = n + noteVolume a }
quieter :: Int -> Score -> Score
quieter n = louder (-n)
310 | Глава 21: Музыкальный пример
Смена инструмента
Изначально мы создаём ноты, которые играются на инструменте с кодом 0, в протоколе General Midi этот
номер соответствует роялю. Но с помощью класса Functor мы легко можем изменить инструмент:
instr :: Int -> Score -> Score
instr n = fmap $ \a -> a{ noteInstr = n, isDrum = False }
drum :: Int -> Score -> Score