MIDI

La norme MIDI (Musical Instrument Digital Interface) intervient dans la transmission physique entre synthétiseurs, séquenceurs, claviers et autres instruments de musique électronique (cables MIDI).
Elle intervient aussi pour stocker cette information dans des fichiers.

La norme MIDI est évoquée ici essentiellement sous l'aspect fichiers. Mais il est bien entendu que ces fichiers stockant des événements MIDI, les deux sont liés.
La norme MIDI est définie par le MMA (Midi Manufacturers Association).

Tables (résumé).

Messages MIDI

Un message MIDI est composé d'un premier octet dit de "status", suivi d'un nombre variable d'octets de données.
Les octets de status sont caractérisés par leur premier bit (de poids fort) à 1, c'est à dire 1xxxxxxx, donc ≥ 128 ou x80 en hexadécimal.

HexaBinaireDonnéesDescription
8n1000cccc2Note-off
9n1001cccc2Note-on
An1010cccc2Polyphonic aftertouch
Bn1011cccc2Control change
Channel mode
Cn1100cccc1Program change
Dn1101cccc1Channel aftertouch
En1110cccc2Pitch bend
Fn1111xxxx*System
La signification du status Bn 1011cccc dépend des données.
Pour les status 8n à En, la valeur de n = cccc est le numéro de canal moins un.
Le canal 1 est ainsi 0000, ... le canal 16 est 1111.

Note on/off

Le message "fondamental", provoquant l'émission d'une note et son arrêt.
Status    Note      Vélocité
100xcccc  0nnnnnnn  0vvvvvvv

x = 0 pour Note-off 8n, x = 1 pour Note-on 9n
cccc est le numéro de canal.
nnnnnnn est le numéro de note :
0 = Do -2 (à 8,176 Hz !)
...
69 = La 3 (440 Hz)
...
127 = Sol 8 (12543 Hz)
Un tableau complet est donné en annexe
vvvvvvv est la "vélocité" (la vitesse de frappe de la touche), de 0 à 127. Influe directement sur le volume émis (entre autres).

Une remarque importante : un message de Note-on avec une vélocité = 0 est compris comme un message de Note-off
Toute note démarrée par un Note-on doit être arrêtée par un Note-off correspondant.
La réaction d'un synthétiseur à deux messages de Note-on successifs sur la même note (v≠0) est indéterminée.

Control change

Les control change agissent sur divers paramètres du son.
Ils agissent sur des "contrôleurs", en temps réel.
Status    Numéro    Valeur
1011cccc  0nnnnnnn  0vvvvvvv
cccc est comme d'habitude le canal
nnnnnnn est le numéro du contrôleur, de 0 à 119
si nnnnnnn > 119 il ne s'agit pas d'un contrôleur mais d'un message "Channel mode"
vvvvvvv est la valeur du paramètre, de 0 à 127.

Les principaux contrôleurs définis par la norme sont :

HexDecContrôleur
00/200/32Bank select MSB/LSB
077Volume
0A10Pan
0B11Expression
4064Sustain

Channel mode

Les contrôleurs de numéros >119 sont en fait des messages de "channel mode", les principaux sont
HexDecMessage
78 00120All sound off
79 00121Reset all controllers
7A 00/7F122Local control On/Off
7B 00123All notes off

Program change

Le message de Program change choisit l'instrument utilisé pour toutes les notes suivantes du canal.
1100cccc 0ppppppp

Quelques instruments "standard" (General Midi)

HexInstrument
01Piano (Acoustic grand piano), défaut
12Piano (Bright Acoustic piano)
...
67Clavecin
...
2A43Violoncelle
...
7E127Applaudissements
7F128Coup de fusil
Il est d'usage de numéroter les intruments par la valeur ppppppp + 1
Ainsi l'instrument n° 1 (Grand Piano) est ppppppp = 0
Une liste complète des instruments "General Midi" en annexe.

L'extension au dela de 128 instruments est effectuée par le message de Bank select, choisissant une banque de 128 instruments parmi 16384 banques, soit un total théorique de 2 millions d'instruments !
Lorsqu'un message de Bank select est utilisé, le message de Program change doit le suivre immédiatement.
De plus le message de Bank select doit définir ses deux octets, c'est à dire deux messages successifs :

Bank select MSB 1011cccc 00000000 0hhhhhhh
Bank select LSB 1011cccc 00100000 0bbbbbbb
sélectionnant la banque hhhhhhhbbbbbbb
Le premier message (contrôleur 0) définit les poids forts MSB hhhhhhh
Le deuxième (contrôleur 32) définit les poids faibles LSB bbbbbbb

Note importante : les bank select sont spécifiques au synthétiseur utilisé.
Divers synthétiseurs utilisent d'autres mécanismes pour étendre le nombre d'instruments possible, par exemple via des messages "System exclusive".

Canal 10 Percussions

Le canal 10 (cccc = 1001 !) est réservé, en l'absence de program change spécifique sur ce canal, aux percussions.
Chaque "note" est affectée à un son de percussion particulier
Hexdec"Note"Instrument
2335B 0 (Si 0)Acoustic Bass Drum
2436C 1 (Do 1)Bass Drum 1
...
3452E 2 (Mi 2)Chinese Cymbal
...
4670A# 3 (La# 3)Maracas
...
5181A 4 (La 4)Open Triangle
Une liste complète des percussions "General Midi" en annexe.

Aftertouch

L'aftertouch modifie les caractérisrtiques du son en cours (entre le Note-on et le Note-off)
Par exemple commandé par la pression sur la touche. Peu utilisé ici, en ce qui nous concerne.
Il y a deux sortes d'aftertouch :
- Note par note (polyphonique), 1010cccc 0nnnnnnn 0vvvvvvv
nnnnnnn est le numéro de note affecté par cet aftertouch
vvvvvvv est la valeur du paramètre

- Par canal, 1101cccc 0vvvvvvv
il affecte toutes les notes en cours sur ce canal
vvvvvvv est la valeur du paramètre

Pitch Bend

Ce contrôleur correspond à une variation en temps réel de la hauteur des notes émises, par exemple par l'action sur la molette "Pitch" du clavier.
La valeur du pitch est définie sur deux octets (14 bits en fait)
1110cccc 0bbbbbbb 0hhhhhhh
La valeur du pitch est alors hhhhhhhbbbbbbb sur 14 bits.
La valeur min (note plus grave, pitch bend à -8192) est 0
La valeur médiane (note normale, pitch bend à 0) est 2000 hexa (octets 00 40)
La valeur maxi (note plus aigüe, pitch bend à +8191) est 3FFF hexa (octets 7F 7F)
L'amplitude exacte du pitch bend dépend du synthétiseur ainsi que d'autres paramètres.

System

Ces messages définissent des "extensions" aux messages ordinaires et s'adressent à l'ensemble des appareils reliés au réseau MIDI, donc sans considération de canal. On distingue les messages :

"System real time" 11111ttt

Utilisés pour la synchronisation (horloge, start etc...)

"System common" 11110sss ....

Avec sss = 1 à 6, et suivi de 0 à 2 octets de donnée.

"System exclusive" 11110000 .... 11110111

Ces messages ont un nombre d'octets de données variable, la fin des données étant marquée par un octet = F7
(rappel : les données MIDI ont leur bit de poids fort à 0)
Il en existe de deux sortes :
Ceux qui dépendent du constructeur, spécifiques d'un matériel donné
Les System exclusive "universels".
Dans les deux cas, le premier octet de donnée (identifiant) indique le constructeur, ou bien s'il s'agit d'un message universel.
7D est utilisé pour des "constructeurs" non commerciaux (recherche).
Les identifiants 7E (temps différé) et 7F (temps réel) caractérisent les System exclusive universels.

Un exemple de message System Exclusive : FO 44 03 00 71 51 21 F7
44 = Casio
03 00 ?? signification non précisée par Casio. Modèle ?
71 Canal 2 (70 à 73, canal 1 à 4)
51 ?? commande ?
21 sélection du deuxième jeu d'instruments (20 1er jeu, 21 deuxième jeu)
F7 fin de message

Nous n'en dirons pas plus ici sur les messages système.

Running status

Pour compresser l'information transmise, il est possible de supprimer l'octet de status, si celui-ci est inchangé depuis le message précédent.
Ceci est d'autant plus intéressant qu'un status de Note-off peut être remplacé par un Note-on avec une vélocité = 0.
Ainsi l'envoi successif de Do Ré Mi qui nécessite 6 messages de chacun 3 octets, soit 18 octets, est réduit à des messages de 2 octets sans status, sauf le premier, soit 13 octets.

Sans running status, avec des messages de Notes-off explicites :
90 3C 50 Note-on Do 3 ( = 3C hexa), v = 80 ( = 50 hexa), canal 1 (0000)
80 3C 40 Note-off Do 3, v = 64 (défaut, indifférent)
90 3E 50 Note-on Ré 3, v = 80
80 3E 40 Note-off Ré 3, v = 64
90 40 50 Note-on Mi 3, v = 80
80 40 40 Note-off Mi 3, v = 64

Avec running status, Notes-off remplacés par des Notes-on à v = 0 :
90 3C 50 Note-on Do 3, v = 80
3C 00 Note-on (=status précédent) Do 3, v = 0, équivaut à Note-off puisque v = 0
3E 50 Note-on Ré 3, v = 80
3E 00 Note-on Ré 3, v = 0
40 50 Note-on Mi 3, v = 80
40 00 Note-on Mi 3, v = 0

Fichiers MIDI

Nous nous interesserons essentiellement au format MIDI 1.
Le MIDI 0 est composé d'une seule piste.
Le MIDI 1 de plusieurs pistes simultanées
Le MIDI 2 de plusieurs séquences (morceaux)

Format d'un fichier MIDI :
Ces fichiers sont structurés en un certain nombre de parties appelées "chunk"
Un chunk est composé :

De quatre octets d'identification du type de chunk
De la longueur des données sur 4 octets
Des données

Le premier chunk est l'entête "Header Chunk"
Les suivants sont des chunks de pistes (tracks)

Header

Il commence par les octets Mthd soit en hexadécimal 4D 54 68 64
Suit la longueur sur 4 octets 00 00 00 06
Format : sur deux octets le type de format 0, 1 ou 2. Soit ici 00 01.
Nombre de pistes sur deux octets
Division : sur deux octets, spécifie l'unité de temps.

Cette unité de temps peut soit être définie en nombre de "ticks" par noire, soit en images/s
Format PPQ (Pulse par Quarter note) 0xxxxxxx xxxxxxxx

Pour subdiviser la noire, il faut bien entendu avoir une valeur > 1, mais si cette valeur est trop élevée le séquenceur risque de "ramer" dans son système temps réel.
Une valeur raisonnable est 192. En tout cas un multiple de 3 et de 2n (pourquoi donc... triolets, doubles et triples croches tout ça...).
La durée absolue d'un tick est définie ailleurs (le tempo).

Format SMPTE 1xxxxxxx yyyyyyyy

Ce format est utilisé fondamentalement pour synchroniser le son MIDI et l'image (video)
Il fait ainsi référence aux images "frames" et à des subdivisions.
xxxxxxx représente le nombre d'images par seconde, en complément à 2
yyyyyyyy le nombre de "ticks" par image
Ce format ne sera pas étudié plus avant ici, et nous utiliserons essentiellement le format PPQ

Exemple de Header :

4D 54 68 64  Mthd

00 00 00 06 longueur des données du Header = 6 octets
00 01 format MIDI 1
00 0D Nombre de pistes = 13
01 80 384 ticks par noire (180 hexa)

Viennent ensuite les chunks de piste :

Pistes

Le format d'un chunk de piste est le suivant
4D 54 68 64  Mtrk
xx xx xx xx  longueur des données du chunk, MSB d'abord
...          données = événements datés

La piste 0 est réservée aux événements de contrôle du séquenceur : changements de tempo et de mesures essentiellement.
Les pistes suivantes représentent généralement un "instrument" virtuel, une voix.
Rien n'impose d'affecter une piste du fichier à un canal MIDI particulier.
Même si générallement une piste = un canal = un instrument, rien n'empêche de mettre dans une piste des événements MIDI destinés à divers canaux et de modifier dynamiquement l'instrument utilisé (par des program change).

Evénements

Les données d'une piste se composent d'une suite d'événements MIDI
C'est à dire d'un message MIDI + le moment où doit être émis ce message.
 Delta time  Message 
L'instant du message est indiqué en relatif par rapport à l'événement précédent.
Le message midi est indiqué tel quel, avec running status éventuellement, à l'exception des messages système et des Meta events
Ces derniers étant des informations annexes, non destinées au réseau MIDI (auteur, titre, copyright etc.).

Delta time

La différence de temps entre l'événement et le précédent est indiquée en longueur variable.
C'est à dire que tant que le bit de poids fort vaut 1, il y a un octet (de 7 bits) suivant.

Par exemple un delta time de 100 = 64 hexa se traduit par un seul octet 01100100

Un delta time de 200 = C8 hexa par deux octets 10000001   01001000,
en concaténant les deux valeurs sur 7 bits on obtient bien 00000011001000

Un delta time de 20000 = 4E20 hexa par trois octets 10000001   10011100   00100000
en concaténant les trois valeurs sur 7 bits on obtient bien 000000100111000100000

Nbre d'octetsValeurs
10 à 127
2128 à 16383
316384 à 2097151
42097152 à 268435455
etc ...

Le delta time est exprimé en "tick" MIDI. La durée physique d'un tick dépend du tempo, et sa relation avec les notes sous l'aspect musical dépend de la résolution PPQ en nombre de ticks par noire du fichier (défini dans le header).

SysEx events

Les messages système MIDI (status Fn = 1111xxxx) ne peuvent être traités tels quels à cause des meta events.
Ils sont préfixés dans le fichier par F0 ou F7

System exclusive F0

Les messages système exclusive MIDI ont le status F0, inutile de le répéter et le format de l'événement dans le fichier est
 delta time  FO  Longueur  message après le F0, terminé par F7 

La longueur (nombre d'octets sans le F0, mais incluant le F7 de fin) est codée en longueur variable comme les delta time.

Par exemple un message MIDI système exclusive FO 44 03 00 71 51 21 F7 est codé

tt F0 07 44 03 00 71 51 21 F7 Longueur = 7 octets, F0 exclus, F7 inclus.
Je ne donnerais pas un exemple de message exclusif à plus de 127 octets pour illustrer le format variable de la longueur !

Morcellement F7

Pour morceler un message système dans le temps, les différents instants des morceaux sont marqués avec leur propre delta time, et chaque morceau additionnel est préfixé F7 au lieu de F0.
pour envoyer un message système en deux fois à 100 ticks d'intervalle

tt FO 03 xx xx xx    au temps tt, les 3 premiers octets

64 F7 04 xx xx xx F7 100 ticks plus tard les 4 derniers, dont le F7 de fin du message

System common et real time F7

Le préfixe F7, utilisé en dehors du morcellement, permet d'envoyer un message quelconque, donc en particulire ceux de status Fn avec n≠0.
 delta time  F7  Longueur  message MIDI quelconque, y compris le status

Par exemple un message Système temps réel "Start" (FA) sera codé tt F7 01 FA (il comporte l seul octet, le status = FA)

Meta events

Le dernier type d'événement stocké dans les pistes d'un fichier MIDI représente diverses informations, à priori non destinées aux instruments MIDI eux même.

 FF  Type  Longueur  Data 
Les principaux Meta Events sont :

Fin de piste

FF 2F 00 (Il comporte 0 octets de données)
Cet évenement est obligatoire en fin de piste

Texte

FF 01 nn texte texte général
FF 02 nn texte copyright
FF 03 nn texte nom du morceau / de la piste
FF 04 nn texte nom de l'instrument
FF 05 nn texte paroles, syllabes des paroles
FF 06 nn texte marqueur
nn est la longueur, en longueur variable comme pour les delta time
Le texte est en ASCII, éventuellement étendu

Tempo

FF 51 03 tt tt tt
tttttt représente la durée d'une noire en microsecondes, MSB d'abord.

Time signature

FF 58 04 nn dd cc bb
définit la mesure utilisée. D'un point de vue musical, une mesure N/D est représentée par
nn = N tel quel
dd = logarithme en base 2 du dénominateur D
ddD
001  
012  
024  
038  
0416
...
cc = 24×nombre de noires/temps
bb = 08, nombre de triples croches par noire
Ainsi une mesure à 6/8 est codée FF 58 04 06 03 24 08
24 hexa représentant 36 décimal, soit 24 * 1.5 soit une noire pointée par temps.

Key signature

FF 59 02 nn gg
nn est le nombre de dièses/bémols à la clé
nnTonalité
F97 bémols Dob majeur/Lab mineur
FA6 bémols Solb majeur/Mib mineur
FB5 bémols Réb majeur/Sib mineur
FC4 bémols Lab majeur/Fa mineur
FD3 bémols Mib majeur/Do mineur
FE2 bémols Sib majeur/Sol mineur
FF1 bémol Fa majeur/Ré mineur
00pas d'altération Do majeur/La mineur
011 dièse Sol majeur/Mi mineur
022 dièses Ré majeur/Si mineur
033 dièses La majeur/Fa# mineur
044 dièses Mi majeur/Do# mineur
055 dièses Si majeur/Sol# mineur
066 dièses Fa# majeur/Ré# mineur
077 dièses Do# majeur/La# mineur
gg = 00 tonalité majeure, gg = 01 tonalité mineure

Les meta events sont générallement regroupés dans la piste 0, à l'exception des textes par piste et du meta event "fin de piste".

Java et MIDI

Le format d'un fichier midi se reflète dans javax.sound.midi sous la forme des classes :
sequence représentant le fichier complet

track une piste
Une différence importante est que les événements stockés dans les tracks ne sont pas datés en relatif (delta time) mais en absolu.

Le Header chunk se retrouve comme propriétés de la séquence

Musiquee Accueil Mail