mardi 5 septembre 2023

MIDI OUT avec le Raspberry Pi Pico (Micropython)

Ce projet consiste à utiliser un Raspberry Pi Pico programmé en Micropython, afin d'envoyer des instructions MIDI à un clavier musical. Le synthétiseur du clavier jouera la musique ayant préalablement été programmée dans le Raspberry Pi Pico.

Circuit

La norme MIDI (Musical Instrument Digital Interface) a été mise au point au début des années 1980 afin de permettre la communication entre divers instruments de musique électronique.

À l'origine, tous les appareils communiquaient en utilisant un niveau logique de 5 V mais puisque le Raspberry Pi Pico (comme la majorité des microcontrôleurs actuels) utilise plutôt un niveau logique de 3,3 V, nous utiliserons le circuit que je vous ai présenté dans le récent article intitulé Fabrication d'un module MIDI (IN et OUT) pour microcontrôleur 3,3 V.

Le circuit est très simple et peut être rapidement monté sur une breadboard. Le seul composant "spécialisé" étant un connecteur DIN-5 femelle dans lequel sera inséré le câble MIDI branché au clavier­. La numérotation des broches de ce connecteur est présenté sur la photographie ci-dessous.

  • Une résistance de 10 Ω est insérée entre la broche GP4 du Raspberry Pi Pico et la broche numéro 5 du connecteur DIN-5 femelle.
  • La broche 2 du connecteur DIN-5 femelle est branchée à une des broches GND du Raspberry Pi Pico.
  • Une résistance de 33 Ω est insérée entre la broche 4 du connecteur DIN-5 femelle et la sortie 3,3 V du Raspberry Pi Pico.  Attention: on recommande une résistance de 0,5 W.  (Pour cette raison, j'ai plutôt utilisé deux résistances de 68 Ω en parallèle)­.

Ce circuit est inspiré des recommandations de la MIDI Association.

Un câble MIDI est inséré dans le connecteur DIN5, et l'autre extrémité du câble est inséré dans le jack MIDI IN du clavier musical.

Script en Micropython #1

Commençons par présenter un script très simple, en Micropython, pour illustrer la procédure: il se contente de ne jouer qu'une seule note.

Les spécifications du protocole MIDI imposent une communication série à une vitesse de 31 250 bauds. Cette vitesse est réglée au début du programme (ligne #15) lorsque nous initialisons le bus UART #1 du Raspberry Pi, qui est lié aux broches GP4 (TX) et GP5 (RX). Dans ce projet, nous n'utilisons que la broche GP4, qui sert à la transmission des données (GP5 serait utile si nous devions recevoir des données, ce qui n'est pas le cas ici).

À la ligne #18, nous réglons le "programme" du synthétiseur, c'est à dire le timbre qui sera utilisé. La norme "General MIDI" définit 128 timbres correspondant à l'imitation d'un instrument de musique. Par exemple, le timbre numéro 57 correspond à un son de trompette. De plus, vous disposez de 16 canaux, chacun de ces canaux pouvant être réglé à son propre timbre (sauf le canal 10, qui est réservé aux percussions).

À la ligne #18, donc, nous assignons un son de trompette au canal 1.  Pour ce faire, nous envoyons un premier octet qui envoie l'instruction "program change" ainsi que le numéro du canal auquel il faut assigner ce timbre:

  • Le nombre hexadécimal C0 modifie le timbre du canal 1
  • Le nombre hexadécimal C1 modifie le timbre du canal 2
  • Le nombre hexadécimal C2 modifie le timbre du canal 3
  • ...
  • Le nombre hexadécimal CF change le timbre du canal 16

Vous l'avez peut-être remarqué: la numérotation officielle des canaux, qui s'adresse aux musiciens plutôt qu'aux programmeurs, va du canal 1 au canal 16 mais dans un programme, nous utilisons les numéros 0 à 15...

Cette instruction est suivie d'un deuxième octet (ligne #19) qui contient le numéro du timbre. Ici encore, les timbres sont officiellement numérotés de 1 à 128 mais nos programmes utilisent une numérotation de 0 à 127. Pour cette raison, nous envoyons "56" parce que la trompette est l'instrument numéro 57!

Pour jouer une note, nous envoyons un message de type "Note On":

  • Le nombre hexadécimal 90 joue une note dans le canal 1
  • Le nombre hexadécimal 91  joue une note dans le canal 2
  • Le nombre hexadécimal 92  joue une note dans le canal 3
  • ...
  • Le nombre hexadécimal 9F  joue une note dans le canal 16

À la ligne #22, nous avons donc envoyé l'instruction 90, en hexadécimal, afin de jouer une note dans le canal 1. 

Il faut aussi lui indiquer quelle note il faut jouer (ligne #23). Le Do4, par exemple, correspond au numéro 60 (voir cette page pour tous les numéros de notes).

Ensuite (ligne #24), il faut envoyer un troisième octet qui indique la vélocité de la note. Plus ce nombre est élevé, plus le volume du son est élevé. 127 représente le maximum.

Nous maintenons ensuite cette note pendant 2 secondes (ligne #26).

En MIDI, il faut envoyer une instruction qui demande explicitement de cesser de jouer la note: c'est le message "note off", qui est très similaire  au message "note on", sauf qu'on remplace le 9 par un 8:

  • Le nombre hexadécimal 80 interrompt une note dans le canal 1
  • Le nombre hexadécimal 81  interrompt une note dans le canal 2
  • Le nombre hexadécimal 82  interrompt une note dans le canal 3
  • ...
  • Le nombre hexadécimal 8F  interrompt une note dans le canal 16

La ligne #29 envoie donc un message "note off" au canal 1.

Il faut ensuite spécifier le numéro de la note qu'on désire interrompre, et il est bien sûr important d'utiliser le même numéro que celui a servi dans le message "note on"! À la ligne #30, nous interrompons la note numéro 60, qui est le do4 qui joue depuis maintenant 2 secondes.

Nous spécifions finalement la vélocité, qui est typiquement nulle pour un message de type "note off". (ligne #31).  (Notez qu'un message "note on" de vélocité nulle aurait eu le même effet qu'on message "note off".)

-

-

Script en Micropython #2

Ce deuxième script joue une mélodie à la basse dans le canal #1, tout en jouant de la batterie dans le canal #10. Ça joue en boucle jusqu'à l'interruption du programme.

-

-

Bibliothèque Micropython-midi-library

Pour des applications plus sérieuses, vous serez peut-être intéressés par la Micropython-midi-library de sensai7. 


À lire également


Yves Pelletier

Aucun commentaire:

Enregistrer un commentaire