.

Hoy se decide la última nota en la melodía de CrowdSound.net, un experimento de composición en masa:

Se está generando una melodía nota a nota, en tiempo real, utilizando el voto popular. […] Esta melodía se convertirá en una canción con una estructura de acordes Do, Sol, La menor, Fa repetida 18 veces. Tendrá una estructura de (Verso / Verso / Coro / Verso / Coro / Conclusión). La canción está a día de hoy en forma de esqueleto.

El resultado del proyecto es curioso, igual que las estadísticas que sacan del proceso, aunque me interesó más ver cómo generaban la partitura con canvas y los sonidos con howler.js. Se puede reproducir la melodía eligiendo con el sonido de qué instrumento se quiere oír, saltar directamente a una parte de la canción y modificar el ritmo de la reproducción.

También resulta curioso, aunque no creo que sea casual, que la progresión armónica utilizada sea la popular I–V–vi–IV. Es casi imposible no oírla a menudo, como señalaron Axis of Awesome, y afianza más mi teoría no verificada ni estudiada (ni siquiera tiene mucho sentido) que su uso debe ser un método para reducir la complejidad de las canciones.

.

Keunwoo Choi es un estudiante del Centro de Música Digital de la Queen Mary, Universidad de Londres. Bajo la tutela del profesor Mark Sandler y el doctor Gyorgy Fazekas ha publicado un texto titulado «Text-based LSTM networks for Automatic Music Composition», disponible en arXiv y que resume en su página web:

RNN de palabras (LSTM) sobre Keras con representaciones textuales empalabradas de ficheros MIDI de la batería de Metallica, provenientes de midiatabase.com.

No es la primera vez que veo el uso de redes neuronales recurrentes para componer música, lo que no quita que me siga pareciendo interesante. Los resultados no son espectaculares pero sí curiosos, y me gustaría tener más tiempo para poder entender mejor cómo se implementa la RNN.

.

Ben Frederickson, un desarrollador de software que vive en Vancouver, ha publicado un par de entradas en su blog sobre cómo calcular la similitud entre dos artistas en términos de distancia. Para ello hace uso de un conjunto de datos sacados de last.fm en 2008 para plantear y desarrollar distintos métodos.

En la primera entrada parte de un criterio de similitud sencillo: el número de usuarios que dos artistas tienen en común. Rápidamente identifica como problema que los grupos más populares los tendrán casi todos los usuarios, con lo que la métrica no resulta especialmente fiable. La solución más sencilla que propone es calcular el coeficiente de Jaccard, aunque también menciona el coeficiente de Sørensen–Dice y el coeficiente de Ochiai. Después explica cómo tratar el problema como uno geométrico, con sus beneficios y penalizaciones, para pasar a comentar y mostrar las ventajas de usar TF-IDF y, finalmente, Okapi BM25.

La segunda entrada se centra en el uso de factorización de matrices para reducir la dimensionalidad de los datos antes de calcular la similitud entre dos artistas. Partiendo de la descomposición en valores singulares para hacer análisis de semántica latente, pasa a explicar e implementar el método descrito en «Collaborative Filtering for Implicit Feedback Datasets».

Para el desarrollo ha usado python, acompañando los resultados de gráficos interactivos hechos con D3.js, lo que hace la lectura aún más interesante.

.

Veía hace unos días una reseña en Hacker News sobre un sintetizador multi-toque hecho con Typescript/React aunque su creador, Luke Phillips, no da detalles de la implementación:

No es la primera vez que menciono sintetizadores hechos con JavaScript, siendo el más conocido probablemente el que hizo Google como homenaje al Dr. Moog.

.

Veo el siguiente código en el blog de Robert Elder:

cat /dev/urandom | hexdump -v -e '/1 "%u\n"' | awk '{ split("0,2,4,5,7,9,11,12",a,","); for (i = 0; i < 1; i+= 0.0001) printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) }' | xxd -r -p | aplay -c 2 -f S32_LE -r 16000

Introducido en una terminal de un sistema Linux con los programas necesarios, genera una melodía aleatoria. En el primer enlace hay una explicación detallada de lo que hace exactamente, aunque se resumir con cada orden entubada:

  1. cat /dev/urandom

    Vuelca los contenidos de /dev/urandom a stdout.

  2. hexdump -v -e '/1 "%u\n"'

    Convierte bytes binarios en enteros (opción -e '/1 "%u\n"') incluyendo las repeticiones (opción -v).

  3. awk '{ split("0,2,4,5,7,9,11,12",a,","); for (i = 0; i < 1; i+= 0.0001) printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) }'

    Procesa la información con AWK de modo que:

    1. split("0,2,4,5,7,9,11,12",a,",");

      Crea un array a con los número de semitonos relativos a la nota base en una escala mayor. Este array se usa para calcular la frecuencia en hercios de una nota de temperamento igual con esta fórmula: 440 × 2^(número de semitonos / 12) 440Hz representa la frecuencia de un La 440.

    2. for (i = 0; i < 1; i+= 0.0001)

      Un contador para generar los tonos. Variar el incremento de cada iteración altera el tempo y la frecuencia percibida de la melodía.

    3. printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i))

      Imprime números hexadecimales de 4 octetos representando la amplitud de la onda sonora en un momento determinado. La fórmula 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) se puede descomponer en varias partes:

      1. a[$1 % 8] / 12

        A partir del valor aleatorio de la entrada ($1) elige el semitono de la escala y lo divide por doce.

      2. exp(… * log(2))

        AWK no tiene una función para calcular potencias de una base cualquiera pero sí calcula potencias del número e y logaritmos naturales, así que para obtener 2x hay que calcular e(x × ln(2)).

      3. 1382

        Es un valor aproximado de 440 × π.

      4. 100

        Un factor de escala para la amplitud de la onda y, por consiguiente, el volumen.

  4. xxd -r -p

    Convierte los 8 bytes de valores hexadecimales en binario.

  5. aplay -c 2 -f S32_LE -r 16000

    Reproduce el sonido equivalente.