Nota: Este manual está en construcción y es muy posible que haya erratas y secciones incompletas. Si quieres ayudar, puedes ver algunos temas a resolver activando la hoja de estilo Default with TODO's. Normalmente en el menu Ver o Visualizar de tu navegador.
El subsistema de secuenciación de ALSA (seq) controla el flujo de eventos musicales, normalmente, de tipo MIDI. Los eventos MIDI describen música desde un punto de vista de interpretación. Ejemplos de eventos MIDI serían:
En contraste con la descripción física del sonido que maneja el subsistema pcm, este flujo tiene menor volumen de datos y facilita la manipulación musical.
Esos mensajes sirven, en última instancia, para controlar elementos del sistema que saben interpretar esa música, normalmente un sintetizador. El sintetizador suele ser:
En todo caso, un aspecto clave de los eventos MIDI es la temporización. Si el evento de inicio de nota empieza en un instante, el evento de fin de nota debe realizarse justo en el momento que hace que la nota tenga la duración precisa.
La única función del secuenciador de ALSA es gestionar la entrega de eventos musicales al destino apropiado en el momento apropiado. Estos eventos musicales suelen ser mensajes MIDI pero podrían ser cualquier otra cosa, el secuenciador los gestionaría igual.
Los posibles receptores y emisores de los eventos que maneja el secuenciador se llaman clientes. Estos clientes son los que gestionan el significado real de los eventos, mientras que el secuenciador se limita a temporizar y encaminarlos.
Ambos, los controladores del hardware MIDI y los programas de usuario (secuenciadores MIDI, filtros, sintetizadores por software...), son clientes del secuenciador ALSA pues todos envian y/o reciben eventos.
Podemos conectar programas de usuario entre sí como si fueran dispositivos hardware puesto que se ven todos los clientes de forma uniforme. El subsistema de secuenciación seq no necesita ningún añadido, como JACK en el subsistema pcm, para hacer este tipo de conexiones.
Cada cliente ofrece a los demás una serie de puertos. Cada puerto de un cliente admite un flujo de eventos de entrada y/o salida independiente.
El archivo virtual /proc/asound/seq/clients nos ofrece información valiosa para ver que clientes y puertos hay en el sistema, sus capacidades y estado. Por ejemplo, el contenido de ese fichero en mi sistema en este momento es:
$ cat /proc/asound/seq/clients Client info cur clients : 8 peak clients : 8 max clients : 192 Client 0 : "System" [Kernel] Port 0 : "Timer" (Rwe-) Port 1 : "Announce" (R-e-) Connecting To: 63:0 Client 63 : "OSS sequencer" [Kernel] Port 0 : "Receiver" (-we-) Connected From: 0:1 Client 64 : "Rawmidi 0 - EMU10K1 MPU-401 (UART)" [Kernel] Port 0 : "EMU10K1 MPU-401 (UART)" (RWeX) Client 65 : "Emu10k1 WaveTable" [Kernel] Port 0 : "Emu10k1 Port 0" (-We-) Port 1 : "Emu10k1 Port 1" (-We-) Port 2 : "Emu10k1 Port 2" (-We-) Port 3 : "Emu10k1 Port 3" (-We-) Client 72 : "Virtual Raw MIDI 1-0" [Kernel] Port 0 : "VirMIDI 1-0" (RWeX) Client 73 : "Virtual Raw MIDI 1-1" [Kernel] Port 0 : "VirMIDI 1-1" (RWeX) Client 74 : "Virtual Raw MIDI 1-2" [Kernel] Port 0 : "VirMIDI 1-2" (RWeX) Client 75 : "Virtual Raw MIDI 1-3" [Kernel] Port 0 : "VirMIDI 1-3" (RWeX)
Este listado nos muestra varias propiedades de los clientes y sus puertos:
Las capacidades de los puertos indican como se pueden establecer conexiones entre ellos.
Cada puerto puede tener habilitada la lectura, la escritura o ambas. Por ejemplo, una UART suele tener habilitadas las dos para enviar y recibir MIDI de dispositivos MIDI externos. Sin embargo, el sintetizador de la tarjeta normalmente solo tiene habilitada la escritura pues solo le podemos enviar MIDI para que lo reproduzca.
Algunos dispositivos permiten lectura y escritura, pero no permiten que se haga de forma simultánea. Se dice que no tienen la capacidad de trabajar en modo dúplex.
Si bien hay puertos que se abren para conectarse específicamente con algun puerto concreto, otros, en cambio, que se dejan disponibles para que cualquier puerto se pueda conectar con ellos, bien para lectura o bien para escritura. Se dice que estos últimos aceptan suscripciones de lectura o escritura. La capacidad de suscripción de lectura (o escritura) necesita para que se pueda usar, evidentemente, que tiene que haber capacidad de lectura (o escritura).
En el listado anterior se indica con r o w minúsculas que un puerto tiene acceso de lectura o escritura pero no permite suscripciones. Con la R y la W mayúsculas se indica que además del tipo de acceso, permite suscripciones. Una X indica que el puerto tiene capacidad dúplex.
Cuando dos puertos complementarios aceptan suscripciones, una tercera aplicación (como aconnect) puede ser la que establezca la suscripción mútua. Un puerto puede restringir, por seguridad, esta posibilidad. Esa es la capacidad que se indica en el listado con la letra e.
En resumen, las capacidades de los puertos:
Las conexiones que se establecen entre los puertos también tienen algunas propiedades:
Gestión del tiempo:
Nota: La sincronización Master/Slave que se explica en este apartado aún no está implementada. De todas formas, explico como funcionará basándome en los documentos de diseño de Takashi Iwai.
La sincronización permite que varios dispositivos MIDI se pongan de acuerdo en como avanza el tiempo en la interpretación. La sincronización toma relevancia cuando nuestro ordenador forma parte de una cadena MIDI con otros dispositivos MIDI externos. También se puede usar para sincronizar dispositivos software, por ejemplo, imagina que tenemos un generador de arpegios MIDI por software y un secuenciador de percusión y queremos que se mantenga sincronizados para que generen MIDI al compas, tendremos que sincronizarlos.
Se dice que hay varios dispositivos MIDI slaves que se sincronizan respecto a otro master. El master envia eventos de sincronización y el resto los usan para saber en que momento de la canción estan. Nuestro ordenador en una cadena MIDI hardware puede hacer de master o de slave.
Hay dos tipos de eventos de sincronización:
En ALSA las colas de eventos son las que temporizan los eventos. Por tanto, las colas, además de los dispositivos, pueden actuar como master o slave.
Sin embargo, los eventos se envian a un puerto y no explícitamente a una cola. Así pues, ALSA ofrece los puertos especiales del dispositivo de sistema 0 (System) para enviar y recibir eventos de temporización dirigidos a cada cola. El número de puerto es el número de la cola más 16.
Capacidades de los puertos en cuanto a sincronización:
Propiedades de las conexiones en cuanto a sincronización:
Alsa, al menos hasta la versión 1.0, sigue un patrón determinado para asignar números a los clientes y puertos. Es el siguiente:
En las siguientes secciones, se ilustran algunos usos del sistema de secuenciación de ALSA. Para ello usaremos un conjunto de herramientas que enumero a continuación:
aconnect | Visualiza y gestiona conexiones entre puertos seq. Existen alternativas gráficas como aconnectgui (fltk), kaconnect (qt/kde), ALSA Patch Bay (gtk)... |
---|---|
aseqview | Cliente que monitoriza de forma gráfica eventos MIDI que recibe y hace algunas transformaciones básicas (filtro de canales y pitch shift) antes de reenviarlos. |
pmidi | Envia el contenido de un archivo midi a un puerto MIDI. |
timidity | Sintetiza por software el MIDI que recibe. |
aseqnet | Cliente que envia y recibe MIDI por la red. |
Usaremos el programa pmidi para reproducir un fichero MIDI con ALSA. Primero usaremos la opción -l para ver que clientes podemos usar para reproducirlo. Es decir, veremos aquellos puertos que
$ pmidi -l Port Client name Port name 64:0 Rawmidi 0 - EMU10K1 MPU-401 (U EMU10K1 MPU-401 (UART) 65:0 Emu10k1 WaveTable Emu10k1 Port 0 65:1 Emu10k1 WaveTable Emu10k1 Port 1 65:2 Emu10k1 WaveTable Emu10k1 Port 2 65:3 Emu10k1 WaveTable Emu10k1 Port 3 72:0 Virtual Raw MIDI 1-0 VirMIDI 1-0 73:0 Virtual Raw MIDI 1-1 VirMIDI 1-1 74:0 Virtual Raw MIDI 1-2 VirMIDI 1-2 75:0 Virtual Raw MIDI 1-3 VirMIDI 1-3
En mi ordenador, con una tarjeta SB-live, me aparecen el puerto UART y 4 puertos para los 64 canales (16x4) del sintetizador de tabla de ondas de la tarjeta. Seguramente, tu tarjeta también tendrá un puerto externo, y un sintetizador hardware interno, ya sea uno por tabla de ondas (wavetable), por sintesis FM (como el Yamaha OPL3 que usaban las SoundBlaster antiguas). En mi caso tambien aparece el modulo VirMIDI que permite comunicar dispositivos/programas seq con programas rawmidi.
Para probar el MIDI de Alsa usaremos un puerto del sinte interno:
$ pmidi -p 65:0 test.mid
Si no suena nada comprueba que:
Es posible que el fichero MIDI tenga más de los 16 canales que acepta cada puerto. En ese caso podemos juntar varios puertos para reproducirlo integramente:
$ pmidi -p 65:0,65:1 test.mid
Mientras se ejecuta pmidi, este programa se convierte en un nuevo cliente y establece una conexión con el puerto que le hemos indicado.
Mientras se esta reproduciendo el fichero, podemos ver que conexiones hay activas con el commando de gestión de conexiones aconnect:
$ aconnect -iol client 0: 'System' [type=kernel] 0 'Timer ' 1 'Announce ' Connecting To: 63:0 client 64: 'Rawmidi 0 - EMU10K1 MPU-401 (UART)' [type=kernel] 0 'EMU10K1 MPU-401 (UART)' client 65: 'Emu10k1 WaveTable' [type=kernel] 0 'Emu10k1 Port 0 ' Connected From: 128:0 1 'Emu10k1 Port 1 ' 2 'Emu10k1 Port 2 ' 3 'Emu10k1 Port 3 ' client 128: 'Client-128' [type=user] 0 'port-0 ' Connecting To: 65:0
pmidi realiza la conexión por sí mismo indicándole el puerto. Pero algunos programas pueden esperar que la hagas tu desde fuera. En esos casos, podemos hacer servir aconnect para establecer la conexión.
$ aconnect [puerto de origen] [puerto de destino]
para desconectarlos:
$ aconnect -d [puerto de origen] [puerto de destino]
para desconectar todos
$ aconnect -x
para hacer una conexión exclusiva
$ aconnect -e [puerto de origen] [puerto de destino]
Evidentemente usando las interfícies gráficas, no hace falta aprenderse tanto comando pero no está nunca de más saberlo.
aseqview es un monitor gráfico de eventos MIDI. Es decir, un cliente que cuando recibe datos MIDI lo notifica visualmente. Nos va a ir muy bien para hacer las primeras pruebas con el secuenciador de ALSA. Cuando lo ejecutamos tenemos disponible otro cliente en el que leer y escribir.
Si le enviamos MIDI con pmidi veremos que se iluminan los monitores.
aseqview también hace funciones sencillas de filtro MIDI. Podemos modificar los eventos MIDI y leerlos con otro dispositivo. Para ver como funciona conectaremos el aseqview con el sintetizador de la tarjeta.
$ aconnect 128:0 65:0
Después de esto deberia de estar sonando la canción. Lo que suena no es directamente lo que envia pmidi sino que pasa por el filtro de aseqview. Podemos comprovarlo enmudeciendo algunos canales pulsando los botones de la izquierda o variando el pitch o la velocidad (fuerza) de las notas con los controles de la parte inferior.
Si has conectado al puerto UART de la targeta, o al puerto USB, segun el caso, un teclado MIDI externo, o cualquier otro dispositivo de entrada de datos MIDI como ahora un windcontroller, puedes hacer sonar el sinte interno de la tarjeta con él. Tan solo tienes que conectar el puerto externo UART (o USB) con el sinte interno:
$ aconnect 64:0 65:0
Si no tienes un teclado MIDI siempre puedes usar un teclado emulado por software. Hay varios programas que hacen esta función. Uno de los mas sencillos es vkeybd. Es una aplicacion que ocupa tambien el primer número de cliente disponible a partir de 128. Solo tenemos que conectarlo con aconnect a uno de los sumideros de MIDI, por ejemplo el sintetizador interno de la tarjeta:
$ aconnect 128:0 65:0 # suponiendo que al vkeybd se le ha asignado el 128
Este teclado emulado lo podemos tocar, bien con el raton, o bien con el teclado (de letras) de nuestro ordenador. El menu view nos deja ver algunos controles para:
De todas formas los controles de vkeybd no son demasiado prácticos de controlar. Si disponemos de un palanca de juegos (joystick) podemos usar la aplicación aseqjoy. Esta aplicación convierte el joystick en un controlador MIDI. Un controlador MIDI es un dispositivo MIDI que envia eventos para controlar parámetros del sintetizador.
El puerto MIDI UART (o el puerto USB) es bidireccional. Igual que entrabamos datos del teclado al ordenador podemos enviar MIDI a un sintetizador externo que este conectado a la UART. Es tan simple como enviar MIDI al cliente de la UART:
$ pmidi -p 64:0
Si no te gusta como suena el sintetizador MIDI por hardware de tu targeta de sonido, o simplemente, no tiene sintetizador, se puede emplear algo de cpu usando un sintetizador por software como timidity.
Los sintetizadores por software reciben eventos MIDI y calculan el sonido que envian a la salida pcm. Le costara más o menos al ordenador, dependiendo de la calidad que queramos, del algoritmo que usa, de la potencia de la máquina y del núcleo de Linux que uses (mejora mucho en 2.4 con los parches de baja latencia o cualquier versión de núcleo superior a 2.6).
Para probar timidity llamalo con un archivo MIDI de ejemplo:
$ timidity test.mid &
Si todo va bien, entonces puedes lanzarlo para que se quede en segundo plano:
$ timidity -iA &
Una vez lanzado, tendrás un nuevo cliente MIDI de escritura. Si miras que número de cliente tiene, puedes lanzar pmidi contra él.
$ pmidi -l Port Client name Port name 64:0 Rawmidi 0 - EMU10K1 MPU-401 (U EMU10K1 MPU-401 (UART) 65:0 Emu10k1 WaveTable Emu10k1 Port 0 65:1 Emu10k1 WaveTable Emu10k1 Port 1 65:2 Emu10k1 WaveTable Emu10k1 Port 2 65:3 Emu10k1 WaveTable Emu10k1 Port 3 128:0 Client-128 TiMidity port 0 128:1 Client-128 TiMidity port 1
Los dispositivos rawmidi controlan flujos de eventos MIDI sin ningún tipo de temporización ni encaminamiento directamente hacia (o desde) un dispositivo MIDI del sistema. Los clientes seq de sistema normalmente redirigen su flujo a dispositivos rawmidi que son los que se comunican finalmente con el controlador de hardware concreto.
ALSA, tal y como suele hacer cualquier sistema UNIX, presenta los dispositivos rawmidi como archivos a los cuales podemos escribir o de los cuales podemos leer. Los archivos de dispositivo rawmidi estan en /dev/snd/midiCcDd, donde c es el número de canal (0-3) y d es el numero de dispositivo (0-16).
Algunas aplicaciones antiguas o otras que no necesitan temporización ni enrutado y van directamente hacia un dispositivo hardware, por ejemplo, la carga o volcado de definiciones de instrumentos, usan este interfaz en pues es más directo de usar.
Algunas aplicaciones ALSA antiguas utilizan directamente los dispositivos rawmidi en vez de los dispositivos seq que actualmente ofrecen más funcionalidades: temporización, sincronización, multiplexación...
El módulo virmidi ofrece un dispositivo rawmidi sobre el cual estas aplicaciones pueden escribir o leer y crea un cliente seq asociado. Los datos que se escriben y leen de los dispositivos rawmidi se pueden leer o escribir en los dispositivos seq asociados. De esta forma podemos usar aplicaciones rawmidi como si fueran seq y así beneficiarnos del secuenciador.
Para activar virmidi solo hay que escribir como root:
# modprobe snd-virmidi
y nos aparecerà una nueva targeta con 4 dispositivos de un solo puerto (normalmente, si nada más hay una targeta instalada, són 72:0,73:0,74:0,75:0) que se corresponden con dispositivos rawmidi /dev/snd/midiC0D[n] consecutivos.
OSS (Open Sound System) es el sistema de àudio que se usaba en Linux (y otras plataformas tipo Unix) antes de ALSA. OSS tambien tenia un secuenciador y dispositivos MIDI planos aunque algo más limitados.
Aún, muchas aplicaciones estan programadas para utilizar el secuenciador de OSS. Un motivo para ello es que, actualmente, OSS es la única posibilidad en otras plataformas UNIX que no son Linux.
De una forma muy similar a como virmidi ofrece compatibilidad hacia atras para aplicaciones rawmidi, otro módulo seq-oss ofrece compatibilidad hacia atrás para las aplicaciones que usan OSS. De esta forma se puede realizar una transición suave de un sistema a otro.
Normalmente el modulo snd-seq-oss crea el puerto 63:0. Los eventos MIDI que se escriben en ese puerto se redirigen al dispositivo OSS /dev/sequencer del cual las aplicaciones OSS reciben MIDI. De la misma manera, lo que se lee en dicho puerto viene de lo que las aplicaciones OSS escribe en /dev/music.
La mayoria de la información en este apartado la he extraido de las transparencias y documentación de la pagina de Takashi Iwai en http://www.alsa-project.org/~iwai.
Tambien de otras fuentes: