Apprendre à programmer un DSL de live-coding


Je travaille en parallèle de ma thèse sur un environnement de live-coding musical nommé Belly. Ayant appris la programmation sur le tard et en autodidacte, la tâche s’avère lente et fastidieuse [1]. Il s’agit d’un client pour SuperDirt en Python. C’est un bon exercice pour comprendre les enjeux de la conception d’un tel système : scheduling temps-réel, manipulation de la syntaxe, couplage avec le moteur audio et avec Emacs. Je posterais le programme et sa documentation lorsque celui-ci atteindra la maturité et la stabilité suffisante pour être utilisé quotidiennement sans trop de heurts. Le but est de se rapprocher, autant que possible, des langages les plus utilisés par la communauté TOPLAP (Tidal Cycles, FoxDot, etc…). Le but est également d’expérimenter avec plusieurs modalités de représentation algorithmique de la notation musicale et de réfléchir sur de potentielles nouvelles notations pour les musiques électroniques et informatiques. J’espère à terme que ces expérimentations mèneront vers un environnement stable que je pourrais utiliser pour enseigner et pratiquer cette approche particulière du jeu et de l’improvisation musicale.

Belly n’est qu’une surcouche logicielle pour SuperCollider et SuperDirt (échantillonnage, synthèse sonore, sorties audios). Le logiciel n’émet donc aucun son : Belly se charge d’organiser la performance en émettant des messages temporels très précis renseignant les différents paramètres et les différents signaux qui composent le jeu musical. Cette architecture est assez commune pour ce type de langages/DSL, ainsi qu’en témoignent Sonic Pi ou Tidal Cycles dont Belly s’inspire très largement. Du fait de la relative jeunesse du programme, je n’ai pas encore précisément décidé du paradigme de programmation attendu de la part de l’utilisateur/musicien : fonctionnel ou impératif. Il s’agit encore d’établir une interface de haut-niveau pour la notation musicale ou pour la manipulation et la description du temps musical. L’idéal serait de programmer entièrement Belly, une seconde fois, dans un langage fonctionnel ou multi-paradigmatique (Common Lisp ?). L’absence de librairies permettant de faciliter la tâche me retient encore de m’y consacrer plus pleinement.

Le programme repose sur un mécanisme très incomplet et approximatif de « récursion temporelle », notion illustrée et largement développée/commentée par Andrew Sorensen [2]. Ce mécanisme ne peut être identique à celui proposé par Sorensen pour au moins une raison. De manière notoire, Python ne supporte pas l’optimisation des fonctions tail recursive qui sont à la base même de ce type particulier de récursion, courant dans des langages tels que Scheme. Racket ou CL. Je souhaite pourtant m’inspirer, autant que possible, des langages fonctionnels ou des langages de type LISP. La sur-représentation du LISP ou des dérivés de SmallTalk dans le milieu de l’informatique musicale ne m’apparaît pas comme une simple coïncidence. Sans doute s’agit-t-il d’une indication du fait que ces langages s’adaptent mieux à certaines contraintes propres au domaine musical : prototypage rapide, hot-reloading, concision et souplesse de la syntaxe, adaptation de cette dernière au domaine (expression musicale, synthèse, composition). La plupart de ces langages proposent une approche in media res de la programmation musicale, permettant la manipulation du programme dans le temps et dans l’action. De manière tout simplement personnelle, j’ai également une préférence esthétique pour l’élégance de ces langages.

Python possède l’une des syntaxes les plus rigides et l’un des interpréteurs les plus contraignants qui soit : espaces signifiants, absence de macros, AST peu déchiffrable, impossibilité de recharger un module, de mettre à jour les instances d’une classe lors d’une redéfinition de l’objet, etc… Pour ces raisons au moins, Belly me semble handicapé par rapport à ce qui peut déjà se faire dans le domaine du live-coding, au travers de langages tels que Clojure ou Haskell. C’est un handicap que j’accepte volontiers, dans la mesure ou je manque encore de pratique et de métier; la programmation n’étant pas mon activité principale ni ma spécialité. Le fait que FoxDot existe reste toutefois la preuve que Python supporte ce type d’applications musicales.

Du point de vue technique

Belly est capable, au travers de SuperDirt, de gérer les entrées et sorties MIDI ou OSC. Cela lui permet de communiquer assez facilement avec l’essentiel des STAN ou des moteurs audios existants. La précision temporelle est tout à fait acceptable, ce qui fait déjà de ce programme un séquenceur efficace pour prototyper et tester plusieurs dispositifs ou instruments simples. De manière détournée, ces deux dernières caractéristiques font de Belly un outil qui peut être employé en dehors de son domaine pour piloter sons, lumières, animations et autres.

L’output du programme est pensé pour être interprété par SuperDirt, le moteur audio par défaut de Tidal Cycles. Tout ce qui est exprimable dans Tidal l’est donc potentiellement avec Belly (manipulation de samples, paramètres de synthèse). Belly est pourtant très loin de permettre la même expressivité que le langage développé par Alex McLean. Pour le moment, Belly reste un DSL très verbeux, peu élégant et peu capable pour ce qui s’agit de représenter la musique et le temps. Il est difficile de faire émerger un sens de la structure, une idée mélodique complexe, ou d’être réellement expressif. J’espère trouver un moyen d’arranger cela au cours des prochains mois. J’ai bon espoir, car le système d’objets de Python est assez flexible, et supporte bien des bizarreries. Les quelques vidéos en annexe de ce post donnent une bonne idée de la syntaxe actuelle, à quelques différences mineures près.

Notes

Médias