Enfocandonos en MIDI
Ya tenemos sonido en nuestra Raspberry Pi, ya reproduce archivos de onda, ahora ¿que hace falta para reproducir archivos MIDI? ¿Que hace falta para que obtengamos sonido de un archivo MIDI?
El acercamiento que tendremos en este proyecto sera muy similar a lo que en seguridad informatica se le conoce como "Man-in-the-middle" en el cual tendremos como origen, el programa reproductor de archivos MIDI aplaymidi que es parte del paquete ALSA que ya instalamos (ver la primera parte de este artículo), en el medio nuestro script de python, y en el otro extremo, el sintetizador de sonido. De esta manera, el reproductor obtiene del archivo todos y cada uno de los eventos MIDI almacenados en el archivo, nuestro script recibira esos mensajes y actuará de acuerdo al los datos enviados en el mensaje, reenviando el mensaje (sin modificarlo, es decir, haciendo la función de MIDI THRU) hacia el sintetizador que finalmente reproducira el sonido.
El reproductor MIDI
Como ya se menciono, utilizaremos aplaymidi como nuestro reproductor MIDI, este se encargará de extraer la informacion de nuestro archivo origen y de enviarla a nuestro script de python. La linea de comando es muy sencilla, tal como se muestra a continuación:aplaymidi /path/a_nuestro/archivo.mid --port 129
Aunque es nuestra fuente de información, esto sera lo ultimo que ejecutaremos, pues necesitamos tener completo todo lo demás para que funcione como esperamos.
Nuestro script de Python
Para poder recibir, poder interpretar y reenviar los mensajes MIDI a otro cliente, necesitamos poder comunicarnos en el mismo medio que es a traves de ALSA, por lo que les sugiero el uso de la librería alsaseq desarrollada por Patricio Paez Serrato (home page pp.com.mx) que tiene las interfaces con Python para la comunicación con secuenciadores ALSA.
El sitio original donde esta la información para la instalación de la libreria es http://pp.com.mx/python/alsaseq/project.html y donde puden descargar la versión mas reciente de alsaseq que al momento de escribir este articulo es la 0.4.1 es http://pp.com.mx/python/alsaseq/
Una vez instalada la libreria alsaseq, solo es necesario copiar y pegar el siguiente script en su editor de texto favorito y guardarlo en una ruta conocida con el nombre midilights.py,
import RPi.GPIO as GPIO
import alsaseq
# Set up the GPIO mode
GPIO.setmode(GPIO.BOARD)
#Initialize a list with the GPIO pin numbers we are going to use
gpiopins = [7,8,10,11,12,13,15,16,18,19,21,22]
# Set up pins listed as outputs
print "Setting up pins ",
for p in gpiopins :
print str(p) + " ",
GPIO.setup(p, GPIO.OUT)
GPIO.setup(p, GPIO.LOW)
print "for OUPUT - LOW completed."
#Initialize all LEDs to off
for y in range(0,12) :
GPIO.output(gpiopins[y],False)
alsaseq.client( 'MIDI Lights', 1, 1, False )
alsaseq.connectfrom( 0, 20, 0 )
alsaseq.connectto( 1, 128, 0 )
while 1:
if alsaseq.inputpending():
ev = alsaseq.input()
alsaseq.output(ev)
if ev[7][0] != 9:
#print ev
event = ev[0]
note = ev[7][1]%12
dura = ev[7][2]
if event == 7:
#print "Turn off ", note
GPIO.output(gpiopins[note],False)
elif event == 6:
if dura == 0:
#print "Turn off ", note
GPIO.output(gpiopins[note],False)
else:
#print "Turn on ", note
GPIO.output(gpiopins[note],True)
else:
print "Not handled : ", ev
# to reset every channel that has been set up by this program to INPUT with no pullup/pulldown and no event detection.
GPIO.cleanup()
Como se puede ver este script inicializa los siguientes puertos GPIO como salidas 7, 8, 10, 11, 12, 13, 15, 16, 18, 19, 21 y 22 por lo que puedes suponer que para obtener el resultado deseado deberemos de conectar un LED a cada uno de ellos.
En este punto asumo que ya sabes como hacer el circuito básico para hacer esto, si no, te recomiendo leer esta entrada del blog :
Controlar un LED con los GPIOs de la Raspberry Pi
El sintetizador de sonido
Podriamos pensar en esto como la cereza del pastel, es decir, donde por fin obtendremos audio y podremos confirmar que las luces responden a los sonidos que inician y terminan durante la reproduccion de la música.
En lo personal les recomiendo Timidity++ que es un sintentizador de muy alta calidad, sin embargo tal vez sea algo demasiado pesado para una computadora sencilla como la Raspberry Pi, pues requiere demasiado CPU para poder ofrecer la calidad que tiene. Para el alcance de este artículo les dare las instrucciones de como instalar Timidity++, sin embargo los invito a que ustedes prueben con otros sintentizadores para que comparen resultados y los compartan con los lectores de este blog.
Timidity++ esta disponible en los repositorios oficiales de Raspbian, por lo que su instalación es sencilla. Primero que nada procederemos a actualizar nuestros repositorios. Desde la consola ejecutar los siguientes comandos;
$ sudo apt-get update
$ sudo apt-get install timidity freepats timidity-daemon pmidi fluid-soundfont-gm fluid-soundfont-gs
tras la ejecución del segundo comando el sistema preguntará si desean descargar e instalar un monton de paquetes mas de los que dependen los que deseamos instalar, hay que aceptar para que tengamos todo instalado correctamente.
Una vez descargados e instalados los paquetes requeridos por Tmidity y sus dependencias, te recomiendo reiniciar tu Raspberry Pi para que de esta manera el daemon de Timidity++ arranque durante el proceso de inicio del sistema y nos olvidemos de el, pues estara disponible cuando lo necesitemos a partir de ese momento.
Iniciemos el show
Cuando el sistema este reiniciado, ya sea que accedamos a el de manera remota (SSH) o de manera local en el teclado y monitor, necesitaremos abrir dos consolas, si lo haces por SSH, solamente conectate dos veces y listo, si lo haces de manera local si estas en modo gráfico (no lo recomiendo), solamente habre dos ventanas de terminar, si estas por consola presiona CTRL+ALT+F2 y te cambiara a una segunda consola, para volver a la primera presiona CTRL+ALT+F1
En una de las dos consolas iremos a la ruta donde guardamos el script arriba mencionado y ejecutaremos el comando:
sudo python midilights.py
Este comando nos dara una salida sencilla avisandonos que configuro los puertos GPIO y que esta a la espera de mensajes MIDI en el puerto 129.
Nos cambiamos a la siguiente ventana/consola/conexión para ejecutar el siguiente comando
aconnect -o
este comando desplegara una salida similar a esta:
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 128: 'TiMidity' [type=user]
0 'TiMidity port 0 '
1 'TiMidity port 1 '
2 'TiMidity port 2 '
3 'TiMidity port 3 '
client 129: 'MIDI Lights' [type=user]
0 'Input port '
lo que nos importa ver es ese cliente numero 129, de nombre 'MIDI Lights' que lo que nos confirma es que nuestro script esta listo para recibir conexiones en el puerto 129.
Ahora si, estamos listos para enviarle los mensajes a nuestro script, esto lo haremos ejecutando el programa reproductor de archivos MIDI, el cual estará direccionado al puerto 129, para que nuestro script haga su trabajo de procesar y reenviar al sintetizador.
Antes de ejecutar este comando no olvides tener unas bocinas conectadas a tu Raspberry Pi para escucharla ejecutar tu archivo
El ultimo comando a ejecutar sera:
aplaymidi /ruta/a_algun/archivo.mid --port 129
si todo ha sido ejecutado y validado con cuidado, a partir de este momento deberiamos tener sonido y un pequeño show de luces como en el siguiente video:
Como siempre, agradezco su atención leyendo este blog y para cualquier duda o comentario, estoy a sus ordenes, solo tengan paciencia si no les contesto pronto pero siempre intentare ayudarles aunque sea tarde.