← Diário de Construção

MIDI para Programadores: Entendendo o Protocolo que Conecta Música e Código

Uma introdução técnica ao protocolo MIDI sob a ótica do desenvolvedor: estrutura binária de mensagens, comunicação serial e como interagir com hardware musical usando código.

Para quem está acostumado a lidar com APIs JSON de alta abstração, interagir com hardware físico às vezes parece um mistério. No entanto, quando entramos no mundo da música eletrônica, dos sintetizadores e dos controladores, descobrimos um protocolo criado nos anos 1980 que resolve a comunicação de hardware de forma extremamente elegante, leve e rápida: o MIDI (Musical Instrument Digital Interface).

Se você sabe programar e gosta de música, entender o MIDI abre as portas para criar seus próprios controladores personalizados, automatizar instrumentos reais e construir sistemas interativos de áudio.

O que realmente é o MIDI?

Um erro comum é pensar que o MIDI transporta áudio (o som físico de um instrumento). Na verdade, o MIDI é apenas um protocolo de dados de performance. Ele descreve o que um músico faz no instrumento, não o som que o instrumento produz.

Quando você aperta uma tecla em um teclado controlador MIDI, ele não envia uma onda sonora para o computador; ele envia um pequeno pacote de dados dizendo: “A tecla de número 60 (Dó central) foi pressionada no canal 1 com uma força (velocity) de 100”. Cabe ao receptor (um software no computador ou outro sintetizador) ler essa mensagem e gerar o som apropriado.

Essa distinção faz com que o fluxo de dados seja minúsculo, permitindo que a transmissão ocorra em tempo real sem latência perceptível.

A anatomia binária das mensagens MIDI

Como programadores, adoramos analisar a estrutura de dados. O MIDI 1.0 utiliza mensagens binárias curtas de 1 a 3 bytes enviadas serialmente.

A maioria das mensagens de canal é composta por:

  1. Status Byte (1 byte): Define o tipo de comando (Note On, Note Off, Control Change, etc.) e o canal MIDI (de 1 a 16). O bit mais significativo (MSB) de um Status Byte é sempre 1 (valores decimais de 128 a 255).
  2. Data Bytes (0, 1 ou 2 bytes): Contêm os parâmetros do comando. O bit mais significativo de um Data Byte é sempre 0 (valores decimais de 0 a 127).

Exemplo prático: O comando Note On (Tocar Nota)

Uma mensagem de “Note On” padrão possui 3 bytes:

  • Byte 1 (Status): 0x90 (onde 9 representa Note On e 0 representa o canal 1).
  • Byte 2 (Nota): 0x3C (valor decimal 60, mapeando para o Dó central - C4).
  • Byte 3 (Velocidade/Força): 0x64 (valor decimal 100, indicando a intensidade do toque).

Para parar de tocar a nota, o controlador envia uma mensagem de Note Off (0x80, 0x3C, 0x00) ou um Note On com força zero (0x90, 0x3C, 0x00).

Comunicação serial e latência

O MIDI tradicional utiliza uma comunicação serial simples assíncrona operando a uma taxa de transmissão fixa de 31.250 bits por segundo (baud rate).

Embora essa taxa pareça extremamente lenta para os padrões atuais (onde gigabits são a norma), ela é perfeitamente balanceada para o hardware de baixo consumo dos microcontroladores e para o tamanho das mensagens. Enviar uma mensagem de Note On de 3 bytes (24 bits no total) leva menos de 1 milissegundo, o que está bem abaixo do limiar de latência perceptível para o ouvido humano (cerca de 10ms).

Atualmente, o MIDI também é encapsulado via USB (USB-MIDI), trafegando na velocidade padrão das portas USB modernas com largura de banda ainda maior.

Interagindo com MIDI via código (Python e C++)

Conectar seu código ao mundo MIDI é simples graças a bibliotecas prontas em praticamente todas as linguagens modernas.

Lendo MIDI com Python (Mido)

Usando a biblioteca mido, você consegue abrir portas MIDI do seu computador e imprimir as mensagens recebidas em tempo real com pouquíssimas linhas de código:

import mido

# Lista as portas de entrada disponíveis
print(mido.get_input_names())

# Abre a primeira porta e escuta as mensagens
with mido.open_input('Nome do Seu Teclado MIDI') as inport:
    for msg in inport:
        if msg.type == 'note_on':
            print(f"Nota Pressionada: {msg.note} | Força: {msg.velocity}")

Gerando MIDI com Arduino (ESP32 / Arduino Uno)

Se você estiver construindo seu próprio pedalboard ou controlador com botões físicos e potenciômetros, pode utilizar a biblioteca MIDI em C++ para enviar comandos para seus sintetizadores:

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  MIDI.begin(MIDI_CHANNEL_OFF);
}

void loop() {
  // Envia a nota C4 (60) no canal 1 com força 100
  MIDI.sendNoteOn(60, 100, 1);
  delay(1000);
  
  // Envia Note Off para parar o som
  MIDI.sendNoteOff(60, 0, 1);
  delay(1000);
}

Conclusão

O MIDI prova que protocolos simples e focados em eficiência de transmissão duram décadas. Ao compreender a arquitetura binária das suas mensagens e o funcionamento da comunicação serial, você pode programar soluções que expandem a criatividade musical, integrando o software que você escreve ao hardware físico que você usa no palco ou no estúdio.

Tecnologias e Conceitos