Scripts MIDI-IN avec Python, MidO et RtMidi (5/6)

Initiation à la programmation MIDI (Musical Instrument Digital Interface) en utilisant le trio « Python – MidO – RtMidi », avec focus sur MIDI-IN

Dans cet article nous allons nous intéresser aux Scripts MIDI-IN avec Python, MidO et RtMidi et nous servir de ce que nous avons déjà vu dans les 4 articles précédents :

Comme écrit dans mon article 1/6, MIDI-IN(PUT) est sûrement le plus complexe à traiter car tout est presque du temps réel et les combinaisons d’information reçues sont multiples, mais aussi le plus motivant par toutes les possibilités proposées pour la gestion des messages MIDI.

♦ MidO et les messages MIDI

Pour mémoire, MidO – MIDI Objects for Python – est actuellement en version 1.2.9. C’est une bibliothèque spécialisée pour travailler avec les messages et les ports MIDI. Il est conçu pour être aussi simple et pythonique que possible. MidO nous permet donc de travailler +/- facilement avec tous les messages MIDI en tant qu’objets Python dans un script ou un projet plus complet.
Une bonne maîtrise de Python 3 est nécessaire pour mener à bien des projets complexes.

Vous trouverez dans la documentation de MidO, entre autres choses :

  • Une liste de tous les messages pris en charge et de leurs paramètres dans Message Types. Un message Mido est un objet Python avec des méthodes et des attributs. Les attributs varient en fonction du type de message,
  • Pour plus de détails sur l’encodage binaire d’un message MIDI, voir Summary of MIDI Messages de Midi.org et Introduction to MIDI programming in Linux,
  • Une liste des types de méta-messages supportés dans Meta Message Types, et
  • Une Bibliothèque de références dans Library Reference incluant Messages, Ports, Backends, Parsing, MIDI Files, SYX Files, Port Classes and Functions, Socket Ports et Frozen Messages.

MIDI Message Generator

Lire une longue documentation technique sur le codage MIDI n’est pas toujours évident. Pour nous simplifier la vie nous trouvons, par exemple, un Générateur de messages MIDI bien pratique à notre disposition sur la toile.

Nous choisissons parmi les 15 Types de Message proposés, puis nous complétons notre demande en fonction du type que nous avons choisi. À la fin, le générateur nous affiche le résultat sous la forme d’une suite encodée.
Par exemple /midi/0x90 60 64 veut dire que ce qui suit est une chaîne MIDI avec Message Type: Note On, Channel: 1, Note: 60 (C3), Velocity: 64.

/midi/ 0x 90 60 64
MIDI hexa Note On – Channel 1 Note (C3) Velocity

Mais attention, les valeurs de Note et Velocity sont données en décimal et pas en hexadécimal. En fonction de vos équipements, si vous avez besoin de faire des conversions, servez-vous de la calculatrice en « mode programmation » disponible dans votre distribution GNU/Linux préférée.
Pour mémoire, en programmation nous pouvons écrire un littéral de plusieurs façons. Par exemple pour 15 (décimal base 10 – 0d15), nous avons 0xF (hexadécimal – base 16) ou 0o17 (octal – base 8) ou 0b1111 (binaire – base 2), etc.

Nota bene : MidO numérote les canaux de 0 à 15 (0x0 à 0xF) au lieu de 1 à 16, idem pour les programmes (sonorités – voix) de 0 à 127 (0x0 à 0x7F) au lieu de 1 à 128. Cela facilite leur travail en Python, mais nous pouvons-devons (en fonction du logiciel et/ou périphérique MIDI utilisé) ajouter ou soustraire 1 lorsque nous communiquons <==> avec une interface utilisateur.

Rappel sur le format des messages MIDI (hors SysEx F0H…..F7H)

Dans la Spécification MIDI, il existe 2 types de base d’octet de message : l’octet d’état (Status) et l’octet de données (Data 1 – Data 2). Le bit le plus significatif (MSB) d’un octet d’état est toujours 1, le bit le plus significatif (MSB) d’un octet de données est toujours 0.
La longueur maximale d’un message MIDI standard est de 3 octets (Status + Data 1 + Data 2), mais elle peut être inférieure pour certains types de message MIDI.

STATUS  Byte
DATA 1  Byte
DATA 2  Byte
1 s s s n n n n 0 x x x x x x x 0 x x x x x x x

Mais il n’y a que 7 bits utiles, dans chaque octet (8 bits), pour représenter les données uniques contenues dans l’octet de message. On peut facilement calculer qu’il n’y a que 2^7, soit 128 valeurs discrètes disponibles par octet. Cela signifie qu’il existe 8 types fondamentaux de messages d’état (s) qui, si un message spécifique à un canal, peuvent être envoyés à l’un des 16 canaux MIDI différents. Si le message d’état n’est pas spécifique à un canal, le quartet inférieur (n – 4 bits) de l’état représente l’une des 16 sous-classes de message différentes.

Il existe 2 classifications différentes de messages MIDI : les Messages de Données MIDI (MIDI Data Messages) et les Messages Système MIDI (MIDI System Messages). Les messages de données MIDI sont spécifiques à un canal, les messages système MIDI ne sont pas spécifiques à un canal.

Summary of MIDI Messages et Expanded Messages List (Status Bytes)
Ces tableaux sont conçus comme une vue d’ensemble du MIDI et ne sont en aucun cas complets. Ils répertorient les principaux messages MIDI par ordre numérique (binaire).

Un extrait de messages MIDI – Toutes les valeurs sont au format Hexadécimal (0x) !

MIDI Message
Status Byte
Data 1 Byte
Data 2 Byte
Note Off 8n Note Number Velocity
Note On 9n Note Number Velocity
Polyphonic Aftertouch An Note Number Pressure
Control Change (CC) Bn Controller Number Data
Program Change (PC) Cn Program Number Not used
Channel Aftertouch Dn Pressure Not used
Pitch Wheel En LSB MSB

n est le numéro de canal MIDI (MIDI Channel Number) de 0x0 à 0xF (0 à 15 décimal).
LSB est l’octet le moins significatif (Least Significant Byte).
MSB est l’octet le plus significatif (Most Significant Byte).
– Il existe plusieurs types de messages de contrôleur (CC). Voir les Spécifications MIDI v.1.0 (1983/85) et la v.1.1 (1999).

♦ Utilisation des scripts Python – MidO

Installer si nécessaire, configurer les logiciels (Audio = Jack, Midi = Alsa, la-les fonte-s sonore-s), et vérifier qu’en appuyant (clavier PC, souris ou écran tactile) sur les touches de VMPK les notes jouées retentissent bien dans les hauts-parleurs de votre PC

  • Système d’exploitation libre GNU/Linux, ici Linux MINT 19.1 Cinnamon 64-bit avec noyau standard
  • Python v.3.6.7+, Python3-Mido v.1.2.7+, Python3-Rtmidi v.1.1.0+ et IDLE Python v.3.6.7+ ou Spyder v.3.2.6+
  • QjackClt v.0.4.5+ et Jackd v.1.9.12+
  • Qsynth v.0.5.0+, FluidSynth et au moins une Fonte sonore .sf2, par exemple FluidR3_GM.sf2
  • VMPK (Virtual Midi Piano Keyboard), de préférence v.0.7.0+ car il intègre beaucoup de nouveautés très intéressantes
  • Patchage v.1.0.0+ (nous pourrions aussi utiliser le bouton Connecter de Qsynth)

Virtual MIDI Piano Keyboard

Dans le Script-1 nous utiliserons VMPK v.0.7.1 (format *.appimage tout-en-un de 24 Mo), un logiciel clavier-contrôleur MIDI virtuel flexible et très pratique. VMPK utilise un framework d’interface graphique moderne : Qt4, qui permet d’excellentes performances et fonctionnalités. L’API RtMidi fournit les fonctionnalités d’entrée/sortie MIDI (comme pour MidO). Ces deux frameworks sont libres et indépendants de la plateforme matérielle, et sont disponibles pour les systèmes d’exploitation libres GNU/Linux, et propriétaires macOS et Windows.

VMPK possède les principales caractéristiques suivantes :
  • 1x MIDI-IN port + 1x MIDI-OUT/THRU port and MIDI standards compliant
  • Configurable number of keys/octaves + starting note + key size + computer keyboard mappings
  • Touch screen support
  • MIDI Output to internal and/or external synthesizers
  • MIDI Input & Output to network, using an ipMIDI compatible protocol
  • MIDI Input & Output to OS native drivers (GNU/Linux, macOS and Windows)
  • Translations to many languages including French

♦ Lecture de MIDI-IN(PUT)

Le principe de base pour la lecture de MIDI-IN est toujours la même : créer ou utiliser une « Boucle sans fin » qui scrute constamment un ou des ports MIDI-IN (RtMidi-IN). Cette boucle peut être plus ou moins complexe en implémentant par exemple un-des filtre-s de messages MIDI incluant les SysEx. La gestion peut prendre différentes formes : du plus simple affichage à l’écran des messages reçus, en passant par le traitement des notes jouées et d’autres messages, voire de leur stockage sur un media (disque dur, SSD ou clé USB) afin de pouvoir les réutiliser ultérieurement.
Nous pouvons utiliser les ports RtMidi-In / RtMidi-Out comme un simple Midi-Thru ou alors retravailler les messages entre ces deux ports en ayant un Midi-Thru intelligent.

NB : Pour des questions d’organisation, je code sur 2 ordinateurs portables (un HP Pavilion DV8 avec écran classique 18,4″ et un HP Spectre x2 avec écran tactile 13,3″) mais toujours sous Linux Mint 19.1 Cinnamon 64-bits. De ce fait, le rendu des captures d’écran ci-après peut être différent.

• SCRIPT-1 / Acquisition de « Messages MIDI »

Ce script va lire les messages MIDI jouées sur le clavier de VMPK, les envoyer par son Output vers RtMidiIn, les afficher sur l’écran de l’ordinateur (formats humain et décimal), rediriger RtMidiOut vers Fluid Synth (QS-M2_TofH-XG) (IN), et faire retentir les messages Notes sur le système Audio du PC en utilisant JACK Audio. Les messages Program Change (PC) seront utilisés pour changer d’instruments MIDI GM (General Midi) sur la SoundFont activée de QSynth.

VMPK Out -> RtMidi In + Écran / RtMidi Out -> QSynth/FluidSynth In -> JACK Audio -> Audio PC

Un exemple de configuration utilisée dans le cadre d’un script « Acquisition de MIDI-IN » codé en Python3 – MidO – RtMidi sous système d’exploitation libre GNU/Linux

Mappage des connexions MIDI ALSA et AUDIO JACK

Patchage permet de voir en un coup d’œil le mappage graphique complet pour les systèmes Audio et MIDI basés sur JACK et ALSA. C’est aussi un excellent outil de vérification et de dépannage des connexions Audio et MIDI. De plus, il autorise d’intervenir directement à la souris sur les connexions (ON/OFF et déplacements) compatibles en cas de besoin.
Par rapport aux précédents articles, sur mon PC HP DV8 j’ai modifié dans QSynth les paramètres de la SoundFont QS-J1_FluidR3-GM pour sa sortie Son de Audio JACK en Audio ALSA. De ce fait, elle n’apparaît plus sur le mappage ci-dessous où l’Audio est tout en JACK.

Un exemple d’utilisation de Patchage dans le cadre du codage d’un script « Acquisition de MIDI-IN » en Python3 – MidO – RtMidi sous système d’exploitation libre GNU/Linux

Fonctionnement du Script-1

Importation de la librairie MidO dans le script Python

1. SCAN Ports MIDI-IN/OUT accessibles à MIDO/RTMIDI sur le PC
Le script lui-même n’a pas besoin de ces lignes et elles peuvent être retirées sans souci. C’est une aide afin que le codeur puisse identifier les bons ports MIDI à intégrer dans son script. Pour mémoire, les ports de l’API RtMidi (RtMidiIn Client et RtMidiOut Client) ne seront visibles qu’une fois le script lancé.

2. START… MIDI INPUTS SCAN
outport = mido.open_output(‘Synth input port (QS-M2_TofH-XG:0)’)
Ouverture du port RtMidiOut avec connexion au port Input du synthétiseur logiciel.
with mido.open_input(‘VMPK Output:out’) as inport:
Ouverture du port RtMidiIn avec connexion au port Output du clavier virtuel VMPK et importation des messages dans ‘inport’.
for msg in inport:  Passe les messages contenus dans ‘inport’ à ‘msg’.
print(‘Humain: ‘, msg)
Affiche à l’écran les messages contenus dans ‘msg’ sous une forme compréhensible par l’utilisateur.
print(‘  Bytes:’, msg.bytes())
Affiche à l’écran les messages contenus dans ‘msg’ sous forme d’une suite décimal.
outport.send(msg)
Envoie les messages contenus dans ‘msg’ de RtMidiOut Client vers le port Input du synthétiseur logiciel.
– La boucle conditionnelle if/else
Permet de sortir de la boucle d’acquisition des messages MIDI en appuyant sur la touche Do1 du clavier virtuel VMPK. Nous aurions pu utiliser d’autres procédures mais celle-ci est la plus simple pour ce script.
exit()  Met fin au script et demande confirmation pour le fermer suite à l’appui sur la touche Do1.

# ============================================
# File name: MIDO-IN_Tests-VMPK.py - June 2019
# MIDO INPUT TESTS ===== by Joe Linux @ Rouen
# ============================================
import mido  # importe bibliothèque MidO qui gère aussi l'API Python RtMidi

print("1. == SCAN Ports MIDI-IN/OUT accessibles à MIDO/RTMIDI sur le PC ==")
print("Scan Midi-IN Ports...")
print("MidO-IN =", mido.get_input_names(),"\n") # liste ports IN disponibles
print("Scan Midi-OUT Ports...")
print("MidO-OUT =", mido.get_output_names(),"\n") # liste ports OUT disponibles

# ***** MIDI-IN / MIDO *****
# Test de réception de messages MIDI envoyés par Virtual Midi Piano Keyboard (VMPK)
#   à RtMidi-In (Thru) vers RtMidi-Out qui le renvoie vers Qsynth/FluidSynth

# Boucle d'acquisition et d'affichage des messages envoyés par VMPK,
#   avec touche Do1 pour sortir de la boucle et terminer le script
print("2. == START... MIDI INPUTS SCAN ==")
print("* Aquisition + Affichage des messages MIDI envoyés par VMPK *")
outport = mido.open_output('Synth input port (QS-M2_TofH-XG:0)') # connexion RtMidi-Out à Synth-In
with mido.open_input('VMPK Output:out') as inport: # connexion VMPK-Out à RtMidi-In
    for msg in inport: # passe contenu 'inport' à 'msg'
        if msg.bytes() != [144, 24, 127]: # touche Do1 pour sortir boucle acquisition messages
            print("Humain: ", msg) # affiche contenu 'msg' Humain à l'écran
            print("  Bytes:", msg.bytes()) # affiche contenu 'msg' Bytes décimal à l'écran
            outport.send(msg) # envoie contenu 'msg' à RtMidi-Out vers Synth-In
        else:
            print("\nACQUISITION MIDI-IN TERMINÉE...")
            exit() # arrête le script avec demande confirmation (fonction IDE utilisé)

Remarque : L’instruction outport = mido.open_output(‘Synth name’) ne ferme pas le port RtMidiOut Client après l’arrêt du script. Pour ce faire, dans les Scripts suivants nous ajouterons l’instruction ad-hoc ainsi qu’une vérification de la bonne fermeture des ports In et Out de RtMidi.

Précision : En Python, l’expression with… as…, avec son mot-clé with, est utile lorsque nous utilisons des ressources non gérées (telles que des flux de fichiers, de données, …). Cela est pratique lorsque nous avons deux opérations connexes que nous souhaitons exécuter en tant que paire, avec un bloc de code entre les deux. Ici, elle permet de lire en boucle les messages MIDI qui se présentent sur RtMidiIn,  de les afficher à l’écran, de les envoyer vers le synthétiseur logiciel, puis de fermer automatiquement le port RtMidiIn Client après l’arrêt du script.

• SCRIPT-2 / Acquisition de « Messages MIDI »

Le Script-2 est identique au Script-1 mais il utilise un clavier-contrôleur MIDI physique, le Roland PC-200 (de 1999), branché au PC par un adaptateur MIDI/USB, le M-Audio Uno MIDI/USB.

Ce clavier n’est pas 100% compatible avec la norme MIDI et en particulier pour les messages « notes ». Il envoie toujours des « note_on » même pour des messages « note_off » en réglant la « velocity » à 0. Ce qui est vrai pour ce clavier l’est aussi pour beaucoup d’autres équipements MIDI. Le codeur devra tenir compte des singularités de chaque équipement utilisé pour adapter son code à l’objectif visé.

Roland PC-200 Midi-Out -> M-Audio Uno Midi-IN/USB -> RtMidi In + Écran / RtMidi Out -> QSynth/FluidSynth In -> JACK Audio -> Audio PC

Un exemple de configuration utilisée dans le cadre d’un script « Acquisition de MIDI-IN » codé en Python3 – MidO – RtMidi sous système d’exploitation libre GNU/Linux, ici avec un clavier-contrôleur MIDI Roland PC-200

Comme nous pouvons le voir dans la capture d’écran ci-dessus, le Roland PC-200 envoie ses messages « notes » sous la forme:
– Note ON : note_on channel=0 note=60 velocity=85 time=0 (90 3C 55 en hexa) √
– Note OFF : note_on channel=0 note=60 velocity=0 time=0 (90 3C 00 en hexa) ⊗
ce qui est correct pour « note_on » mais pas pour « note_off » qui devrait être :
– Note OFF : note_off channel=0 note 60 velocity=0 time=0 (80 3C 00 en hexa). √
Voir plus haut : le Tableau « Extrait de messages MIDI ».

Un exemple d’utilisation de Patchage dans le cadre du codage d’un script « Acquisition de MIDI-IN » en Python3 – MidO – RtMidi sous système d’exploitation libre GNU/Linux, ici avec un clavier-contrôleur MIDI Roland PC-200 (GIF animé)

1. SCAN Ports MIDI-IN/OUT accessibles à MIDO/RTMIDI sur le PC
Les commentaires dans le Script-1 étaient sujet à interprétation et ils ont été revus et simplifiés ici afin de clarifier et préciser le propos. Comme écrit plus haut, le script lui-même n’a pas besoin de ces lignes et elles peuvent être ajoutées ou retirées sans souci.

print("1. == SCAN Ports MIDI-IN/OUT accessibles à MIDO/RTMIDI sur le PC ==")
print("Scan Ports Midi-OUT des équipements accessibles à RtMidi-IN...")
print(mido.get_input_names(),"\n")
print("Scan Ports Midi-IN des Équipements accessibles à RtMidi-OUT...")
print(mido.get_output_names(),"\n")

Fonctionnement du Script-2

Le fonctionnement du Script-2 est similaire à celui du Script-1. Pour les ajouts et modifications, voyez les commentaires dans le corps du script.

Pour résumer les évolutions dans les grandes les lignes :
– Clavier-contrôleur physique Roland PC-200 remplace clavier-contrôleur virtuel VMPK.
– Ajout d’une interface physique M-Audio Uno MIDI/USB entre le PC-200 et MidO (RtMidi).
– Sortie du script par touche Do2 au lieu de Do1 et détection vélocité à 0.
– Avant la sortie du script, envoi d’une RàZ (reset) de toutes les notes et de tous les contrôleurs sur chaque canal.
– Fermeture propre du port RtMidi-Out avec vérification.

# ==============================================
# File name: MIDO-IN_Tests-Roland.py - June 2019
# Ordinateur HP Spectre x2 - Joe Linux @ Rouen
# ==============================================
import mido  # importe bibliothèque MidO qui gère aussi l'API Python RtMidi

# ***** ACQUISITION MIDI-IN / MIDO-RTMIDI *****
# Test de réception de messages MIDI envoyés par Roland PC-200 à M-Audio Uno MIDI/USB
#   puis de RtMidi-In (Thru) vers RtMidi-Out qui les renvoie vers Qsynth/FluidSynth
print("2. == Boucle Acquisition + Affichage Messages envoyés par Clavier physique ==")
outport = mido.open_output('Synth input port (QS3_TofH-GM:0)') # connexion RtMidi-Out à Synth-In
with mido.open_input('USB Uno MIDI Interface MIDI 1') as inport: # connexion RtMidi-In à M-Audio-Out
    for msg in inport: # passe contenu 'inport' à 'msg'
        if msg.bytes() != [144, 36, 0]: # teste touche Do2 ON/OFF pour sortir boucle acquisition
            outport.send(msg) # envoie contenu 'msg' à RtMidi-Out vers Synth-In
            print("Humain: ", msg) # affiche contenu 'msg' Humain à l'écran
            print("  Bytes décimal:", msg.bytes()) # affiche contenu 'msg' Bytes à l'écran
            print("  Bytes hexadéc:", msg.hex()) # affiche contenu 'msg' Bytes à l'écran
            # ATTENTION: chaque "print" introduit du retard dans le jeu temps réel
            #   des notes jouées. Il faut structurer le script en conséquence.
        else:
            outport.reset() # envoie "All notes off" + "Reset all controllers" sur chaque canal
            # outport.panic() # stoppe toutes notes qui sonnent mais sans RàZ des contrôleurs
            outport.close() # ferme le port RtMidi-Out proprement
            if outport.closed: # test si port bien fermé
                print("\nLe port RtMidi a bien été fermé !")
            print("\nTouche DO 2 appuyée puis relachée = EXIT !", msg.bytes())
            print("ACQUISITION MIDI-IN TERMINÉE...")
            # Le port RtMidi-IN a été fermé automatiquement à la fin de la procédure with...as 
            exit() # arrête le script avec demande confirmation (fonction IDE utilisé)

• SCRIPT-3 / Acquisition de « Messages MIDI SysEx »

Le Script-3 est identique au Scripts-2 mais se concentre sur l’acquisition des SysEx (and Sun 😛 ) et utilise un clavier – synthétiseur – séquenceur MIDI matériel, le PSR-620 (FR) de Yamaha sorti en 1994.
Et oui, il a déjà 25 ans d’âge (un quart de siècle) et il est toujours pleinement opérationnel, après avoir remplacé son Lecteur de disquettes 3.5″ 720 Ko 2DD par un Émulateur USB de Lecteur de disquettes.

Les Messages Exclusifs au Système (System Exclusive ou SysEx) expliquent en grande partie la flexibilité et la longévité de la norme MIDI. Les fabricants les utilisent pour créer des messages propriétaires contrôlant leur équipement plus minutieusement que les messages MIDI standard. Les messages SysEx sont adressés à un périphérique spécifique dans un système. Chaque fabricant a un identificateur unique (43H pour Yamaha Corporation) qui est inclus dans ses messages SysEx, ce qui permet de garantir que seul le périphérique ciblé répond au message et que tous les autres l’ignorent. Les messages SysEx peuvent inclure des fonctionnalités allant au-delà de celles fournies par la norme MIDI. Ils ciblent un instrument spécifique et sont ignorés par tous les autres périphériques du système.

SysEx est une partie spéciale du protocole MIDI. Tous les messages MIDI, à l’exception de SysEx (ou presque), ont une longueur définie et chaque octet a une signification spécifique. Dans les messages SysEx, les seuls octets définis sont START (F0H ou 0xF0) et END (F7H ou 0xF7). Tous les octets entre START et END sont arbitraires et la signification du message dépend uniquement du fabricant qui l’implémente. C’est la raison pour laquelle la plupart des contrôleurs MIDI qui implémentent un type de configuration utilisateur utilisent des messages SysEx personnalisés pour configurer le périphérique en question.

Universal System Exclusive Messages – Les SysEx universels sont définis comme étant en temps réel ou non, et sont utilisés pour les extensions MIDI qui ne sont PAS destinées à être exclusives à un fabricant donné (malgré le nom).

Le PSR-620 supporte les 8 messages SysEx (Début F0H – Fin F7H en Hexa) suivants, voir les pages 100 et suivantes de sa documentation ci-dessus, mais d’autres possibilités existent aussi.
QUOI SYSEX (H = 0x = Hexa)
DESCRIPTION
<SysEx Dump Request>
<= dans les 2 sens =>
F0H 43H … … … … … F7H Yamaha ne documente pas tout un tas de possibilités, détails à confirmer après tests
<GM system ON> F0H, 7EH, 7FH, 09H, 01H, F7H
Universal SysEx
RàZ du système General MIDI
<DISK ORCHESTRA ON> F0H, 43H, 73H, 01H, 14H, F7H Active Disk Orchestra de Yamaha
<DISK ORCHESTRA OFF> F0H, 43H, 73H, 01H, 13H, F7H Désactive Disk Orhestra
<MIDI Master Volume> F0H, 7FH, 7FH, 04H, 01H, ll, mm, F7H
Universal SysEx
Règle le volume de tous les canaux avec un contrôleur extérieur
<MIDI Master Tuning> F0H, 43H, 1nH, 27H, 30H, 00H, 00H, mm, ll, cc, F7H Permet d’ajuster la hauteur MIDI de toutes les notes
<Panel Voice> F0H, 43H, 76H, 1BH, cc, vv, F7H Permet de choisir les voix du Panneau ou celles GM
<XG System On> F0H, 43H, 1nH, 4CH, 00H, 00H, 7EH, 00H, F7H Bascule le système en EXtended General MIDI de Yamaha
<XG Parameter Change> F0H, 43H, 1nH, 4CH, aaH, bbH, ccH, ddH……..F7H Permet de changer les paramètres XG

Comme pour le Roland PC-200, le Yamaha PSR-620 n’est pas 100% compatible avec la norme MIDI et en particulier pour les messages « notes ». Il envoie toujours des « note_on » même pour des messages « note_off » en réglant la « velocity » à 0. À gérer par le codeur.

Yamaha PSR-620 Midi-Out -> M-Audio Uno Midi-IN/USB -> RtMidi In + Écran

Un exemple de configuration utilisée dans le cadre d’un script « Acquisition de MIDI-IN » codé en Python3 – MidO – RtMidi sous système d’exploitation libre GNU/Linux, ici avec un clavier – synthétiseur – séquenceur MIDI Yamaha PSR-620

Fonctionnement du Script-3

Le fonctionnement du Script-3 est +/- similaire à celui du Script-2. Pour les ajouts et modifications, voyez les commentaires dans le corps du script.

Pour résumer les évolutions dans les grandes les lignes :
– Clavier-synthétiseur-séquenceur MIDI Yamaha PSR-620 remplace clavier-contrôleur physique Roland PC-200.
– À nouveau, I/F physique M-Audio Uno MIDI/USB entre le PSR-620 et MidO (RtMidi).
– Utilisation d’une boucle IF/ELIF/ELSE (Pyhton) avec IF pour tester si ‘msg.type’ (MidO) est égal à SysEx, ELIF pour tester ON/OFF touche Do2 = EXIT et ELSE qui confirme la fin du script.
– Sortie du script par touche Do2 avec détection vélocité à 0 (= relachement).
– Le port RtMidi-IN est toujours fermé automatiquement à la fin de la procédure ‘with…as’.

# ===============================================
# File name: MIDO-IN_Tests-PSR-620.py - June 2019
# Ordinateur HP Pavilion DV8 - Joe Linux @ Rouen
# ===============================================
import mido  # importe bibliothèque MidO qui gère aussi l'API Python RtMidi

# ***** ACQUISITION MIDI-IN / MIDO-RTMIDI *****
# Test de réception de messages MIDI envoyés par Yamaha PSR-620-OUT à M-Audio Uno MIDI-IN/USB

print('== Boucle Acquisition + Affichage Messages SYSEX + Autres envoyés par Clavier physique ==')
nsys = 0
naut = 0
with mido.open_input('USB Uno MIDI Interface MIDI 1') as inport: # connexion RtMidi-In à M-Audio-Out/USB
    for msg in inport: # passe contenu 'inport' à 'msg'
        if msg.type == 'sysex': # test si Type de message est égal à SysEx
            # Si nous voulons tester-gérer autre que SysEx, suffit de choisir Type de message ad-hoc
            nsys = nsys +1 # numérotation des messages SysEx reçus
            print('\n', nsys, 'TYPE de message reçu:', msg.type) # affiche que test SysEx est vrai
            print('   Humain:', msg) # affiche contenu 'msg' Humain à l'écran
            print('   Bytes décimal:', msg.bytes()) # affiche contenu 'msg' Bytes à l'écran
            print('   Bytes hexadéc:', msg.hex(), '\n') # affiche contenu 'msg' Bytes à l'écran
        elif msg.bytes() != [144, 36, 0]: # teste touche Do2 ON/OFF pour sortir boucle acquisition
            naut = naut +1 # numérotation des messages Autres reçus
            print (naut, 'Type + détail message reçu:', msg) # affiche messages reçus autres que SysEx
        else:
            print('\nTouche DO2 appuyée puis relachée = EXIT !', msg.bytes())
            print('ACQUISITION MIDI-IN TERMINÉE...')
            # Le port RtMidi-IN a été fermé automatiquement à la fin de la procédure 'with...as'
            exit() # arrête le script avec demande confirmation (fonction IDE utilisé)

 

Voilà, avec ces 5 articles « Initiation à la programmation MIDI (Musical Instrument Digital Interface) en utilisant le trio Python – MidO – RtMidi » et la lecture assidue de la documentation MidO, vous êtes maintenant fin prêt à coder et tester vos premiers scripts MIDI sous GNU/Linux. 😎

♦ Prochain et dernier focus pour cette série

Une Application MIDI (IN/OUT) avec Interface graphique (Tkinter de Python) incluant un Enregistrement de « Messages MIDI » sur disque pour mettre en musique tout ce que nous avons vu dans ces 5 articles.
Actuellement, mon idée est de coder un Enregistreur-Lecteur MIDI basique possédant certaines fonctionnalités de l’expandeur MDR-3 pour les orgues électroniques Electone HS Series (1987) de Yamaha ou autre chose. À voir en fonction de mon humeur et du temps disponible.

• À suivre… QUAND CE SERA… VRAIMENT… PRÊT…
⇒ Scripts Enregistreur-Lecteur MIDI ou Autre chose avec Python, MidO et RtMidi (6/6)