B.3.4 Artikulationszeichen zu Noten hinzufügen (Beispiel)

Am einfachsten können Artikulationszeichen zu Noten hinzugefügt werden, indem man zwei musikalische Funktionen in einen Kontext einfügt, wie erklärt in @ref{Kontexte erstellen}. Hier soll jetzt eine musikalische Funktion entwickelt werden, die das vornimmt.

Eine $variable innerhalb von #{...#} ist das gleiche wie die normale Befehlsform \variable in üblicher LilyPond-Notation. Es ist bekannt dass

{ \music -. -> }

in LilyPond nicht funktioniert. Das Problem könnte vermieden werden, indem das Artikulationszeichen an eine Pseudonote gehängtwird:

{ << \music s1*0-.-> }

aber in diesem Beispiel soll gezeigt werden, wie man das in Scheme vornimmt. Zunächst wird die Eingabe und die gewünschte Ausgabe examiniert:

%  Eingabe
\displayMusic c4
===>
(make-music
  'EventChord
  'elements
  (list (make-music
          'NoteEvent
          'duration
          (ly:make-duration 2 0 1 1)
          'pitch
          (ly:make-pitch -1 0 0))))
=====
%  gewünschte Ausgabe
\displayMusic c4->
===>
(make-music
  'EventChord
  'elements
  (list (make-music
          'NoteEvent
          'duration
          (ly:make-duration 2 0 1 1)
          'pitch
          (ly:make-pitch -1 0 0))
        (make-music
          'ArticulationEvent
          'articulation-type
          "marcato")))

Dabei ist zu sehen, dass eine Note (c4) als EventChord repräsentiert ist, mit einem NoteEvent-Ausdruck in ihrer Elementenliste. Um eine Marcato-Artikulation hinzuzufügen, muss ein ArticulationEvent-Ausdrcuk zu der Elementeigenschaft des EventChord-Ausdrucks hinzugefügt werden.

Um diese Funktion zu bauen, wird folgerndermaßen begonnen:

(define (add-marcato event-chord)
  "Add a marcato ArticulationEvent to the elements of `event-chord',
  which is supposed to be an EventChord expression."
  (let ((result-event-chord (ly:music-deep-copy event-chord)))
    (set! (ly:music-property result-event-chord 'elements)
          (cons (make-music 'ArticulationEvent
                  'articulation-type "marcato")
                (ly:music-property result-event-chord 'elements)))
    result-event-chord))

Die erste Zeile definiert eine Funktion in Scheme: Die Bezeichnung der Funktion ist add-marcato und sie hat eine Variable mit der Bezeichnung event-chord. In Scheme geht der Typ einer Variable oft direkt aus der Bezeichnung hervor (das ist auch eine gute Methode für andere Programmiersprachen).

"Add a marcato..."

ist eine (englische) Beschreibung, was diese Funktion tut. Sie ist nicht unbedingt notwendig, aber genauso wie klare Variablen-Bezeichnungen ist auch das eine gute Methode.

(let ((result-event-chord (ly:music-deep-copy event-chord)))

let wird benutzt, um die lokalen Variablen zu definieren. Hier wird eine lokale Variable benutzt: result-event-chord. Sie erhält den Wert (ly:music-deep-copy event-chord). ly:music-deep-copy ist eine LilyPond-spezifische Funktion, die wie alle Funktionen mit dem Präfix ly: versehen ist. Sie wird benutzt, um eine Kopie eines musikalischen Ausdrucks anzufertigen. Hier wird event-chord (der Parameter der Funktion) kopiert. Die Funktion soll ja nur ein Artikulationszeichen an einen EventChord gehängt werden, deshalb ist es besser, den EventChord, der als Argument gegeben wurde, nicht zu verändern, weil er woanders benutzt werden könnte.

Jetzt gibt es result-event-chord, wobei es sich um einen NoteEventChord-Ausdruck handelt, welcher gleichzeigt eine Kopie von event-chord ist. Das Makro wird seiner Eigenschaftsliste hinzugefügt:

(set! place new-value)

Was in diesem Fall „gesetzt“ werden soll („place“) ist die ‚elements‘-Eigenschaft des result-event-chord-Ausdrucks.

(ly:music-property result-event-chord 'elements)

ly:music-property ist die Funktion, mit der musikalische Eigenschaften erreicht werden können (die 'elements, 'duration, 'pitch usw., die in der Ausgabe von \displayMusic weiter oben angezeigt werden). Der neue Wert ist, was ehemals die Elemtneigenschaft war, mit einem zusätzlichen Element: dem ArticulationEvent-Ausdruck, der aus der Ausgabe von \displayMusic kopiert werden kann:

(cons (make-music 'ArticulationEvent
        'articulation-type "marcato")
      (ly:music-property result-event-chord 'elements))

cons wird benutzt, um ein Element zu einer Liste hinzuzufügen, ohne dass die originale Liste verändert wird. Das ist es, was die Funktion tun soll: die gleiche Liste, aber mit dem neuen ArticulationEvent-Ausdruck. Die Reihenfolge innerhalb der Elementeeigenschaft ist hier nicht relevant.

Wenn schließlich die Marcato-Artikulation zu der entsprechenden elements-Eigenschaft hinzuzugefügt ist, kann result-event-chord ausgegeben werden, darum die letzte Zeile der Funktion.

Jetzt wird die add-marcato-Funktion in eine musikalische Funktion umgewandelt:

addMarcato = #(define-music-function (parser location event-chord)
                                     (ly:music?)
    "Add a marcato ArticulationEvent to the elements of `event-chord',
    which is supposed to be an EventChord expression."
    (let ((result-event-chord (ly:music-deep-copy event-chord)))
      (set! (ly:music-property result-event-chord 'elements)
            (cons (make-music 'ArticulationEvent
                    'articulation-type "marcato")
                  (ly:music-property result-event-chord 'elements)))
      result-event-chord))

Eine Überprüfung, dass die Funktion richtig arbeitet, geschieht folgendermaßen:

\displayMusic \addMarcato c4

Andere Sprachen: English.

LilyPond – Extending