Tutorial · Laboratorio DIY
MIDI vs MusicXML en Python: qué se pierde y qué no
Un experimento con music21 y pretty_midi: la misma frase con digitación, ligadura y dinámica, exportada a MIDI y a MusicXML. Qué sobrevive en cada formato, con cifras reales.
MIDI es el formato que todo el mundo que ha tocado con un teclado electrónico conoce, aunque sea de oídas. MusicXML lo conoce mucho menos gente, y sin embargo hay una pregunta que aparece en cuanto se necesita algo más que “que suene”: ¿y si lo que hace falta es la partitura, no el sonido? Digitación, ligaduras, matices de dinámica —todo eso que un intérprete lee y un ordenador puede necesitar conservar—. Este tutorial no explica de nuevo qué es cada formato —para eso están ¿Qué es MIDI? y ¿Qué es MusicXML?— sino que lo demuestra: construye la misma frase musical una sola vez, la exporta a los dos formatos y comprueba, con datos reales, qué sobrevive en cada uno.
El experimento
La idea es sencilla: escribir una frase corta con music21 —digitación en cada nota, una ligadura y una marca de dinámica incluidas— y exportarla dos veces, una a MusicXML y otra a MIDI. Después, leer cada fichero de vuelta y ver qué queda.
from music21 import stream, note, meter, tempo, dynamics, articulations, spanner, clef
s = stream.Part()
s.append(clef.TrebleClef())
s.append(meter.TimeSignature('4/4'))
s.append(tempo.MetronomeMark(number=100))
n1 = note.Note('C5', quarterLength=1)
n1.articulations.append(articulations.Fingering(1))
n2 = note.Note('E5', quarterLength=1)
n2.articulations.append(articulations.Fingering(3))
n3 = note.Note('G5', quarterLength=0.5)
n3.articulations.append(articulations.Fingering(5))
n4 = note.Note('E5', quarterLength=0.5)
n4.articulations.append(articulations.Fingering(3))
n1.dynamic = dynamics.Dynamic('mp')
slur = spanner.Slur(n3, n4)
s.append(n1); s.append(n2); s.append(n3); s.append(n4)
s.insert(0, dynamics.Dynamic('mp'))
s.insert(0, slur)
s.write('musicxml', fp='ejemplo.musicxml')
s.write('midi', fp='ejemplo.mid')
Cuatro notas —Do5, Mi5, Sol5, Mi5—, cada una con su dedo indicado, las dos últimas ligadas entre sí y toda la frase marcada mezzopiano. Nada exótico: es exactamente el tipo de información que un intérprete espera ver impresa en una partitura.

Leyendo el MIDI de vuelta
Con pretty_midi se puede abrir ejemplo.mid y listar las notas tal como
quedaron codificadas:
pitch=72 start=0.00 end=0.60 velocity=81 (C5)
pitch=76 start=0.60 end=1.20 velocity=81 (E5)
pitch=79 start=1.20 end=1.50 velocity=81 (G5)
pitch=76 start=1.50 end=1.80 velocity=81 (E5)
Cuatro eventos de nota, cada uno con altura (pitch), instante de inicio y
fin en segundos, y una velocity —81 en las cuatro, resultado de traducir
la única dinámica mp de la frase a un valor MIDI fijo—. Es exactamente lo
que cabe esperar de MIDI: instrucciones de cuándo suena qué, con qué
intensidad. Ni rastro de la digitación, ni de la ligadura, ni de que hubo
alguna vez una marca “mp” en la partitura: esa información no tiene dónde
vivir en el protocolo. Se toca igual de bien, pero se ha perdido para
siempre en cuanto se guardó.
Leyendo el MusicXML de vuelta
Con music21.converter.parse sobre ejemplo.musicxml, la misma frase
devuelve mucho más:
C5: digitación=[1]
E5: digitación=[3]
G5: digitación=[5]
E5: digitación=[3]
Ligaduras (slurs) codificadas explícitamente: 2
Marcas de dinámica: ['mp']
Las cuatro digitaciones están intactas, la ligadura sigue codificada como tal
—no como una coincidencia de tiempos, sino como un elemento <slur>
explícito— y la marca “mp” sigue siendo “mp”, no un número de velocidad. Todo
lo que MIDI no tenía dónde guardar, MusicXML lo conserva porque describe la
partitura, no la interpretación.
Un fragmento del XML generado deja ver por qué: cada uno de esos elementos es una etiqueta legible, no un número de protocolo.
<dynamics default-x="-36" default-y="-80">
<mp />
</dynamics>
...
<fingering alternate="no" substitution="no">1</fingering>
...
<slur number="1" type="start" />
Lo que dicen los bytes
La diferencia también se ve, literalmente, en el tamaño y la forma de cada
fichero. ejemplo.mid pesa 99 bytes; ejemplo.musicxml, 3560 bytes
—36 veces más para la misma frase de cuatro notas—. No es ineficiencia: es
la diferencia entre guardar solo instrucciones de reproducción y guardar una
descripción completa de la notación escrita.
Los primeros bytes del MIDI, en hexadecimal, son binario puro:
4d54 6864 0000 0006 0001 0002 2760 4d54
726b 0000 0014 00ff 5103 0927 c000 ff58
Sin un parser de por medio, esto no dice nada. El MusicXML, en cambio, es
texto XML que cualquier persona puede abrir en un editor y leer —los
fragmentos de arriba (<dynamics>, <fingering>, <slur>) se entienden sin
más contexto que el propio nombre de la etiqueta—.
Tabla comparativa del experimento
MIDI (ejemplo.mid) | MusicXML (ejemplo.musicxml) | |
|---|---|---|
| Notas (altura, tiempo) | ✔ Conservadas | ✔ Conservadas |
| Digitación | ✘ Perdida | ✔ Conservada ([1], [3], [5], [3]) |
| Ligadura | ✘ Perdida (solo tiempos contiguos) | ✔ Conservada como <slur> explícito |
| Dinámica (“mp”) | Aproximada a velocity=81 | ✔ Conservada como texto (mp) |
| Tamaño | 99 bytes | 3560 bytes |
| Legible por una persona | ✘ Binario | ✔ Texto XML |
Por qué importa en la práctica
Esto no es una curiosidad de formato: decide qué herramienta usar según lo que se necesite conservar. Para reproducir, secuenciar o controlar un sintetizador, MIDI sobra y es más ligero. Para notación, pedagogía —una digitación que un alumno necesita ver impresa— o archivo de una partitura que se quiere editar más adelante, MIDI se queda corto por diseño, no por descuido: nunca prometió guardar eso.
Es también la razón de que un sistema de transcripción automática de música tenga que elegir con cuidado su formato de salida según el uso final: MIDI si el objetivo es que la transcripción suene, MusicXML si el objetivo es que alguien la lea, la corrija o la use para enseñar. En mi propia investigación doctoral trabajo con piano como corpus, y esta misma disyuntiva aparece en cuanto un sistema de AMT termina de decidir qué notas sonaron: el siguiente paso es en qué formato entregar ese resultado, y no es una decisión neutra.
Bibliografía
Las referencias en las que se apoya este artículo y por dónde seguir leyendo:
- The MIDI Association. The Official MIDI Specifications (MIDI 1.0, General MIDI, MIDI 2.0).
- W3C Music Notation Community Group. (2021). MusicXML 4.0.
- Cuthbert, M. S., & Ariza, C. (2010). music21: A Toolkit for Computer-Aided Musicology and Symbolic Music Data. Proceedings of the 11th International Society for Music Information Retrieval Conference (ISMIR).
- Raffel, C., & Ellis, D. P. W. pretty_midi: A Python Library for Handling MIDI Data — repositorio y documentación oficial.