1.3.5 Ajout d’articulation à des notes (exemple) (GNU LilyPond – Extension des fonctionnalités)

#### 1.3.5 Ajout d’articulation à des notes (exemple)

Le moyen d’ajouter une articulation à des notes consiste à juxtaposer deux expressions musicales. L’option de réaliser nous-mêmes une fonction musicale à cette fin.

Un `$variable` au milieu de la notation `#{ … #}` se comporte exactement comme un banal `\variable` en notation LilyPond traditionnelle. Nous pourrions écrire

    { \musique -. -> }

mais, pour les besoins de la démonstration, nous allons voir comment réaliser ceci en Scheme. Commençons par examiner une saisie simple et le résultat auquel nous désirons aboutir :

    %  saisie
    \displayMusic c4
    ===>
    (make-music
      'NoteEvent
      'duration
      (ly:make-duration 2 0 1/1)
      'pitch
      (ly:make-pitch -1 0 0))))
    =====
    %  résultat attendu
    \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))

Nous voyons qu’une note (`c4`) est représentée par une expression `NoteEvent`. Si nous souhaitons ajouter une articulation accent, nous devrons ajouter une expression `ArticulationEvent` à la propriété `articulations` de l’expression `NoteEvent`.

Construisons notre fonction en commençant par

    (define (ajoute-accent note-event)
      "Ajoute un accent (ArticulationEvent) aux articulations de `note-event`,
      qui est censé être une expression NoteEvent."
      (set! (ly:music-property note-event 'articulations)
            (cons (make-music 'ArticulationEvent
                    'articulation-type 'accent)
                  (ly:music-property note-event 'articulations)))
      note-event)

La première ligne est la manière de définir une fonction en Scheme : la fonction Scheme a pour nom `ajoute-accent` et elle comporte une variable appelée `note-event`. En Scheme, le type d’une variable se déduit la plupart de temps de par son nom – c’est d’ailleurs une excellente pratique que l’on retrouve dans de nombreux autres langages.

    "Ajoute un accent…"

décrit ce que fait la fonction. Bien que ceci ne soit pas primordial, tout comme des noms de variable évidents, tâchons néanmoins de prendre de bonnes habitudes dès nos premiers pas.

Vous pouvez vous demander pourquoi nous modifions directement l’événement note plutôt que d’en manipuler une copie – on pourrait utiliser `ly:music-deep-copy` à cette fin. La raison en est qu’il existe un contrat tacite : les fonctions musicales sont autorisées à modifier leurs arguments – ils sont générés en partant de zéro (comme les notes que vous saisissez) ou déjà recopiés (faire référence à une variable musicale avec ‘`\nom`’ ou à de la musique issue d’expressions Scheme ‘`$(…)`’ aboutit à une copie). Dans la mesure où surmultiplier les copies serait contre productif, la valeur de retour d’une fonction musicale n’est pas recopiée. Afin de respecter ce contrat, n’utilisez pas un même argument à plusieurs reprises, et n’oubliez pas que le retourner compte pour une utilisation.

Dans un exemple précédent, nous avons construit de la musique en répétant un certain argument musical. Dans ce cas là, l’une des répétitions se devait d’être une copie. Dans le cas contraire, certaines bizarreries auraient pu survenir. Par exemple, la présence d’un `\relative` ou d’un `\transpose`, après plusieurs répétitions du même élément, entraînerait des « relativisations » ou transpositions en cascade. Si nous les assignons à une variable musicale, l’enchaînement est rompu puisque la référence à ‘`\nom`’ créera une nouvelle copie sans toutefois prendre en considération l’identité des éléments répétés.

Cette fonction n’étant pas une fonction musicale à part entière, elle peut s’utiliser dans d’autres fonctions musicales. Il est donc sensé de respecter le même contrat que pour les fonctions musicales : l’entrée peut être modifiée pour arriver à une sortie, et il est de la responsabilité de l’appelant d’effectuer des copies s’il a réellement besoin de l’argument dans son état originel. Vous constaterez, à la lecture des fonctions propres à LilyPond, comme `music-map`, que ce principe est toujours respecté.

Revenons à nos moutons… Nous disposons maintenant d’un `note-event` que nous pouvons modifier, non pas grâce à un `ly:music-deep-copy`, mais plutôt en raison de notre précédente réflexion. Nous ajoutons l’accent à la liste de ses propriétés `'articulations`.

    (set! emplacement nouvelle-valeur)

L’emplacement est ce que nous voulons ici définir. Il s’agit de la propriété `'articulations` de l’expression `note-event`.

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

La fonction `ly:music-property` permet d’accéder aux propriétés musicales – les `'articulations`, `'duration`, `'pitch`, etc. que `\displayMusic` nous a indiquées. La nouvelle valeur sera l’ancienne propriété `'articulations`, augmentée d’un élément : l’expression `ArticulationEvent`, que nous recopions à partir des informations de `\displayMusic`.

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

`cons` permet d’ajouter un élément en tête de liste sans pour autant modifier la liste originale. C’est exactement ce que nous recherchons : la même liste qu’auparavant, plus la nouvelle expression `ArticulationEvent`. L’ordre au sein de la propriété `'articulations` n’a ici aucune importance.

Enfin, après avoir ajouté l’articulation accent à sa propriété `articulations`, nous pouvons renvoyer le `note-event`, ce que réalise la dernière ligne de notre fonction.

Nous pouvons à présent transformer la fonction `ajoute-accent` en fonction musicale, à l’aide d’un peu d’enrobage syntaxique et mention du type de son argument.

    ajouteAccent = #(define-music-function (note-event) (ly:music?)
      "Ajoute un accent (ArticulationEvent) aux articulations de `note-event`,
      qui est censé être une expression NoteEvent."
      (set! (ly:music-property note-event 'articulations)
            (cons (make-music 'ArticulationEvent
                    'articulation-type 'accent)
                  (ly:music-property note-event 'articulations)))
      note-event)

Par acquis de conscience, vérifions que tout ceci fonctione :

    \displayMusic \ajouteAccent c4

#### GNU LilyPond – Extension des fonctionnalités v2.26.0 (stable-branch).

- 1 Tutoriel Scheme
  - 1.1 Introduction à Scheme
    - 1.1.1 Le bac à sable de Scheme
    - 1.1.2 Scheme et les variables
    - 1.1.3 Types de données Scheme simples
    - 1.1.4 Types de données Scheme composites
      - Paires
      - Listes
      - Listes associatives (alists)
      - Tables de hachage
    - 1.1.5 Scheme et les calculs
    - 1.1.6 Scheme et les procédures
      - Définition de procédures
      - Prédicats
      - Valeurs de retour
    - 1.1.7 Scheme et les conditions
      - if
      - cond
  - 1.2 Scheme et LilyPond
    - 1.2.1 Syntaxe Scheme dans LilyPond
    - 1.2.2 Variables LilyPond
    - 1.2.3 Débogage de code Scheme
    - 1.2.4 Saisie de variables et Scheme
    - 1.2.5 Import de code Scheme dans LilyPond
    - 1.2.6 Propriétés des objets
    - 1.2.7 Variables LilyPond composites
      - Décalages (offsets)
      - Fractions
      - Étendues (extents)
      - Propriété en alist
      - Chaînes d’alist
    - 1.2.8 Le modèle de boîte de LilyPond
    - 1.2.9 Représentation interne de la musique
  - 1.3 Construction de fonctions complexes
    - 1.3.1 Première approche (exemple)
    - 1.3.2 Affichage d’expressions musicales
    - 1.3.3 Propriétés musicales
    - 1.3.4 Doublement d’une note avec liaison (exemple)
    - 1.3.5 Ajout d’articulation à des notes (exemple)
- 2 Interfaces pour programmeurs
  - 2.1 Blocs de code LilyPond
  - 2.2 Fonctions Scheme
    - 2.2.1 Définition de fonctions Scheme
    - 2.2.2 Utilisation de fonctions Scheme
    - 2.2.3 Fonctions Scheme fantômes
  - 2.3 Fonctions musicales
    - 2.3.1 Définition de fonctions musicales
    - 2.3.2 Utilisation de fonctions musicales
    - 2.3.3 Fonctions de substitution simple
    - 2.3.4 Fonctions de substitution intermédiaires
    - 2.3.5 De l’usage des mathématiques dans les fonctions
    - 2.3.6 Fonctions dépourvues d’argument
    - 2.3.7 Fonctions musicales fantômes
  - 2.4 Fonctions événementielles
  - 2.5 Fonctions pour markups
    - 2.5.1 Construction d’un markup en Scheme
    - 2.5.2 Fonctionnement interne des markups
    - 2.5.3 Définition d’une nouvelle commande de markup
      - Syntaxe d’une commande markup
      - Attribution de propriétés
      - Exemple commenté
      - Adaptation d’une commande incorporée
      - Conversion de markups en chaînes
    - 2.5.4 Définition d’une nouvelle commande de liste de markups
  - 2.6 Contextes pour programmeurs
    - 2.6.1 Évaluation d’un contexte
    - 2.6.2 Application d’une fonction à tous les objets de mise en forme
  - 2.7 Fonctions de rappel
  - 2.8 Conteneurs requalifiants
  - 2.9 Retouches complexes
- 3 Interfaces LilyPond Scheme
- Appendix A GNU Free Documentation License
- Appendix B Index