Usando el protocolo MIDI con Arduino

Aprovechando este tiempo de vacaciones estoy retomando proyectos sonoros que tenía bastante abandonados. Hoy es el turno de MIDI.

MIDI (Musical Instrument Digital Interface) es un estándar tecnológico que describe un protocolo, una interfaz digital y conectores que permiten que varios instrumentos musicales electrónicos, computadoras y otros dispositivos relacionados se conecten y comuniquen entre sí (Wikipedia).

Existen varias maneras de encarar un proyecto MIDI, y en este artículo les voy a contar sobre mis experiencias con Arduino y un software que servirá de nexo entre el hardware y la computadora.

¿Qué hardware necesito?

Voy a experimentar con hardware de muy bajo costo, luego habrá tiempo para ir escalando y mejorando el equipamiento. La placa elegida es la Arduino Nano, clon chino con el driver CH340, junto a un módulo de periféricos.

Módulo de periféricos y Arduino Nano

El módulo de periféricos está formado por los controles que gobernarán nuestra aplicación y unos pocos componentes adicionales. Tendremos a disposición:

  • Dos potenciómetros deslizables
  • Dos pulsadores

El circuito es el siguiente, y debido a su sencillez lo monté en una placa experimental.

Diagrama esquemático

¿Qué software necesito?

Nuestro trabajo consistirá en capturar los mensajes que envía por el puerto serie la placa Arduino y enviarlos a la aplicación que entiende MIDI. Utilizaremos el programa Hairless MIDI<->Serial Bridge que será el puente entre el dispositivo serie con la computadora. Es software libre, gratuito y compatible con Mac OSX, Microsoft Windows y GNU/Linux.

Hairless MIDI corriendo en Ubuntu 20.04

Debido a que el programa Hairless MIDI<->Serial Bridge es un ejecutable de 32 bits y la mayoría de las distribuciones GNU/Linux actuales son de 64 bits, tendremos que instalar las dependencias de 32 bits para poder correrlo. Por ejemplo para instalar las dependencias en Ubuntu 20.04, en una terminal escribimos el siguiente comando:

sudo apt install libasound2:i386 libsm6:i386 libxrender1:i386 libfontconfig1:i386 libasound2-plugins:i386 libxext6:i386

Para las pruebas estoy utilizando Virtual MIDI Piano Keyboard, que es un teclado virtual MIDI. Se puede usar con el teclado de la computadora, con el mouse o con hardware MIDI. Al igual que Hairless MIDI<->Serial Bridge es software libre y gratuito.

Para instalarlo en Ubuntu debemos tipear en la terminal:

sudo apt install vmpk

Si todo salió bien al ejecutar el programa vamos a ver una interfaz como la siguiente:

Software que controlaremos vía el hardware MIDI

Primeras pruebas

Antes que nada hay que conocer el protocolo MIDI, les recomiendo leer la especificación MIDI explicada por Sergi Jordà Puig en este enlace y luego empezar a experimentar. Para mi aplicación voy a usar los siguientes mensajes del protocolo:

  1. Note On. Este mensaje le indica al dispositivo que debe iniciar una nota, usualmente es generado cuando desde un teclado MIDI se aprieta una tecla.
    • El primer byte de datos indica la altura de la nota. MIDI contempla 128 posibles notas, siendo la 0 la nota más grave y la 127 la más aguda.
    • El segundo byte indica la velocidad de ataque, que viene determinada por la fuerza con que se ha apretado la tecla.
  2. Note Off. Similar al mensaje Note On pero con velocidad 0, por lo que se envía cuando se libera la tecla pulsada.
    • El primer byte es la altura de la nota.
    • El segundo byte es la velocidad de liberación.
  3. Control Change. Este mensaje engloba a 128 posibles mensajes de control diferentes que afectan de alguna forma a la calidad del sonido.
    • El primer byte indica el tipo de control.
    • El segundo byte indica el valor de este control, generalmente en el rango de 0 a 127.

Una vez que tenemos en claro el funcionamiento del protocolo MIDI, nos resta conectar el hardware y programar la placa Arduino Nano. Las conexiones de mi hardware son muy sencillas, sólo 6 cables:

Conexión Arduino Nano con el módulo de periféricos.

Antes de empezar a escribir el programa, tendremos que instalar la librería MIDI. Lo podemos hacer desde el Gestor de Librerías que incluye el IDE de Arduino:

Gestor de librerías de Arduino IDE

Voy a utilizar las siguientes funciones de la librería MIDI. Es muy recomendable leer la documentación completa de la misma antes de ponerse a programar:

  • MIDI_CREATE_DEFAULT_INSTANCE(). Crea una instancia de la librería.
  • MIDI.begin(). Inicializa la librería.
  • MIDI.sendNoteOn(nota, velocidad, canal). Envía un NoteOn.
  • MIDI.sendNoteOff(nota, velocidad, canal). Envía un NoteOff.
  • MIDI.sendControlChange(cc, valor, canal). Envía un ControlChange.

El siguiente sketch de ejemplo se encarga de leer los pulsadores y potenciómetros. Acto seguido envía una nota asociada, o los valores correspondientes a cambios en Volumen o Sustain.

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

const int POT_A = A0;
const int POT_B = A1;
const int PUL_A = 3;
const int PUL_B = 2;
boolean reboteA = false;
boolean reboteB = false;
int controlChange1 = 0;
int controlChange2 = 0;
int ultValor1 = 0;
int ultValor2 = 0;

void setup() {
  pinMode(PUL_A, INPUT);
  pinMode(PUL_B, INPUT);
  MIDI.begin();
  Serial.begin(115200);
}

void loop() {

  if (digitalRead(PUL_A) == LOW) {
    reboteA = true;
  }
  if (digitalRead(PUL_A) == HIGH && reboteA == true) {
    MIDI.sendNoteOn(60, 127, 1);
    delay(500);
    MIDI.sendNoteOff(60, 127, 1);
    delay(500);
    reboteA = false;
  }

  if (digitalRead(PUL_B) == LOW) {
    reboteB = true;
  }
  if (digitalRead(PUL_B) == HIGH && reboteB == true) {
    MIDI.sendNoteOn(80, 127, 1);
    delay(500);
    MIDI.sendNoteOff(80, 127, 1);
    delay(500);
    reboteB = false;
  }

  controlChange1 = analogRead(POT_A) / 8;
  if (controlChange1 != ultValor1) {
    MIDI.sendControlChange(7, controlChange1, 1); //Volumen
    ultValor1 = controlChange1;
  }

  controlChange2 = analogRead(POT_B) / 8;
  if (controlChange2 != ultValor2) {
    MIDI.sendControlChange(64, controlChange2, 1); //Sustain
    ultValor2 = controlChange2;
  }
}

En el vídeo una breve demostración del funcionamiento completo:

Conclusiones

Si bien este tutorial está basado en software corriendo sobre Ubuntu, se puede aplicar a otro tipo de sistemas. Por ejemplo en el caso de utilizar Windows hay que instalar además un puerto virtual MIDI. En está página hay un breve tutorial con los pasos a seguir.

A futuro se puede crecer en hardware para poder controlar más parámetros o crear un controlador personalizado. Por ejemplo es posible sumar potenciómetros, pulsadores y sensores (de luz, de sonido) y diseñar todo un ecosistema de hardware para la creación y producción de música.

Artículos relacionados