A.3.4 Afegir articulacions a les notes (exemple) (Extender LilyPond)

#### A.3.4 Afegir articulacions a les notes (exemple)

La manera fàcil d’afegir una articulació a les notes és juxtaposar dos expressions musicals. Malgrat això, suposem que volem escriure una funció musical que ho faci.

Una `$variable` dins de la notació `#{…#}` és com una `\variable` normal en la notació clàssica del LilyPond. Podríem escriure

    { \music -. -> }

però als efectes d’aquest exemple, aprendrem ara com fer-lo a l’Scheme. Comencem examinant la nostra entrada i la sortida desitjada.

    %  input
    \displayMusic c4
    ===>
    (make-music
      'NoteEvent
      'duration
      (ly:make-duration 2 0 1/1)
      'pitch
      (ly:make-pitch -1 0 0))))
    =====
    %  sortida desitjada
    \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))

Veiem que una nota (`c4`) es representa como una expressió `NoteEvent`. Per afegir una articulació d’accent, s’ha d’afegir una expressió `ArticulationEvent` a la propietat `articulations` de l’expressió `NoteEvent`.

Per construir aquesta funció, comencem amb

    (define (add-accent note-event)
      "Afegeix un accent ArticulationEvent a les articulacions de `note-event',
      que se suposa que és una expressió NoteEvent."
      (set! (ly:music-property note-event 'articulations)
            (cons (make-music 'ArticulationEvent
                    'articulation-type 'accent)
                  (ly:music-property note-event 'articulations)))
      note-event)

La primera línea és la forma de definir una funció a l’Scheme: el nom de la funció és `add-accent`, i té una variable anomenada `note-event`. A l’Scheme, el tipus de variable sol quedar clar a partir del seu nom (això també es una bona pràctica a d’altres llenguatges de programació).

    "Afegeix un accent…"

és una descripció del que fa la funció. No és estrictament necessari, però d’igual forma que els noms clars de variable, és una bona pràctica.

Us preguntareu perquè modifiquem l’esdeveniment de nota directament enlloc de treballar sobre una còpia (es pot usar `ly:music-deep-copy` per això). La raó és un contracte silenciós: es permet que les funcions musicals modifiquin els seus arguments; o bé es generen partint de zero (com l’entrada de l’usuari) o estan ja copiades (referenciar una variable de música com ‘`\name`’ o la música procedent d’expressions de l’Scheme immediates ‘`$(…)`’ proporcionen una còpia). Donat que seria ineficient crear còpies innecessàries, el valor retornat d’una funció musical no es copia. Així doncs, per complir aquest contracte, no hem d’usar cap argument més d’un cop, i retornar-lo compta com un cop.

A un exemple anterior, hem construït música mitjançant la repetició d’un argument musical donat. En aquest cas, almenys una repetició ha d’haver sigut una còpia de sí mateixa. Si no ho fos, podrien ocórrer coses molt estranyes. Per exemple, si usem `\relative` o `\transpose` sobre la música resultant que conté els mateixos elements diverses vegades, estarien subjectes diverses vegades a la relativització o al transport. Si els assignem a una variable de música, es trenca el curs perquè fer referència a ‘`\name`’ crearà de nou una còpia que no reté la identitat dels elements repetits.

Ara bé, tot i que la funció anterior no és una funció musical, s’usarà normalment dins de funcions musicals. Així doncs, té sentit obeir el mateix conveni que usem per a les funcions musicals: l’entrada pot modificar-se per produir la sortida, i el codi que crida és responsable de crear les còpies si encara li cal el propi argument sense modificar. Si observem les pròpies funcions del LilyPond com `music-map`, veurem que respecten els mateixos principis.

En quin punt ens trobem? Ara tenim un `note-event` que podem modificar, no a causa de la utilització de `ly:music-deep-copy` sinó per una explicació molt desenvolupada. Afegim l’accent a la seva propietat de llista `'articulations`.

    (set! place new-value)

Aquí el que volem establir (el ‘place’) és la propietat `'articulations` de l’expressió `note-event`.

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

`ly:music-property` és la funció utilitzada per accedir a les propietats musicals (les `'articulations`, `'duration`, `'pitch`, etc, que veiem a dalt a la sortida de `\displayMusic`). EL nou valor de la propietat `'articulations`, amb un element addicional: l’expressió `ArticulationEvent`, que copiem a partir de la sortida de `\displayMusic`,

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

S’usa `cons` per afegir un element a la part d’endavant d’una llista sense modificar la llista original. Això és el que volem: la mateixa llista d’abans, més nova expressió `ArticulationEvent`. L’ordre de la propietat `'articulations` no té importància aquí.

Finalment, un cop hem afegit l’articulació d’accent a la seva propietat `articulations`, podem retornar `note-event`, per això l’última línea de la funció.

Ara transformem la funció `add-accent` en una funció musical (és qüestió d’una mica d’ajustament sintàctic i una declaració del tipus de argument).

    addAccent = #(define-music-function (note-event)
                                         (ly:music?)
      "Afegir un accent ArticulationEvent a les articulacions de `note-event',
      que se suposa que és una expressió NoteEvent."
      (set! (ly:music-property note-event 'articulations)
            (cons (make-music 'ArticulationEvent
                    'articulation-type 'accent)
                  (ly:music-property note-event 'articulations)))
      note-event)

A continuació verifiquem que aquesta funció musical funciona correctament:

    \displayMusic \addAccent c4

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

- Appendix A Tutorial de l’Scheme
  - A.1 Introducció a l’Scheme
    - A.1.1 Banc de sorra de l’Scheme
    - A.1.2 Variables de l’Scheme
    - A.1.3 Tipus de dades simples de l’Scheme
    - A.1.4 Tipus de dades compostes de l’Scheme
      - Parelles
      - Llistes
      - Llistes associatives (llistes-A)
      - Taules de hash
    - A.1.5 Càlculs a l’Scheme
    - A.1.6 Procediments de l’Scheme
      - Definició de procediments
      - Predicats
      - Valors de retorn
    - A.1.7 Condicionals de l’Scheme
      - if
      - cond
  - A.2 Scheme dins del LilyPond
    - A.2.1 Sintaxi de l’Scheme del LilyPond
    - A.2.2 Variables del LilyPond
    - A.2.3 Variables d’entrada i l’Scheme
    - A.2.4 Importació de l’Scheme dins del LilyPond
    - A.2.5 Propietats dels objectes
    - A.2.6 Variables del LilyPond compostes
      - Desplaçaments
      - Fraccions
      - Dimensions
      - Llistes-A de propietats
      - Cadenes de llistes-A
    - A.2.7 Representació interna de la música
  - A.3 Construcció de funcions complicades
    - A.3.1 Presentació de les expressions musicals
    - A.3.2 Propietats musicals
    - A.3.3 Duplicació una nota amb lligadures (exemple)
    - A.3.4 Afegir articulacions a les notes (exemple)
- B Interfícies per a programadors
  - B.1 Blocs de codi del LilyPond
  - B.2 Funcions de l’Scheme
    - B.2.1 Definició de funcions de l’Scheme
    - B.2.2 Ús de les funcions de l’Scheme
    - B.2.3 Funcions de l’Scheme buides
  - B.3 Funcions musicals
    - B.3.1 Definicions de funcions musicals
    - B.3.2 Ús de les funcions musicals
    - B.3.3 Funcions de substitució senzilles
    - B.3.4 Funcions de substitució intermèdies
    - B.3.5 Matemàtiques dins de les funcions
    - B.3.6 Funcions sense arguments
    - B.3.7 Funcions musicals buides
  - B.4 Funcions d’esdeveniments
  - B.5 Funcions de marcatge
    - B.5.1 Construcció d’elements de marcatge a l’Scheme
    - B.5.2 Com funcionen internament els elements de marcatge
    - B.5.3 Definició d’una ordre nova de marcatge
      - Sintaxi de la definició d’ordre de marcatge
      - Quant a les propietats
      - Un exemple complet
      - Adaptació d’ordres incorporades
    - B.5.4 Definició de noves ordres de llista de marcatge
  - B.6 Contextos per a programadors
    - B.6.1 Avaluació de contextos
    - B.6.2 Execució d’una funció sobre tots els objectes de la presentació
  - B.7 Funcions de callback
  - B.8 Ajustaments difícils
- C Interfícies de l’Scheme del LilyPond
- Appendix D GNU Free Documentation License
- Appendix E Índex del LilyPond