Xevia AccueilBlogActualitésA propos

Un pont réseau/MIDI

Toujours dans mes problèmes de contrôleurs MIDI, j'essaie aujourd'hui de transférer des flux MIDI d'un ordinateur à un autre ... pour contrôler claviers, tables de mixages et autres à distance, pourquoi pas. N'ayant pas trouvé de solutions satisfaisantes sur Internet, je me vois contraint de programmer moi-même une petite application servant de "pont" entre le réseau et les appareils MIDI. Il y a bien rtpMIDI, qui en plus est compatible avec les appareils de la marque Apple, et puis ipMIDI, payant donc à laisser tomber. J'aurais pu essayer rtpMIDI mais il m'aurait fallu installer de nouveaux pilotes, ce que j'essaie d'éviter.

Le programme que je vais présenter là s'appelle Aloades et son but est simple : recevoir des paquets TCP du réseau pour les traduires ensuite en messages MIDI qui seront envoyés vers un appareil MIDI. Je ne vais ici publier que la petite partie du code qui se charge de recevoir les données du flux réseau et d'émettre des commandes MIDI.

C#
private void Route(object deviceID)
{
outDevice = new OutputDevice((int)deviceID);
while (true)
{
Socket socket = tcpListener.AcceptSocket();
Stream stream = new NetworkStream(socket);
StreamReader inputStream = new StreamReader(stream);
while (true)
{
byte[] buffer = new byte[4];
int count = stream.Read(buffer, 0, 4);
if (count != 0)
{
ChannelMessageBuilder builder = new ChannelMessageBuilder();
builder.MidiChannel = Math.Min((int)buffer[1],0x7F);
builder.Data1 = Math.Min((int)buffer[2],0x7F);
builder.Data2 = Math.Min((int)buffer[3],0x7F);
builder.Build();
outDevice.Send(builder.Result);
}
}
stream.Close();
socket.Close();
}
}

Ici, tcpListener est un objet de type System.Net.Sockets.TcpListener, il attend la connexion d'ordinateurs externes en écoutant sur un port choisi. outDevice est un objet de type Sanford.Multimedia.Midi.OutputDevice : c'est par le biais de cette instance que l'on émet des données sur un flux MIDI. Chaque appareil MIDI a un identifiant, la connexion à cet appareil se fait grâce à cet identifiant ; cet identifiant est passé à Route() comme étant de type object, en fait cela permet d'appeler Route() comme un thread et de router les flux de données de manière asynchrone, indispensable si on ne veut pas planter l'interface utilisateur. Remarquez l'utilisation de Math.Min() : elle est indispensable au bon fonctionnement du programme, en effet les données MIDI sont codées sur 7 bits, soit 128 valeurs possible, donc si on dépasse 127, ou 0x7F, le programme va générer une exception.

La lecture dans le flux réseau se fait par paquets de 4 octets. Les messages envoyés sur le réseau doivent être de la forme suivante : un octet de début qui sert ... à rien, un octet pour le numéro du canal MIDI, un octet pour data 1 et un octet pour data 2. Pour l'instant, ce code ne permet pas de gérer autre chose que des messages de commandes MIDI et ne prend pas en charge l'intégralité du contenu d'une commande MIDI mais il est très facile de le développer un peu pour qu'il le fasse. Aussi, le programme qui émet les données à travers le réseau doit absolument coder les données de cette manière, sinon évidemment ça ne fonctionne pas (logique). Une version "inverse" de Aloades en somme, donc pas très difficile à programmer. Il n'y a qu'à regarder la longueur du code, même pas une trentaine de lignes ...

Aloades

La vue ci-dessus montre un screenshot du programme ... c'est très petit et très simple mais ça fonctionne néanmoins. Mieux, c'est gratuit ... ipMIDI de nerds.de est très pratique, c'est en gros l'équivalent de ce programme mais dans les deux directions (celui-ci ne gère que l'entrée réseau) et avec des ports MIDI virtuels dédiés. Ce programme est vendu 70€ ! Alors qu'à côté de ça, et sur le même site, on peut télécharger gratuitement LoopBe1 qui, combiné à Aloades, fournit exactement les même fonctionnalités. Soit une économie de 70€ !