A.3.4 Añadir articulaciones a las notas (ejemplo)
La manera fácil de añadir articulación a las notas es mezclar dos expresiones musicales en un solo contexto, como se explica en Crear contextos. Sin embargo, supongamos que queremos escribir una función musical que lo haga.
Una $variable dentro de la notación #{...#} es como
una \variable normal en la notación clásica de LilyPond.
Sabemos que
{ \music -. -> }
no funciona en LilyPond. Podríamos evitar este problema adjuntando la articulación a una nota falsa,
{ << \music s1*0-.-> }
pero a los efectos de este ejemplo, aprenderemos ahora cómo hacerlo en Scheme. Empezamos examinando nuestra entrada y la salida deseada,
% input
\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))))
=====
% desired output
\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")))
Vemos que una nota (c4) se representa como una expresión
EventChord, con una expresión NoteEvent en su lista de
elementos. Para añadir una articulación de marcato, se debe añadir
una expresión ArticulationEvent a la propiedad elements de la
expresión EventChord.
Para construir esta función, empezamos con
(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))
La primera línea es la forma de definir una función en Scheme: el
nombre de la función es add-marcato, y tiene una variable
llamada event-chord. En Scheme, el tipo de variable suele
quedar claro a partir de su nombre (¡esto también es una buena
práctica en otros lenguajes de programación!)
"Add a marcato..."
es una descripción de lo que hace la función. No es estrictamente necesaria, pero de igual forma que los nombres claros de variable, es una buena práctica.
(let ((result-event-chord (ly:music-deep-copy event-chord)))
Se usa let para declarar las variables locales. Aquí usamos
una variable local, llamada result-event-chord, a la que le
damos el valor (ly:music-deep-copy event-chord).
ly:music-deep-copy es una función específica de LilyPond, como
todas las funciones que comienzan por ly:. Se usa para hacer
una copia de una expresión musical. Aquí, copiamos event-chord
(el parámetro de la función). Recuerde que nuestro propósito es
añadir un marcato a una expresión EventChord. Es mejor no
modificar el EventChord que se ha dado como argumento, porque
podría utilizarse en algún otro lugar.
Ahora tenemos un result-event-chord, que es una expresión
NoteEventChord y es una copia de event-chord. Añadimos
el marcato a su propiedad de la lista de 'elements.
(set! lugar valor-nuevo)
Aquí, lo que queremos establecer (el ‘lugar’) es la propiedad
'elements de la expresión result-event-chord.
(ly:music-property result-event-chord 'elements)
ly:music-property es la función que se usa para acceder a las
propiedades musicales (los 'elements, 'duration,
'pitch, etc, que vimos en la salida de \displayMusic
anterior). El nuevo valor es la antigua propiedad 'elements,
con un elemento adicional: la expresión ArticulationEvent, que
copiamos a partir de la salida de \displayMusic,
(cons (make-music 'ArticulationEvent
'articulation-type "marcato")
(ly:music-property result-event-chord 'elements))
cons se usa para añadir un elemento a una lista sin modificar
la lista original. Esto es lo que queremos: la misma lista que antes,
más la expresión ArticulationEvent nueva. El orden dentro de
la propiedad 'elements no es importante aquí.
Finalmente, una vez hemos añadido la articulación marcato a su
propiedad elements, podemos devolver result-event-chord,
de ahí la última línea de la función.
Ahora transformamos la función add-marcato en una función
musical:
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))
Podemos verificar que esta función musical funciona correctamente:
\displayMusic \addMarcato c4