Набор современной музыки в LilyPond

    Однажды я уже рассказывал, что такое LilyPond, и с чем его едят. Обещания написать простую статью я, к сожалению, пока выполнить не смог, зато собрался описать, как я набирал ужасающий нотный пример из музыки Н. Корндорфа

    («Welcome!» для шести женских голосов)


    Какие сложности здесь есть?
    • Разные темпы на разных станах
    • Разное количество длительностей на одно и то же время
    • Составной размер
    • Несовпадение тактовых черт


    Для решения первой задачи нужно заглянуть в справочник по внутренностям. Там написано, что контекст Score содержит в себе отвечающий за отображение обозначения темпа Metronome_mark_engraver. Следующие строки переносят его в контекст Staff (нотного стана), позволяя написать разные темпы на разных строчках (и не только).
    \layout {
      \context {
        \Score
        \remove "Timing_translator"
        \remove "Default_bar_line_engraver"
        \remove "Metronome_mark_engraver"
        ...
      }
      \context {
        \Staff
        \consists "Timing_translator"
        \consists "Default_bar_line_engraver"
        \consists "Metronome_mark_engraver"
      }
      ...
    }
    

    Также здесь из контекста партитуры в контекст стана переносятся Default_bar_line_engraver и Timing_translator, отвечающие за тактовые черты и соблюдение размера (к третьему пункту).

    Вторая проблема решается с помощью масштабирования длительностей. Команда \scaleDurations изменяет длительности в указанном соотношении. Порядок аргументов (такой же как у команды \times, создающий триоли, квартоли, квинтоли и другие мультиоли [англ: tuplet] ), я запомнил так: вместо 88 — 80. Я специально не сокращал дробь, поскольку она соответствует соотношению темпов (пример: второй стан).
    \scaleDurations #'(88 . 80)
    {
      \relative c' {
        f4\repeatTie ( g2) g4 ~ g8. g16 ( ~ g4 ~ g8. fis16 ~ fis4 fis8 g ~ g4 |
        ...
      }
      \addlyrics {
      _ la ka ma na pa ra sa 
      }
    }


    С размерами и тактовыми чертами я поступил следующим образом. Во-первых, в версии 2.15 (вот-вот выйдет стабильный 2.16) появилась простая команда \compoundMeter, с помощью которой можно нарисовать тактовый размер с плюсиками. Но простое использование этой команды не даст нам желаемого эффекта: в таком случае размер такта будет равен сумме всех компонентов, а здесь же нужно разделить их тактовыми чертами. На помощь приходит ручная установка размера такта (пример: первый стан).
    \compoundMeter #'((11 4) (11 4) (11 4) (11 4))
    \set Timing.measureLength = #(ly:make-moment 11 4)
    


    С третьим и шестым станами сложнее: у них компоненты не равны (пример: третий стан).
    \compoundMeter #'((9 4) (3 4) (6 4) (6 4) (3 4) (9 4))
    \tempo 4 = 72
    \relative c' {
      \dynamicUp
      \scaleDurations #' (88 . 72)
      {
        \set Timing.measureLength = #(ly:make-moment 11 4)
        e8.\repeatTie ( f16 ~ f4 ~f8 e ~ e4 dis4 ~ dis8. e16 ~ e4 ~ e8.) e16~ ( e4 |
        \set Timing.measureLength = #(ly:make-moment 11 12)
        e8 f ~ f4 e ~ |
        \set Timing.measureLength = #(ly:make-moment 11 6)
        e8. dis16 ~ dis4 dis16 e8. ~ e4) e2
        \once \override Staff.BarLine #'allow-span-bar = ##f
        \set Timing.measureLength = #(ly:make-moment 11 6)
        e4~( e8. dis16 ~ dis4 ~ dis8 e8 ~ e4 dis4 ~ |
        \set Timing.measureLength = #(ly:make-moment 11 12)
        dis8. e16 ~ e4 ~ e8.) e16~ |
        \set Timing.measureLength = #(ly:make-moment 11 4)
        e4 ~ e8 e8\mp\<~( e4 dis ~ dis8. e16 ~ e4 ~ e8. ) f16->\mf~f4 ~ f8 f8~ | \bar "||"
        f4
      }
    }
    

    Здесь в каждом новом такте устанавливается свойство Timing.measureLength в соответствующую величину. Функция #(ly:make-moment) создаёт определённую длительность. Внимание: внутри scaleDurations-блока размеры тактов должны всё равно исчисляться по глобальному времени: отсюда размеры 11/4, 11/6 и 11/12. Кроме того, единократное (\once) изменение свойства allow-span-bar запрещает соединять эту тактовую черту с ещё одной на пятом стане. В этом же месте такая же конструкция прописана и на четвёртом стане.

    В чём отличие \set от \override
    Команда \set управляет свойствами контекста, а \override — свойстами грóбов (grob = graphical object). Также существует команда \tweak, изменяющая свойства у непосредственно следующего объекта, его тип даже не обязательно указывать. Вариант \once \override переопределяет свойство только на одно использование (но не обязательно следующее непосредственно за данной командой)

    Косметические изменения включали в себя уменьшение параметра spacing-increment (увеличение расстояния между нотами относительно базового при удвоении их длительности) с дефолтного 1,2 но 0
    ,5 и изменение шрифта и размера текста:
    \layout {
        ...    
        \override SpacingSpanner #'spacing-increment = #0.5
      }
      ...
      \context {
        \Lyrics
        \override LyricText #'font-name = #"Century"
        \override LyricText #'font-size = #3
      }
    }
    


    С удовольствием разъясню ещё какие-нибудь нюансы набора, если будут непонятны.

    Исходный код: pastebin.com/EXsYRQzg
    Скачать последнюю unstable-версию: lilypond.org/development.html (на 2.14 работать не будет).
    • +26
    • 3,3k
    • 9
    Поделиться публикацией

    Комментарии 9

      +1
      А есть ли какой конвертер с Sibelius/Finale/MusicXML в LilyPond? Уж очень клёвая штука, жаль не знал про неё раньше.
        +1
        Из MusicXML есть встроенный конвертер (http://lilypond.org/doc/v2.15/Documentation/usage/converting-from-other-formats), а ещё есть sib2ly, уже год не обновляющийся, к сожалению.

        А вообще освоить синтаксис совсем не так сложно, как кажется.
          0
          Синтаксис не проблема (тем более что с ТеХом работал уже). Проблема в том что есть уже набранные ноты (в Sibelius/Finale), которые хотелось бы перевести. Люблю я plaintext :)
        0
        Можете объяснить неофиту — чем такой формат хранения нот (именно нот, а не форматирования, с ним как раз всё понятно) лучше испытанного временем midi? По-моему, было бы гораздо уместнее использовать именно его с навеском в виде описания формата и другой побочной информации, типа текста.
          0
          Ничем не лучше, просто у них немного разные цели.

          Традиционная нотная запись предназначена для живых исполнителей и даёт им повод и возможность к привнесению собственной индивидуальности в исполнение, а MIDI даёт просто точные инструкции к автоматизированному исполнению.
            0
            Гм, я прекрасно понимаю разницу между нотами и MIDI; но зачем внутри формата нот делать другой формат для музыки, если уже есть MIDI? По мне, так логично его же здесь и использовать — пусть результатом будет не использование в DAW, а просто распечатка. Или он для этого оказывается неудобен?
              0
              В MIDI нет средств к обозначению традиционных нотных знаков.
                0
                Понятно, спасибо.
                0

                Ответ в вашем первом сообщении — "именно нот, а не форматирования".
                Лилипонд как раз отвечает за практически идеальное форматирование (для человека), опуская "ноты" (сочетание тональности, а также времени начала, длительности, громкости и прочей экспрессии).

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое