Archivos

El Juego Filarmónico: aproximación técnica


Introducción al Juego filarmónico

El Juego filarmónico es la versión digital de un manuscrito propiedad de la Biblioteca Nacional de España que contiene las reglas para generar un número muy elevado de minuetos diferentes tirando un par de dados.

Ya hemos hablado de la historia del manuscrito en la propia web del Juego filarmónico y en el blog de la BNE, así que ahora vamos a contar algunos detalles de las tripas del proyecto. Si queréis remangaros aún más, el código completo del proyecto está disponible en la cuenta de GitHub de la Biblioteca Nacional de España.

Experiencia de usuario

En el siglo XVIII, en una época en la que no había radio, ni discográficas ni hits musicales, de repente se pone al alcance de los músicos un manuscrito que permite componer cuatrillones de melodías diferentes (ciento veintinueve mil cuatrillones, en concreto). ¿Cómo podemos trasladar el manuscrito al mundo digital, explicar en qué consiste y componer nuestros propios minuetos? Además, queríamos llegar a un número muy amplio de perfiles con diferente grado de conocimiento de música y de nuevas tecnologías.

El benchmarking era imposible. Nadie antes había recreado el Juego filarmónico en digital salvo algún experimento que ya no funcionaba, por lo que teníamos que idear la interacción desde cero. Nuestra única referencia era el documento originalde la Biblioteca Nacional, pero teníamos algo muy claro: había que huir de la estética de los CDs interactivos de los años 90.

juego filarmonico

El corazón del proyecto es la tabla de correspondencias entre las tiradas de los dados y los compases del manuscrito. Cada entrada de la tabla representa un compás (grupo de notas musicales). En el juego original estamos obligados a tirar los dados 32 veces, buscar los números y los compases, y apuntarlos en ese orden para crear el minueto. Pensando en el proceso, nos surgieron muchas preguntas, unas relacionadas con la repetición de las tiradas (¿cómo podemos componer un minueto sin matar de aburrimiento al usuario? ¿Cómo mostramos cualquier acción 32 veces? ¿Ponemos 32 botones de “Tirar dados”? ¿Hacemos que el usuario tenga que darle al mismo botón 32 veces? ) y otras relacionadas con las reglas en sí (¿cómo mostramos la equivalencia entre números y notas musicales? ¿Cómo hacemos ver que es el usuario quien ha creado la pieza musical? ¿Cómo explicamos qué está sonando cuando pulsas Play?).

Nos dimos cuenta de que si generamos el minueto instantáneamente, de golpe, la experiencia quedaba muy pobre, se perdía la historia. Lo ideal era mostrar el proceso de creación de la melodía, compás a compás, con un código de colores que relaciona las tiradas y los compases. El movimiento permitió hacer el Juego Filarmónico visualmente más sencillo y con mucho más significado.

Estructura de la web

La estructura del proyecto es sencilla: un pequeño enrutador escrito en PHP y dos plantillas HTML. Inicialmente nos planteamos una Single Page Application, pero nos dimos cuenta de que complicaría innecesariamente el HTML con cambios de estado. Al ser el backend el que se encarga de esos cambios, conseguimos que el código front quedara más claro, pudiendo refinar la estrategia de SEO y facilitando el intercambio de información con la base de datos.

Diseño responsive

El siguiente reto al que nos enfrentamos fue el de cómo plasmar de manera fiel el diseño y las interacciones definidas en la experiencia del usuario, teniendo en cuenta la variedad existente de dispositivos.

Para respetar la mecánica y el aspecto del manuscrito, conservamos las tablas de compases. Al ser un diseño responsive, había que adaptar esas tablas a diferentes anchos para que no perdieran visibilidad ni usabilidad. Para ello usamos Bootstrap y ‘media queries’.

Juego filarmonico 1

Aparte de las tablas, también teníamos que adaptar el ancho de los compases de la partitura (generados previamente en formato .png), para lo que usamos JavaScript, lo que nos ha permitido definir el número de compases de la partitura que aparecen en pantalla, y cuánto se desplaza la partitura durante la reproducción.

Juego filarmonico 2

Y para terminar, el reproductor tuvo que pasar por el proceso de “responsivización”, ya que el botón de “play/stop” no se muestra exactamente igual en una pantalla táctil.

El player

Todo lo anterior no vale de nada si el player sólo funciona en un navegador determinado, así que tuvimos que desarrollar un reproductor compatible con la mayor cantidad de dispositivos y navegadores posible, y además ligero y robusto. Para ello nos apoyamos en la librería MIDI.js.

El player recibe del API la lista de compases que forman el minueto, en formato MIDI. Para cada compás, extrae las pistas, los canales y las notas de cada canal y a continuación -terminadas con éxito todas las promesas de extracción de información de cada fichero-  ordena la información de todas las notas de todos los tracks y canales obtenidos.

Las notas se ordenan cronológicamente a partir del tiempo transcurrido desde la nota anterior, corrigiendo el silencio inicial que tenían algunos compases y que no forma parte de la melodía. Una vez ordenadas, usamos la librería MIDI.js y lanzamos un temporizador que hace sonar las notas con precisión de milisegundos.

Hablando de compatibilidad, en los iPhone comprobamos que no se activa el sistema de audio automáticamente, sino que requiere de una acción del usuario. Para simular esto, si estamos generando el minueto en un iPhone, en el momento que lo tenemos listo, lanzamos la primera nota de la melodía con duración cero y volumen cero, “rebobinamos” y el sistema queda listo para usar normalmente.

Tras identificar el navegador, definimos los intervalos de animación/reproducción concretos con window.requestAnimationFrame, y empezamos a animar la partitura usando timeOut. Al jugar de esta forma con las propiedades de las notas logramos sincronizar la reproducción del minueto con el avance de la partitura, haciendo del Juego filarmónico una experiencia más completa.

Estructura de las URL

Cuando un usuario crea un minueto o lo comparte en las redes sociales, la URL de la página tiene que contener el ID del minueto. Además, este ID debe codificar de manera unívoca los compases, evitando una consulta a la base de datos.

Así, cuando tiramos los dados, primero creamos un número en base once que codifica las tiradas. El número es en base once porque dos dados nos devuelven un número entre el dos y el doce, es decir, once valores posibles. Además, restamos dos para que los valores vayan del cero al diez en vez del dos al doce. Por ejemplo, para la primera parte del minueto, el número resultante sería: 110 * (primera tirada-2) + 111 * (segunda tirada-2) + 112 * (tercera tirada-2) + …. Una vez que tenemos ese número, para compactarlo, lo pasamos a base 62, y así nunca usaremos más de diez caracteres para representarlo. Para la segunda parte del minueto, donde sólo tiramos un dado, el número que obtenemos es  60 * (primera tirada-1) + 61 * (segunda tirada-1) + 62 * (tercera tirada-1) + … Igualmente, lo pasamos a base 62, lo que nos permite usar solo 7 caracteres, quedando un identificador con este aspecto: 2P96MNmBnT-ld3NPgB

Con este método podemos asignar a cada minueto un ID único, relativamente compacto (17 caracteres), fácil de chequear con una expresión regular y que nos ahorra un acceso a la base de datos. Eso sí, tenemos que usar la extensión BC Math, incluida en PHP desde la versión 4.0.4, que permite el uso de números de precisión arbitraria.

Controlando el ancho de banda

La siguiente decisión es elegir cómo reproducimos el sonido equilibrando calidad y ancho de banda consumido. Podíamos componer el minueto usando fragmentos de MP3 (que contendrían el audio, la grabación) o unir los ficheros MIDI (que contienen la descripción de la música, equivalente a la partitura: qué nota suena, en qué instante suena, a qué volumen…) y luego reproducirlos.

Si optábamos por los ficheros MIDI, el reproductor sería más complejo, necesitaríamos un fichero de audio por cada nota musical (uno para el do, otro para el do sostenido, …) pero  tendríamos más control sobre los eventos. Si optábamos por los MP3, la calidad del sonido sería mayor, pero como contrapartida se notaría el salto entre los diferentes compases, perderíamos el control fino de los eventos y (pensábamos que) el ancho de banda consumido iba a ser mayor.

Al usar el formato MIDI, necesitábamos un fichero (soundfont) con el audio de todas las notas musicales, ya que no todos los navegadores lo incorporan. Para reducir el tamaño de ese fichero hicimos un script previo que mostraba las notas que no se usan en los minuetos, y así eliminarlas del fichero maestro. Al hacer este filtro, conseguimos reducir en un 30% el tamaño del fichero, optimizando la transmisión de datos.

Realizamos varias pruebas contrastando el tiempo de carga comparando los ficheros MIDI con los mp3. Sopesando ambas posibilidades y la futura evolución del proyecto, finalmente elegimos el formato MIDI. Efectivamente, la cantidad de datos transmitida era menor y nos ofrecía más compatibilidad a la hora de hacer un player multinavegador.

Desafíos SEO

Por parte del SEO, hay dos desafíos principales: medir los eventos y evitar que los buscadores piensen que hay contenido duplicado. Para medir los eventos, se definió un evento por interacción: “Tirar los dados”, “Escuchar la melodía”, “Guardar el minueto”, “Compartir en Twitter” y “Compartir en Facebook”.

Al final nos decantamos por la siguiente fórmula para evitar inflar la tasa de rebote:

ga('send', 'event', 'botón', 'clic', 'nombrebotón', {

    nonInteraction: true

});

Una vez creados los nombres de las categorías, las acciones y los labels correspondientes, el cliente puede monitorizar estas estadísticas en Google Analytics.

El segundo desafío era evitar que se indexasen todas las URLs de los minuetos. Al existir la posibilidad de tener cuatrillones de minuetos, no queríamos correr el riesgo de tener demasiadas URL indexadas que, a ojos de Google, tendrían un contenido idéntico.

Al principio se pensó en poner una etiqueta “meta robots” que indicase a Google que esas páginas no se debían indexar. Si hubiéramos usado una arquitectura “Single Page”, no hubiéramos podido crear dinámicamente propiedades y etiquetas <meta> por cada minueto. Al usar un index.php como enrutador podíamos crear etiquetas <meta> de forma dinámica, gracias a un flag: en caso de existir, significa que la página muestra un minueto, y añade una etiqueta <meta> para que no indexe la página.

Para ello, diferenciamos los <metas> de los minuetos y los de la home. Además, las URL de los minuetos incluirían la ruta /minueto/ bloqueando esa carpeta en el archivo robots.txt.

Al tener un <meta> noindex, indicamos a los motores de búsqueda que esas páginas no se deben indexar. El fichero robots.txt hace de segunda barrera: al tener la carpeta bloqueada, el buscador no emplea recursos para indexar estas páginas, evitando tener indexadas cientos de páginas de “thin content”.

Siguiendo el compás

Los compases que componen el minueto se han generado previamente en formato png. Estuvimos evaluando la posibilidad de convertir el MIDI en partitura directamente, pero las librerías que encontramos utilizaban una notación intermedia, con lo cual tendríamos que convertir todos los ficheros (272 compases en total) a esa notación. Además, los compases generados tendrían un ancho diferente, lo que complica la sincronización.

Optamos por una solución de fuerza bruta. Usando el programa de notación musical MuseScore y un par de macros que programamos, capturamos los 272 compases, forzando el ancho de los mismos (reconocemos que esto es hacer un poco de trampa, los compases deberían ser proporcionales a las notas que contienen).

Una herramienta al servicio del público

Esta interfaz genera un número casi infinito de posibles piezas musicales. Gracias a la combinación de tecnologías y formatos musicales, se nos ocurre una lista de ideas para hacer que el proyecto siga evolucionando. Dichas ideas incluyen, por ejemplo, la posibilidad de reservar bloques de cientos de miles de minuetos y ofrecerlos como packs exclusivos a clientes interesados en ellos, packs que pueden ser distribuidos a través de distintos canales comerciales.

En palabras de José Luis Bueren, director de Biblioteca Digital y Sistemas de Información en la BNE: “Gracias a este proyecto, trillones de minuetos condenados al olvido van a poder ser escuchados por todos aquellos que lo deseen y se transformará en acción sonora el conocimiento que atesora uno de los muchos manuscritos del fondo documental de la BNE. Por otro lado, esperamos que además puedan servir de fuente de inspiración de apps u otros juegos digitales”.

El Juego Filarmónico: aproximación técnica

Back to top