177 lines
5.2 KiB
TeX
177 lines
5.2 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 di 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.
|
|
|
|
% ---------------------------------------------------------
|
|
\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{Et après ?}
|
|
|
|
OSC\index{OSC} (page \pageref{chap:osc}) semble une possibilité
|
|
pour aller au-delà.
|
|
|
|
% ---------------------------------------------------------
|