Haciendo música con Python

Voy a hablar sobre música y Python. Ambas cosas me apasionan pero de la teoría de lo primero, la música, no tengo ni idea y de lo segundo, Python, más bien poco, por lo que si cometo algún error espero me disculpéis.

¿Cómo empiezo esto? Un poco de teoría musical

Voy a intentar simplificar mucho todo esto de la música comentando solo una serie de conceptos muy básicos (y algún comentario, seguramente, esté mal).

  • El pentagrama: Es un conjunto de cinco líneas paralelas, horizontales y equidistantes. En ellas escribimos una serie de signos. Las líneas se enumeran de abajo a arriba. Sirve para escribir música.
Imagen descargada de Wikipedia con licencia CC BY-SA 3.0
  • La clave (clave de sol, clave de fa,…): Es un signo que se pone, normalmente, al principio del pentagrama (aunque se puede cambiar en cualquier momento) y sirve para indicar la altura de la música escrita. En este caso, la altura sirve para diferenciar un sonido agudo de un sonido grave y depende de la frecuencia del sonido, que es la que determina el nombre de las notas. Por ejemplo, la clave de sol, 𝄞, se escribe sobre la segunda línea e identifica que en esa línea está la nota SOL y subiendo y bajando en el pentagrama estarán representadas el resto de notas.
  • La partitura: Es como un script de Python, el código. La partitura está compuesta por el pentagrama junto con todas las anotaciones incluidas en el mismo.
  • El compás: está delimitado por líneas verticales en el pentagrama y sirve para indicar los pulsos musicales. Por ejemplo, en un vals sueles contar 1-2-3, 1-2-3, 1-2-3,… Esto indica que el compás se divide en tres fracciones de tiempo (el numerador de lo que va a continuación de la clave de sol en el ejemplo de la imagen inferior). El número del denominador indica la duración de cada fracción.
Imagen descargada de Wikipedia y de dominio publico.
  • La duración: corresponde al tiempo que se mantienen las vibraciones producidas por un sonido. Los símbolos siguientes indican la duración que hay que tocar una nota. Debajo puedes ver la representación de la redonda, la blanca, la negra, la corchea, la semicorchea, la fusa y la semifusa, respectivamente. La redonda es una unidad de duración. La blanca es la mitad de la redonda, es decir, una redonda equivale a dos blancas. La negra es la mitad de la blanca, es decir, una redonda equivale a cuatro negras y una blanca equivale a dos negras. La corchea es la mitad de la negra,…, la redonda corresponde a 64 semifusas. Ver esta figura para clarificar esto. En el compás indicábamos que podía ser, por ejemplo, 3/4, La parte de abajo indica que son negras (1/4) y el compás será 3 fracciones de negras (1/4 de una redonda). Si fuera 6/8 serían 6 fracciones de corcheas,…

𝅝   𝅗𝅥   𝅘𝅥   𝅘𝅥𝅮   𝅘𝅥𝅯   𝅘𝅥𝅰   𝅘𝅥𝅱

  • Intervalo musical: Es la distancia entre dos notas. Pero hay varias formas de medir estas distancias… Mejor mira el vídeo.
  • Las alteraciones: sirven para subir o bajar la tonalidad de una nota. Por ejemplo, un sostenido, ♯, sirve para subir medio tono a una nota. Un bemol, ♭, sirve para bajar medio tono a una nota,… Se colocan antes de la nota y afecta a esa nota o al principio de la partitura en una línea para indicar que todas las notas de esa línea habrá que subirles o bajarles la tonalidad.
  • Un semitono: es la unidad de menor medida que, supuestamente, diferencia un tono de otro según lo percibe el oído humano.
    • La octava: Está explicado en el vídeo anterior de intervalo musical. Pero desde un punto de vista físico es el rango de frecuencias entre dos notas que están separadas por una relación 2:1. Es decir, un LA en una escala más aguda tiene una frecuencia que dobla el LA de la escala anterior, más grave. Como las posibles frecuencias son infinitas se toma el LA de la cuarta octava como la referencia y se sitúa en 440 Hz. De esta forma, el LA en la quinta octava, más aguda, tendría una frecuencia de 880 Hz mientras que el LA en la tercera octava, más grave, tendría una frecuencia de 220 Hz. Aquí puedes ver la frecuencia de las notas en diferentes octavas. Este artículo es muy completo.

De la música a la física

Viendo lo anterior he derivado una fórmula para calcular las frecuencias de las notas. En esta fórmula hay que considerar el DO como un 1 y el SI como un 12 (y en medio el resto de semitonos). También hay que saber la octava que usamos y puede ir de 0 a 8.

Dejo una tabla con la referencia de números y notas:

NúmeroNombreCódigo
1DOC
2DO♯ / RE♭C♯ / B♭
3RED
4RE♯ / MI♭D♯ / E♭
5MIE
6FAF
7FA♯ / SOL♭F♯ / G♭
8SOLG
9SOL♯ / LA♭G♯ / A♭
10LAA
11LA♯ / SI♭A♯ / B♭
12SIB

Y la fórmula que vamos a usar:

\(frec(nota, octava) = 440 · (\sqrt[12]{2})^{octava · 12 + nota – 58}\)

Por tanto, un LA4 (nota LA en la cuarta octava) será:

\(frec(10, 4) = 440 · (\sqrt[12]{2})^{4 · 12 + 10 – 58} = 440 \)

Y, de la misma forma, un LA en una escala menor, 3, será:

\(frec(10, 3) = 440 · (\sqrt[12]{2})^{3 · 12 + 10 – 58} = 220 \)

Y ahora voy a a hablar un poco de ondas. De la Wikipedia:

Una onda sonora es una onda longitudinal que transmite lo que se asocia con sonido. Si se propaga en un medio elástico y continuo genera una variación local de presión o densidad, que se transmite en forma de onda esférica periódica o cuasiperiódica. Mecánicamente las ondas sonoras son un tipo de onda elástica.

https://es.wikipedia.org/wiki/Onda_sonora

En la anterior figura se puede ver un ejemplo de onda y vuelve a aparecer la frecuencia. En este contexto la frecuencia indica la cantidad de ciclos o pulsos por unidad de tiempo. Una frecuencia de 440 Hz indica que la onda tendrá 440 crestas y 440 valles durante cada segundo, es decir, 440 ciclos o pulsos.

¿Qué tiene que ver todo esto con nuestro oido?

Nuevamente, de la Wikipedia:

El hercio (Hz) es la unidad que expresa la cantidad de vibraciones que emite una fuente sonora por unidad de tiempo (frecuencia). Se considera que el oído humano puede percibir ondas sonoras de frecuencias entre los 20 y los 20 000 Hz, si bien también se consideran rangos entre 16 Hz (aproximadamente la nota más grave de un órgano de iglesia: do0 = 16,25 Hz) y 16 000 Hz (o 16 kHz). Las ondas que poseen una frecuencia inferior a la audible se denominan infrasónicas y las superiores ultrasónicas.

https://es.wikipedia.org/wiki/Onda_sonora

Y estas ondas llegan al oido y ahí se transforman en pulsos eléctricos que nuestro cerebro es capaz de interpretar:

Y llegamos a Python

Para esta parte os va a hacer falta instalar una biblioteca que se llama sounddevice. que podéis instalar usando conda o pip de la siguiente forma, siempre desde la línea de comandos y siempre recomiendo usar un entorno virtual:

Importamos una serie de cosas que usaremos:

La fórmula que hemos derivado antes la podemos meter en una función:

Si ahora quiero crear una onda de 440Hz puedo usar lo siguiente:

En lo anterior el frame rate es el número de valores que uso para definir cada paso, duration es el tiempo que sonará (en este caso lo defino en milisegundos, por tanto, un segundo). t será el número de pasos temporales que vamos a usar para definir nuestra onda. En frequency meto el valor que sale de la fórmula para LA4, 440 Hz y data será la amplitud de la onda. Si dibujo lo anterior usando matplotlib veré algo así:

Ahí no se ve gran cosa porque hay 440 ciclos, crestas y valles, metidos.

Voy a sacar ahora el DO0, el DO de la octava 0:

Aquí ya se ve algo más claro. Ese gráfico, convertido en onda sonora haría que nuestro oido transformase eso en un DO en la octava 0.

Voy a empaquetar la anterior forma de calcular la onda en una función que llamaré beep y vamos a usar sounddevice para transformarlo en sonido:

Podéis ir a la documentación de sounddevice para saber lo que hace play y wait pero es un poco evidente.

Si ahora hacemos lo siguiente:

Deberías escuchar un LA4 durante un segundo.

Pues, vamos a tocar algo, ¿no?

Ya que habéis llegado hasta aquí y hemos ido juntando ingredientes podemos tocar alguna cosa. Vamos a tocar primero los doce semitonos de la cuarta octava con cada semitono sonando un cuarto de segundo:

Lo anterior debería sonar algo parecido a esto:

No suena increible pero estamos haciendo música con Python y ciencia!! Podéis poner la octava en 3 y veréis que suena más grave. Lo mismo, podéis poner la escala en 5 y veréis que suena más agudo.

Ahora algo más complejo. Debajo pongo una parte de una partitura. Con lo explicado más arriba debería ser, más o menos, suficiente para leerla.

La partitura empieza con la clave de sol que nos da la referencia de que el SOL está en la segunda línea (leyendo desde abajo). También empieza con \(_{4}^{4}\) que nos indica que tenemos 4 partes de tiempo y cada parte tiene la duración de una negra. Luego vienen las notas. Por ejemplo, en el primer compás tenemos LA4 negra, LA4 negra, LA4 negra, FA4+DO5 (corcheas). En código python, con las funciones tal como las hemos definido sería:

  • Las notas: 10, 10, 10, 6, 1
  • La escala: 4, 4, 4, 4, 5

En este contexto voy a considerar que las negras duran medio segundo (500 milisegundos) por lo que una corchea serán 250 milisegundos.

  • La duración: 500, 500, 500, 250, 250

Dejo debajo un poco de código para poder tocar esos siete compases. Seguro que la música os sonará:

El resultado debería ser algo como lo siguiente:

Si alguien tiene tiempo estos días de confinamiento y saca la partitura completa (la de más arriba) o cualquier otra y la convierte a Python que me la mande y la incluyo aquí (citando a tu persona, claro) 🙂

Y hasta aquí he llegado con todo esto que me ha llevado días y días de leer y aprender cosas para no meter la pata de forma muy grosera. Espero que no haya cometido errores muy garrafales. Repito, la música me apasiona pero soy un 0 a la izquierda en todo lo que es la teoría de la misma.

Espero que os haya gustado.

Saludos.

9 pensamientos sobre “Haciendo música con Python”

  1. Hola! me ha parecido muy impresionante este tema, yo estudie música y justo estoy comenzando a aprender python así que ver música y python en un proyecto se me hace sorprendente, crees que exista la posibilidad de que pueda ver el repo de tu código?

    1. Hola, Berenice.

      No he hecho un repo para este código. Todo el código está en el artículo. Puedes copiar y pegar para poder ejecutarlo en tu ordenador.

      Si encuentro tiempo igual publico más artículos relacionados y si evoluciona el código a algo más completo igual creo un repositorio para dejar el código este y nuevo.

      Gracias por comentar 🙂

  2. Hola.

    Me gustó mucho tu programa, completé la canción con un rango de velocidad más lento ya que en la velocidad de 500 al ejecutar la semicorchea y tresillo no se distinga el sonido, además la transporte en la tonalidad original Gm.

    Saludos.

    700 = negra

    imnote = [
    8,8,8,8,8,4,
    8,8,8,8,8,4,
    8,8,8,8,8,4,
    8,8,8,8,8,4,
    8,8,8,4,11,
    8,4,11,8,
    3,3,3,4,11,
    7,4,11,8,
    8,8,8,8,7,6,
    5,4,5,9,2,1,12,
    11,10,11,4,7,4,7,
    11,8,11,3,
    8,8,8,8,7,6,
    5,4,5,9,2,1,12,
    11,10,11,4,7,4,11,
    8,4,11,8,
    8,8,8,8,8,4,
    8,8,8,8,8,4,
    8,8,8,8,8,4,
    8,8,8,8,8,4,
    8,8,8,4,11,
    8,4,11,8,
    3,3,3,4,11,
    7,4,11,8,
    8,8,8,8,7,6,
    5,4,5,9,2,1,12,
    11,10,11,4,7,4,7,
    11,8,11,3,
    8,8,8,8,7,6,
    5,4,5,9,2,1,12,
    11,10,11,4,7,4,11,
    8,4,11,8
    ]
    imoctave = [
    3,3,3,3,3,3,
    3,3,3,3,3,3,
    3,3,3,3,3,3,
    3,3,3,3,3,3,
    4,4,4,4,4,
    4,4,4,4,
    5,5,5,5,4,
    4,4,4,4,
    5,4,4,5,5,5,
    5,5,5,4,5,5,4,
    4,4,4,4,4,4,4,
    4,4,4,5,
    5,4,4,5,5,5,
    5,5,5,4,5,5,4,
    4,4,4,4,4,4,4,
    4,4,4,4,
    3,3,3,3,3,3,
    3,3,3,3,3,3,
    3,3,3,3,3,3,
    3,3,3,3,3,3,
    4,4,4,4,4,
    4,4,4,4,
    5,5,5,5,4,
    4,4,4,4,
    5,4,4,5,5,5,
    5,5,5,4,5,5,4,
    4,4,4,4,4,4,4,
    4,4,4,5,
    5,4,4,5,5,5,
    5,5,5,4,5,5,4,
    4,4,4,4,4,4,4,
    4,4,4,4
    ]
    imlong = [
    700,233,233,233,700,700,
    700,233,233,233,700,700,
    700,233,233,233,700,700,
    700,233,233,233,700,700,
    700,700,700,525,175,
    700,525,175,1400,
    700,700,700,525,175,
    700,525,175,1400,
    700,525,175,700,525,175,
    175,175,700,175,700,525,175,
    175,175,700,175,700,525,175,
    700,525,175,1400,
    700,525,175,700,525,175,
    175,175,700,175,700,525,175,
    175,175,700,175,700,525,175,
    700,525,175,1400,
    700,233,233,233,700,700,
    700,233,233,233,700,700,
    700,233,233,233,700,700,
    700,233,233,233,700,700,
    700,700,700,525,175,
    700,525,175,1400,
    700,700,700,525,175,
    700,525,175,1400,
    700,525,175,700,525,175,
    175,175,700,175,700,525,175,
    175,175,700,175,700,525,175,
    700,525,175,1400,
    700,525,175,700,525,175,
    175,175,700,175,700,525,175,
    175,175,700,175,700,525,175,
    700,525,175,1400
    ]
    for n, o, d in zip(imnote, imoctave, imlong):
    beep(n, o, d)

  3. Hola! Increíble el artículo, y como podemos combinar música con programación! Tengo una pregunta, conocen alguna libreria de machine learning de python con la cual se puede hacer música? Soy músico y estoy fuertemente aprendiendo python y matemáticas para involucrarme en el mundo de la Inteligencia Artificial, Machine Learning, Redes neuronales etc. He estado investigado, pero no encuentro una librería para el desarrollo de música con IA, conocen alguna? Un saludo!

Responder a Berenice Soto Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

twelve − six =