Contrôles MIDI / OSC

Musical Instrument Digital Interface

Depuis la version 3.0, Sonic-Pi permet de recevoir ou d’émettre des messages MIDI (Musical Instrument Digital Interface). Il s’agit d’un protocole de communication standardisé pour l’échange d’information entre synthétiseurs et logiciels musicaux. Adopté au cours des années 1980, le MIDI reste aujourd’hui la norme la plus stable de l’industrie [0]. Ce protocole définit un certain nombre d’informations qu’il est possible d’échanger et leur donne à chacune un code particulier. Vous pouvez consulter la très longue liste des différents messages sur le site officiel de la MIDI Association  : Expanded Messages List. Je me contenterais pour ma part d’une explication lacunaire :

  • le MIDI simplifie l’envoi / réception des notes entre logiciels et synthétiseurs (note, vélocité, durée de la note)
  • le MIDI permet de suivre en temps réel la position ou le jeu d’un élément d’interface (un bouton, un potentiomètre, un slider)
  • le MIDI permet d’échanger des informations concernant certains contrôles traditionnels d’un synthétiseur (molettes de pitch-bend, etc..)
  • le MIDI permet enfin d’encoder certaines informations propres à un système (SysEx) ou à un constructeur. Vous pouvez bien sur construire un interpréteur pour vos messages MIDI et leur faire réaliser à peu près tout et n’importe quoi.

Le MIDI est le protocole privilégié pour communiquer rapidement, sans perte d’informations, sans latence, entre plusieurs systèmes. Il est donc notre allié naturel pour étendre les capacités d’expression de Sonic-Pi et l’implémentation du MIDI était le grand ajout de la version 3.0 de Sonic-Pi. En émettant du MIDI depuis le logiciel, vous pouvez utiliser celui-ci comme un séquenceur omnipotent et entièrement configurable. Ouvrez la liste des commandes avec Ctrl + I et observez la liste nombreuse des messages qu’il est possible d’envoyer. En toute honnêteté, vous n’utiliserez que les messages les plus classiques, et vous aurez rarement — c’est à dire jamais —  à tous les employer.

Selon votre configuration et votre système d’exploitation, il est possible que vous ayez à configurer des ports midi virtuels, ou que vous passiez par une interface MIDI externe. Cela dépasse le propos de ce guide, et je vous confie sur ce point à votre moteur de recherche favori. Voici tout de même quelques guides en fonction de vos systèmes respectifs :

Les valeurs MIDI

Le protocole MIDI fonctionne sur une base de 0 à 127, de A0 à C8. Cela concerne non seulement les notes, mais également la vélocité, 0 valant pour silence, 127 pour la vélocité maximale, ou encore tout simplement n’importe quelle valeur. Certains systèmes auront besoin de convertir un message émi entre 0 et 127 en message reçu entre 0 et 1, ou entre 0 et 1000. Nous verrons plus tard comment nous charger de ce problème technique. Si vous utilisez un synthétiseur standard, vous ne rencontrerez aucun problème.

Il en est de même pour les valeurs MIDI Control.

Configuration et avertissements

Nous quittons à proprement parler le domaine de Sonic-Pi. Si vous souhaitez continuer à suivre cet article, je dois donc m’assurer que vous possédiez un DAW (Ableton, Logic Pro, Cubase, Bitwig, Cubase, Reason, ProTools, Renoise, peu me chaut !). Vous pouvez également utiliser n’importe quelle interface capable d’interpréter un message MIDI. Assurez-vous que :

  • vous ayez activé la réception MIDI sur tout les ports disponibles/utilisables.
  • vous soyez au fait de l’utilisation de MIDI entrant et sortant sur votre DAW ou synthétiseur favori.
  • vous soyez capables d’assigner un message MIDI entrant à un synthétiseur ou à un instrument virtuel / synthétiseur / boîte à rythme [1].

Pour ma part, j’utilise Mac Os Mojave 10.14, et je compte utiliser Sonic-Pi pour séquencer des instruments virtuels rangés sur différentes pistes d’Ableton 10 Suite. Tout logiciel commercial professionnel est capable de la même chose s’il est bien configuré.

Veuillez également vous assurer que Sonic-Pi est capable de détecter ces ports MIDI virtuels en vous rendant dans les options :

 Emettre des notes

Au cours des articles précédents, nous utilisions play pour émettre des notes en interne. Cette fois-ci, remplaçez cette instruction par midi, et voilà :

live_loop :midi_go do midi :c4, channel: 1 ; sleep 1 end

Je précise ici channel: pour cibler un canal particulier. Par défaut, vous devriez disposer de 16 canaux différents. Je préfère toujours préciser le canal. Non seulement vous aurez toujours pour but de réserver un canal à l’un de vos instruments, mais vous aurez aussi à coeur d’éviter de surcharger le serveur de Sonic-Pi. Sur mon système personnel, il se montre particulièrement fragile dès lors qu’il s’agit d’émettre des notes sur tout les canaux simultanément, comportement par défaut du logiciel. L’interface de Sonic-Pi est parfois même gêlée, plante, comportements que vous devez éviter à tout prix.

Une note MIDI émise aura toujours un nombre défini d’informations qui lui sont attachées :

  • un nombre correspondant à la note émise (de 0 à 127).
  • un canal (de 1 à 16).
  • un port (votre port MIDI).
  • quelques valeurs annexes (portamento, slide).

Vous n’êtes pas obligés d’utiliser des numéros pour indiquer la note dans Sonic-Pi. Si vous vous demandiez pourquoi :c4 avait besoin du : le précédant, vous êtes maintenant en mesure de le deviner. Il s’agit d’un nom attribué par Sonic-Pi au numéro 60. Il n’existe pour le logiciel aucune différence entre ces deux notations [2].

Si tout se passe bien, l’exemple précédent n’a eu aucune incidence sonore. Nous n’avons connecté aucun synthétiseur, ou si vous l’avez fait, vous êtes en avance et je vous en félicite. Une note MIDI n’est qu’un message, et aucune information sonore quelle qu’elle soit n’y est rattachée. Une note émise en MIDI se compose elle-même de plusieurs signaux (oui, il faut en être conscient) :

  • midi_note_in (channel, port, velocity)
  • midi_note_off (channel, port, velocity)

Ces deux instructions existent dans Sonic-Pi. Faisons le tour des messages les plus élémentaires implémentés dans le langage du logiciel :

midi_all_notes_off

Celui-ci est souvent affectueusement appelé “panic button“. Il arrive que des notes restent suspendues (si le note_off n’est pas reçu par exemple) ou qu’un incident technique survienne. Il a pour rôle d’envoyer un signal de fin à toute note ainsi qu’à tout contrôle actuellement en cours d’émission. Il vous rend la sérénité intérieure nécessaire à votre vie de musicien. Ce message — comme tout message MIDI — reçoit un canal et un port. N’hésitez pas à créer une abstraction dans votre init.rb pour pouvoir convoquer rapidement une instruction qui enverra le message à tout les canaux et ports disponibles.

midi_pc :c4

Ce message envoie un program_change, par défaut à tout les ports et canaux. Cela fait référence aux différents sons du standard General MIDI. Cela vaut le détour si votre système possède un canal General MIDI. Il peut également être utile si vous souhaitez traduire certaines informations MIDI dans un logiciel de notation (MuseScore, Finale, Sibelius), etc.. Ceux-ci émettent toujours par défaut (en 2018) du General MIDI lorsque rien d’autre n’est disponible.

midi_to_hz

Ce message permet de convertir une note en fréquence. Cela rend possible certaines manipulations particulières de fréquences, et vous sauvera un temps précieux dès lors que vous vous intéresserez à la synthèse sonore dans Sonic-Pi.

Contrôler un paramètre MIDI

Il existe un message similaire à midi prévu pour contrôler les messages de MIDI Control (interface, etc..). Typiquement, vous vous en servirez pour contrôler les paramètres des synthétiseurs externes à Sonic-Pi. Voici un exemple :

midi_cc 1, (line 1, 100, steps: 50).look, channel: 1

Ce message aura pour effet de modifier le premier midi_cc et d’incrémenter progressivement cette valeur. Il reçoit également un paramètre pour déterminer sa portée : canal, port. Grâce à la syntaxe en votre possession, vous êtes capables de dessiner n’importe quel type de variation de ces paramètres.

Limitations propres au MIDI

La norme MIDI est excellente pour tout ce qui concerne les synthétiseurs, les boîtes à rythme et les logiciels commerciaux. Elle l’est beaucoup moins dès qu’il s’agit de s’intégrer à d’autres types de systèmes. Beaucoup d’utilisateurs aiment utiliser Sonic-Pi conjointement à d’autres langages de programmation, à des systèmes mécaniques personnalisés, des capteurs, des interfaces de contrôle physiques, etc.. Si vos besoins excèdent ceux pour lesquels la norme MIDI est pensée, c’est un signe qu’il vous faut passer au protocole OSC (Open Sound Control).

Open Sound Control

OSC est un protocole de communication beaucoup plus récent, et à vocation plus généraliste. Celui-ci a été développé au CNMAT, centre de recherche mondialement connu, situé à l’université de Berkeley en Californie. Il se veut plus précis et plus puissant que le MIDI. La communication à l’aide de ce standard passe par les protocoles UDP/TCP, ce qui permet techniquement de partager l’information sur tout réseau informatique standard. On peut désormais imaginer contrôler un synthétiseur situé à l’autre bout de la planète. Ce protocole offre également une grande liberté dans la définition des messages.

Preuve en est, Sonic-Pi communique avec SuperCollider en passant par ce protocole. Tout message s’affichant dans la console des marqueurs, en bas à droite de l’interface, est un témoin de transmission d’un message OSC vers le serveur. Même le protocole MIDI que nous utilisions jusqu’à présent suit en réalité cette route :

OSC (Sonic-Pi -> SuperCollider) -> MIDI (SuperCollider -> votre synthétiseur)

Il n’y a aucun problème particulier de latence dès lors que le message est construit et réceptionné de manière adéquate. Il est parfois nécessaire d’établir une compensation de latence, qui établit un certain délai entre l’interprétation du code et la traduction en évènement sonore. Ceci est particulièrement sensible si vous jouez avec des amis sur Internet (les groupes d’improvisation collective existent !), ou si vous utilisez un routeur de mauvaise qualité. Toutefois, vous utiliserez dans l’essentiel des cas votre réseau local, ce qui disqualifie tout ce que je viens de mentionner.

Emettre un message OSC

La syntaxe pour émettre un message OSC est un peu plus chargée que celle relative au MIDI mais permet une plus grande précision :

use_osc “localhost”, 8000 osc “/un/message” Nous commençons par déclarer l’adresse à laquelle nous cherchons à envoyer le message. Il s’agit d’une adresse réseau. “localhost” signifie que nous visons le réseau interne à l’ordinateur (typiquement, pour échanger de l’information entre logiciels). Cela aurait pu être un serveur distant ; sous la forme d’une adresse IP.
8000 est utilisé ici comme exemple : il s’agit du port sélectionné pour recevoir le message. Il faudra toujours le mentionner, autant lors de l’émission que pour indiquer dans une autre application quel port écouter. Votre ordinateur en utilise toujours une bonne centaine pour diverses raisons. Quelques conseils :
  • Les ports de 0 à 1023 sont généralement réservés à la communication des fonctions importantes du système. Ne les utilisez pas.
  • Plus vous montez, plus faible est la probabilité que cette adresse ne soit pas utilisée. La plus haute valeur autorisée est 65535, soit un nombre entier de 16 bits.

Cela vous laisse toute latitude pour envoyer vos messages à bon port.

Si use_osc est utilisé pour déclarer l’adresse, osc est utilisé pour émettre le message lui-même. Un message OSC se compose à la manière d’un arbre hiérarchique. Prenons l’exemple d’un synthétiseur imaginaire donc nous voudrions contrôler l’enveloppe, nous aurions les messages suivants :

“synth/env/attack/”, 1 “synth/env/decay/x”, 1 “synth/env/sustain/x”, 0.5 “synth/env/release/x”, 1 “synth/play/note”, 65, “woooooh”

Vous remarquerez qu’OSC me permet d’ordonner hiérarchiquement mes messages à l’aide de la barre oblique, ce dont je ne me prive pas. IL est possible d’envoyer plusieurs paramètrs à l’aide d’un seul message OSC, si tant est que ceux-ci respectent un format classique (string, integer, etc..).

Pour les envoyer, il suffit désormais d’ajouter l’instruction osc et d’entourer mon message de guillemets anglais afin de signifier qu’il s’agit d’une chaîne de caractères (string) :

osc “synth/env/attack/x”

Des versions alternatives de ce message peuvent également être utilisées, afin de faciliter la tâche :

osc_send “localhost”, 4545, “/tarte/pomme”, 80

Ce message aura pour faculté de pouvoir ignorer une quelconque définition de type use_osc. Vous pouvez l’utiliser pour cibler temporairement une adresse particuilère, au prix d’une syntaxe plus lourde.

Réception d’un message OSC

Par défaut, Sonic-Pi désactive la réception de messages OSC. Rendez-vous dans les options pour l’activer en vérifiant que les deux options suivantes sont cochées :

  • Activer serveur OSC
  • Recevoir des messages OSC distants.

Vous y trouverez également quelques informations utiles comme l’adresse IP locale ainsi que le port d’écoute de Sonic-Pi. Notez ces informations. Vous pouvez maintenant utiliser votre application externe pour créer un message particulier que vous souhaitez faire passer à Sonic-Pi. Traditionnellement, les messages OSC sont utilisés pour créer des interfaces graphiques supplémentaires ou des surfaces de contrôle. Vous aurez alors un hybride entre contrôle physique et contrôle textuel.

Si un message est reçu, celui-ci s’affichera dans la console, et Sonic-Pi ajoute à chaque message entrant le préfixe /osc/ pour le séparer des contrôles internes essentiels.

Vous pouvez ensuite donner à ce message un nom valable, en l’assignant par exemple à une variable qui aura pour fonction de contrôler un paramètre au sein d’un live_loop :

bien_recu = sync “tarte/pomme” play :c4, release: bien_recu

J’aurai certainement l’occasion de revenir cet article et d’ajouter quelques informations complémentaires.

 

 

 

 

[0] MIDI 2.0 : La presse musicale s’est récemment émue de l’annonce du MIDI 2.0. Au-delà de l’effet d’annonce et du coup marketing, personne ne sait vraiment ce qu’il en sera. Le MIDI reste donc pour un long moment un gage de stabilité.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[1] Note : Certains systèmes modulaires sont particulièrement lourds à configurer. Cette gravité est typique des systèmes modulaires capables de recevoir du MIDI. Il faut souvent convertir un signal MIDI en différentes CV/Gates, etc.. Vous aurez plus de chance si vous demandez de l’aide sur un espace de discussion dédié au module en question.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[2] Enfin.. : je n’ai pas d’exemple spécifique en tête, mais il m’est déjà arrivé d’avoir à utiliser explicitement la numérotation MIDI pour obtenir précisément ce que je souhaitais entendre. La page sera mise à jour dès lors que je serai tombé à nouveau sur un tel cas de figure.