J'ai exploré la communication entre un Arduino et un clavier musical par l'entremise du protocole MIDI. J'ai d'abord réalisé
le circuit (très simple) proposé ici : il est constitué de quelques fils, une résistance de 220 Ω et un jack MIDI femelle, aussi appelés DIN5 (j'allais en commander un quand je me suis souvenu de mon antique interface Mac Man qui ne fonctionne plus avec mes ordinateurs actuels: j'ai donc récupéré ses 4 jacks MIDI).
Le
code proposé sur la même page web se contente de jouer toutes les notes en ordre croissant. En plus d'émettre des message "note on", je voulais utiliser plusieurs canaux MIDI en même temps, chacun produisant le son d'un instrument distinct. C'est ce que j'ai réalisé avec le sketch ci-dessous.
J'ai assigné un son d'instrument aux canaux MIDI 0, 1 et 2 en me basant sur les
spécifications du General MIDI . Par convention, le canal 10 est réservé aux percussions et n'est pas affecté par les messages "program change".
On joue une note par un message "note on" en spécifiant le canal, le numéro de la note (
référence ici) et sa vélocité (son volume sonore, en gros). On interrompt la note de la même façon, en lui assignant une vélocité de zéro. Lorsqu'on oublie d'interrompre la note, ça peut être très laid!
Cette première expérimentation pourrait ouvrir la voie à des projets plus ambitieux comme exécuter des fichiers MIDI stockés sur une carte SD, ou construire un contrôleur MIDI...
/*
MIDI OUT DEMO
Ce sketch permet à l'Arduino de jouer une mélodie sur un clavier MIDI.
Inspiré de ce fichier: http://www.arduino.cc/en/Tutorial/MIDI
(voir au même endroit pour le circuit)
*/
/* On définit quelques notes qu'on va utiliser: ce sera plus pratique que les valeurs hexadécimales!
Voir http://www.wavosaur.com/download/midi-note-hex.php */
#define NOTE_G2 0x2B
#define NOTE_C3 0x30
#define NOTE_C4 0x3C
#define NOTE_D4 0x3E
#define NOTE_E4 0x40
#define NOTE_F4 0x41
#define NOTE_G4 0x43
#define NOTE_A4 0x45
#define NOTE_B4 0x47
#define NOTE_C5 0x48
#define NOTE_D5 0x4A
#define NOTE_E5 0x4C
#define NOTE_F5 0x4D
#define NOTE_G5 0x4F
#define NOTE_A5 0x51
#define NOTE_B5 0x53
void setup() {
// Réglage du MIDI baud rate:
Serial.begin(31250);
}
void loop() {
// préparation des instruments:
ProgChange(0,34); // Bass guitar sur le canal 0
ProgChange(1,16); // orgue sur le canal 1
ProgChange(2,80); // synthé sur le canal 2
// le canal 9 joue toujours des percussions
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
noteOn(0x99, 36, 0x45); // Bass Drum
noteOn(0x90, NOTE_C3, 0x45); // Basse
noteOn(0x92, NOTE_E5, 0x50); // Synthé
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x99, 36, 0x00); // Bass Drum fin
noteOn(0x92, NOTE_E5, 0x00); // Synthé fin
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
noteOn(0x92, NOTE_D5, 0x50); // Synthé
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x90, NOTE_C3, 0x00); // Basse fin
noteOn(0x92, NOTE_D5, 0x00); // Synthé fin
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
noteOn(0x99, 38, 0x45); // Bass Drum
noteOn(0x91, NOTE_C4, 0x65); // orgue
noteOn(0x91, NOTE_E4, 0x65); // orgue
noteOn(0x91, NOTE_G4, 0x65); // orgue
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x99, 38, 0x00); // Bass Drum fin
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x91, NOTE_C4, 0x00); // orgue fin
noteOn(0x91, NOTE_E4, 0x00); // orgue fin
noteOn(0x91, NOTE_G4, 0x00); // orgue fin
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
noteOn(0x99, 36, 0x45); // Bass Drum
noteOn(0x90, NOTE_G2, 0x45); // Basse
noteOn(0x92, NOTE_G5, 0x50); // Synthé
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x99, 36, 0x00); // Bass Drum fin
noteOn(0x92, NOTE_G5, 0x00); // Synthé fin
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
noteOn(0x92, NOTE_E5, 0x50); // Synthé
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x90, NOTE_G2, 0x00); // Basse fin
noteOn(0x92, NOTE_E5, 0x00); // Synthé fin
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
noteOn(0x99, 38, 0x45); // Bass drum
noteOn(0x91, NOTE_C4, 0x65); // orgue
noteOn(0x91, NOTE_E4, 0x65); // orgue
noteOn(0x91, NOTE_G4, 0x65); // orgue
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x99, 38, 0x00); // Bass drum fin
noteOn(0x99, 42, 0x45); // Closed Hi-Hat
delay(200);
noteOn(0x99, 42, 0x00); // Closed Hi-Hat fin
noteOn(0x91, NOTE_C4, 0x00); // orgue fin
noteOn(0x91, NOTE_E4, 0x00); // orgue fin
noteOn(0x91, NOTE_G4, 0x00); // orgue fin
}
void noteOn(int cmd, int pitch, int velocity) {
Serial.print(cmd, BYTE);
Serial.print(pitch, BYTE);
Serial.print(velocity, BYTE);
}
void ProgChange(int channel, int prognumber) {
Serial.print(0xC0+channel, BYTE);
Serial.print(prognumber, BYTE);
}
void PitchBend (int low,int high){
Serial.print(0xE0, BYTE);
Serial.print(low, BYTE);
Serial.print(high, BYTE);
}