[ << Grabado musical ] | [Arriba][Índice general][Índice] | [ Lista de referencias bibliográficas >> ] |
[ < Hacer las cosas bien ] | [ Subir : Grabado musical ] | [ Representación musical > ] |
1.4 Construcción del software
Esta sección describe algunas de las decisiones de programación que hicimos cuando diseñamos el programa LilyPond.
Representación musical | ||
¿Qué símbolos grabar? | ||
Arquitectura flexible |
[ << Grabado musical ] | [Arriba][Índice general][Índice] | [ Lista de referencias bibliográficas >> ] |
[ < Construcción del software ] | [ Subir : Construcción del software ] | [ ¿Qué símbolos grabar? > ] |
Representación musical
Idealmente, el formato de entrada de cualquier sistema de formateado de alto nivel es una descripción abstracta del contenido. En este caso, eso sería la propia música. Ello presenta un enorme problema: ¿cómo podemos definir qué es la música realmente? En lugar de buscar una respuesta, le hemos dado la vuelta a la pregunta. Escribimos un programa capaz de producir música impresa, y luego ajustamos el formato de forma que sea lo más escueto posible. Cuando el formato ya no se puede recortar más, por definición nos estamos quedando con el propio contenido. Nuestro programa sirve como una definición formal de un documento musical.
La sintaxis es también el interfaz de usuario de LilyPond, de aquí que sea tan fácil teclear:
{ c'4 d'8 }
para crear un Do central negra (Do 4) y un Re por encima del Do central, corchea (Re 4).
A una escala microscópica, esta sintaxis es fácil de usar. A una escala mayor, la sintaxis necesita también una estructura. ¿De qué otra forma podríamos introducir piezas complejas como sinfonías u óperas? La estructura se forma por medio del concepto de expresiones musicales: combinando pequeños fragmentos de música dentro de otros más grandes, se puede expresar una música más compleja. Por ejemplo:
f'4
Las notas simultáneas se pueden construir encerrándolas dentro de
<<
y >>
:
<<c4 d4 e4>>
La expresión se pone en secuencia encerrándola dentro de llaves
{ … }
:
{ f4 <<c4 d4 e4>> }
Esto es también una expresión, y así se puede combinar de nuevo con
otra expresión simultánea (una blanca) utilizando <<
, \\
y >>
:
<< g2 \\ { f4 <<c4 d4 e4>> } >>
Tales estructuras recursivas se pueden especificar limpia y formalmente dentro de una gramática independiente del contexto. El código del analizador sintáctico también se genera a partir de esta gramática. Dicho de otra forma, la sintaxis de LilyPond está definida claramente y sin ambigüedades.
Los interfaces de usuario y la sintaxis son aquello que la gente ve y con lo que trata más frecuentemente. Son, en parte, cuestión de gusto, y también objeto de mucha discusión. Aunque las discusiones sobre el gusto tienen su mérito, no son muy productivas. Bajo el punto de vista más amplio de LilyPond, la importancia de la sintaxis de la entrada es pequeña: inventarse una sintaxis limpia es fácil, pero escribir un código de formatead que sea decente es mucho más difícil. Esto queda ilustrado por la cantidad de líneas que están dedicadas a los componentes respectivos: el análisis sintáctico y la representación se llevan menos del 10% del código fuente.
Cuando estábamos diseñando las estructuras utilizadas dentro de LilyPond, tomamos algunas decisiones de forma diferente a como es aparente en otros programas. Consideremos la naturaleza jerárquica de la notación musical:
En este caso, hay notas agrupadas en acordes que están dentro de compases, que pertenecen a pentagramas. Esto se parece a una estructura ordenada de cajas anidadas unas dentro de otras:
Desgraciadamente la estructura resulta ordenada porque está basada en algunas suposiciones excesivamente restrictivas. Este extremo se hace aparente si tenemos en cuenta un ejemplo musical más complejo:
En este ejemplo, los pentagramas parecen iniciarse y terminar a capricho, las voces saltan de un pentagrama a otro, y las pautas tienen tipos de compás diferentes. Muchos programas se las ven y se las desean para reproducir este ejemplo porque están construidos sobre la estructura de las cajas anidadas. Con LilyPond, por el contrario, hemos tratado de conservar el formato del código de entrada y la estructura lo más flexibles posible.
[ << Grabado musical ] | [Arriba][Índice general][Índice] | [ Lista de referencias bibliográficas >> ] |
[ < Representación musical ] | [ Subir : Construcción del software ] | [ Arquitectura flexible > ] |
¿Qué símbolos grabar?
El proceso de formateo decide dónde colocar los símbolos. Sin embargo, esto sólo puede hacerse una vez que se ha decidido qué símbolos se deben imprimir: en otras palabras, qué notación utilizar.
La notación musical común es un sistema de registro de la música que ha evolucionado durante los últimos mil años. La forma que es hoy día de uso común data del Renacimiento temprano. Aunque la forma básica (es decir, puntos sobre una pauta de cinco líneas) no ha cambiado, los detalles aún evolucionan para expresar las innovaciones de la notación contemporánea. De aquí que la notación musical común abarque unos quinientos años de música. El ámbito de sus aplicaciones comprende desde melodías monofónicas hasta monstruosos contrapuntos para gran orquesta.
¿Cómo podemos ensillar a tal bestia de siete cabezas, y forzarla
dentro de los confines de un programa de ordenador? Nuestra solución
es escindir el problema de la notación (en oposición al grabado, es
decir, a la tipografía) en fragmentos fácilmente digeribles y
programables: cada tipo de símbolo se maneja por parte de un módulo
separado conocido como plug-in. Cada plug-in es completamente modular
e independiente, de manera que cada uno se puede desarrollar y mejorar
por separado Estos plugines reciben el nombre de engraver
s o
“grabadores”, por analogía con los artesanos que traducían las
ideas musicales en símbolos gráficos.
En el ejemplo siguiente, comenzamos con un plug-in para la cabeza de
las notas, el grabador Note_heads_engraver
.
A continuación, un grabador del pentagrama, el
Staff_symbol_engraver
, añade la pauta:
el grabador de la clave o Clef_engraver
define un punto de
referencia para el pentagrama:
y el grabador de las plicas Stem_engraver
añade las plicas.
El grabador Stem_engraver
que traza las plicas recibe una
notificación por cada nota que le llega. Cada vez que se ve la cabeza
de una nota (o más, en el caso de un acorde), se crea un objeto plica
y se conecta a la cabeza. Añadiendo grabadores para las barras,
ligaduras, acentos, alteraciones, líneas divisorias, la indicación de
compás y la armadura, obtenemos un fragmento de notación musical
completo.
Este sistema funciona bien para la música a una voz, pero ¿qué tal para la polifonía? En la notación polifónica, muchas voces pueden llegar a compartir el mismo pentagrama.
En esta situación, las alteraciones accidentales y la pauta se comparten, pero las plicas, ligaduras, barras, etc., son privadas para cada voz. De aquí que los grabadores deban estar agrupados. Los grabadores de la cabeza de las notas, plicas, ligaduras, etc., van a un grupo llamado ‘contexto de voz’, mientras que los grabadores de la armadura, las alteraciones, los compases, etc., van a un grupo llamado ‘contexto de pauta’. En el caso de la polifonía, un solo contexto de pauta contiene más de un contexto de voz. De forma similar, varios contextos de pentagrama se pueden reunir dentro de un único contexto de partitura. El contexto de partitura es el contexto de notación del nivel más alto que hay.
Véase también
Referencia de funcionamiento interno: Contexts.
[ << Grabado musical ] | [Arriba][Índice general][Índice] | [ Lista de referencias bibliográficas >> ] |
[ < ¿Qué símbolos grabar? ] | [ Subir : Construcción del software ] | [ Poner a LilyPond a trabajar > ] |
Arquitectura flexible
Al principio escribimos el programa LilyPond completamente en el lenguaje de programación C++; la funcionalidad del programa estaba grabada en piedra por parte de los desarrolladores. Se comprobó que esto no era satisfactorio por unas cuantas razones:
- Cuando LilyPond comete errores, los usuarios necesitan sobreescribir las decisiones de formateo. Por tanto, el usuario debe tener acceso al motor de formateo. De aquí que las reglas y los ajustes predeterminados no se puedan fijar por nuestra parte en el tiempo de compilación sino que deben estar accesibles para los usuarios en el tiempo de ejecución.
- El grabado musical es cuestión de juicio visual, y por tanto está en el terreno del buen gusto. Por más entendidos que pretendamos ser, nuestros usuarios siempre podrían discrepar de nuestras decisiones personales. Por ello, las definiciones del estilo tipográfico debe también ser accesible para el usuario.
- Finalmente, nos encontramos refinando continuamente los algoritmos de formateo, por lo que necesitamos un enfoque flexible para las reglas. El lenguaje C++ fuerza un cierto método de agrupación de las reglas que no está preparado para aplicarse al formateo de la notación musical.
Estos programas se han solucionado integrando un intérprete para el lenguaje de programación Scheme y reescribiendo partes de LilyPond en Scheme. La arquitectura de formateo actual está construida alrededor de la noción de objetos gráficos, descritos por medio de variables y funciones de Scheme. Esta arquitectura coordina las reglas de formateo, el estilo tipográfico y las decisiones de formateo individuales. El usuario tiene acceso directo a la mayoría de esos controles.
Las variables de Scheme controlan las decisiones de disposición en la página. Por ejemplo, muchos objetos gráficos tienen una variable de dirección que codifica la elección entre arriba y abajo (o izquierda y derecha). A continuación vemos dos acordes, con acentos y símbolos de arpegio. En el primer acorde, los objetos gráficos tienen todas las direcciones hacia abajo (o hacia la izquierda). El segundo acorde tiene todas las direcciones hacia arriba (o hacia la derecha).
El proceso de dar formato a una partitura comprende la lectura y escritura de las variables de los objetos gráficos. Algunas variables tienen un valor preestablecido. Por ejemplo, el grosor de muchas líneas (una característica del estilo tipográfico) es una variable con un valor preestablecido. Somos libres de alterar este valor, dando a nuestra partitura una impresión tipográfica distinta.
Las reglas de formateado también son variables preestablecidas: cada objeto tiene variables que contienen procedimientos. Estos procedimientos realizan el formateo propiamente dicho, y mediante la sustitución de unos u otros, podemos modificar el aspecto de los objetos. En el ejemplo siguiente, la regla que gobierna qué objetos de cabeza se utilizan para producir el símbolo de la cabeza, se cambia a lo largo del fragmento musical.
[ << Grabado musical ] | [Arriba][Índice general][Índice] | [ Lista de referencias bibliográficas >> ] |
[ < ¿Qué símbolos grabar? ] | [ Subir : Construcción del software ] | [ Poner a LilyPond a trabajar > ] |