Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas Curso: Organización de Lenguajes y Compiladores 2 Plataforma: Linux/Windows

Trabajando con JFugue Descripción: Con este tutorial usted aprenderá a configurar y utilizar el API JFugue en sus aplicaciones Java, el cual es muy útil cuando se desea implementar sonido en las mismas. Esta API permite epecialmente fácil acceso a los estándares MIDI además de poseer una interfaz programática flexible y funcional.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Índice Introducción----------------------------------------------------------------------------------------------------------3 Manejo del API Java Fugue---------------------------------------------------------------------------------------5 Configuración--------------------------------------------------------------------------------------------------------5 Modo de uso (MusicStrings)-------------------------------------------------------------------------------------8 Archivos MIDI-------------------------------------------------------------------------------------------------------14 Conclusiones--------------------------------------------------------------------------------------------------------15 Bibliografía----------------------------------------------------------------------------------------------------------16 Recomendaciones-------------------------------------------------------------------------------------------------17

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Introducción En la actualidad las aplicaciones desarrolladas con contenido multimedia son cada vez más solicitadas y a su vez más aceptadas por los usuarios (es un cículo vicioso). El formato de manipulación de audio MIDI está un tanto olvidado con la salida del mp3 al mercado y todas las ventajas que éste nos proporciona. El API JFugue nos da un enlace al formato MIDI para nuestras aplicaciones JAVA de una forma sencilla y factible de tal manera que la edición de melodías no es cuestión más que de una cadena de caracteres de configuración. A diferencia de otros paquetes para el manejo del Java Sound API, JFugue establece todas las características del audio en simples cadenas sin la necesidad de crear objetos para cada característica o lo que sería peor, para cada nota. El MIDI nos permite la edición de melodías reproducidas en paralelo (llamadas voces) con una amplia gama de instrumentos, lo que permite crear melodías más complejas y a su vez más atractivas. En este documento se muestra la forma de implementar el API JFugue en los proyectos de NetBeans 5.5, aunque la configuración en otras interfaces es bastante similar. También se trata a profundidad el formato de las MusicStrings a través de la definición de sus componentes respaldado en ejemplos que han sido previamente verificados. Por último se presenta la forma en que JFugue se comunica con los archivos MIDI. A continuación, el API JFugue.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Objetivos General •

Introducir al lector en el uso del API Jfugue como una herramienta para aplicaciones que utilicen sonido em formato MIDI.

Específicos • • • •

Configurar Jfugue para ser utilizado en un proyecto. Comprender el modo de trabajo con el API. Aprender a desarrollar melodías en base a las MusicStrings, según las opciones que estas proveen, así como el uso de Patterns. Establecer un enlace entre los archivos MIDI y los proyectos realizados com Jfugue.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Manejo del API Jfugue Es un proyecto open-source creado especialmente para manejar el formato MIDI de una maner sencilla. Posee una gran cantidad de formas de configuración y de uso con simples instrucciones, al contrario de otros proyectos que manejan un objeto por cada elemento MIDI que se desa implementar. La versión más reciente es la 3.2 que incluye opciones como el cambio de clave de las melodías, convertir arhivos MIDI a MusicStrings (se tratara más adelante), creación de ritmos, entre otros. ¿Cómo funciona? El modo de trabajo más común que se utiliza en JFugue es la edición de MusicStrings, las MusicStrings no son más que simples objetos tipo String cuyo valor debe escribirse con un formato específico; se introducen las opciones a manera de tokens. Los Patterns reciben estos MusicString a continuación los parsea y por último se produce una salida ya sea en nuestra vocinas, en pantalla (el contenido del MusicString) o en un archivo tipo MIDI, etc. Dependencias La versión 3.2 de JFugue necesita por lo menos la versión de Java 1.5.0; versiones anteriores de dicho api (como la 2.1) pueden trabajar con Java 1.3 y 1.4. Configuración Ahora procederemos a configurar JFugue. Lo haremos en NetBeans 5.5 pero la configuración en otros IDES es similar. 1. Iniciamos descargando la versión 3.2 de JFugue http://www.jfugue.org/download.html. Descargaremos 3 archivos:   

desde

el

Jfugue.jar (Indispensable) Jfugue-source.zip (Nos permite ver el código fuente) Jfugue-javadoc.zip (Proporciona acceso a la documentación)

2. A continuación creamos un nuevo proyecto en NetBeans y le llamaremos jfugue_1.

url:

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Fig1. Creación del proyecto. 3. Agregamos a las librerias de nuestro IDE (en este caso NetBeans) JFugue. Vamos al menú: Tools--> Library Manger y a continuación click en New Library.

Fig.2 Agregando la librería JFugue

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas 4. Ahora que ya creamos una nueva libraría agregamos al classpath de ésta el JAR de JFugue. Seleccionando la ficha de Classpath, luego en Add Jar/File y buscamos en el equipo el archivo, lo seleccionamos y listo.

Fig 3. Especificando el Classpath de JFugue. 5. Ahora que ya hemos agregado el API, vamos a agregar el source y el javadoc para tener acceso a estos cuando lo necesitemos. Se sigue el mismo proceso que en el paso anterior. Para el código fuente seleccionamos el fichero Sources y agregamos el archivo Jfugue-soruce.zip y luego el fichero Javadoc Jfugue-javadoc.zip. 6. Ahora incluiremos en nuestro proyecto (jfugue_1) las librerias del Jfugue.

Fig 4. Agregando JFugue al proyecto actual.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Fig 5. Agregamos JFugue a nuestro proyecto. Ahora estamos listos para comenzar a programar con JFugue! Probando JFugue Vamos a cerciorarnos que la configuración se haya hecho correctamente. Ingresando el siguiente código en nuestro método main del proyecto en el que estámos trabajando, compilando y ejecutándolo debemos escuchar una escala musical. Player jukebox = new Player(); jukebox.play("C D E F G A B"); Nota:

 Recordar hacer la importación: import org.jfugue.*;  Encender las bocinas. Modo de Uso JFugue posee una gran cantidad de opciones para las MusicStrings, a continuación se definen y ejemplifican: MusicStrings Cadenas que el api toma para crear las secuencias MIDI. Cada parte de la cadena es tomada como un token, la forma de separar cada token es con un especio vacío. No hace diferencia entre mayúsculas y minúsculas. • Notas y alteraciones: Permite especificar las notas de la melodía, la nomenclatura que se sigue es la siguiente: Do=C, Re=D, Mi=E, Fa=F, Sol=G, La=A, Si=B, Silencio=R. Otra forma de escribir las notas es de acuerdo a un

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas número (entre corchetes) correspondiente a las mismas, se muestra a continuación en la siguiente tabla.

Las alteraciones se especifican como “b” para bemol y “#” para sostenido. JFugue solo permite un sostenido o un bemol como alteración. Ejemplo: Player jukebox = new Player(); jukebox.play("C D E F G A B"); jukebox.play("[60] [62] [64] [65] R R G A B"); jukebox.play("C# D# Eb Fb G# A B"); •

Octavas: Como se puede observar en la tabla, la primera columna del lado izquierdo nos muestra la octava en que se reproducirá la nota, esto es el grado de agudez. El tipo de octava solo se agrega delante de cada nota. Tomar en cuanta que debe escribirse pegado a la nota ya que es una alteración de la nota por lo que la toma como un solo token. Entre más grande es el valor de la octava, la nota será más aguda. La octava de las notas es por default 5.

Ejemplo: jukebox.play("C3 D4 E5 F6 G7 A8 B9"); En el caso de las notas escritas por su código ( [84] por ejemplo) ya incluyen el valor de octava, por lo que el agregárselo producira un error: jukebox.play("[84]5 [64]8 [65]3"); X •

Acordes: Un acorde es el sonido que producen 2 o más notas presionadas a la vez, los acordes mayores y menores se componen de 3 notas, pero hay una gran variedad de acordes compuestos por mas de 3 notas.

Ejemplo: Las notas que componen al acorde Do son: Do, Mi, Sol (C, E,G). Para que suenen al mismo tiempo deberán ser escritas con el operador +. En el siguiente ejemplo se tocará el acorde Do y luego el acorde Re. Note el espacio entre la G y la D, marcan la diferencia de token. jukebox.play(“C+E+G D+F#+A”)

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas Otra forma de escribir los acordes es mediante los acordes definidos que posee JFugue, en este caso no se necesita saber que notas componen a los acordes. La siguiente tabla muestra las notaciones para los acordes. Nombre Conocido

Representación en JFugue

Ejemplo: jukebox.play( “ Cmaj Cmaj Amin Amin Fmaj Fmaj Gmaj Gmaj”);

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas Nota, la octava de los acordes es por default: 3. •

Duración: Es el tiempo que dura cada nota o acorde.

Ejemplo: jukebox.play (“C8w D8h E6q C4majw”); •

Clave: Permite establecer la clave en que se escribirá la melodía. La clave por default es Sol. Su sintaxis es: la letra “K” seguido de la clave.

Ejemplo: jukebox.play ("KCbmaj C8w D8h E6q C4majw"); En este caso la clave es: Do bemol mayor. •

Instrumento: Permite definir el instrumento con el que se va a interpretar. Estos instrumentos(128) están basados en los estándares MIDI. La sintaxis es la letra “I” seguido del nombre o el código del instrumento entre corchetes. A continuación el listado de instrumentos.

PIANO 0 BRIGHT_ACOUSTIC 1 ELECTRIC_GRAND 2 HONKEY_TONK 3 ELECTRIC_PIANO 4 ELECTRIC_PIANO_1 4 ELECTRIC_PIANO_2 5 HARPISCHORD 6 CLAVINET 7 CELESTA 8 GLOCKENSPIEL 9 MUSIC_BOX 10 VIBRAPHONE 11 MARIMBA 12 XYLOPHONE 13 TUBULAR_BELLS 14 DULCIMER 15 DRAWBAR_ORGAN 16 PERCUSSIVE_ORGAN 17 ROCK_ORGAN 18 CHURCH_ORGAN 19

SYNTHSTRINGS_1 50 SYNTHSTRINGS_2 51 CHOIR_AAHS 52 VOICE_OOHS 53 SYNTH_VOICE 54 ORCHESTRA_HIT 55 TRUMPET 56 TROMBONE 57 TUBA 58 MUTED_TRUMPET 59 FRENCH_HORN BRASS_SECTION SYNTHBRASS_1 SYNTHBRASS_2 SOPRANO_SAX ALTO_SAX TENOR_SAX BARITONE_SAX OBOE ENGLISH_HORN

60 61 62 63 64

65 66 67 68 69

PAD_POLYSYNTH 90 POLYSYNTH 90 PAD_CHOIR 91 CHOIR 91 PAD_BOWED 92 BOWED 92 PAD_METALLIC 93 METALLIC 93 PAD_HALO 94 HALO 94 PAD_SWEEP 95 SWEEP 95 FX_RAIN 96 RAIN 96 FX_SOUNDTRACK 97 SOUNDTRACK 97 FX_CRYSTAL 98 CRYSTAL 98 FX_ATMOSPHERE 99 ATMOSPHERE 99 FX_BRIGHTNESS

100

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas REED_ORGAN 20 ACCORIDAN 21 HARMONICA 22 TANGO_ACCORDIAN 23 GUITAR 24 NYLON_STRING_GUITAR 24 STEEL_STRING_GUITAR 25 ELECTRIC_JAZZ_GUITAR 26 ELECTRIC_CLEAN_GUITAR 27 ELECTRIC_MUTED_GUITAR 28 OVERDRIVEN_GUITAR 29 DISTORTION_GUITAR 30 GUITAR_HARMONICS 31 ACOUSTIC_BASS 32 ELECTRIC_BASS_FINGER 33 ELECTRIC_BASS_PICK 34 FRETLESS_BASS 35 SLAP_BASS_1 36 SLAP_BASS_2 37 SYNTH_BASS_1 38 SYNTH_BASS_2 39 VIOLIN 40 VIOLA 41 CELLO 42 CONTRABASS 43 TREMOLO_STRINGS 44 PIZZICATO_STRINGS 45 ORCHESTRAL_STRINGS 46 TIMPANI 47 STRING_ENSEMBLE_1 48 STRING_ENSEMBLE_2 49

BASSOON CLARINET PICCOLO FLUTE RECORDER PAN_FLUTE BLOWN_BOTTLE SKAKUHACHI WHISTLE OCARINA

70 71 72 73 74 75 76 77 78 79

LEAD_SQUARE 80 SQUARE 80 LEAD_SAWTOOTH 81 SAWTOOTH 81 LEAD_CALLIOPE 82 CALLIOPE 82 LEAD_CHIFF 83 CHIFF 83 LEAD_CHARANG 84 CHARANG 84 LEAD_VOICE 85 VOICE 85 LEAD_FIFTHS 86 FIFTHS 86 LEAD_BASSLEAD 87 BASSLEAD 87 PAD_NEW_AGE 88 NEW_AGE 88 PAD_WARM 89 WARM 89

BRIGHTNESS FX_GOBLINS GOBLINS FX_ECHOES ECHOES FX_SCI-FI SCI-FI SITAR BANJO SHAMISEN KOTO KALIMBA BAGPIPE

100 101 101 102 102 103 103 104 105 106 107 108 109

FIDDLE 110 SHANAI 111 TINKLE_BELL 112 AGOGO 113 STEEL_DRUMS 114 WOODBLOCK 115 TAIKO_DRUM 116 MELODIC_TOM 117 SYNTH_DRUM 118 REVERSE_CYMBAL 119 GUITAR_FRET_NOISE 120 BREATH_NOISE 121 SEASHORE 122 BIRD_TWEET 123 TELEPHONE_RING 124 HELICOPTER 125 APPLAUSE 126 GUNSHOT 127

Ejemplo: jukevox.play(“I[30] Ci Ci Ci Ai Ai F G6i F G G”); o bien: jukevox.play(“I[DISTORTION_GUITAR] Ci Ci Ci Ai Ai F G6i F G G”); •

Voces: Permite la ejecución entre varias melodías al mismo tiempo, cada “voz” debe verse como fueran personas que cantan en en grupo. Así pueden definirse 16 voces (de la voz 0-15). Se representa mediante una “V” seguida del número de voz que será. Debe incluirse al inicio del MusicString. La décima voz (V9) es especial para percusiones. Antes de proceder al ejemplo, definiremos los “Patterns”. Pattern: Permite crear, transformar, distribuir piezas de música, imaginemos que en un compás se repite tres veces en una partitura, pues entonces solo creamos el patrón de un compás y lo reproducimos 3 veces. Los Pattern permiten insertar MusicStrings así como otros Pattern dentro de ellos.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas Ejemplo: Player jukebox = new Player(); Pattern parte1 = new Pattern(“ G G A A B G G”); Pattern parte2 = new Pattern(“ B B A A G”); Pattern cancion= new Pattern(); cancion.add(parte1,2); // se agrega 2 veces cancion.add(parte2,2); // se agrega 2 veces jukebox.play(cancion); La forma de agregación entre patrones debemos verla como si concatenaramos los MusicString de cada uno. Ejemplo: Player jukebox = new Player(); Pattern voz1 = new Pattern ("V1 Cmaj Cmaj Cmaj Amin Amin Amin"); Pattern voz2 = new Pattern("V2 i[30] Rw Rh C D Ei Fi C Cb Ch"); Pattern voz3 = new Pattern("v3 i[violin] Rw Rh C7w D7h Cb7w D7h"); Pattern cancion= new Pattern(); cancion.add(voz1,3); cancion.add(voz2,2); cancion.add(voz3); jukebox.play(cancion); •

Tiempo: Define los pulsos por minuto que se cuentan según el compás, el defaul es 120. Nota: Alterar esto alterara la duración común de los tiempos. Debe ir al inicio del MusicString.

Ejemplo: Player jukebox = new Player(); Pattern parte1 = new Pattern ( “ D F# F# D A”); Pattern parte2 = new Pattern(“T160 D D D G G G”); Pattern parte3 = new Pattern(“E E D F# F#”); Pattern cancion = new Pattern(); cancion.add(parte1); cancion.add(parte2); cancion.add(parte3); jukebox.play(cancion); Si ejecutamos la siguiente melodíaa nos podemos dar cuenta que desde la parte2 se comienza a interpretar mas lento, a pesar que todas las notas tienen la misma duración (por default “q”) lo que sucede que que el “T160” afecta al MusicString que esta después de el, como se dijo anteriormente la adición de patrones no es más que concatenar los string, de tal forma que lo anterior queda asi: D F# F# D A T160 D D D G G G E E D F# F# Por lo que, desde la segunda parte se altera la forma de medición del tiempo.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas •

Constantes: Permite la definición de constantes para comodidad del usuario, hay que tomar en cuenta que se deben definir antes de usar. Tiene la siguiente sintaxis: $nombre=valor

Ejemplo: Player jukebox = new Player(); Pattern constante = new Pattern("$instrumento=30"); Pattern cancion= new Pattern(); cancion.add(constante); cancion.add(" I[instrumento] B C# D# E D# C# Bh"); jukebox.play(cancion); En el ejemplo anterior, si no se hubiera agregado al Pattern cancion el patern constante, mostraría un error pues serían como dos MusicString diferentes y el player no encontraría la constante “instrumento”. Archivos MIDI JFugue permite grabar archivos según el contenido de MusicStrings así como también obtener el MusicString de un archivo MIDI. A continuación un ejemplo: Pattern con = new Pattern("$FAV=30"); Pattern n = new Pattern(); n.add(con); n.add(" I[FAV] Ci Ci Ci Ai Ai F G6i F G G"); Pattern n2 = new Pattern(); n2.add(n,2); player.play(n2); Pattern n3 = new Pattern(" I[FAV] Cmaji Cmaji Cmaji Amaji Amaji Fmaj Gmaji Fmaj Gmaj Gmaj"); Pattern n4 = new Pattern(); n4.add(n3,2); player.play(n4); Pattern union = new Pattern(); n2.insert("V0"); n4.insert("V1"); union.add(n2); union.add(n4); try{ player.saveMidi(union,new File("Uno.midi")); // Graba el Music String de Union en //Uno.midi Pattern p = player.loadMidi(new File("Uno.midi")); //Carga el MusicString de Uno.midi System.out.println(p.getMusicString()); //al Pattern p y lo imprime en pantalla }catch(Exception err){ System.out.println(err.getMessage()); }

Recuerde importar la biblioteca: java.IO.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Conclusiones a) JFugue es una herramienta muy sencilla de usar gracias a las MusicStrings las cuales simplifican en un String la configuración MIDI de las melodías. b) Se puede implementar de forma sencilla en cualquier proyecto con tan solo agregar la librería Jfugue.jar. c) El API provee un acceso simple a la creación y lectura de archivos MIDI. d) Cuando se graban MusicStrings en archivos .MIDI se percibe una disminución en el volumen de la melodía. e) Con JFugue tenemos un acceso inmediato a las características del formato MIDI sin necesidad de manipularlo a bajo nivel.

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Tutorial desarrollado por: Nery Chucuy El contenido de este tutorial puede ser editado total o parcialmente, siempre y cuando se respenten los derechos de autor.

Bibliografía 1. http://www.jfugue.org/ 2. http://www.cs.cofc.edu/~manaris/spring04/cs220-handouts/JFugue/JFugueUserGuide.html

Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas

Recomendaciones a) Agregue en la librería de JFugue el código fuente del API así como la documentación; para poder investigarlo a profundidad en el momento que lo necesite. b) Para obtener mejores resultados del Java Sound API se pueden descargar los soundbaks que provee Sun: http://java.sun.com/products/javamedia/sound/soundbanks.html. c) Es recomendable incluir en cada aplicación que realizamos una copia de JFugue para evitar problemas cuando el usuario ejecute la aplicación. d) Cuando grabe archivos MIDI desde el programa, incremente el volumen de las melodías con el control de eventos de JFugue, ya que se percibe un decremento de volumen en el proceso de grabación. e) Se recomienda tomar en cuenta el orden en que se explico cada componente del MusicString en este tutorial ya que la sintaxis debe respetar dicho orden, en especial para las modificaciones de las notas.