Parmi les précurseurs des systèmes automatiques d'aujourd'hui, on trouve les grands orgues qui animaient les foires au XIXe siècle. Sans avoir la prétention de nous lancer dans quelque chose d'aussi magistral, nous n'avons pas résisté à la tentation de faire un petit instrument automatique piloté par ordinateur à base de modules Yoctopuce pour voir où seraient les difficultés. Bilan: c'est assez facile, et ce n'est même pas très long à faire... preuve en vidéo à l'appui !
Notre objectif était de construire un orgue de barbarie capable de jouer des fichiers MIDI. Soyons clair: vu le temps disponible pour ce projet (en gros 3 jours), nous avons privilégié les solutions que nous maîtrisions. On espère que les esthètes et les puristes des instruments mécaniques nous le pardonneront...
Construction
Un orgue n'est pas très compliqué. Il s'agit d'un ensemble de "flûtes", chacune responsable d'une seule note, dans lesquelles il faut envoyer de l'air lorsqu'on veut jouer la note. Pour faire un orgue automatique, on doit donc disposer d'une réserve d'air légèrement sous pression, et d'un moyen d'ouvrir automatiquement la vanne d'arrivée d'air de chaque tube.
Un jeu de 22 tuyaux d'orgue
Pour les notes, nous avons acheté un jeu de 22 tuyaux d'orgue d'occasion vendu sur Internet à un prix très amical. Les tuyaux ont été fournis avec un support en bois fort pratique, dont la base creuse permet de conduire l'air vers chaque tuyau.
Chacun des tubes est relié via une électrovanne au distributeur d'air principal. Comme une pression régulière est critique pour la stabilité des notes, nous avons ajouté à l'entrée du distributeur un petit régulateur de pression de précision.
Schéma de notre orgue
Les électrovannes sont pilotées en 24V, et consomment environ 100mA. Nous avons donc pu les piloter directement à l'aide de trois Yocto-MaxiCoupler, fournissant au total 24 canaux. L'alimentation électrique est fournie par un simple bloc secteur 24V récupéré. Notre "instrument" étant un peu encombrant pour tenir sur un bureau, nous y avons ajouté un YoctoHub-Wireless-SR afin de pouvoir le piloter à distance par le réseau Wi-Fi.
Le module de commande électropneumatique
Au final, il a suffit d'une journée de travail pour assembler le tout et faire les premiers tut-tut. De quoi se rendre compte qu'il allait falloir procéder en priorité à un accordage des tuyaux pour éviter que la suite de ce projet ne se transforme en séance de torture...
On accorde un tuyau d'orgue en modifiant la forme de son ouverture, mais aussi en baissant la pression à l'aide de petits trous dans le circuit d'arrivée d'air
En accordant notre instrument, on a découvert les notes dont on disposait. Il est fréquent que les petits orgues de barbarie ne disposent pas de toutes les notes. Le nôtre ne fait pas exception, il n'a qu'une gamme majeure (c-à-d. les notes blanches du piano), et encore, avec une note manquante au milieu. Voilà qui rajoute un petit défi au projet...
L'orgue complet, prêt pour sa première représentation
Le programme de commande
Pour jouer une note, il suffit d'activer l'électrovanne correspondante pendant la durée de la note. La librairie Yoctopuce utilisée pour piloter le Yocto-MaxiCoupler fournit à cet effet une classe Relay avec une méthode pulse(durée_en_millisecondes). Pour savoir sur quel tuyau on joue, on va donner à chaque sortie du Yocto-MaxiCoupler un nom logique correspondant à la note relative qu'il joue: le tuyau le plus bas s'appellera tune00, celui qui est 2 demi-tons plus haut tune02 et ainsi de suite:
Voici donc comment jouer une gamme majeure sur notre orgue, en C++:
string errmsg;
YAPI::RegisterHub("192.168.1.71", errmsg);
// On utilisera un objet YRelay pour piloter chacune des notes
const char *tunes[8] = {"00","02","04","05","07","09","11","12"};
YRelay *notes[8];
for(int i = 0; i < 8; i++) {
notes[i] = YRelay::FindRelay("tune"+string(tunes[i]));
}
// On joue une gamme (chaque note pendant 500ms)
for(int i = 0; i < 8; i++) {
notes[i]->pulse(500); // le relais coupera la vanne après 500ms
YAPI::Sleep(500,errmsg); // on attend la fin de la note avant la suivante
}
C'est déjà bien, mais le déclenchement des notes une par une, avec une attente entre chaque note, n'est pas idéal: si l'on veut faire un accord, il faut que toute les notes partent exactement ensemble. On va donc utiliser une fonction encore un peu plus subtile, qui programme une impulsion à retardement: delayedPusle(délai,durée). Voici le nouveau code qui joue la gamme:
for(int i = 0; i < 8; i++) {
notes[i]->delayedPulse(i*500, 500);
}
// Le programme est terminé, mais la gamme continue...
Dernière subtilité: on ne peut pas programmer un pulse pendant qu'un autre pulse est en cours sur le même relais. Donc il faut en réalité combiner les deux approches: si le relais est inactif, on utilise un delayedPulse et on passe directement à la note suivante. Sinon, on fait un YAPI::Sleep pour attendre que le relais ait terminé son impulsion, et on préprogramme la note suivante sur le même relais dès que l'impulsion est finie.
C'est tout ce qu'il fallait savoir sur la librairie Yoctopuce pour automatiser notre orgue. Le reste n'est plus que des questions de musique et de fichiers MIDI.
Le lecteur MIDI
Si pour chaque note à jouer nous avions dû écrire à la main un appel à delayedPulse, on ne serait pas allé bien loin avec ce projet. On a donc ajouté à notre programme la possibilité de lire le morceau à jouer au format MIDI, dont on trouve des milliers d'exemples sur Internet. Pour gagner du temps nous sommes partis de la librairie écrite par Craig Stuart Sapp.
Une fois la séquence de notes en mémoire, il faut attribuer à chaque note un tuyau d'orgue. Mais comme notre instrument n'a pas toutes les notes, il nous a fallu coder un arrangeur automatique qui remplace les notes manquantes par d'autres qui sonnent presque pareil. Notre arrangeur utilise deux méthodes: la transposition (décalage vers le haut ou le bas de toute la pièce) pour minimiser le nombre de notes manquantes, et la substitution harmonique (remplacement par une note partageant un maximum d'harmoniques communes). Si vous voulez des détails, demandez-nous des explications ou jetez un coup d'oeil au code source...
Voilà le résultat sur la Marche Turque de Mozart, fruit de la deuxième journée de travail sur ce projet:
Encore plus loin
Il est évidemment tentant d'essayer toutes sortes de morceaux sur cet instrument. On se rend compte qu'ils ne sonnent pas forcément tous bien. En effet, un bon nombre de morceaux ont des harmonisations orchestrales avec beaucoup d'instruments en parallèle, qui ne peuvent pas être réduits sur un si petit instrument. Nous avons donc ajouté dans notre programme une liste des différentes voix présentes dans le fichier MIDI, avec la possibilité de les désactiver. Au passage, nous avons automatiquement désactivé les voix de percussion. On aurait bien rajouté un tambourin pneumatique, mais là il n'y avait juste plus le temps...
On peut aussi parfois améliorer le rendu orchestral en raccourcissant automatiquement les notes en fonction de leur volume MIDI. Cela permet de rendre plus discret les lignes d'accompagnement, qui ont tendance à couvrir la mélodie vu que tous les tuyaux jouent à la même force.
Si vous voulez vous amuser à reproduire cette expérience, vous trouverez le code source de notre programme sur GitHub. Et pour finir en musique, voici un petit pot-pourri illustrant notre réalisation: