Analizador Armonia Musical
Analizador Armonia Musical
Analizador Armonia Musical
Alvaro
de los Reyes Guzm
an
Departamento de Sistemas Informaticos y Programacion
Facultad de Informatica
Universidad Complutense de Madrid
Curso 2005-2006
Indice general
1. Introducci
on
1.1. Que es un analizador armonico . . . . . . . . . . . . . . . . . . . . .
1.2. Motivacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3. Estado del arte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
6
8
10
2. Detalles de la implementaci
on
2.1. Herramientas y recursos utilizados . . . . . . . .
2.2. Arquitectura de la aplicacion . . . . . . . . . . .
2.2.1. Analizador armonico . . . . . . . . . . . .
2.2.2. Lectura y procesamiento de ficheros midi
2.2.3. Interfaz grafica . . . . . . . . . . . . . . .
.
.
.
.
.
13
13
17
17
35
43
3. Incidencias en el desarrollo
3.1. Problemas y soluciones . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2. Ayudas y contactos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
49
54
4. Manual de usuario
4.1. Requisitos . . . . . . . . . .
4.2. Instalacion . . . . . . . . .
4.3. Ejecucion y manual de uso .
4.3.1. Ejecucion . . . . . .
4.3.2. Manual de usuario .
.
.
.
.
.
59
59
59
60
60
60
la aplicaci
on
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
65
65
66
67
5. Caractersticas y mejora
5.1. Caractersticas . . . .
5.2. Que se puede mejorar
5.3. Posibles ampliaciones .
de
. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6. Conclusiones
69
7. Bibliografa
71
INDICE GENERAL
Captulo 1
Introducci
on
A lo largo de la Historia se han dado m
ultiples definiciones de lo que es la M
usica,
ya sea de una manera mas filosofica, estetica o cientfica. Sin embargo, a partir del
siglo XVIII se empieza a establecer, gracias al trabajo de Rameau o de Rousseau que
la M
usica es la union de ritmo, meloda y armona (o galantera, seg
un Mattheson).
Tomando la armona como uno de los elementos musicales basicos, tiene sentido
llevar a cabo una profundizacion mayor. A la hora de abordar el analisis de una obra
musical, se suelen seguir ciertos pasos que garanticen un recorrido coherente de los
elementos y caractersticas presentes en la obra, para luego deducir mas informacion
de la facilitada por el analisis. En este sentido, todo buen analisis debe empezar por
los elementos basicos: atender al ritmo presente en la obra, las caractersticas de las
melodas y de las lneas utilizadas y tambien el uso que de la armona se hace en
ella.
Dar una definicion de armona es difcil, ya que tiene m
ultiples connotaciones.
A rasgos generales, la armona es el arte de combinar sonidos entre s. En la m
usica
occidental, entendemos por armona una jerarquizacion de los 12 sonidos posibles,
de los que se toman 7 para formar lo que se llama una escala. Desde la Edad Media
se fue produciendo un proceso de modalizacion, en el que se tomaban unos sonidos,
a partir de los cuales crear las melodas para usar en una obra. En el siglo XVI se fue
asentando una jerarquizacion de estos sonidos en torno a uno llamado tonica, y mas
adelante sobre otro denominado dominante. Con el establecimiento de la tonalidad,
una seleccion de 7 sonidos, empezaron a desarrollarse las primeras nociones de lo que
hoy distinguimos por armona tonal en Occidente. As, surgen las escalas tonales,
que estan formadas por esos 7 sonidos colocados uno tras otro de manera ascendente
o descendente, empezando por uno principal, denominado tonica.
Los acordes son una disposicion de notas. Tambien esto es una vision general
que, aplicada al campo de la tonalidad, nos lleva a la definicion del caso mas basico:
un acorde trada esta formado por tres sonidos en sucesion, cada uno a intervalo de
tercera respecto al anterior, y uno de los cuales da nombre al acorde, denominandose
fundamental. En la armona tonal, sobre cada nota de la escala se forma un acorde, tomando la correspondiente nota como fundamental del mismo. As se llega al
concepto de armona: en un contexto tonal, donde existe una tonalidad definida que
se usa como referente para la composicion de una obra, a partir de cada nota del
acorde se crean acordes, que toman el nombre dentro de la tonalidad de la nota que
usan como fundamental.
5
CAPITULO 1. INTRODUCCION
1.1.
Qu
e es un analizador arm
onico
Volviendo a una vision mas practica, el analizar una obra musical supone atender
al ritmo, a la meloda, a la armona, a la estructura formal, a los instrumentos
utilizados, a la relacion de la obra con su contexto historico y a muchos aspectos
adicionales. Sin embargo, de todos ellos quizas es la armona el que supone un
proceso mas minucioso: hay que determinar la tonalidad utilizada y a partir de ello,
ir comprobando las simultaneidades de notas para deducir a partir de ellas acordes.
Cuando estos acordes han sido reconocidos, se debe entonces asignar a cada uno
de ellos una funcion dentro de la tonalidad, que es lo que llamamos el grado del
acorde. Puesto que cada tonalidad tiene un acorde formado a partir de las notas
de su escala, estos acordes desempe
nan un grado dentro de la misma. Los grados
se ordenan usando los n
umeros romanos, haciendo corresponder al de tonica el I y
siendo los acordes siguientes numerados correlativamente.
Ademas, cada uno de los acordes puede presentarse en distinta inversion: si tomamos un acorde de tres notas, el acorde puede aparecer en tres posiciones, correspondiendo cada una de ellas a la nota del acorde que se sit
ua como nota mas grave
del conjunto. Cuando la nota mas grave del acorde es su fundamental se dice que el
acorde esta en estado fundamental. Cuando esto no ocurre, el acorde se encuentra en
inversion. Para indicar la inversion de un acorde se usan cifrados: son indicaciones
numericas que se
nalan el tipo de acorde (en algunos casos especiales) y cual es la
nota de las que lo forman que esta situada como nota mas grave. Los tipos de acorde
ES UN ANALIZADOR ARMONICO
1.1. QUE
CAPITULO 1. INTRODUCCION
1.2.
Motivaci
on
1.2. MOTIVACION
esto es uno de los grandes retos de las aplicaciones que hacen edicion de partituras:
cuando tratan un fichero midi, al abrirlo, muestran indistintamente las notas con
alteracion como sostenidos o bemoles. Es el caso, por ejemplo, de Finale. Al no
haber en el fichero midi ninguna indicacion de la tonalidad utilizada en la obra,
estos programas no pueden resolver que nombre debe tener cada sonido codificado
en el archivo. Nuestra aplicacion podra ayudar a esta labor, realizando un analisis
en segundo plano que, mediante la determinacion de la tonalidad, facilite distinguir
si un sonido debe ser representado como una nota con sostenido o la correspondiente
con bemol.
Pero las posibles funciones que nuestra aplicacion puede desarrollar como ayuda
a otros productos no quedan aqu. Tener un modulo que realice un analisis armonico
facilita tambien la generacion musical: imaginemos un programa que, dada una obra
musical, sepa distinguir la meloda principal y tenga capacidad de generar acompa
namientos. El uso del modulo de analisis de nuestro trabajo facilitara enormemente la tarea de la generacion de un acompa
namiento que mantuviera la armona
existente en la obra de entrada, pero enriquecida con un acompa
namiento distinto.
Por ejemplo, en la Facultad de Informatica de la Universidad Complutense se desarrollo durante el pasado curso academico Genaro, que podra ser utilizado para,
tomando una obra, obtener su secuencia armonica, eliminar el acompa
namiento que
tiene y generar un nuevo utilizando Genaro.
El dise
no modular de la aplicacion, que mas adelante sera indicado, supone tener
el motor de analisis en Prolog. Ademas, este motor tambien es modular, puesto que
el analisis se lleva a cabo en distintas fases, desarrolladas por modulos independientes. Aunque aqu nos hemos centrado en la armona tonal por la trascendencia que
tiene en la m
usica occidental as como ser la armona con la que mas familiarizados
estamos, podra modificarse alguno de esos modulos de analisis para aceptar otras
armonas, como puede ser la armona por cuartas de Paul Hindemith. El dise
no modular de la aplicacion favorece que haya mejoras que se puedan realizar rapidamente,
mientras que los demas modulos se mantienen invariables.
Desde un punto de vista mas general, el desarrollo de esta aplicacion puede
suponer el primer paso hacia otras aplicaciones que contin
uen el analisis. Teniendo la estructura armonica de una obra es mas facil llevar a cabo otros analisis
mas avanzados, como puede ser el reconocimiento de estructuras formales, de desarrollos melodicos, incluso el reconocimiento tematico debido a la repeticion de un
acompa
namiento armonico asociado. Todos estos trabajos pueden verse ayudados
de nuestra aplicacion, en el sentido de que ya se dispone de un modulo que lleva a
cabo el analisis armonico, base de otros posibles.
Como informaticos, este proyecto supone un reto: trabajar en una aplicacion
multilenguaje, con modulos conectados pero desarrollados en distintos lenguajes
(Java y Prolog) y formalizar un area de conocimiento cuyo tratamiento no es habitual
en nuestros estudios. Es una de las lneas de trabajo que se puede seguir a la hora
de aplicar la Informatica hacia otros campos del conocimiento: como en base a unas
reglas se dise
na una aplicacion que pretende satisfacer las especificaciones, en este
caso determinadas por la armona tonal.
CAPITULO 1. INTRODUCCION
10
1.3.
Estudiar el estado del arte supone atender a otras aplicaciones que, si bien no
tienen la misma funcionalidad, s aportan caractersticas similares a la que es nuestro
proposito. Hay que indicar que es difcil encontrar una aplicacion reservada u
nicamente al analisis armonico, puesto que generalmente las aplicaciones aprovechan
este motivo para trabajar en otra direccion o para profundizar en el analisis.
Una de las aplicaciones a destacar dentro del estado del arte es CLAM Music
Annotator, desarrollado por el Grupo de Investigacion en Tecnologa Musical de la
Universidad Pompeu Fabra de Barcelona. CLAM es el acronimo de C++ Library
for Audio and Music, y esta compuesto por varios modulos, uno de los cuales se
llama Music Annotator, que es una utilidad para visualizar, comprobar y modificar
informacion musical extrada de un archivo de audio. La informacion musical la
recibe en la entrada como fichero de audio, y no utiliza ficheros midi como nosotros.
Esto lleva a tener que utilizar Transformadas de Fourier para adivinar las notas que
aparecen en la obra musical y, en base a su potencia y frecuencia de aparicion, se
produce una estimacion de los acordes que son usados en una obra musical.
The Melisma Music Analyzer, desarrollado por Daniel Sleator y Davy Temperley,
se define como un potente sistema para analizar m
usica y extraer informacion de
ella. El analizador toma un fragmento musical como una lista de eventos (pudiendose
usar entonces un archivo midi) y extrae informacion sobre el ritmo, el compas, la
estructura en frases, la estructura del contrapunto y tambien la armona. Supone
un trabajo a bastante buen nivel, puesto que resuelve los problemas que nosotros
tambien encontramos, aunque quizas de una manera simplista. Ante el problema de
la deteccion de la tonalidad, divide la obra de entrada en fragmentos en los que se
distingue el uso de una tonalidad distinta a la de los demas. Facilita el uso de varios
metodos a la hora del este calculo, como pueden ser estrategias bayesianas, el metodo
de Krumhansl-Schmuckler, o el modelo CBMS. Al igual que nuestro desarrollo, se
basa en tomar los distintos resultados que estos metodos han facilitado para, a partir
de ellos, deducir la tonalidad principal en cada fragmento. Una vez determinada esta
tonalidad, realiza un analisis de los acordes, asignando a cada uno de ellos su grado en
la tonalidad principal. Las diferencias con lo que pretendemos en nuestro desarrollo
son evidentes: esta aplicacion utiliza salida en modo de texto para mostrar sus
resultados, en realidad a modo de depuracion, puesto que se ofrece tambien como
complemento hacia otras aplicaciones. Nosotros pretendemos dar una vision mas
continuista de la tonalidad: como incluso en los cambios de tonalidad los acordes
presentes pueden ser encajados en la tonalidad principal mediante el calculo de
modificaciones. Como contrapartida, este desarrollo ofrece mas metodos heursticos
que los que nuestro desarrollo va a utilizar.
La Harmony Library es una librera dinamica desarrollada en Power Basic por
Godfried-Willem Raes, profesor doctor del Real Conservatorio e Instituto Superior
para la M
usica de Gent (Belgica). Es un trabajo que lleva dos a
nos sin ser actualizado. Se ofrece como librera adicional para cualquier lenguaje capaz de usar DLL,
que incorpora un conjunto de procedimientos y funciones que implementan reglas de
la armona tradicional. Permite una descripcion de procesos armonicos, mediante el
uso de metodos que facilitan el trabajo con acordes, notas, secuencias de acordes y
reglas de armona. Utiliza una codificacion en enteros similar a la que se va a usar en
11
este desarrollo, mientras que destaca por ofrecer un trabajo complementario a otra
aplicacion, al mostrarse como librera dinamica. Como contrapartida, no dispone de
ning
un modulo de visualizacion de resultados, dejando esta labor a quien vaya a
usarla para su aplicacion.
En cuanto a los grandes programas de edicion de partituras y de sonidos, no
se puede destacar ninguna funcion especfica para el analisis armonico dentro de
ellos. Rosegarden dispone de un modulo de analisis: si en la ventana de edicion de
una parte de piano, por ejemplo, se escriben algunas notas y tras seleccionarlas se
accede al Harmony Browser, se realiza una estimacion de que acorde pueden formar
esas notas, y entonces as aparece indicado. Sin embargo, no ofrece un analisis mas
exhaustivo, profundizando en un reconocimiento tonal ni en un nivel de detalle
como el que pretendemos en nuestra aplicacion. Otro editor de partituras, Sibelius,
dispone de una opcion como la comentada anteriormente: realiza adaptaciones de
obras de entrada para agrupaciones instrumentales a peticion del usuario, pero la
solucion no pasa por la armona: produce un reparto de las voces existentes en los
datos de entrada y un peque
no analisis armonico para completar en vertical acordes
cuando a alguna de las voces que se esta escribiendo no se le puede asignar una
nota tomada de la obra original. Este tipo de aplicaciones se veran enriquecidas si
incorporaran un modulo de analisis armonico como el que se pretende desarrollar,
ya que ademas se solucionaran los problemas de enarmona entre notas que se han
comentado anteriormente.
12
CAPITULO 1. INTRODUCCION
Captulo 2
Detalles de la implementaci
on
A continuacion, vamos a describir todos los detalles referentes a la implementacion, es decir, las herramientas y tecnicas usadas, el motivo por el que hemos
escogido dichas herramientas y la arquitectura software de la aplicacion.
2.1.
14
con formato de texto. La ventaja que hemos tenido al utilizar ABC ha sido el tratar
directamente con un archivo de texto y poder convertirlo a nuestro formato a traves
de un parser.
Para la interfaz, tambien hemos usado otras libreras, las comunmente conocidas
como Look and Feels. Estas libreras sirven para cambiar el aspecto que Java nos da
por defecto para una aplicacion. De hecho, el aspecto NimRod con el que comienza
la aplicacion cuando la ejecutamos, no es el aspecto por defecto que nos da Java, si
no que es un Look And Feel que hemos usado.
Para hacer mas sencilla la implementacion, utilizamos el popular entorno de
desarrollo Eclipse que nos ofrece una amplia gama de facilidades a la hora de programar. Mientras programamos, nos avisa de los errores de sintaxis y de tipos, nos
muestra las advertencias, es capaz de hacer los metodos get y set automaticamente
para los atributos de una clase, nos genera el Javadoc, puede corregir la identacion
del codigo, etc. Es una herramienta muy u
til y gratuita, que puede descargarse de
www.eclipse.org. El u
nico incoveniente que tiene es que necesita un equipo relativamente potente para funcionar bien.
Para la generacion de los logotipos e iconos de la aplicacion, hemos usado la
herramienta Corel PaintShopPro, que es un editor grafico bastante potente y sencillo
de usar.
Para la realizacion de las paginas de ayuda en html de la aplicacion, hemos
usado el editor NVU de Mozilla, para hacer esta tarea mucho mas rapidamente que
implementando el codigo html a mano. NVU puede descargarse de www.nvu.org
Para el modulo de analisis de la aplicacion se ha escogido Prolog debido a sus
caractersticas y como beneficiaran nuestro trabajo. Como primer punto a destacar,
Prolog proporciona trabajar facilmente en la b
usqueda de soluciones mediante la
aplicacion de reglas, que es uno de los principios fundamentales del analisis. La
propia estrategia de resolucion de objetivos que sigue el lenguaje hace que, definiendo
una base de hechos en la que queden reflejadas las reglas de la armona, lanzando
a ejecucion un predicado se busque la solucion que satisfaga esas reglas. Esto se ha
realizado a m
ultiples niveles: en el Analisis Nominal, quizas hubiera sido mejor que el
calculo de la forma prime se hiciera mediante alg
un lenguaje imperativo, ya que son
mas apropiados para el calculo numerico. Sin embargo, a la hora de reconocer acordes
el trabajo en Prolog facilita enormemente la tarea: basta usar alguna condicion en
los parametros de cada definicion de un predicado para as ya poder distinguir entre
casos distintos y es el propio motor de ejecucion el que se encarga de ir aplicando
las reglas definidas seg
un el caso que se presente.
La facilidad que Prolog ofrece a la hora de trabajar con listas hace que el proceso de analisis sea mas facil para el desarrollador: la creacion de listas se realiza
automaticamente en cada definicion de un predicado en base a los casos que luego
son aplicados por el motor de ejecucion. A la hora de intentar reconocer un acorde
que no esta en una forma pura, la definicion de reglas mediante hechos hace que
consecutivamente el modulo en Prolog las vaya intentando aplicar hasta tener exito.
Esto permite definir reglas de manera mas clara, mediante distintos predicados, y
que a la hora de interpretar el codigo fuente sea mas facil su comprension. El reconocimiento de acordes realizado en el Analisis Musical tambien se ve favorecido
por el uso de Prolog en el caso de querer contemplar mas tipos de acordes para
su reconocimiento: basta con a
nadir una definicion del predicado reconAcor tal que
15
encaje con la forma prime correspondiente al nuevo tipo de acorde y a partir de ello,
definir las normas de tratamiento.
El uso que en basico.pl se hace de reglas basicas de la armona supone una
facilidad a la hora de extender el modulo hacia otro tipo de armonas: cambiando
las definiciones realizadas en este archivo se puede conseguir un reconocimiento de
otros lenguajes, y tambien mediante la correspondiente modificacion en analisis.pl
se puede disponer de un Analisis Nominal que reconozca cualquier tipo de armona
que pueda ser formalizada. Este tipo de definicion de reglas aprovecha la sintaxis de
Prolog para presentarse de una manera mas clara, y con los distintos tipos de acorde
separados en definiciones del predicado. En un lenguaje imperativo este proceso de
reconocimiento de acordes hubiera supuesto grandes estructuras if...then para
comprobar cada caso encontrado con un acorde, ademas de no facilitar tanto la
modificacion de las reglas formalizadas o la inclusion de otras nuevas.
Para el reconocimiento de la tonalidad, en Prolog nos vemos beneficiados gracias
a la posibilidad de buscar todas las soluciones mediante el predicado findall. En la
heurstica que contaba para todas las tonalidades cuantos acordes caen bajo cada
una de ellas se utiliza este tipo de tecnicas para obtener una lista con los resultados y luego, aprovechando la facilidad con que Prolog maneja listas, escoger la
mejor solucion. Quizas aqu no hay mucha mejora respecto a lo que se podra haber
obtenido usando un lenguaje imperativo, pero tambien es cierto que este lenguaje
declarativo facilita mecanismos para ciertas operaciones de proceso mas secuencial.
En el Analisis Sintactico tambien hay una mejora sustancial gracias al uso de Prolog.
En primer lugar, la intencion de maximizar la zona de modulacion, buscando todas
las tonalidades posibles se ve de nuevo favorecida gracias a la b
usqueda de todas
las soluciones que facilita Prolog. Aqu se maneja una gran cantidad de informacion
para cada posibilidad, que sin embargo no supone demasiado problema gracias al
tratamiento en memoria que realiza Prolog con las listas. En un lenguaje imperativo el consumo de memoria hubiera sido superior, salvo que hubieramos utilizado
tecnicas de optimizacion de recursos. De nuevo, las reglas aplicadas, que estan definidas en predicados, son facilmente modificables mediante la nueva definicion de
los predicados afectados: podra cambiarse la consideracion de la b
usqueda de una
nueva modulacion seg
un otro criterio rapidamente, cambiando unas lneas de codigo
sin que el resto del modulo de Analisis Sintactico se vea afectado.
El propio tratamiento de los acordes dentro de un contexto tonal se puede modificar si, como se ha propuesto antes, se pretende reconocer otro estilo armonico.
Aqu hay que redefinir el predicado sacaGrados. E incluso, dentro de las definiciones
actuales, se puede eliminar el reconocimiento de modulaciones, si se quiere hacer
un analisis mas plano en el contexto tonal. Es en este modulo donde se pueden
ampliar las reglas disponibles para reconocer otro tipo de acordes incluidos en el
Analisis Nominal. Supongamos que se a
naden las sextas alemanas para su reconocimiento. Esto supondra a
nadir una nueva regla al Analisis Nominal que reconozca
la forma prime correspondiente y dentro del modulo de Analisis Sintactico una regla
que indique como tratar ese acorde dentro de una modulacion, o si se acepta como
modificacion de un acorde de la tonalidad.
La manera en que las notas son codificadas mediante enteros, pero almacenada
con hechos en salida.pl hace que sea muy rapido modificar la codificacion. Cambiando el entero asociado con cada nota se dispone de una nueva posibilidad. Lo mismo
16
ocurre con todo tipo de asignaciones que se haya hecho a los enteros que internamente se manejan en el modulo en Prolog. El principal beneficio en el uso de este
lenguaje esta en que al estar basado en hechos podemos cambiar estos rapidamente
y, al derivarse las reglas aplicadas en la ejecucion de los hechos indicados, cambia
completamente el resultado.
El trabajo del analisis armonico supone tener que manejar muchas posibilidades
ante un mismo suceso y escoger entre ellas la mejor, debido a la gran indeterminacion
que se introduce al considerar las notas como enteros, lo que conlleva que haya que
resolver los nombres de las notas por las enarmonas. La principal ventaja que hemos
aprovechado con el uso de Prolog es el uso de un lenguaje que permite formalizar
rapidamente reglas de muchos ambitos del conocimiento. Al ser un lenguaje de mas
alto nivel que otros imperativos que podramos haber usado, esto nos ha facilitado
no atender tanto a como se produce la ejecucion desde un punto de vista interno
y s poder dedicar mas tiempo a la definicion de hechos y reglas de derivacion con
las que se pueda formalizar el analisis armonico. Esto puede verse como una falta
de preocupacion por el rendimiento, pero sin embargo, Prolog es extremadamente
eficiente en el uso de listas y la optimizacion de memoria que produce cuando estas
tienen una longitud considerable, as como la formalizacion de reglas de analisis
armonico es mucho mas facil y rapida usando un lenguaje declarativo como Prolog
que no su materializacion en instrucciones imperativas como hubiera sido el caso de
usar Java.
Para la edicion del codigo y el trabajo con Prolog se ha utilizado el programa
SWI Prolog Editor, desarrollado por Gerhard Rohner, que facilita un entorno sencillo con el que llevar a cabo el proceso de programacion. En concreto, tiene realce
de la sintaxis del lenguaje, remarcando aquellas palabras reservadas y el entorno
de ejecucion de SWI Prolog esta integrado en el mismo programa, lo que facilita
enormemente el trabajo de comprobacion y depuracion.
Para comunicar la parte en Prolog con la desarrollada en Java podra haberse
utilizado los conectores que la implementacion de SWI dispone. Esto supondra
un trabajo adicional al que hemos seguido nosotros: sabiendo que vamos a usar
intercambio de informacion musical codificada en enteros, y que se va a utilizar un
formato reconocible por Prolog para su entrada y una lista de tuplas de enteros para
la salida, se puede hacer directamente la comunicacion mediante ficheros de texto.
En el archivo entradaProlog.txt se escribe una lista con la informacion pertinente de
tal forma que pueda ser leda directamente desde la parte de Prolog como tal, y
ser tratada. Para la salida, en el archivo salidaProlog.txt, se dispone de una serie de
tuplas de enteros dispuestas en lneas independientes. Usar los conectores hubiera
supuesto mas trabajo: utilizar las clases y metodos facilitados para despues realizar
la interpretacion de la informacion almacenada. Aprovechando los procedimientos
de lectura de archivos en disco desde Java, se produce una lectura secuencia de
lneas de texto, a partir de las cuales se realiza la interpretacion de los enteros del
archivo. Esto supone un proceso mucho mas rapido tanto en el desarrollo como en
la ejecucion.
Por u
ltimo, aunque no por ello menos importante, tenemos que destacar el uso
de algunos editores de partituras como son Finale y GuitarPro, que ademas de
proporcionarnos una edicion sencilla (aunque tediosa en algunos casos) nos ha permitido exportar la partitura a formato MIDI y modificar los instrumentos asignados
2.2. ARQUITECTURA DE LA APLICACION
17
a las pistas MIDI. Gracias a esto hemos podido comprobar que nuestra aplicacion
funcionaba correctamente.
2.2.
Arquitectura de la aplicaci
on
Podemos decir, que la aplicacion esta formada por tres modulos claramente diferenciados.
El analizador armonico, que es la parte encargada de realizar el analisis a partir de
un fichero de entrada llamado entradaProlog.txt. El segundo modulo es el procesador
midi que tiene como entrada un fichero midi, se encarga de extraer toda la informacion necesaria del fichero para el analisis y la representacion de la partitura, y
genera como salida salidaProlog.txt. Por u
ltimo, la interfaz, que lleva el control de la
aplicacion, cuando el usuario quiere abrir un midi, obtiene la ruta del fichero elegido
por el usuario, llama al procesador midi y, una vez generado entradaProlog.txt, la
interfaz llama al analizador para que haga su trabajo. Por u
ltimo, la interfaz lee la
partitura generada por el procesador midi y el fichero salidaProlog.txt generado por
el analizador, y muestra por pantalla el resultado del analisis y la partitura correspondientes.
A continuacion describiremos con detalle cada uno de estos modulos.
2.2.1.
Analizador arm
onico
La parte en Prolog del analizador armonico esta representada por un ejecutable, hecho con la implementacion de SWI de este lenguaje. Recibe la informacion
necesaria para el analisis mediante un fichero de texto, entradaProlog.txt, que la
parte en Java deja en el directorio de trabajo. La especificacion de este archivo ha
sido indicada anteriormente: se trata una lista de tuplas, la primera de las cuales
indica el resultado que el Algoritmo de Evaluacion de Alteraciones ha encontrado
para determinar la tonalidad. El resto de los elementos de la lista son tuplas con
dos componentes: un entero, que indica la duracion en valores del acorde, y una
lista con las notas del acorde, colocadas desde lo mas grave a lo mas agudo. Para
devolver la informacion del analisis, la parte en Prolog utiliza otro fichero de texto,
salidaProlog.txt, cuya especificacion se indicara mas adelante.
Como modulo de analisis, puede ser dividido en otros tres modulos especializados,
cada uno con una funcion especfica, que seran tratados por separado. Hay un primer
modulo que realiza un analisis nominal de los acordes recibidos: los procesa, y les da
un nombre, como por ejemplo, Do Mayor. Realizado el analisis nominal de todos los
acordes encontrados en la lista de entrada de datos, se puede proceder al analisis de
en que tonalidad esta escrita la obra recibida y, una vez con la tonalidad calculada,
se puede abordar el proceso de asignar a cada acorde reconocido en la primera etapa
un grado en la tonalidad correspondiente. Ademas, en esta tercera fase es cuando se
produce el analisis de modulaciones, pretendiendo localizar aquellos puntos en los
que se ha abandonado la tonalidad principal para pasar a otra.
Hay que aclarar que en un principio, se va a aplicar el termino acorde a cualquier disposicion vertical de notas encontrada como lista de notas en la lista de
tuplas del fichero entradaProlog.txt. A lo que se llama aqu acorde puede no coincidir
con la vision tradicional de lo que puede ser un acorde trada, ya que la implementa-
18
An
alisis Nominal
El modulo de Analisis Nominal, entrada a la parte en Prolog, se encuentra en
su mayor parte en el fichero analisis.pl. Hay un predicado de entrada al modulo en
Prolog, analizar, que, aun estando en este fichero, realiza todo el proceso de analisis.
Este predicado se encarga de ir llamando a los modulos de manera secuencial, e
ir pasando de uno a otro los resultados que son necesarios para cada etapa. La
primera operacion que se realiza es leer de entradaProlog.txt la lista de acordes a
analizar, proveniente de la aplicacion en Java. Como en esta lista el primer elemento
es una tupla con dos enteros, que indican la tonalidad encontrada por una de las
heursticas para su determinacion, tendremos que retirar esta informacion de la lista
de entrada, pues nos hara falta mas adelante, y continuar con el resto de la lista, que
es donde estan los acordes a analizar. Una vez que se ha ledo la lista de entrada,
se inicializa la salida al fichero de depuracion, debugProlog.txt, en el que se recoge
toda la informacion sobre el proceso de analisis, para su tratamiento.
El modulo de Analisis Nominal esta representado por el predicado sacaAcordes,
cuyos parametros son: el acorde anteriormente inicializado (con valor 0 si se trata del
primer acorde a analizar), el acorde actual a analizar, pero en la forma en la que es
recibido en el fichero de entrada: (Duraci
on, ListaDeNotas). El tercer parametro
es el resto de la lista de acordes a analizar, seguido del n
umero de compas y un
parametro de salida Z, por el que el predicado va a devolver el resultado del analisis
nominal.
En cuanto al analisis nominal, los primeros desarrollos de esta aplicacion realizaban un trabajo mas exhaustivo: para cada acorde recibido en la lista se realizaba un
proceso de b
usqueda en el que, considerando las notas recibidas, se intentaba determinar de que acorde se trataba atendiendo a que tipo de acorde encajaba mejor
con las notas presentadas. Sin embargo, esto se mostro un trabajo demasiado costoso
en tiempo y, sobre todo, con un resultado incierto. Fue aqu cuando se descubrio la
Set Theory Primer for Music, desarrollada a partir de 1998 por Larry Solomon. Se
basa en tomar un conjunto de notas para, a traves de operaciones matematicas con
su representacion numerica, poder determinar de que tipo de acorde se trata y su
fundamental. En el caso de nuestro analisis, podemos saber tambien en que inversion
se encuentra el acorde, ya que tenemos como primer elemento de la lista de notas
del acorde la nota mas grave, a partir de la cual determinar la posicion del acorde.
La Set Theory Primer supone calcular la llamada forma prime de un acorde: una
lista de enteros que indica la distancia en semitonos de las notas del acorde respecto
a su fundamental. De esta manera, podemos determinar el tipo de acorde de que
se trata. El calculo de la forma prime se realiza en el fichero solomons.pl, a traves
del predicado getPrime. Su primer parametro es una lista con las notas a partir de
las cuales realizar el calculo, y a continuacion tiene dos parametros de salida: la
fundamental encontrada en el acorde, y la lista de enteros que representa la forma
prime. El calculo a traves de la teora de Larry Solomon puede producir un mayor
tiempo de calculo numerico, pero tiene dos ventajas frente al proceso de b
usqueda
realizado inicialmente: se realiza mucho menos backtracking, puesto que el resultado
2.2. ARQUITECTURA DE LA APLICACION
19
20
2.2. ARQUITECTURA DE LA APLICACION
21
22
entero especial para el tipo de acorde, que nos permita continuar con el analisis. El
cifrado, de igual forma, esta indicado por un entero especial, que en la parte en Java
esta asociado en la clase de constantes con un cifrado vaco.
Una vez repasados los tipos basicos de acordes y como son distinguidos mediante
la forma prime, cabe abordar el caso de acordes en vertical cuya forma prime no
coincida con ninguna de las que indican un tipo de acorde basico. Esto se produce
especialmente en aquellos acordes con a
nadidos (en los que, como se ha visto, la
nota a
nadida pasa a tener igual importancia que los duplicados de las del acorde)
o acordes incompletos. Estos casos se contemplan en el archivo analisis.pl tras las
definiciones de reconAcor destinadas a los casos basicos de acorde. El primero a
abordar es aquel caso en el que a un acorde perfecto mayor se le a
nade una nota
ajena. Esto se produce, por ejemplo, si a un acorde de Do Mayor: Do Mi Sol, se
le a
nade un Re o un Fa. En este caso, la forma prime sera la correspondiente a
un acorde perfecto mayor, pero tambien reflejara la distancia de la nota adicional
respecto a la nota adicional.
Para superar esta situacion, al igual que ocurrira en el caso de un perfecto menor, en reconAcor se toma la forma prime recibida y se quita de la lista los enteros
que corresponden a la forma prime de acorde mayor o menor. En la lista resultante
tenemos entonces la distancia en semitonos de la nota adicional respecto a la fundamental devuelta por el calculo de la forma prime. Sumando esa distancia a la
fundamental, obtenemos la propia nota, ante lo que se puede llamar al predicado
buscaNotaAdicional, definido en el archivo basico.pl. Este predicado recibe la lista
de notas de los acordes anterior, actual, y siguiente, as como la nota que queremos
comprobar si es adicional al acorde. El primer paso es recorrer las tres listas, descartando sus elementos hasta encontrar en la lista del acorde actual la nota recibida
como adicional. Hecho esto, hay que aplicar las normas de la armona tradicional
para comprobar si esa nota es adicional: es una apoyatura si esta a tono o semitono
ascendente de la nota siguiente; es nota de paso si sigue la lnea ascendente o descendente de las correspondientes notas del acorde anterior o posterior sin mostrar
un intervalo mayor al tono; es nota pedal si se mantiene entre los tres acordes; es
anticipo si coincide con la nota del acorde siguiente y es un floreo si la nota anterior
y posterior coinciden y la del acorde actual esta a un semitono o tono inferior o
superior.
Cuando ninguno de los casos anteriores se cumple, pasamos a considerar que el
acorde este incompleto: puede tratarse de una u
nica tercera. En este caso, si es una
tercera mayor, la forma prime devuelta sera [4], ante lo que podemos suponer que
pertenece al acorde perfecto mayor correspondiente, pero con la quinta del acorde
sin aparecer. De la misma forma podemos suponer que se trata de un acorde perfecto
menor si la forma prime es [3].
Si ya el acorde no es una tercera u
nicamente, pasamos a tener mayor consideracion: puede tratarse de un acorde incompleto, que por la disposicion vertical de
acordes que se hace en la parte en Java se ha producido su division en dos acordes
cuyo analisis debe ser realizado de una manera conjunta. En este caso, procedemos
primero a fusionar con el anterior y luego con el siguiente. En el caso de fusionar
con el anterior, tenemos que comprobar que el acorde anterior existe (el primer
parametro es distinto de cero). Tras fusionar la lista de notas del acorde actual con
el acorde anterior, restamos todos los -1 encontrados (pues representan silencios), y
2.2. ARQUITECTURA DE LA APLICACION
23
24
que han producido un exito en el reconocimiento del acorde. Como tampoco hay que
descartar que se sustituyan notas con el acorde anterior, a esta lista se le concatena
otra, resultado de realizar un findall usando esta vez el entero de control para indicar
que se sustituyan notas con el acorde anterior. Finalmente, se realiza otra b
usqueda
con sustituye, esta vez usando el entero de control que permite tomar notas del acorde
anterior y del siguiente, concatenando estos resultados a los de la lista anterior.
En el caso de que el acorde se encuentre en parte debil la secuencia de sustituciones es inversa: primero se piensa en sustituir notas tomandolas del acorde anterior;
luego del siguiente y por u
ltimo de los dos. Cuando un acorde se encuentra en parte
debil, por lo general podemos asumir que sus notas adicionales estan derivadas de
las del acorde anterior. Una vez que tenemos la lista con todas las posibles modificaciones del acorde actual tomando notas del anterior y del siguiente, es momento
de usar el entero que en sustituye indicaba el n
umero de cambios realizados. Para
ello se ha definido en el mismo archivo el predicado daMenorModif, que recorre la
lista con las modificaciones y devuelve la primera aparicion cuyo n
umero de cambios
sea el menor de la lista. Es aqu cuando tiene sentido el distinguir primero entre
si sustituir con el acorde siguiente o el anterior, y por tanto el orden en el que se
concatenan las listas de resultados parciales a la general.
Cuando ninguna de estas tecnicas ha dado resultado positivo, llegamos al caso
en el que no se sabe que hacer con el acorde actual, y para ello se utiliza una tupla
especial en la lista de resultados del Analisis Nominal: (66, Dr), que representa que
se ha encontrado un acorde no reconocible con duracion Dr. Sin embargo, durante las
pruebas realizadas en el proceso de desarrollo no se ha encontrado ning
un caso en el
que se produzca un acorde no reconocido, quizas por la diversidad de posibilidades
que se contempla cuando un acorde no esta completo o tiene a
nadidos.
Tipo de acorde
Perfecto mayor
Perfecto menor
Septima de dominante
Quinta disminuida
Menor con septima diatonica
Mayor con septima diatonica
Quinta vaca
Quinta aumentada
Nota u
nica
Forma prime
[0,4,7]
[0,3,7]
[0,3,6,8]
[0,3,6]
[0,3,5,8]
[0,1,5,8]
[5]
[0,4,8]
[]
Entero
0
1
2
3
4
5
6
7
8
Cifrados
0, 1, 2
0, 1, 2
3, 4, 5, 6
7, 8, 9
10, 11, 12, 13
10, 11, 12, 13
0, 14
18
Cuadro 2.1: Correspondencia entre tipos de acorde, su forma prime, el entero con el
que se codifican en la tupla de resultado del Analisis Nominal y los enteros usados
para la codificacion de su cifrado.
Reconocimiento de la tonalidad
Una vez que tenemos determinado el analisis de los acordes recibidos en la entrada, podemos abordar un paso mas: intentar esclarecer cual es la tonalidad de la obra.
Debemos recordar llegado este punto que los ficheros midi no tienen indicacion de
armadura, lo que hara automatica la deteccion de la tonalidad. Ademas, las notas
2.2. ARQUITECTURA DE LA APLICACION
25
26
2.2. ARQUITECTURA DE LA APLICACION
Tipo de acorde
Perfecto mayor
Perfecto menor
Septima de dominante
Quinta disminuida
Menor con septima diatonica
Mayor con septima diatonica
Quinta vaca
Quinta aumentada
Nota u
nica
Entero
0
1
2
3
4
5
6
7
8
Reducido
0
1
3
2
1
0
4
27
Tipo reducido
Mayor
Menor
Septima de dominante
Quinta disminuida
Menor
Mayor
Quinta vaca
Nota u
nica
Cuadro 2.2: Reduccion de los tipos de acorde a aquellos que pueden ser encontrados
en una tonalidad, junto a su codificacion en enteros.
a
nadido no importa a la hora de determinar si ese acorde pertenece a una tonalidad,
ante lo que tiene sentido considerar tipos de acorde en su vision simplificada, para
no cargar as los casos a contemplar en la definicion del predicado tipoAcorde. Es
en este caso donde se permite la existencia del acorde de sexta napolitana: en una
tonalidad menor, el grado 8 (que haba sido asociado antes con el acorde cuya fundamental esta a un semitono ascendente de la de la tonalidad), debe ser un acorde
perfecto mayor. Por u
ltimo, ante el caso de un acorde de quinta vaca, pertenece a
la tonalidad si el grado asociado es de un acorde perfecto mayor o perfecto menor.
Volviendo a daGradoPropio, el proceso se resume a: reducir el tipo de acorde
recibido a uno de los enteros basicos, comprobar si el acorde recibido pertenece a
la tonalidad indicada mediante el predicado grado y, a su vez, obtener el grado
correspondiente a ese acorde en la tonalidad indicada. Por u
ltimo, si el modo del
acorde coincide con el que ese grado tendra en la tonalidad recibida, podemos
afirmar que el acorde pertenece a la tonalidad. As, en cuentaAcordes se permite
saber si un acorde pertenece a la tonalidad, y aumentar por lo tanto la puntuacion
asociada.
Cuando busqTodasTonalis ha realizado el calculo de la puntuacion de todas las
tonalidades respecto a la lista de acordes recibida, para obtener el resultado de esta
heurstica de conteo se recurre al predicado daMasAbundTonal, definido en el archivo
recontonal.pl. Este predicado recibe la lista con las tuplas que asignan a cada dos
enteros que representan una tonalidad una puntuacion y devuelve aquella tonalidad
en la lista con mayor puntuacion. En el caso de igualdad de puntuaciones (algo poco
probable, debido al sistema de bonificaciones), se escoge la primera tonalidad en
la lista cuya puntuacion coincida con el maximo, y es aqu donde tiene sentido el
haber usado la lista con las tonalidades recorriendo el crculo de quintas, ya que se
escogera la tonalidad con menor n
umero de alteraciones.
La tonalidad resultado de esta heurstica es almacenado en una lista temporal,
mediante el predicado ponListaHeurist, definido en el mismo archivo, que hace un
tratamiento especial: recibe el resultado de una heurstica a almacenar y la posible
lista actual de resultados. Si la tonalidad a almacenar no esta en la lista actual, se
almacena al final con un contador inicializado a 1. Si la tonalidad a almacenar esta en
la lista actual, su contador se incrementa en una unidad. Tras almacenar el resultado
de la primera heurstica, se almacena el resultado de la heurstica facilitado por el
28
An
alisis Sint
actico
Realizado el determinar la tonalidad de la obra con el modulo anterior, hay que
abordar el proceso de Analisis Sintactico de los acordes recibidos. Esto se produce
mediante el predicado sacaGrados, definido en el fichero sintaxis.pl, junto a todos los
auxiliares en esta parte del analisis. Este predicado recibe por un lado la lista de
acordes obtenida en el Analisis Nominal, la tonalidad que se ha obtenido mediante
el uso de heursticas y devuelve una lista de tuplas con el resultado del analisis
sintactico. Puesto que la parte en Prolog tiene que devolver a la parte en Java
la tonalidad principal calculada, a partir de la cual se ha realizado el analisis, la
tupla que recibe sacaGrados indicando la tonalidad se pasa como primer elemento
de la tupla de resultados. El proceso de Analisis Sintactico se realiza recorriendo
progresivamente la lista de acordes, mediante el predicado sacaGrados/4, que recibe
como parametros la lista y la tonalidad a partir de la cual realizar el analisis.
sacaGrados analiza siempre el primer acorde en la lista recibida y devuelve en la
lista de resultado una tupla con enteros adicionales que facilitan informacion sobre
el analisis sintactico. Para continuar, se produce una llamada a sacaGrados con el
resto de la lista, a partir de la cual se obtiene el resto de la lista de resultados.
El caso mas sencillo de la definicion de este predicado es aquel en el que el acorde
actual a analizar pertenece a la tonalidad recibida. Sabemos que el acorde pertenece
a la tonalidad usando el predicado daGradoPropio que se explico anteriormente.
Cuando esta llamada tiene exito, el acorde pertenece a la tonalidad, y entonces se
produce una llamada al predicado completa. Este predicado recibe el tipo de la
tonalidad, el grado del acorde y el tipo de acorde. Esta pensado para completar en
aquellos acordes que eran de quinta vaca su informacion, indicando el modo que
correspondera a ese acorde en la tonalidad de referencia. Cuando el acorde no es de
quinta vaca, la llamada a completa no surte efecto.
La lista de resultados esta formada por tuplas de enteros, que codifican la informacion correspondiente. Tras el Analisis Sintactico, las tuplas de resultado ya
tienen completa la informacion del analisis, ante lo que habra que destinar un entero especficamente a cada dato que se quiera devolver. Como resultado del Analisis
Nominal, al modulo de Analisis Sintactico le llegan tuplas con cuatro enteros. Aqu se
ampla esta informacion con dos enteros mas: se mantienen los cuatro enteros recibidos, referentes a la fundamental del acorde, el tipo de acorde reconocido, el cifrado
que le corresponde y la duracion del acorde. En esta etapa se a
naden dos enteros:
2.2. ARQUITECTURA DE LA APLICACION
29
uno que indica que grado es el acorde actual en la tonalidad principal y un entero
denominado Modificador, que en aquellos acordes que no pertenecen a la tonalidad
principal facilita informacion sobre que modificacion se ha realizado en el acorde
actual respecto a su original en la tonalidad de referencia. En el caso mas sencillo de sacaGrados, cuando el acorde pertenece a la tonalidad principal, el valor del
Modificador es -1.
El siguiente caso que se puede presentar es recibir que el acorde actual es de quinta aumentada. Como se ha explicado antes, se ha delegado a esta etapa del analisis
la resolucion del acorde. Sabemos distinguir la tupla del acorde de quinta aumentada ya que el segundo entero tiene valor 7. El principio que se sigue a la hora de
resolver este acorde consiste en buscar aquella posicion del acorde que supone tener
mas notas en la tonalidad principal. Recordemos que un acorde de quinta aumentada es cclico: cualquiera de sus notas puede actuar como fundamental. Ademas,
el caracter cclico de este acorde hace que solo existan cuatro posibles acordes de
quinta aumentada. Como se indico en un apartado anterior, aqu no tiene sentido
guardar en la tupla la fundamental del acorde, puesto que todava no se ha resuelto.
Por eso, en la primera posicion de la tupla de entrada se encuentra la lista de notas
del acorde sin duplicados. Esta lista de notas se va a utilizar para saber cuantas
notas del acorde pertenecen a la tonalidad principal.
Para esto se hace una llamada al predicado daNotasEnTonal, que recibe por
parametro la lista de notas del acorde, la fundamental y el modo de la tonalidad y
devuelve el n
umero de notas del acorde que pertenecen a la tonalidad, as como una
lista con esas notas. Para saber si una nota pertenece a una tonalidad solo hay que
comprobar que esa nota sea la fundamental de un acorde que pueda ser un grado en la
tonalidad. Por esto tiene sentido la division que se explico anteriormente: para saber
si un acorde perteneca a una tonalidad, se comprobaba primero si su fundamental
perteneca al acorde, luego que tipo de acorde correspondera a ese grado y por
u
ltimo si ese tipo de acorde corresponda con el del acorde recibido. Ahora se puede
utilizar parte de los predicados de ese calculo. En concreto, mediante una llamada al
predicado grado podemos ir recorriendo la lista de notas del acorde, de tal manera
que si esa nota pertenece a la tonalidad principal, aumentamos el contador y la
incorporamos a la lista del resultado.
Con la lista de notas que del acorde de quinta aumentada pertenecen a la tonalidad, podemos pasar a buscar su fundamental. Para ello, se utiliza el predicado
daFundQuintAum, que recibe por parametro la lista de notas del acorde en la tonalidad junto a su n
umero y devuelve la fundamental del acorde. Si pensamos en
los cuatro acordes posibles de quinta aumentada, nos damos cuenta que, para una
tonalidad cualquiera, tres de ellos tienen dos notas en la tonalidad y el cuarto tiene
una. Este hecho se utiliza para determinar la fundamental del acorde, manteniendo
que puesto que se trata de un acorde modificado, se busca que haya el mayor n
umero
de notas del acorde en la tonalidad. Ademas, cuando hay dos notas del acorde en la
tonalidad, estas dos notas siempre son consecutivas en el acorde, por lo que forman
un intervalo de tercera mayor. En este caso, vamos a considerar como fundamental
del acorde la nota inferior del intervalo, pues es la que tomandola como fundamental
del acorde que tiene a la otra, deja a la tercera nota del acorde de quinta aumentada como modificacion de la quinta del acorde correspondiente perfecto mayor en la
tonalidad. En el caso de que solo haya una nota de ese acorde en la tonalidad, esa
30
misma nota es la que se va a tomar como fundamental del acorde. De esta forma,
en el predicado daFundQuintAum se procede a calcular si las dos notas recibidas
estan en intervalo de tercera o sexta (su inversion) o si se trata de una u
nica nota,
procediendo entonces a devolver la fundamental siguiendo la norma descrita. Calculada la fundamental del acorde de quinta aumentada, podemos obtener su cifrado,
mediante llamada al predicado cifrado.
Ahora llega el proceso mas complejo del Analisis Sintactico. Cuando un acorde no
pertenece a la tonalidad principal, admitimos que se trata de un acorde modificado, y
entonces, para completar la informacion del analisis, debemos dar datos de como ese
acorde ha sido modificado respecto al que correspondera en la tonalidad principal.
El primer paso a realizar, algo que se entendera posteriormente, es determinar el
ambito de las alteraciones de la tonalidad: si la tonalidad actual trabaja con bemoles
o con sostenidos. Para ello, se utiliza el predicado daAmbito, definido en el archivo
basico.pl. Este predicado recibe como parametros la fundamental de la tonalidad y su
modo, devolviendo en un entero el ambito de la misma (0 para sostenidos y 1 para
bemoles). Aqu se produce una primera solucion del problema de las enarmonas
por la codificacion de notas en enteros: es un primer paso hacia distinguir que, por
ejemplo, el entero 6 (Fa sostenido o Sol bemol) representa como fundamental a
la tonalidad Sol bemol cuando su modo es mayor y no a Fa sostenido, ya que la
primera tiene menos alteraciones: 6 bemoles frente a 7 sostenidos. Esta informacion
esta introducida a modo de hechos para las tonalidades mayores. En el caso de las
menores, su ambito es el mismo que el de su relativo mayor.
Determinado el ambito de la tonalidad principal, se produce una llamada al predicado resuelveGrado, definido en sintaxis.pl. Este predicado recibe como parametros
la fundamental y el modo de la tonalidad, la fundamental y el tipo del acorde a considerar, as como el ambito de la tonalidad, y devuelve de que grado se trata y el
entero con el que indicar la modificacion que se ha realizado del acorde respecto al
de la tonalidad principal. La primera comprobacion que se realiza en resuelveGrado
es ver si la fundamental del acorde corresponde con la de un acorde de la tonalidad
recibida, usando para ello el predicado grado, que se detallo anteriormente. Si esto
se cumple, entonces hay que distinguir dos posibilidades: que el acorde tenga como
tipo el que le correspondera siendo acorde de la tonalidad recibida, ante lo que se
devuelve -1 como valor para el modificador. En el caso de que esto no ocurra, hay
que devolver un entero para el entero Modificador de la tupla de resultado, con el
que indicar que modificacion se ha hecho sobre el acorde de la tonalidad, de tal
manera que es un acorde cuya fundamental s pertenece a la tonalidad, pero cuyo
tipo no corresponde con el que debera tener.
Para ello, se utiliza el predicado cadAjeno, que hace corresponder el tipo reducido
del acorde recibido con un entero que codifica la modificacion que se ha realizado del
acorde. Atendiendo a los valores que se han indicado en el cuadro 2.2, hay que asignar
un entero a la modificacion realizada sobre tipos de acordes reducidos representados
por los enteros 0, 1, 2, 3 y 7. En esa tabla se haba indicado que el entero que
representa el acorde de quinta aumentada no tiene reduccion puesto que no hay
acorde de quinta aumentada en ninguna tonalidad. Sin embargo, en la llamada a
resuelveGrado desde sacaGrados no se haba producido una reduccion del entero que
representa el tipo de acorde, para contemplar este caso como excepcion. Los enteros
usados como codificacion de la modificacion de un acorde aparecen asociados a su
2.2. ARQUITECTURA DE LA APLICACION
Entero
0
1
2
3
4
5
6
7
8
9
10
11
31
n del acorde
Modificacio
Mayor
Menor
Rebajado
Aumentado
Rebajado mayor
Rebajado menor
Aumentado mayor
Aumentado menor
Quinta disminuida
Rebajado quinta disminuida
Aumentado quinta disminuida
Quinta aumentada
Cuadro 2.3: Valores para el campo Modificador de una tupla de la lista de resultado
junto a la modificacion que significa en el acorde correspondiente.
significado en el cuadro 2.3.
Volviendo al caso de tratar la quinta aumentada, la llamada a resuelveGrado nos
ha devuelto el entero a guardar como modificador en la tupla de resultados, con lo
que queda resuelto el acorde, determinandose su fundamental, a que grado pertenece
respecto a la tonalidad principal y el entero que debe representar su modificacion.
sacaGrados se completa contemplando las situaciones adicionales definidas en la
fase de Analisis Nominal: ante un cambio de compas, se mantiene en la lista final
de resultado, ocurriendo lo mismo con un silencio general de todas las voces. En el
caso de un acorde no reconocido, el proposito es informar al usuario de que no se
ha podido realizar ninguna identificacion con ese acorde, ante lo que se mantiene
en la lista resultado la tupla correspondiente, indicando la duracion de ese acorde
anomalo.
Ahora podemos plantear otra situacion: y si el acorde actual en el Analisis
Sintactico no pertenece a la tonalidad? Podemos suponer dos alternativas: que sea
una peque
na modificacion de un acorde de la tonalidad, con el fin de dar colorido, o
que sea el primer acorde de una zona de modulacion. Esta u
ltima alternativa es la
que primero se comprueba en el analisis. Cuando sacaGrados encuentra un acorde
que no pertenece a la tonalidad, se realiza una b
usqueda de una posible modulacion.
Para ello, se utiliza el predicado tonalisPosibles, definido en el mismo archivo. Este
predicado recibe la fundamental y el tipo de acorde y devuelve la fundamental y el
modo de una tonalidad a la que puede pertencer el acorde recibido. Para ello, utiliza
el predicado reduce, para as obtener el entero reducido del tipo de acorde. Luego
se produce una llamada a tipoAcorde para saber, con ese tipo reducido de acorde
y el modo de la tonalidad, que grado de la misma puede ser el acorde recibido. Por
u
ltimo, se produce una llamada a sabeGrado, definido en el archivo basico.pl, que
recibiendo la fundamental de un acorde y el grado que desempe
na en una tonalidad,
devuelve de que tonalidad se trata, mediante el calculo con aritmetica modular. De
esta forma, tonalisPosibles es una manera de obtener todas las tonalidades posibles
a las que puede pertenecer un acorde.
Y es precisamente ese proceso el que se realiza ante un acorde que no pertenece a
32
2.2. ARQUITECTURA DE LA APLICACION
33
34
2.2. ARQUITECTURA DE LA APLICACION
35
2.2.2.
El formato MIDI
MIDI (Musical Instrument Digital Interface) es un protocolo creado en los a
nos
70, estandarizado, que realiza la transmision de los datos a partir de eventos y mensajes (y no de se
nales de audio). El formato MIDI describe una norma de comunicacion
fsica entre los sistemas (conectores, cables, protocolos de comunicacion...) y las caractersticas del lenguaje que hacen posible el intercambio de informacion entre ellos.
Un archivo MIDI se puede entender como una partitura, ya que en sus mensajes
esta almacenados tanto cuando tiene que sonar una nota como las caractersticas de
dicha nota.
Dentro del formato MIDI existen varios tipos:
SMF (Standard Midi File) 0: todas las pistas individuales se juntan en una
u
nica pista. Al cargar el archivo, por ejemplo, con un programa de notacion,
no se distingue a que pista pertenece cada voz.
SMF 1: En este caso las pistas permanecen separadas, lo que facilita su representacion en una partitura.
SMF 2: Es una ampliacion del SMF 1, que cuenta con diferentes patrones de
pistas separadas.
CAPITULO 2. DETALLES DE LA IMPLEMENTACION
36
2.2. ARQUITECTURA DE LA APLICACION
37
nos permita manejar midis en los que las pistas comenzaran en tiempos distintos
(que eran la mayora).
Como solucion a este problema decidimos utilizar el programa midi2abc. Se trata de un programa que dado un fichero midi produce un archivo *.abc (se puede
abrir con un editor de texto). La ventaja de ABC sobre jMusic es que las duraciones
de las notas estan mucho mejor definidas, ademas de que reconoce los instrumentos,
compas, comienzo de pistas, ttulo... Todas ellas son caractersticas de ABC que al
final hemos tenido que utilizar para hacer el procesamiento del archivo MIDI.
CAPITULO 2. DETALLES DE LA IMPLEMENTACION
38
1. Pruebas de pistas, para comprobar que las distintas pistas se separaban correctamente en el analisis.
2. Pruebas con silencios al principio de la partitura, en una voz o en varias,
anacrusas...
3. Pruebas para comprobar si los compases se obtenan bien.
4. Pruebas para comprobar la obtencion de la tonalidad en Java/Prolog
Ademas tenemos que indicar que estas pruebas con midis creados por nosotros
no se han realizado solamente en la fase inicial del proyecto, sino que nos hemos
valido de nuestros propios midis a lo largo de todo el curso. Como ejemplo esta la
creacion de midis con instrumentos definidos en cada pista para la comprobacion de
las etiquedas de los instrumentos en la interfaz.
C
omo se procesan los archivos *.mid
A continuacion explicamos con mas detalle el proceso que siguen los midis, desde
que son leidos hasta que se genera el archivo entradaProlog.txt.
Lectura del fichero MIDI y generaci
on del fichero ABC :
Como hemos indicado, para obtener la informacion del fichero MIDI hemos utilizado la herramienta midi2abc: se trata de un programa que dado un fichero *.mid
genera un archivo *.abc, es decir, traduce el archivo midi a formato ABC.
La ejecucion del programa midi2abc desde nuestra aplicacion Java se ha hecho
a traves de una llamada al sistema operativo (igual que la llamada al analizador de
Prolog).
Teniendo en cuenta que la sintaxis desde lnea de comandos para ejecutar midi2abc es
midi2abc -f ficheroEntrada [-o ficheroSalida]
la llamada realizada desde Java ha sido Process p = Runtime.getRuntime().exec(
cmd /C start midi2abc -f rutaMIDI rutaABC); p.waitFor(); Una vez realizado esto,
en el directorio raiz del proyecto se encuentra un fichero *.abc que contiene el MIDI
indicado traducido a formato ABC.
Tratamiento del fichero ABC para la obtenci
on del objeto Score :
Una vez generado el fichero ABC, se procede al parseo del mismo. Para ello
leemos el fichero y analizamos las lneas que nos interesan:
Longitud de la nota mas corta
Armadura
Nueva voz
Instrumento
Lista de notas
2.2. ARQUITECTURA DE LA APLICACION
39
40
2.2. ARQUITECTURA DE LA APLICACION
41
42
Simplificaci
on de los acordes : Tras el proceso de analisis inicial hemos conseguido una lista de acordes, todos de igual duracion. El siguiente paso es unir los
distintos acordes para obtener as, ademas de los acordes en s, la duracion real de
cada uno. Con este fin, para cada acorde de la lista inicial de acordes:
1. Se compara cada acorde con el siguiente.
2. En caso de que sean iguales, se funden los dos acordes, sumandole la duracion
del segundo a la duracion que tena el primero.
Generaci
on del fichero de entrada a Prolog : Como u
ltimo paso esta la creacion del archivo que servira como entrada al analizador en Prolog. Este fichero debe
tener una estructura concreta, para que el analizador en Prolog lo pueda interpretar correctamente. La estructura la podemos representar a traves de una expresion
regular:
fichero = [ (tono,modo),(acorde)(,(cambioCompas,)? (acorde)+)*]
Es decir, una lista en la que el primer componente sera siempre el par tono-modo
que indicara la tonalidad de la partitura, seguido de una lista de uno o mas acordes.
Los acordes estan separados por comas y en ocasiones, entre acorde y acorde, se
genera una marca de cambio de compas.
Las distintas partes de la expresion regular se definen as:
tono = [0..11]. 0 representa la nota DO, 1 la nota DO#/REb, 2 la nota RE...
modo = [0,1]. 0 indica que el modo es mayor, 1 que es menor.
cambioCompas = 20.
acorde = duracion , [ listaNotas ]. Un acorde viene indicado, en primer lugar, por
su duracion, y en segudo lugar por la lista de notas que lo forman. En caso de que
el acorde sea parte fuerte, su duracion se ve incrementada en 20.
listaNotas = nota; listaNotas = nota , listaNotas es una nota seguida de una lista
de notas, o simplemente es una nota. La nota viene representada por un enter [0..1],
igual que en el tono.
2.2. ARQUITECTURA DE LA APLICACION
2.2.3.
43
Interfaz gr
afica
La interfaz grafica de la aplicacion ha sido implementada en Java 1.5.05, concretamente usando Swing. A traves de ella, el usuario tiene todo el control de la
aplicacion.
El usuario podra abrir un fichero midi para ver su analisis, editar la partitura, actualizar el analisis, reproducir la partitura y consultar la ayuda. La interfaz es el
modulo que tiene el control de la aplicacion, y hace uso del procesador midi y del
analizador cuando es necesario.
La interfaz esta compuesta del paquete gui, aunque en ocasiones, usa las clases
de los paquetes constantes y utilidades, que explicaremos mas adelante. Tambien hay
que destacar que para cambiar el aspecto a la interfaz hemos usado distintos Look
And Feels.
A continuacion vamos a describir las clases que hay dentro de cada paquete:
Paquete gui
Es el paquete que contiene todas las clases relativas a la interfaz.
BotonAcorde
Se usa cuando estamos leyendo el resultado del analisis que nos devuelve el
analizador mediante el fichero salidaProlog.txt. Se usa para almacenar toda
la informacion necesaria para poder despues dibujar todos los botones de los
acordes de forma correcta. Como se puede ver por los atributos de esta clase,
la informacion necesaria es el ancho que tiene que tener el boton, la fundamental, el tipo de acorde, el cifrado, la duracion, el grado, el grado ajeno y
una cadena de caracteres adicional para cuando sea un acorde ajeno, el tooltip
que queremos poner al boton cuando lo dibujemos, el n
umero de boton y el
n
umero de compas en el que esta el boton.
BotonAnalisis
Contiene la misma informacion que la anterior, salvo que ademas tiene un
atributo booleano llamado botonAcorde que si es true nos indica que el boton
muestra el grado del acorde. Si es false, nos indica que el boton muestra la
inversion del acorde. Este booleano tiene su importancia, porque los botones
de grado tienen borde y los de inversion no, y a la hora de mostrarlos en
pantalla hay que tenerlo en cuenta.
FiltroFicheros
Hereda de la clase FileFilter que viene incluida en Java. Esta clase sirve para
que, cuando se abre un cuadro de dialogo para abrir o guardar un fichero, solo
se muestre el tipo de ficheros que nos interesen. En nuestro caso, los u
nicos
ficheros que nos interesan son aquellos que tienen como extension .mid.
MuestraMensaje
Es una clase muy simple, pero muy usada en la implementacion de la interfaz.
Lo u
nico que hace es mostrar un mensaje del tipo que queramos. Su constructor
tiene los siguientes parametros: el mensaje que vamos a mostrar, el ttulo de la
ventana del mensaje y el tipo del mensaje. El tipo puede ser error, informacion
y confirmacion. El mensaje que muestra es un JOptionPane.
44
2.2. ARQUITECTURA DE LA APLICACION
45
Los metodos de accion como abrirMidi, analisis, salir, etc., son abstractos y
estan implementados en su clase hija.
AbstractVentanaPrincipal
Es la clase hija de IVentanaPrincipal y en ella se implementan los metodos
de accion, es decir, aquellos metodos que son ejecutados cuando el usuario
presiona un boton de accion de la interfaz como el boton para abrir midi,
actualizar el analisis, consultar la ayuda o anterior y siguiente al visualizar
una partitura. Es una clase abstracta, al igual que la anterior, cuya clase hija
es VentanaPrincipal. Uno de sus metodos abstractos es rellenaPanelAcordes que
lo comentamos mas abajo.
VentanaPrincipal
Al igual que la clase anterior se encarga de ejecutar las acciones que solicita el
usuario, VentanaPrincipal se encarga de realizar los cambios visuales. Por ejemplo, cuando se abre un nuevo fichero midi o cuando se actualiza un analisis,
el analisis que se muestra por pantalla tiene que cambiar. Es decir, se encarga
del contenido dinamico de la interfaz. Pues bien, la clase anterior, cuando el
usuario quiere hacer una de estas dos cosas, llama al metodo rellenaPanelAcordes despues de seleccionar un fichero y de llamar al procesador midi, que
genera entradaProlog.txt y al analizador, que genera salidaProlog.txt usando
entradaProlog.txt como entrada. Pues bien, este metodo, rellenaPanelAcordes,
lee salidaProlog.txt a traves de un automata finito, siguiendo los pasos necesarios para interpretar correctamente la informacion del analisis, tal y como se
explica en la parte del analizador. El automata es el siguiente:
46
2.2. ARQUITECTURA DE LA APLICACION
47
10. Si la variable dibuja es true, dibujamos los botones de los acordes y metemos separadores en todas las cajas que contienen los botones de acordes,
tonalidad, duracion, etc., porque en este estado, entramos cuando nos encontramos un nuevo compas en salidaProlog.txt. Tambien incrementamos
numeroCompas y actualizamos dibuja y dibujaAnt.
11. En este estado entramos, como se puede ver en el automata cuando hay
una zona doble, es decir, una zona con modulacion. Si dibuja es true,
ponemos hayZonaDoble a true y llamamos al metodo dibujaBotonesAcordesZS para que se dibujen todos los botones que queden por dibujar
de la zona anterior sin modulacion. Ademas leemos la fundamental que
vamos a mostrar para la modulacion.
12. Leemos el tipo de acorde que vamos a mostrar para la modulacion.
13. Si dibuja es falsa y dibujaAnt es cierta, se dibuja la flecha (o lnea) que
abarca a todos los botones afectados por la modulacion.
14. Estado que se ejecuta cuando nos encontramos un nuevo compas en salidaProlog.txt en una zona con modulacion o zona doble. Es muy similar
al estado 10.
15. Leemos la fundamental en una zona con modulacion.
16. Leemos el tipo de acorde del acorde actual en una zona con modulacion.
17. Leemos el cifrado en una zona con modulacion.
18. Leemos la duracion en una zona con modulacion.
19. Leemos el grado en una zona con modulacion.
20. Leemos el grado ajeno.
21. Leemos el modificador en una zona con modulacion.
22. Dibujamos los botones de la zona doble.
23. Dibujamos la lnea que afecta que abarca los botones de las acordes a los
que les afecta la modulacion.
24. Ha ocurrido un error en el analisis. Paramos el analisis y mostramos un
boton de acorde cuyo texto es error.
25. Nos encontramos un silencio en una zona sin modulacion. Asignamos
a fundamental y tipoAcorde la cadena vaca y leemos la duracion del
silencio de salidaProlog.txt.
26. Dibujamos el boton de silencio.
27. Nos encontramos un silencio en una zona con modulacion. Hacemos lo
mismo que en el estado 25.
28. Dibujamos un boton de silencio de una zona con modulacion.
29. Ignoramos la entrada porque no hay que dibujar. Se incrementa el contador en seis unidades para leer la informacion del siguiente acorde. La
razon de que exista un estado como este es que, cuando dibuja es false,
podemos ignorar mucha informacion ahorrando as mucho trabajo a la
aplicacion. El incremento del rendimiento es muy considerable gracias a
este estado.
CAPITULO 2. DETALLES DE LA IMPLEMENTACION
48
Paquete constantes
Captulo 3
Incidencias en el desarrollo
En esta parte, vamos a hablar sobre las dificultades con que nos hemos encontrando a lo largo de todo el desarrollo, como se han ido solucionando y la ayuda que
hemos recibido de otras personas.
3.1.
Problemas y soluciones
Uno de los principales intereses que haba en la librera jMusic era su capacidad para mostrar partituras, algo que no se haba encontrado en otra librera. Los
resultados parecan ser bastante interesantes, pero el panorama cambio conforme
nuestro desarrollo evolucionaba. El primer problema lo tuvimos al darnos cuenta de
que los compases no aparecan alineados en vertical, de tal manera que la lnea de
fin de compas no coincida en cada una de los pentagramas representados. Puestos
en contacto con los desarrolladores de jMusic, se nos indico que eso no tena solucion
y que habra que realizar el proyecto desde cero para solucionarlo. Sin embargo, un
analisis del codigo utilizado nos permitio llegar a una solucion realmente u
til. Los
tipos de pentagramas que jMusic puede representar son: un pentagrama con clave
de Fa (BassStave), un pentagrama con clave de Sol (TrebleStave), un sistema de
dos pentagramas para la escritura pianstica (PianoStave) y algo que pretenda ser
una modificacion para alg
un instrumento o agrupacion instrumental con un ambito extenso, pero que luego ni siquiera es contemplado en las clases de la librera
(GrandStave). Estas cuatro clases derivan de una clase llamada Stave, donde se definen algunos metodos comunes a ellas.
El metodo paint() de cada clase estaba escrito para, a partir de la informacion
almacenada en la frase asociada al pentagrama ir colocando las imagenes en la
representacion grafica. As, se dibuja primero las lneas del pentagrama, luego la
clave o claves correspondientes, la armadura y la indicacion de compas y finalmente
empieza a colocarse nota por nota. El principal problema es que cada clase utiliza
su propia definicion del metodo paint(), lo que hace que haya mucho codigo repetido
entre las clases, de tal manera que una modificacion en ello sea muy costosa. Nuestra
primera solucion fue incorporar todo codigo com
un a las clases derivadas de Stave en
esta, utilizando una gran definicion del metodo paint() de esta clase para proceder
a la colocacion de las notas. Como hay informacion que no puede ser compartida
entre las clases, se definio una variable protegida de tipo entero en la clase padre de
tal forma que en el constructor de cada clase hijo se almacenara para la instancia
49
50
51
52
el ancho, se utiliza una constante definida para saber cuantos compases se muestran
por pagina: se consideran tantos compases por pagina como la suma de sus anchos
no exceda el ancho en pxeles asignado a cada pagina.
A nivel de codigo de Stave, una vez mas, la modificacion era facil debido a que se
haba reunido el codigo en una sola clase. Hubo que usar una variable para ir contando el n
umero de compases. En cada llamada al metodo paint() de cada pentagrama,
el codigo de jMusic lo que hace es recorrer todas las notas de la frase musical y
las va colocando en el doble buffer. Se tuvo que a
nadir la comprobacion para que
solo fueran a
nadidas a la imagen virtual aquellas notas que se sit
uen los compases
correspondientes a la pagina actual de pintado, lo que se consigue facilmente usando
sentencias condicionales. De esta manera, cuando el usuario presiona el boton para
avanzar o retroceder pagina, se cambia en la clase Stave unos enteros que indican
desde que y hasta que compas representar y en la ejecucion del metodo paint() esta
comprobacion se hace constantemente.
El uso de paginacion soluciono los principales problemas: el consumo de memoria
se redujo drasticamente al usar solo un fragmento de la representacion grafica que
queramos, ademas de poder controlar el tama
no asignado a la imagen del doble
buffer. Tambien la interfaz grafica quedo mucho mas agradable al usuario, al no
tener que usar tanto las barras de desplazamiento para visualizar una partitura y
poder desplazarse por esta usando paginas.Sin embargo, llego a otro problema: la
edicion de la partitura. jMusic tiene una clase asignada al tratamiento de eventos
que ocurren sobre los pentagramas, llamada StaveActionHandler.
Cuando con el raton se pincha sobre una nota y se desplaza, esta nota es modificada (ya sea en altura o en duracion). La manera que tiene el codigo de saber
sobre que nota se ha hecho clic es ir almacenando en un vector el n
umero de nota
en la frase junto a la posicion horizontal en pxeles a la que esta se sit
ua. Despues,
tomando del evento del raton la posicion horizontal en la que ha ocurrido, se recorre ese vector buscando la nota correspondiente, tomando la posicion en la que
se encuentra y modificando entonces en la frase la nota en la misma posicion. Al
usar paginacion, esto solo funciona en la primera pagina, ya que en las siguientes las
notas estan desplazadas respecto a su posicion total en la frase. Para solucionar esto
hubo que implementar un contador de notas, de tal manera que para cada nota se
supiera cuantas iban antes que ella, en la pagina y as, a la hora de detectar que nota
se haba modificado, se sumara el n
umero de notas que haba antes de la actual a la
posicion obtenida en el vector correspondiente, y as modificar la nota adecuada en
la frase musical.
Con la edicion tambien se detecto otro problema: el modificar la duracion de las
notas provocaba que todo se desencajara verticalmente, ya que la voz correspondiente en la que se realizaba la modificacion llegaba a ocupar mas o menos. Para
solucionar esto, se ha desactivado el tratamiento del evento que ocurre cuando el
usuario arrastra horizontalmente el raton, intentando modificar la duracion de las
notas. Solo se permite modificar la altura de una nota existente, manteniendo su
duracion. Ocurre algo parecido con el a
nadido de las notas: en el tratamiento de un
evento, si el clic se ha hecho en una zona en la que no hay notas, se a
nade una nueva
en la frase musical en la posicion relativa al clic dentro de la partitura, desplazando
a las siguientes. Esto, de nuevo, lleva a un desajuste de las voces, maxime cuando
no se permite el borrado de una nota a
nadida, lo que puede llevar a equivocacion
53
54
La solucion que primero se nos ocurrio fue intentar localizar en el codigo del MIDI
el comienzo de cada pista, y asignarle instante de comienzo correcto, pero esta
solucion no era viable, ya que ponernos a manejar el flujo de bytes del midi con este
fin lo veamos completamente imposible. Como segunda solucion pensamos hacer lo
siguiente: ya que el problema estaba solo al comienzo de cada pista, pero a partir
de ah pareca que la medida se mantena bien, podamos intentar insertar una nota
al comienzo de todas las pistas, para asegurarnos de que todas comenzaban en el
instante 0.0 de tiempo. Esta solucion se intento implementar a traves del programa
abc2midi. El proceso era el siguiente: leamos un fichero MIDI ejecutando midi2abc, al
fichero resultante le introducamos una nota al comienzo de cada track, generabamos
un nuevo midi gracias a abc2midi y por u
ltimo procesabamos este midi. La idea era
muy buena, pero jMusic resulto dar fallos en varios sitios, no solo en el startTime,
y el analisis segua descuadrandose. Como u
ltima opcion se nos ocurrio tratar todo
el fichero generado por ABC, parsearlo y convertirlo a un objeto Score para, a
partir de ah, poder continuar con nuestro analisis igual que lo hacamos antes.
Aprovechabamos as que los ficheros generados por midi2abc tenan una estructura
rtmica mucho mejor definida que jMusic (como detalle, indicar que ABC genera
barras de compas y jMusic no). De esta manera conseguimos finalmente una lectura
de midis normal, sin sobresaltos a no ser que ABC incluyera en la generacion alg
un
caracter extra
no (por ejemplo, dosillos, tresillos...).
Siguiendo con los problemas del jMusic, otro de ellos fue que no reconoca el
compas de una partitura: siempre era 4/4. En un principio (antes de usar ABC) se
realizaba una pasada por el codigo de bytes del midi, y se buscaba la cadena de bytes
que indicaba el compas. En un principio funciono correctamente, pero al comenzar
a utilizar ABC comprobamos que este tambien resolva el compas. Evidentemente,
entre realizar una pasada por el codigo de bytes del MIDI o leer una lnea del
fichero ABC en la que se indicaba el compas, nos quedamos con esta u
ltima solucion
(as tambien mejoraba un poco el rendimiento de la aplicacion).
En cuanto a salvar los cambios que realizasemos en una partitura mediante un
fichero midi, JMusic tampoco lo haca correctamente. Este problema ha quedado
sin solucion debido a los numerosos contratiempos que hemos tenido con JMusic.
Haba problemas a los que les hemos dado mayor prioridad como son la alineacion
vertical de los compases o la lectura de ficheros midi. La solucion habra sido pasar
el objeto Score a notacion ABC y ejecutar luego abc2midi para generar el midi
correspondiente, y ya tendramos la funcionalidad de salvar un fichero midi.
Y para terminar con los problemas de jMusic, se
nalar que este no indicaba los
instrumentos utilizados en cada pista (a pesar de tener un campo especfico para
ello). La solucion volvio a ser el fichero ABC generado para procesar las notas.
Gracias a ese fichero, y a un traductor que construimos que nos devolva la cadena
asociada al instrumento que representaba la nota, hemos podido mostrar, tanto en
la partitura como el cuadro que solicita al usuario las pistas que quiere utilizar, los
instrumentos seleccionados.
3.2.
Ayudas y contactos
Una de las principales ayudas para el modulo de analisis fue la de Larry Solomon.
Su teora era conocida por el profesor director de este trabajo quien, ante el problema
55
que tenamos por todo el trabajo que haca Prolog al reconocer acordes, nos propuso
usar su teora musical. Se ha explicado antes que el calculo de la forma prime supone
realizar una serie de calculos numericos con las notas de un acorde para obtener una
secuencia numerica que identifica de forma unvoca cada tipo de acorde. Esto avanza
mucho trabajo en el proceso de Analisis Nominal, de tal manera que facilito las cosas.
Sin embargo, el principal problema es que considera por igual las notas presentes
en un acorde, independientemente del n
umero de apariciones. Esto era problematico
en el reconocimiento de acordes que tuvieran alguna nota a
nadida, ya que esta nota
pasaba a tener igual importancia que las del acorde al quitar los duplicados.
Nos pusimos en contacto con el para explicarle la situacion que habamos detectado, y como en un acorde de Do Mayor, con las tres notas que lo forman varias
veces presentes en un gran acorde, si se a
nada un La, la forma prime devolva que
se trataba de un acorde de La menor con septima diatonica. En concreto, el correo
electronico que le enviamos fue el siguiente:
Somos estudiantes de Informatica que estamos desarrollando un proyecto sobre
reconocimiento armonico. La idea es dar un fichero midi a la aplicacion como entrada
y entonces reconocer los acordes utilizados. Para restringir la b
usqueda en Prolog,
estamos tomando cada acorde y, a partir del calculo de su forma prime, saber as de
que tipo de acorde se trata (por ejemplo, Sol Mayor).
El problema es que pensamos que el calculo de la forma prime da igual relevancia
a cada nota en el conjunto del acorde debido a la eliminacion de duplicados. Supongamos que tenemos el siguiente conjunto de notas: Do Mi Sol Sol Mi Mi Sol Sol Do
Do Sol Mi La. Esta nota La es una nota de paso entre dos, una del acorde anterior
y otra del siguiente, por lo que La no pertenece al acorde de Do Mayor. Usando el
calculo de la forma prime, este acorde es reconocido como La menor con septima en
vez de Do Mayor con una nota adicional.
Que nos aconseja que podemos hacer para evitar esto?
La respuesta de Larry Solomon fue muy rapida y quizas esclarecedora:
Habeis tocado uno de los principales problemas del analisis armonico que todava no esta resuelto, llamado la Teora de la Particion, que consiste en como
decidir que notas de un acorde le pertenecen y cuales no. No hay ninguna teora
generalmente aceptada sobre esto, pero creo que en mi website hay algo al respecto,
en el apartado de MAS y Set Theory. Basicamente, pienso que es necesario realizar
un analisis estadstico preliminar sobre cada acorde, para establecer la consistencia
del lenguaje armonico, reduciendo los acordes con sus a
nadidos a unos pocos acordes
esenciales que aparecen recurrentemente. Entonces, hay que buscar de nuevo esos
acordes.
En la m
usica tradicional, esta recurrencia esta claramente instaurada: sabemos
que hay unos tipos basicos de acordes que hay que buscar, establecidos por la tradicion. Sin duda, la solucion mas simple (y mas elegante) es la preferida, al igual que
ocurre en la ciencia. Sin embargo, en muchas de las obras contemporaneas del siglo
XX, por ejemplo en las de Schomberg, no hay establecido ning
un lenguaje armonico.
Establecer particiones en ese tipo de m
usica es una pesadilla.
Por lo tanto, tambien esta el problema de como explicar las notas adicionales de
un acorde (aquellas que no pueden ser consideradas dentro de el). Una mnima parte
de este problema esta en la definicion de tonos no armonicos (comprueba en mi web
el ensayo sobre este asunto). Incluso en un analisis armonico tradicional, es posible
56
llegar a varios y diferentes, aunque todos correctos, resultados para la misma obra.
57
58
Captulo 4
Manual de usuario
4.1.
Requisitos
4.2.
Instalaci
on
Para la instalacion del Analizador Armonico, aparte de tener instalado JRE como
hemos comentado antes, lo u
nico que hay que tener es una copia de la aplicacion.
Una vez hayamos conseguido la copia, lo u
nico que hay que hacer es guardarla en
59
60
nuestro disco duro en la carpeta que queramos y ya estara la aplicacion lista para
funcionar.
4.3.
4.3.1.
Ejecuci
on y manual de uso
Ejecuci
on
4.3.2.
Manual de usuario
En el manual de usuario, veremos paso a paso como usar la aplicacion. Hay que
destacar que la aplicacion tiene ayuda, que podemos consultar para cualquier duda
que nos pueda surgir.
Nada mas arrancar la ejecucion con ejec.bat en Windows o ejec.sh en Linux, vemos la siguiente pantalla:
Y MANUAL DE USO
4.3. EJECUCION
61
Abrir Midi
es el que usamos para abrir un fichero midi. Cuando pulsamos
El boton
sobre el siguiente boton, se dan una serie de pasos. Lo primero que vemos es un
cuadro de dialogo como este para seleccionar el fichero que queremos abrir:
Una vez seleccionado el fichero que deseamos, la interfaz llama al procesador midi
para generar entradaProlog.txt. Una vez generado este fichero, se muestra una lista
de instrumentos (o de voces) que tiene el fichero midi, para que el usuario pueda
elegir que voces se consideran al realizar el analisis. Una vez seleccionados los instrumentos, se llama al analizador en Prolog para que genere salidaProlog.txt. Y por
u
ltimo, cuando el analizador ha terminado su trabajo, la interfaz lee salidaProlog.txt
y muestra el analisis generado por pantalla, as como los pentagramas de las voces
seleccionadas. Obtendramos una pantalla similar a esta:
62
Reproducir una partitura
Si tenemos una partitura cargada que hemos modificado, al presionar el boton play
se reproducira la partitura modificada, no la cargada inicialmente al abrir un fichero
midi.
Consultar la ayuda
Hemos incluido ayuda en formato html para que el usuario pueda guiarse para
usar la aplicacion. La ayuda incluye una breve explicacion de para que sirve un
analizador de armona musical y que es capaz de hacer, as como los pasos a seguir
para usar correctamente la aplicacion. Se puede navegar por la ayuda a traves de
los enlaces que tiene como si fueran paginas web.
Y MANUAL DE USO
4.3. EJECUCION
63
64
Captulo 5
Caractersticas y mejora de la
aplicaci
on
A continuacion vamos a describir las caractersticas de la aplicacion, as como
las mejoras que se podran realizar, como podran llevarse a cabo y cuanto esfuerzo
costara.
5.1.
Caractersticas
El analizador armonico musical cumple la funcion para la que fue creado, que
es realizar un analisis de la armona de una forma inteligente y efectiva. Como
comentaremos mas adelante, hay muchas cosas que se podran mejorar y ampliar,
pero este analizador tiene caractersticas muy interesantes.
Una caracterstica del analizador es que sienta unas bases firmes para lo que en
un futuro podra ser una aplicacion musical de mucha mas envergadura. Si se llevasen
a cabo las ampliaciones y mejoras que podran realizarse, muchas de ellas facilmente
implementables si se diesen unas determinadas condiciones, como que en futuras
versiones de JMusic muchos fallos actuales fuesen corregidos, este analizador podra
convertirse en una aplicacion muy completa e interesante para una gran cantidad de
personas interesadas en la m
usica. Ademas de ser una aplicacion muy interesante,
podra usarse para la formacion de estudiantes y de m
usicos.
Ademas, el hecho de que sea muy modular, hace que sea muy facilmente mantenible, y ampliable. Esto, como todos sabemos, es algo muy importante en una aplicacion, y en este punto, nuestro analizador cumple perfectamente. Esta caracterstica,
hace viable que pudiera ser el principio de una aplicacion mucho mas practica y potente. El uso de Java en la implementacion, que no es un lenguaje difcil de dominar
y que es un lenguaje orientado a objetos, facilita mas todava estas tareas.
Otra de las caractersticas de JMusic es su sencillez, lo que hace que cualquier
persona pueda usar el programa. Para la correcta interpretacion del analisis y de la
partitura, logicamente, hay que tener ciertos conocimientos de solfeo.
El analizador de nuestra aplicacion, que es su punto fuerte, ha sido implementado de manera rigurosa. Para la implementacion del analizador, as como las demas
partes pero especialmente en esta, hemos buscado informacion sobre distintas tecnicas que podramos seguir. En ello ha colaborado activamente, como en los demas
65
66
problemas que hemos tenido, nuestro tutor Jaime, en diversas reuniones que hemos
tenido a lo largo de todo el a
no.
Esta aplicacion, en definitiva, es una aplicacion sencilla pero cumple lo que promete. La parte del analizador armonico es la mas elaborada, por ser la mas importante de ellas.
5.2.
Qu
e se puede mejorar
En nuestro analizador de armona musical hay varias cosas que se pueden mejorar, como en cualquier aplicacion.
La mayor parte de los problemas con los que nos hemos enfrentado han surgido
por el mal funcionamiento de JMusic. Si no hubiese sido as, la aplicacion hubiera
contado con mas funcionalidad de la que tiene.
Se podra mejorar por ejemplo, la edicion de partituras, ya que, por problemas
con JMusic, hemos tenido que limitar la edicion de partituras a cambiar la altura de
las notas. Originalmente, en JMusic, existe la posibilidad de a
nadir notas, borrarlas,
etc. Tambien sera interesante a
nadir a JMusic la posibilidad de a
nadir nuevas voces
a una partitura, tambien podramos cambiar el instrumento, etc. En definitiva, que la
aplicacion fuera ademas de un buen analizador un potente editor. Esto tendra mucho
interes por ejemplo, tanto en ejercicios de analisis como en tareas de composicion.
Esta es una mejora que dara mucho juego y que hara del analizador armonico
musical una aplicacion mucho mas interesante todava, aunque para que esta mejora
fuese realmente practica, debera ir acompa
nada de la posibilidad de salvar ficheros
midi.
Otra cosa que podra mejorarse es la interfaz. Por ejemplo, en los ficheros sin modulacion, el analisis podra aparecer mas cerca de la partitura y as el usuario podra
visualizar simultaneamente mas cosas. La interfaz ademas, es algo muy subjetivo y
que a unos puede gustar mas y a otros menos, por lo tanto, aqu las posibilidades
de mejora son infinitas.
Tambien podra mejorarse la lectura y el proceso de ficheros midi, para que leyese
obras con dosillos y tresillos, ya que, la aplicacion no es capaz de leer todos los ficheros
midi. Lo ideal sera que JMusic hiciera bien esto, ya que esta implementado, y que
nosotros no hubieramos tenido que usar ABC para hacer este proceso. Esto hara al
analizador mas simple, ya que ahora se construye el objeto Score a partir de ABC
pista a pista y despues lo volvemos a recorrer pista a a pista para generar el analisis.
El codigo de JMusic tambien admite muchsimas mejoras. Esto no es parte de
nuestro proyecto, pero sera interesante optimizar el codigo porque podra verse
muy afectado el rendimiento. Una de las mejoras mas importantes que le hemos
introducido al codigo de JMusic es la paginacion, y ha incrementado notablemente
el rendimiento, al tener que hacer menos trabajo por solo mostrar una parte de la
partitura y del analisis y ademas, ha reducido muchsimo el consumo de memoria, ya
que con el codigo original de JMusic la aplicacion lanzaba excepciones de memoria.
En el codigo de JMusic se usan metodos de Java que estan cayendo en desuso y
que deberan ser sustituidos por los nuevos metodos para asegurar la continuidad
de la librera a medida que salen nuevas versiones de Java, pero eso es algo que
corresponde a los desarrolladores de JMusic.
Tambien es posible modificar el analizador en Prolog para que interprete acordes
67
5.3.
Posibles ampliaciones
68
Captulo 6
Conclusiones
Durante todo este curso trabajando en esta aplicacion hemos aprendido muchas
cosas. Es muy importante la planificacion y saber en todo momento que es exactamente lo que se quiere hacer. Esto lo hemos tenido claro durante todo el curso, pues
cada uno de nosotros tena clara cual era su funcion. En ocasiones, hemos tenido que
ayudarnos unos a otros para poder seguir adelante con problemas que se nos han
resistido, de forma que tambien ha habido, como es de esperar, trabajo en equipo.
En algunos momentos hemos visto que nos aparecan demasiados problemas y
cuando todo iba mejor, volvan los problemas. Pero la mayor parte de ellos han sido
superados a base de esfuerzo y constancia.
Como hemos comentado antes, esta aplicacion puede servir perfectamente para
ser la base de otra mas completa, y si no es as, al menos, merece la pena pensar que
la implementacion que hemos realizado, la informacion que hemos recopilado y las
tecnicas que hemos seguido les puedan servir de gua a otros alumnos que realicen
proyectos relacionados.
Estamos contentos con el desarrollo y el trabajo realizado durante todo el curso.
Sabamos que era una tarea complicada, pero desde el principio estaba claro lo
que haba que hacer y cada uno tena su parte de trabajo totalmente separada del
trabajo del otro. La organizacion del trabajo, en este sentido, ha sido satisfactoria.
Cuando uno de nosotros tena una nueva version de lo que estamos desarrollando,
simplemente haba que cambiar la version anterior por la nueva en la interfaz y de
la forma mas sencilla, ya funcionaba la nueva version con todo lo demas. Muy pocas
veces haba que realizar alg
un cambio en el codigo de la interfaz para integrar una
nueva version. Esto tambien ha facilitado enormemente el trabajo entre los tres, y
ha sido el mayor acierto que hemos tenido durante todo el desarrollo.
Tambien hemos aprendido que informatizar la m
usica no es una tarea facil.
Solo el proceso de leer un midi, tiene mucha mas complejidad de lo que puede
parecer. A partir de ah, las complicaciones se multiplican. Solo representar una
partitura en un programa informatico es una gran complicacion, ya que no hay
tantas herramientas que faciliten esto. Por ejemplo, en un principio pensamos en
usar Lylipond para representar las partituras. Lylipond permite crear un fichero pdf
a partir de un fichero de texto con las especificaciones de la partitura en un lenguaje
parecido a Latex. El problema de esto, es que no nos permite editar la partitura y
habra que mostrarla en una ventana diferente a la de la aplicacion, porque habra
que lanzar el lector de pdf predeterminado del sistema. Desechamos esta solucion en
69
70
CAPITULO 6. CONCLUSIONES
cuanto conocimos JMusic, porque era muy interesante la opcion de que el usuario
pudiera cambiar una partitura y pudiera ver los efectos de esos cambios en el analisis.
Aunque la implementacion haya tenido dificultades en algunos momentos, ha
merecido la pena todo el trabajo realizador, el trabajo en equipo y el resultado ha
sido satisfactorio, porque hemos conseguido implementar lo que nos proponamos.
Ademas, tambien hemos aprendido mucho en el campo de la programacion. Aunque todos sabamos programar en Java, esta aplicacion ha servido para que ampliemos mucho mas nuestros conocimientos sobre este lenguaje y hayamos tenido que
implementar cosas con las que nunca antes nos habamos enfrentado. Esto hace que
el dominio del lenguaje sea mucho mayor. Aunque la novedad mas importante ha
sido el analizador en Prolog, ya que nosotros no sabamos demasiado sobre Prolog.
La posibilidad de implementar este analizador, nos ha hecho entrar de lleno en la
implementacion en Prolog, de la que tenamos una ligera idea, ya que el analizador
es un modulo de bastante complejidad que usa muchsimas reglas y heursticas para
llevar a cabo el analisis. Es la base de nuestra aplicacion.
La implementacion de un sistema experto, en este caso experto en analisis
armonico, no es normalmente una tarea facil y no lo ha sido en este caso. Para
llevar a cabo este objetivo, han sido determinantes la ayuda de nuestro profesor director y nuestra capacidad para buscar informacion por nuestra cuenta, sobre todo
por Internet, ya que, los problemas que no nos han surgido por JMusic, han sido
problemas conceptuales en las partes del analizador y del procesador midi, y tpicos
problemas de programacion en los tres modulos que forman la aplicacion, e Internet
es la mejor herramienta para encontrar informacion muy especfica.
Por u
ltimo, hay que comentar que, si todo nos hubiera salido como esperabamos
con JMusic y hubiera funcionado de forma correcta, hubieramos tenido mucho mas
tiempo para mejorar la aplicacion y para incluir nuevas funcionalidades. Al menos,
es muy importante que, si alg
un da, estos problemas son solucionados en JMusic,
es muy facil adaptar la aplicacion para que aproveche todas estas mejoras, as como
sera bastante sencilla su ampliacion.
Captulo 7
Bibliografa
Para la elaboracion de esta aplicacion as como para profundizar en los contenidos
tratados se pueden consultar las siguientes fuentes:
1. ROWE, R. Machine musicianship. The MIT Press, Massachusetts, 2.001.
2. CEBALLOS, Fco Javier. Java 2 Curso de programacion. Rama, 2000.
3. Solomons Music Theory Resources. http://www.solomonsmusic.net.
4. PISTON, W. Armona. Idea Books, Barcelona, 2.001.
5. jMusic - Computer music composition in Java. http://jmusic.ci.qut.edu.au/.
6. MIDI File format - http://www.borg.com/jglatt/tech/midifile.htm.
7. JFugue - Java API for Music programming - http://www.jfugue.org/javadoc/.
8. The ABC Musical notation language - http://staffweb.cms.gre.ac.uk/c.walshaw/abc/.
9. How to interpret ABC music notation - http://www.lesession.co.uk/abc/abc notation.htm.
10. Tutorial sobre Swing y JFC (Java Foundation Classes) http://www.programacion.com/java/tutorial/swing.
71