Historique: Decryptage-fichier-MIDI
Aperçu de cette version: 20
note
Cette page concerne la partie descriptive du fichier MIDI et des codes contrôles de ce standard.
Pour la présentation du protocole MIDI voir ici
attention
Page en cours d'écriture ardoisebleue 04-12-2014 / 07-12-2014
Table des matières
Préambule :
Cet article est rédigé à partir de tests et du déchiffrage partiel d'un fichier au standard MIDI. Il existe quelques pages web sur ce protocole, mais elles ne sont pas accessibles pour corriger, modifier ou ajouter des informations ; C'est pour cette raison que j'ai entamé cette documentation afin que vous y ayez tous accès et puissiez l'améliorer et la faire évoluer.
Les généralités de cette norme sont décrites ici
Pour mes tests j'ai utilisé le langage de programmation C++(QT5) et me suis basé sur deux fichiers .MID , l'un exporté depuis le séquenceur Rosegarden, et l'autre étant un ancien export de Cakewalk.
Dans le texte qui suit :
- Toutes les valeurs des codes sont exprimées en hexadécimal sauf indication contraire.
- SMF = Standard MIDI File
- Les types de données sont décrits en annexe A.
Le format du fichier "mid"
Ce type de fichier est organisé en format RIFF (fichier bloc) voir ici pour des informations plus détaillées sur le principe des fichiers RIFF.
Le format de codage des données du fichier est variable suivant le message envoyé au matériel ou interprété par le séquenceur. Certains de ces messages ne sont destinés qu'au séquenceur, et font partie des métadonnées. Ces formats d'envoi de code sont constitués d'une suite d'octet, dont le ou les premiers, représente le délai par rapport à l'action précédente (pour certain code il est nul, donc un octet = 00 ), ensuite le codage détermine l'action à mener, le type de data à traiter et la ou les données à traiter.
à propos du délai
le délai n'est pas donné en valeur temps (sec ou mn), mais en nombre de division de la noire (voir ..... )
Définition du nombre de données à transmettre :
- le nombre de données est défini et est obligatoire :
| 80 40 7F | stopper la note MI(3) de vélocité d127 |
- Un seul paramètre dont la valeur peut dépasser 7F (d127)
| 05 20 | la valeur du paramètre est inférieure à d127 |
| 05 01 25 20 | la valeur 01 est l'octet de poids fort, et la valeur 20, qui suit le code 25 de dépassement de valeur, est l'octet de poids faible. |
- La longueur en octet du paramètre doit être est indiquée
| FF 07 03 41 42 43 | dans ce cas : FF 07 est le code pour un texte, 03 la longueur de cette chaine, et les 3 octets qui suivent forment la chaine. |
- La valeur et les data sont variables
| F0 0A xx xx ...... F7 | Ici le codage après F0 et avant xx peut contenir 1 ou 3 octets, la suite est une série de données qui se termine par le code F7. |
Il faut savoir que les données de type "texte" n'utilisent pas la terminaison 00 ; il faut utiliser la valeur donnée par l'octet de dimension de chaine. Ce qui implique qu'une chaine ne peut excéder 255 caractères.
Le premier bloc
Copy to clipboard
struct entete{ DWORD typestructure; DWORD tailledata;// nombre d'octets des données suivantes (ici 6) WORD typesmf WORD nbzonedata WORD diviseur }
Avec ce bloc de 14 octets nous récupérons :
- le type de structure : toujours MThd (fichier MIDI)
- type de standard SMF : SMF (Standard Midi File) valeur de 0 à 2.
- 0 : une seule zone data où se mélangent les événements de plusieurs canaux.
- 1 : plusieurs zones qui se suivent dans le fichier, mais sont jouées simultanément. Les métadonnées se trouvent dans la première zone. (Type le plus utilisé).
- 2 : plusieurs zones, jouées l'une après l'autre.
- Nombre de zones data : nombre de zones de données "MTrk" (MIDI track) de 1 à 65.535 octets
- diviseur pour 1 temps (valeur de la note noire) : codage pour 1 temps
- le premier bit du premier octet = 0 : le restant des bits définissent la valeur : 120, 240, 480, 960. ex : 01 e0 nous donne d480 tics pour la noire : 01*FF + E0.
- les trois premiers bits du premier octet = 64 (d100), ils indiquent une unité suivant la norme SMPTE.
| 4d 54 68 64 | MThd |
| 00 00 00 06 | 3 fois 2 octets suivent |
| 00 01 | type de SMF |
| 00 02 | deux zones de données |
| 01 e0 | 480 |
Le bloc data
Ce bloc peut contenir une ou plusieurs zones MTrk, suivant la valeur de "type de standard SMF" donné en entête (dans l'exemple utilisé, il y a deux zones). Ces zones contiennent les événements musicaux, contrôles et métadonnées. La dimension du blocdata étant donné sur 4 octets elle ne peut excéder d65535, sa structure est :
Copy to clipboard
struct zonedata{ DWORD balise; DWORD taille du blocdata; // ... data BYTE; BYTE; BYTE; 3 BYTE pour balise de fin de zone : obligatoire }
exemple :
| 4d 54 72 6b | MTrk |
| 00 00 00 72 | taille 114 octets : taille = taille du bloc - 3 octets ( code de fin ) |
| ....... | data |
| FF 2F 00 | code de fin du bloc MTrk |
Chaque zone de données Mtrk se termine impérativement par ces trois octets : FF 2F 00 ; Même si la zone est unique.
La plupart du temps, l'exportation vers un fichier MID, crée une zone MTrk par piste définie dans le séquenceur.
Organisation du codage
Le premier bloc data, quelle que soit la valeur du paramètre SMF, contient les métadonnées destinées au séquenceur et ne sont pas envoyées à l'appareil. Certaines d'entre elles servent d'informations et n'ont aucune utilité pour le jeu de la musique ; Ces métadonnées commencent obligatoirement par deux codes de valeur 00 FF, suivie d'un octet pour indiquer la fonction de la donnée (ex : 02 -> texte de copyright).
ex : 00 FF 02 03 41 42 43 donnée = "ABC" (dans la suite d'octet de ce code "chaine" l'octet <03> définit la taille de la chaine)
| 4d 54 72 6b | MTrk |
| 00 00 00 72 | 114 octets |
| 00 ff | ce qui suit est un message |
| 02 | texte de copyright |
| 1d | sa taille est de 29 caractères |
| 43 6f ....6f 6e | Copyright (c).... |
Ensuite il peut y avoir une suite de code "00ff" de type "07" définissant divers textes tel que le logiciel qui a créé le fichier. A leur suite vont apparaître d'autres métadonnées qui sont nécessaires aux appareils et/ou aux séquenceur tels le tempo ou l'indication de mesure, et celles-ci ont une position dans le temps pour être exécutées, dans ce cas le codage change, au lieu du "00 ff" on trouvera "8x xx ff" où "8x xx" définit le délai pour exécuter la fonction du code depuis le codage précédent.
Si un texte de chant est prévu, il est situé dans la deuxième zone MTrk et utilise le code ff05.
Codage du tempo
Pour coder le tempo le calcul s'effectue en microsecondes (µs). Par exemple un tempo de d80 battements/minute donne : 60/80 = 0.75 c'est à dire d750.000 µs par battement qui vont être codés comme suit :
| xx xx ff 51 03 0b 71 b0 | |
| xx xx | délai pour changer le tempo ( le premier code tempo est toujours en 00ff ) |
| ff 51 | code du tempo |
| 03 | nombre d'octets de définition |
| 0b 71 b0 | d750.000 => h 0b 71 b0 Le bit de poids fort en premier et celui de poids faible en dernier. |
S'il y a une suite de tempo différents, ils sont écrits à la suite l'un de l'autre dans ce même premier Mtrk.
| 00 ff 51 03 0b 71 b0 | premier tempo à 80 |
| 87 40 ff 51 03 07 a1 20 | changement de tempo qui monte à 120 à la mesure suivante |
| 87 40 ff 51 03 16 e3 60 | il redescend à 40 à la mesure suivante |
| 8f 00 ff 51 03 07 a1 20 | et revient à 120 après deux mesures |
La création d’accélération ou ralentissement se fera par une succession d'envoi de code. Suivant le séquenceur utilisé l'exportation de ces changement n'est pas la même. A titre d'exemple Rosegarden crée un code 51 à chaque événement musical qui semble calculé par rapport au moment où il a lieu, tandis que CakeWalk crée une suite de code 51, pour obtenir des "pentes" qui font abstraction des événements. Mathématiquement ces deux principe se valent, mais la deuxième méthode "bourre" le fichier de code 51.
à propos d'une suite de tempo
La suite des changements de tempo n'est pas directement placée derrière le tempo de départ, mais en général, tous les changements de tempo sont groupés dans le premier bloc MTrk avec le tempo de départ.
Codage de la mesure
Ce codage est définit par 4 valeurs : numérateur - dénominateur - métronome et nb de triple croches par 24 clics. le numérateur représentant le nombre de temps et le dénominateur le rang de la division de la ronde (0=ronde, 1 blanche, 2=noire, 3=croche...).
exemple pour une mesure en 2/2
| xx ff 58 04 02 02 18 08 | |
| xx ff 58 | où xx est le délai. En général, il n'y a qu'une définition de mesure. |
| 04 | nombre d'octets de définition |
| 02 02 | pour 2/2 |
| 18 | valeur du métronome : d24 pour la noire |
| 08 | 8 triple-croches pour valeur du métronome |
Codage de la clé
à développer
L'indication de la clé se précise sur deux octets
- l'altération de la tonalité est indiquée par un octet signé de F9 à 7
- le mode sur un octet : 00=majeur, 01=mineur.
00 ff 59 02: code la clé de départ
xx
00 : mode majeur
Codage d'une note
Le principe est d'envoyer un message noteON de démarrage de la note, puis un noteOFF d'arrêt de cette note.
ICICICICICI
Le décalage ou délai pour traiter le code
La succession des traitements des actions est pilotée par un délai qui débute chaque codage. Ce délai est donné par rapport à l'action précédente (délai relatif et non pas absolu) et s'exprime en nombre de division de la noire (Valeur donnée par les deux derniers octets du bloc MThd).
Si ce délai est inférieur ou égal à 7f, il n'y aura qu'un octet pour le définir.
S'il est supérieur à 7f, il peut y a voir deux ou plusieurs octets ; Le premier bit de tous les octets sauf le dernier est à 1, le dernier octet aura obligatoirement le premier bit est à 0. Les 7 autres bits représentent le facteur de la valeur du délai.
info
Le premier bit de l'octet juste avant le code MIDI est obligatoirement à 0 (donc valeur <= 7f). Il permet ainsi d'indiquer, s'il y a plusieurs octets pour le délai, qu'il est le dernier octet représentant ce délai.
exemple :
| 59 | un seul octet < 7f : délai = d89 tics | |
| A5 40 A5 40 |
1010 0101 0100 0000 |
le premier bit est ignorer => 100101 = d165 le premier bit est à 0 => dernier octet pour définir le délai : d64 délai = 165*128 + 64 = d21184 tics de délai avant d’exécuter le codage qui suit. |
| 92 d8 60 92 d8 60 |
1001 0010 1101 1000 0110 0000 |
premier bit ignorer => 10010 = d18 idem dessus => 1011000 = d88 dernier octet => d96 délai = 18*(128^2) + 88*128 + 96 = d306272 tics avant exécution. 306272/480 = 638 tics (unités de temps) |
limite du délai
La norme MIDI limite à 4 octets la définition du délai entre deux codages ce qui offre une valeur confortable.
annexes
description des types de données :
- DWORD 4 octets
- WORD 2 octets
- BYTE 1 octet
Codes des événements métadonnées :
Données texte
Tous ces codes sont précédés de xx xx FF où les xx représentent le délai avant l’exécution. Certaines métadonnées n'étant que des informations, le code avec le délai sera 00 FF.
Format : FF cc NN
| 01 | Texte quelconque |
| 02 | Copyright |
| 03 | nom de la piste |
| 04 | nom de l'instrument. |
| 05 | Sert à indiquer les paroles, ajustées à la musique. |
| 06 | Remarque quelconque, souvent sur la première piste Il peut y avoir plusieurs occurences de ce code |
| 07 | Indique un événement à un endroit précis de la partition exemple : le nom d'un fichier son à télécharger. |
| 08 | nom de l'instrument choisi, en association avec le choix de la banque de son. |
| 09 | nom unique du périphérique de sortie d'une piste, en précisant par exemple le nom du synthétiseur. À placer en tout début de zone MTrk, avant le contrôle de la banque de son ou de l'instrument, et avant tout envoi d'événement. info Un nom d'instrument doit être unique dans les fichiers avec SMF = 1 (une seule zone data) |