Mostrando las entradas con la etiqueta ALSA. Mostrar todas las entradas
Mostrando las entradas con la etiqueta ALSA. Mostrar todas las entradas

lunes, 28 de abril de 2014

Raspberry Pi procesando eventos MIDI con Python (Parte 2)

Al estar leyendo esta segunda parte de este artículo, se asume que ya se tienen cubiertos todos los requisitos técnicos y de conocimientos cubiertos en la primera parte, si aún no estan completos, te invito a que des un click aquí y la visites.


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.

viernes, 4 de octubre de 2013

Raspberry Pi procesando eventos MIDI con Python (Parte 1)

Otro de mis pasatiempos, y para el que no soy muy bueno por cierto, es la música. He intentado aprender a tocar algunos instrumentos pero no he tenido la paciencia necesaria para desarrollar las habilidades, sin embargo gracias a familiares cercanos que viven de la música he aprendido un poco de las bases y esto me ha servido para poder ayudarles en el escenario como parte de su staff conectando cables tanto de audio como MIDI, llevandome a trasladar esos conocimientos a mi area de comfort, las computadoras.


Las computadoras y el sonido


Desde los inicios de la computación casera, las computadoras han sido capaces de generar sonido, las antiguas computadoras traian una bocinita integrada al chasis, que era incapaz de reproducir la gran gama de sonidos que actualmente son capaces de reproducirse gracias a las tarjetas de sonido y sintetizadores integrados.


Bocina integrada al chasis de la computadora

Al dia de hoy, es muy sencillo y hasta natural esperar sonido de alta definición en nuestras computadoras ya sea originado por procesamiento de ondas o por síntesis.

Esto último es importante entenderlo y diferenciarlo para el alcance de este proyecto.


Archivos de onda


La reproducción de archivos de onda es la generación de sonido teniendo como datos de entrada los valores de los muestreos de la amplitud de onda a determinada frecuencia, es decir, los valores discretos de la onda a una frecuencia y resolucion determinadas, un ejemplo de esto es la reproducción de un CD de música y archivos WAV (entre otros) que tienen valores típicos de frecuencia de muestreo de 44.1 KHz (o 44100 muestras por segundo) con una resolución de 16 bits (2^16 = 65536) para los valores de la amplitud de onda por cada canal.


Discretización de una onda análoga

Una de las ventajas de este acercamiento es que la reproducción es independiente del dispositivo y debería de sonar igual en todos lados (sin considerar variables como amplificadores o altavoces) pues la onda original se esta reconstruyendo de la manera mas fiel posible con referencia a la fuente.

Estos archivos suelen ser muy grandes en tamaño para mantener su fidelidad y son ideales para ser procesados en cualquier DAW (Digital Audio Workstation).


Archivos MIDI


MIDI es el acrónimo en ingles para Musical Instrument Digital Interface que describe todo un protocolo, interfaz digital y conectores que permiten el intermabio de información entre instrumentos musicales electrónicos, computadoras y dispositivos compatibles.

La tecnología MIDI fue estandarizada en 1983, por lo que debemos de entender que es algo un poco viejo, sin embargo es un estandar actualmente muy utilizado en la industria musical actual, a pesar de sus 30 años de vida.

Si han puesto atención habrán notado que hasta el momento jamas he hablado de sonido relacionado con MIDI, y es porque el sonido no se transmite a traves de las conexiones MIDI, lo unico que viaja entre dispositivos son mensajes MIDI que el dispositivo receptor interpretará de acuerdo a su implementación, esto puede ser algo como un tick de reloj o el evento de reproducir la nota B# de un piano de cola por 123 milisegundos, que hacer con cierto mensaje, depende totalmente de quien recibe el mensaje, nada mas.

El sonido generado por un dispositivo MIDI es una característica muy particular del dispositivo en si, es decir, si uno tiene dos sintetizadores MIDI de diferente marca y ambos reciben el mismo mensaje de reproducir una cierta nota de un instrumento especifico, no sonarán igual, y es posible que aún dos dispositivos de la misma marca y modelo, expuestos a diferentes situaciones de trabajo, temperatura y uso generen sonido diferente para el mismo evento.

La razón del comportamiento anterior es que el sonido es generado por la circuitería que sintetiza la onda del sonido solicitado, por lo que cada implementación es única. Existe también la opcion de sintetizar el sonido por software, y esta es la opción que mas adelante nosotros utilizaremos.

Ya para finalizar solo queda mencionar que el tamaño de los archivos MIDI es muy pequeño, pues solo guarda los mensajes que deben ser enviados, no el sonido en si, para escucharlos se requiere de un sintetizador, ya sea por software o por hardware y que a pesar de todo tienen grandes ventajas como poder variar los instrumentos que se reproducen, cambiar el tempo y hasta generar la partitura de la música almacenada.


Sonido en la Raspberry Pi


Ya que tenemos conocimiento de las bases sobre las que sustentaremos nuestro proyecto, comenzaremos con la configuración del sonido en la Raspberry Pi.

Dependiendo de la versión de Raspbian instalada en su computadora, el módulo de sonido puede estar o no configurado por default. Para saberlo, haremos la siguiente prueba:

lsmod | grep snd_bcm2835

Si este comando nos devuelve algo, significa que el módulo esta cargado en memoria y puedes evitar los siguientes pasos de esta sección.

Al leer esta linea, asumo que el módulo de sonido no esta instalado y que necesitas un poco de guia al respecto, asi que sigamos los siguientes pasos.

Primero, instalar ALSA que es el acrónimo de Advanced Linux Sound Architecture, para esto, hay que ejecutar los siguientes comandos para instalar ALSA y sus utilerias y posteriormente reiniciar el equipo:
$ sudo apt-get install alsa-utils
$ sudo reboot

Espera que la Raspberry Pi reinicie, una vez reiniciada, cargaremos el módulo de sonido de manera manual
  1. $ sudo modprobe snd_bcm2835

y lo configuraremos para que utilice la salida de audio de 3.5mm

  1. $ sudo amixer cset numid=3 1

En este punto deberiamos de ser capaces de escuchar algo al conectar bocinas o audifonos a la computadora. Podemos probar instalando el reproductor de linea de comando mpg321, el siguiente comando lo hará por nosotros:

$ sudo apt-get -y install mpg321

Una vez instalado mpg321 y sus dependencias, descarguemos un MP3 y reproduzcamoslo:

$ wget http://www.flashkit.com/imagesvr_ce/flashkit/soundfx/Cartoon/Laughter/demonic_-daniel_a-8513/demonic_-daniel_a-8513_hifi.mp3

$ mpg321 demonic_-daniel_a-8513_hifi.mp3

Debes de haber escuchado una risa malevola como la que cualquiera haría una vez que ha configurado el sonido por primera vez en linux :)

Por el momento dejare hasta aqui esta entrada, sabiendo que quienes estan siguiendola ya tienen el sonido configurado, en la segunda parte nos dedicaremos a la parte MIDI y a procesarlos con Python para obtener algo similar a esto



Como siempre, si tienen cualquier duda o comentario, no duden en hacerlo!

Saludos y hasta la próxima!