1.3.4 Artikulationszeichen zu Noten hinzufügen (Beispiel) (LilyPond erweitern)

#### 1.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 Kontexte erstellen und referenzieren. Hier soll jetzt eine musikalische Funktion entwickelt werden, die das vornimmt. Daraus ergibt sich der zusätzliche Vorteil, dass diese musikalische Funktion eingesetzt werden kann, um eine Artikulation (wie etwa eine Fingersatzanweisung) einer einzigen Note innerhalb eines Akkordes hinzugefügt werden kann, was nicht möglich ist, wenn einfach unabhängige Noten ein einem Kontext miteinander verschmolzen werden.

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 einen leeren Akkord gehängt wird:

    { << \music <> -. -> >> }

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
      'NoteEvent
      'duration
      (ly:make-duration 2 0 1/1)
      'pitch
      (ly:make-pitch -1 0 0))))
    =====
    %  gewünschte Ausgabe
    \displayMusic c4->
    ===>
    (make-music
      'NoteEvent
      'articulations
      (list (make-music
              'ArticulationEvent
              'articulation-type 'accent))
      'duration
      (ly:make-duration 2 0 1/1)
      'pitch
      (ly:make-pitch -1 0 0))
    \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))))

Dabei ist zu sehen, dass eine Note (`c4`) als `NoteEvent`-Ausdruck repräsentiert ist. Um eine Akzent-Artikulation hinzuzufügen, muss ein `ArticulationEvent`-Ausdruck zu der Elementeigenschaft `articulations` des `NoteEvent`-Ausdrucks hinzugefügt werden.

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

    (define (add-accent note-event)
      "Add an accent ArticulationEvent to the articulations of `note-event',
      which is supposed to be a NoteEvent expression."
      (set! (ly:music-property note-event 'articulations)
            (cons (make-music 'ArticulationEvent
                    'articulation-type 'accent)
                  (ly:music-property note-event 'articulations)))
      note-event)

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

    "Add an accent..."

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.

Es kann seltsam scheinen, warum das Notenereignis direkt verändert wird, anstatt mit einer Kopie zu arbeiten (`ly:music-deep-copy` kann dafür benützt werden). Der Grund ist eine stille Übereinkunft: musikalische Funktionen dürfen ihre Argumente verändern: sie werden entweder von Grund auf erstellt (wie Eingabe des Benutzers) oder sind schon kopiert (etwa Verweis auf eine Variable mit ‘`\Bezeichnung`’ oder Noten aus einem Scheme-Ausdruck ‘`$(…)`’ sind Kopien). Weil es uneffizient wäre, unnötige Kopien zu erstellen, wird der Wiedergabewert einer musikalischen Funktion nicht kopiert. Um sich also an die Übereinkunft zu halten, dürfen Argumente nicht mehr als einmal benützt werden, und sie wiederzugeben zählt als eine Benutzung.

In einem früheren Beispiel wurden Noten konstruiert, indem ein musikalisches Argument wiederholt wurde. In diesem Fall muss wenigstens eine Wiederholung eine Kopie ihres Arguments sein. Wenn es keine Kopie ist, können seltsame Dinge passieren. Wenn man beispielsweise `\relative` oder `\transpose` auf die resultierenden Noten anwendet, die die gleichen Elemente mehrmals enthalten, werden die Elemente mehrmals der `\relative`-Veränderung oder Transposition unterworfen. Wenn man sie einer musikalischen Variable zuweist, wird dieser Fluch aufgehoben, denn der Verweis auf ‘`\Bezeichnung`’ erstellt wiederum eine Kopie, die nicht die Identität der wiederholten Elemente überträgt.

Während die Funktion oben keine musikalische Funktion ist, wird sie normalerweise inmitten musikalischer Funktionen eingesetzt. Darum ist es sinnvoll, der gleichen Übereinkunft zu folgen, die für musikalische Funktionen gelten: Die Eingabe kann verändert worden sein, um die Ausgabe zu produzieren, und der den Aufruf erstellt, ist verantwortlich für die Erstellung von Kopien, wenn er immernoch die unveränderten Argumente benötigt. Wenn man sich LilyPonds eigene Funktionen wie etwa `music-map` anschaut, sieht man, dass sie denselben Prinzipien folgen.

Aber wo waren wir? Jetzt gibt es ein `note-event`, das verändert werden kann, nicht unter Einsatz von `ly:music-deep-copy` sondern aufgrund einer langen Erklärung. Der Akzent wird zu seiner `'articulations`-Liste hinzugefügt:

    (set! place neuer-Wert)

Was in diesem Fall „gesetzt“ werden soll („place“) ist die ‚’articulations‘-Eigenschaft des `note-event`-Ausdrucks.

    (ly:music-property note-event 'articulations)

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

    (cons (make-music 'ArticulationEvent
            'articulation-type 'accent)
          (ly:music-property result-event-chord 'articulations))

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

Wenn schließlich die Akzent-Artikulation zu der entsprechenden `elements`-Eigenschaft hinzugefügt ist, kann `note-event` ausgegeben werden, darum die letzte Zeile der Funktion.

Jetzt wird die `add-accent`-Funktion in eine musikalische Funktion umgewandelt (hierzu gehört etwas syntaktischer Zuckerguß und eine Deklaration des Typs ihres einzigen „wirklichen“ Arguments:

    addAccent = #(define-music-function (note-event)
                                         (ly:music?)
      "Add an accent ArticulationEvent to the articulations of `note-event',
      which is supposed to be a NoteEvent expression."
      (set! (ly:music-property note-event 'articulations)
            (cons (make-music 'ArticulationEvent
                    'articulation-type 'accent)
                  (ly:music-property note-event 'articulations)))
      note-event)

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

    \displayMusic \addAccent c4

#### LilyPond erweitern v2.26.0 (stable-branch).

- 1 Scheme-Tutorium
  - 1.1 Einleitung in Scheme
    - 1.1.1 Scheme-Sandkasten
    - 1.1.2 Scheme-Variablen
    - 1.1.3 Einfache Scheme-Datentypen
    - 1.1.4 Zusammengesetzte Scheme-Datentypen
    - 1.1.5 Berechnungen in Scheme
    - 1.1.6 Scheme-Prozeduren
    - 1.1.7 Scheme-Konditionale
  - 1.2 Scheme in LilyPond
    - 1.2.1 LilyPond Scheme-Syntax
    - 1.2.2 LilyPond-Variablen
    - 1.2.3 Eingabe-Variablen und Scheme
    - 1.2.4 Scheme in LilyPond importieren
    - 1.2.5 Objekteigenschaften
    - 1.2.6 Zusammengesetzte LilyPond-Variablen
    - 1.2.7 Interne musikalische Repräsentation
  - 1.3 Komplizierte Funktionen erstellen
    - 1.3.1 Musikalische Funktionen darstellen
    - 1.3.2 Eigenschaften von Musikobjekten
    - 1.3.3 Verdoppelung einer Note mit Bindebögen (Beispiel)
    - 1.3.4 Artikulationszeichen zu Noten hinzufügen (Beispiel)
- 2 Schnittstellen für Programmierer
  - 2.1 LilyPond-Codeabschnitte
  - 2.2 Scheme-Funktionen
    - 2.2.1 Definition von Scheme-Funktionen
    - 2.2.2 Benutzung von Scheme-Funktionen
    - 2.2.3 Leere Scheme-Funktionen
  - 2.3 Musikalische Funktionen
    - 2.3.1 Definition der musikalischen Funktionen
    - 2.3.2 Benutzung von musikalischen Funktionen
    - 2.3.3 Einfache Ersetzungsfunktionen
    - 2.3.4 Mittlere Ersetzungsfunktionen
    - 2.3.5 Mathematik in Funktionen
    - 2.3.6 Funktionen ohne Argumente
    - 2.3.7 Leere musikalische Funktionen
  - 2.4 Ereignisfunktionen
  - 2.5 Textbeschriftungsfunktionen
    - 2.5.1 Beschriftungskonstruktionen in Scheme
    - 2.5.2 Wie Beschriftungen intern funktionieren
    - 2.5.3 Neue Definitionen von Beschriftungsbefehlen
      - Syntax der Definition von Textbeschriftungsbefehlen
      - Über Eigenschaften
      - Ein vollständiges Bespiel
      - Eingebaute Befehle anpassen
    - 2.5.4 Neue Definitionen von Beschriftungslistenbefehlen
  - 2.6 Kontexte für Programmierer
    - 2.6.1 Kontextauswertung
    - 2.6.2 Eine Funktion auf alle Layout-Objekte anwenden
  - 2.7 Callback-Funktionen
  - 2.8 Scheme-Code innerhalb LilyPonds
  - 2.9 Schwierige Korrekturen
- 3 LilyPond Scheme-Schnittstellen
- Appendix A GNU Free Documentation License
- Appendix B Register