TetaTricks/chap/MIDI.tex

194 lines
5.7 KiB
TeX

\chapter{Musical Instrument Digital Interface}
\label{chap:MIDI} \index{MIDI}
Dans un premier temps, je vais me concentrer sur les
services \textsc{midi} offerts par la couche ALSA d'un
système Linux.
Ensuite,
nous passerons aux
\textit{raw devices} (page \pageref{midi:raw}).
Mais avant tout, un petit rappel sur ce qu'est le MIDI.
\begin{quote}
\textsl{Wikipedia} :
C'est un protocole de communication et un format de fichier dédiés
à la musique, et utilisés pour la communication entre instruments
électroniques, contrôleurs, séquenceurs, et logiciels de musique.
Apparu dans les années 1980, issu d'une volonté de l'industrie de
normaliser les échanges entre les différents instruments,
ce protocole est devenu aujourd'hui un standard très répandu
dans le matériel électronique de musique.
\end{quote}
Attention, ce système \textbf{ne} transporte \textbf{pas} de
signal audio, mais de petits messages
(quelques octets, en général 3) de \textbf{commande} informatique%
\footnote{C'est une confusion fréquente qui complique les choses}.
Un exemple de message basique, c'est celui-ci, exprimé en
hexadécimal\index{hexa.} :
\texttt{93 5B 3A} un message qui va déclencher, sur le canal 3,
la note \textsf{Sol5}, à
un niveau assez bas. Et c'est l'instrument à l'autre bout du fil
qui va générer le signal audio.
% ---------------------------------------------------------
% ---------------------------------------------------------
\section{Outils de base}
\subsection{aseqdump}
\index{aseqdump}
Cet outil permet de voir de façon relativement claire
\textbf{tous} les évènements \textsc{midi} qui rentre
par un chemin donné, et, en première étape,
surtout de lister ces chemins.
\begin{verbatim}
tth@plop:~/Muzak/Samples$ aseqdump -l
Port Client name Port name
0:0 System Timer
0:1 System Announce
14:0 Midi Through Midi Through Port-0
\end{verbatim}
\subsection{aconnect}
Maintenant que nous savons ce qui rentre dans notre machine,
il est temps de savoir comment le faire ressortir. Il faut
donc créer une connexion quelque part au tréfond des tables
obscures de la kernelle.
\subsection{aseqnet}
\begin{quote}
aseqnet is an ALSA sequencer client which sends and receives
event packets over the network.
\end{quote}
% ---------------------------------------------------------
\section{ALSA tips}
\index{ALSA}
\textbf{cat /proc/asound/seq/clients}
\begin{verbatim}
Client info
cur clients : 4
peak clients : 4
max clients : 192
Client 0 : "System" [Kernel]
Port 0 : "Timer" (Rwe-)
Port 1 : "Announce" (R-e-)
Connecting To: 15:0
Client 14 : "Midi Through" [Kernel]
Port 0 : "Midi Through Port-0" (RWe-)
Client 15 : "OSS sequencer" [Kernel]
Port 0 : "Receiver" (-we-)
Connected From: 0:1
Client 128 : "TiMidity" [User]
Port 0 : "TiMidity port 0" (-We-)
Port 1 : "TiMidity port 1" (-We-)
Port 2 : "TiMidity port 2" (-We-)
Port 3 : "TiMidity port 3" (-We-)
Output pool :
Pool size : 500
Cells in use : 0
Peak cells in use : 0
Alloc success : 0
Alloc failures : 0
Input pool :
Pool size : 1000
Cells in use : 0
Peak cells in use : 0
Alloc success : 0
Alloc failures : 0
\end{verbatim}
% ---------------------------------------------------------
\section{Raw devices}
\label{midi:raw}
Plutôt que de passer par la couche ALSA, il est aussi possible
d'attaquer directement le \textit{device}, et de blaster soi-même
tous les petits octets directement sur le fil. Voici un petit
exemple en
Python\index{Python}\footnote{Oui, je sais, c'est un langage de djeunz,
mais bon, ça fait plaisir à mon gamin}, facilement transposable
dans un langage plus sérieux :
\begin{lstlisting}[language=python]
#!/usr/bin/env python
import time
def note_on(note):
tx.write("%c%c%c" % (0x90, note, 100))
tx.flush()
def note_off(note):
tx.write("%c%c%c" % (0x90, note, 0))
tx.flush()
def progchange(prog):
tx.write("%c%c" % (0xc0, prog))
tx.flush()
tx = open("/dev/midi", "w")
for valeur in range(30,90):
progchange(valeur)
note_on(valeur)
time.sleep(1)
note_off(valeur)
time.sleep(1)
tx.close()
\end{lstlisting}
% ---------------------------------------------------------
\section{Et en Perl ?}
\index{Perl}
En Perl\footnote{Oui, je sais, c'est un langage de vieux,
mais bon, il faut bien se faire plaisir de temps en temps\dots},
il existe un certain nombre de modules très évolués pour
jouer avec les fichiers MIDI, ce qui est un domaine légèrement
différent, il faut le reconnaitre.
\begin{verbatim}
MIDI (3pm) - read, compose, modify, and write MIDI files
MIDI::Event (3pm) - MIDI events
MIDI::Filespec (3pm) - MIDI File Specification
MIDI::Opus (3pm) - functions and methods for MIDI opuses
MIDI::Score (3pm) - MIDI scores
MIDI::Simple (3pm) - procedural/OOP interface for MIDI composition
MIDI::Track (3pm) - functions and methods for MIDI tracks
\end{verbatim}
Un petit essai, par exemple extraire la valeur du \textsc{bpm}
d'un fichier \texttt{.mid} ?
\lstinputlisting[language=perl]{code/midifile.pl}
Voilà.
% ---------------------------------------------------------
\section{midish} \index{midish}
Vous avez aimé \textsl{packet filter} ? Alors vous allez
adorer midish\dots
% ---------------------------------------------------------
\section{Et après ?}
OSC\index{OSC} (page \pageref{chap:OSC}) semble une possibilité
pour aller au-delà. Mais, \textsl{amho}, rien ne pourra vraiment
remplacer le midi tel que nous le connaissons depuis les années 80.
% ---------------------------------------------------------