2020-09-29 10:41:53 +02:00
|
|
|
\chapter{Musical Instrument Digital Interface}
|
2020-11-13 01:35:31 +01:00
|
|
|
\label{chap:MIDI} \index{MIDI}
|
2020-09-29 10:41:53 +02:00
|
|
|
|
|
|
|
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}).
|
2020-11-13 01:35:31 +01:00
|
|
|
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}, à
|
2021-10-23 14:25:18 +02:00
|
|
|
un niveau assez bas. Et c'est l'instrument à l'autre bout du fil
|
2020-11-13 01:35:31 +01:00
|
|
|
qui va générer le signal audio.
|
|
|
|
|
2021-10-23 14:25:18 +02:00
|
|
|
% ---------------------------------------------------------
|
2020-11-13 01:35:31 +01:00
|
|
|
|
2022-01-01 00:04:23 +01:00
|
|
|
\section{Seq24}\index{seq24}
|
|
|
|
|
|
|
|
Seq24 has a unique convention for entering and editing notes that seems
|
|
|
|
confusing at first but quickly makes sense once you use it once or twice.
|
|
|
|
|
|
|
|
\begin{itemize}
|
|
|
|
\item{Right-click to activate the pen tool, and left-click (while still
|
|
|
|
holding the right-click button) to draw a note.}
|
|
|
|
\item{Left-click to select a note. Left-click and drag to draw a
|
|
|
|
selection box.}
|
|
|
|
\item{Middle-click and drag to modify the length of a selected note.}
|
|
|
|
\end{itemize}
|
2020-09-29 10:41:53 +02:00
|
|
|
|
|
|
|
% ---------------------------------------------------------
|
|
|
|
\section{Outils de base}
|
|
|
|
|
2021-10-30 15:54:36 +02:00
|
|
|
Le sous-système ALSA vient avec quelques utiltaires bien pratique
|
|
|
|
dans un usage d'exploration.
|
|
|
|
|
2020-09-29 10:41:53 +02:00
|
|
|
\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,
|
2020-11-13 01:35:31 +01:00
|
|
|
surtout de lister ces chemins.
|
2020-09-29 10:41:53 +02:00
|
|
|
|
|
|
|
\begin{verbatim}
|
|
|
|
tth@plop:~/Muzak/Samples$ aseqdump -l
|
2020-11-13 01:35:31 +01:00
|
|
|
Port Client name Port name
|
|
|
|
0:0 System Timer
|
|
|
|
0:1 System Announce
|
|
|
|
14:0 Midi Through Midi Through Port-0
|
2021-10-30 15:54:36 +02:00
|
|
|
20:0 nanoKONTROL nanoKONTROL MIDI 1
|
|
|
|
\end{verbatim}
|
|
|
|
|
|
|
|
Voici ce qu'on obtient quand on remue les boutons d'un
|
|
|
|
nanoKontrol de Korg, et voyez bien qu'on retrouve les
|
|
|
|
trois octets dont on causait l'autre jour. Le premier
|
|
|
|
contient à la fois le numéro ce canal et le type d'évènement,
|
|
|
|
le second le numéro du contrôle concerné, et le troisième
|
|
|
|
la nouvelle valeur~:
|
|
|
|
|
|
|
|
\begin{verbatim}
|
|
|
|
tth@fubar:~/Documents/TetaTricks$ aseqdump -p 20
|
|
|
|
Waiting for data. Press Ctrl+C to end.
|
|
|
|
Source Event Ch Data
|
|
|
|
20:0 Control change 1, controller 45, value 127
|
|
|
|
20:0 Control change 1, controller 45, value 0
|
|
|
|
20:0 Control change 1, controller 14, value 120
|
|
|
|
20:0 Control change 1, controller 14, value 119
|
2020-09-29 10:41:53 +02:00
|
|
|
\end{verbatim}
|
|
|
|
|
2021-10-30 15:54:36 +02:00
|
|
|
Un exemple d'utilisation d'un nanoKontrol pour piloter Chuck
|
|
|
|
se trouve (peut-être) aux alentours de la
|
|
|
|
page \pageref{chuck-midi}.
|
|
|
|
|
|
|
|
% -------------------------
|
|
|
|
|
2020-09-29 10:41:53 +02:00
|
|
|
\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.
|
|
|
|
|
2021-10-15 23:22:38 +02:00
|
|
|
\subsection{aseqnet}
|
|
|
|
|
|
|
|
\begin{quote}
|
|
|
|
aseqnet is an ALSA sequencer client which sends and receives
|
|
|
|
event packets over the network.
|
|
|
|
\end{quote}
|
|
|
|
|
2021-10-30 15:54:36 +02:00
|
|
|
\subsection{pmidi}
|
|
|
|
|
|
|
|
Jouer un fichier MIDI (aka \textsl{midifile}) au travers du
|
|
|
|
séquenceur ALSA.
|
|
|
|
|
2020-09-29 10:41:53 +02:00
|
|
|
% ---------------------------------------------------------
|
|
|
|
\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
|
2020-12-12 04:13:54 +01:00
|
|
|
exemple en
|
|
|
|
Python\index{Python}\footnote{Oui, je sais, c'est un langage de djeunz,
|
2020-09-29 10:41:53 +02:00
|
|
|
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}
|
|
|
|
|
2020-12-12 04:13:54 +01:00
|
|
|
Un petit essai, par exemple extraire la valeur du \textsc{bpm}
|
|
|
|
d'un fichier \texttt{.mid} ?
|
|
|
|
|
|
|
|
\lstinputlisting[language=perl]{code/midifile.pl}
|
|
|
|
|
|
|
|
Voilà.
|
2020-09-29 10:41:53 +02:00
|
|
|
|
|
|
|
% ---------------------------------------------------------
|
|
|
|
|
2021-10-15 23:22:38 +02:00
|
|
|
\section{midish} \index{midish}
|
|
|
|
|
|
|
|
Vous avez aimé \textsl{packet filter} ? Alors vous allez
|
|
|
|
adorer midish\dots
|
|
|
|
|
|
|
|
% ---------------------------------------------------------
|
|
|
|
|
2020-10-26 23:06:17 +01:00
|
|
|
\section{Et après ?}
|
|
|
|
|
2021-06-26 19:17:02 +02:00
|
|
|
OSC\index{OSC} (page \pageref{chap:OSC}) semble une possibilité
|
2021-06-27 02:02:19 +02:00
|
|
|
pour aller au-delà. Mais, \textsl{amho}, rien ne pourra vraiment
|
|
|
|
remplacer le midi tel que nous le connaissons depuis les années 80.
|
|
|
|
|
2020-10-26 23:06:17 +01:00
|
|
|
|
|
|
|
% ---------------------------------------------------------
|