Aller au contenu
roomi fields

Audio et matériel

FaustScript

Langage qui ajoute à Faust le nom d'une instance et les gestes pour la modifier pendant qu'elle joue ; il se traduit en Faust.

expérimental dernière modification 10 octobre 2026 licence MIT

Code source Site

En Faust, un nom est une macro : écrire fi.lowpass deux fois construit deux filtres, et aucune expression ne peut désigner un filtre qui existe déjà. FaustScript donne cette adresse, pour pouvoir dire en plein concert « ce filtre-là, ouvre-le ». Sa limite principale : il ne produit aucun son, il écrit du Faust ; recompiler pendant que l’audio tourne revient à l’hôte, et les vrais fichiers .dsp ne se lisent pas encore en entier.

Le projet s’appelait FaustX jusqu’au 7 octobre 2026 ; ses fichiers s’écrivaient alors en .fx, ils finissent désormais en .fsc.

Pas de démo jouable : il n’existe pas encore d’hôte qui fasse sonner FaustScript. Le site du projet montre les cinq signes de Faust et ce que chacun devient.

Décorer les signes de Faust, sans en inventer

Le : reste la connexion ; ce qui l’entoure la qualifie. Trois règles suffisent : un ! devant annule ce qui suit, un chiffre après dit combien, le point entre dans une instance. Le = donne une valeur, le : ne fait que connecter.

ÉcritEffet
let lpf1 fi.lowpassplace une instance
lpf1 fi.lowpass(fc=400)remplace son corps, mémoire gardée
saw1 :8 lpf1connecte en huit instances
saw1 !: lpf1coupe le fil
_ lpf1 · !_ lpf1contourne · rétablit
! lpf1retire l’instance et ses fils
lpf1.fc = 400règle un contrôle
lfo1 : lpf1.fcmodule un contrôle par un signal

Un module s’écrit sous son nom Faust, préfixe compris : fi.lowpass, pas lowpass. Une définition Faust court jusqu’à son ;, comme en Faust ; toute autre ligne est un geste.

Commencer

Il faut Node 22 ou plus récent.

git clone https://github.com/roomi-fields/faustscript
cd faustscript
npm install
npx faustscript examples/1-drone-that-plays-alone.fsc

La commande affiche le Faust produit ; -o fichier.dsp l’écrit dans un fichier. Elle a tourné telle quelle le 28 octobre 2026, sur le dépôt au 10 octobre 2026. Un geste refusé part sur la sortie d’erreur, avec sa raison et sa ligne, et le reste du fichier est traduit quand même. Par exemple :

let saw1 os.sawtooth(freq=110)
let lpf1 fi.lowpass(fc=800)

saw1 : lpf1 : process

devient :

import("stdfaust.lib");
saw1 = vgroup("saw1", os.sawtooth(hslider("freq[unit:Hz][scale:log]", 110, 0.08, 220, 0.001)));
lpf1 = vgroup("lpf1", fi.lowpass(4, hslider("fc[unit:Hz][scale:log]", 800, 2, 8000, 0.001)));
process = saw1 : lpf1;

L’ordre du filtre reste une constante, fc devient un curseur à échelle logarithmique avec ses vraies bornes, et le nom de l’instance donne le chemin de contrôle /lpf1/fc. Ces informations viennent du catalogue, pas de ce qu’on a écrit.

Ce qu’il fait

  • Traduire en Faust, que le compilateur de Faust compile sans modification, avec les fonctions que ses bibliothèques déclarent.
  • Connaître 1 172 modules de ces bibliothèques : paramètres, valeurs de départ, bornes, nombre d’entrées et de sorties mesuré, et plage de sortie mesurée pour 848 d’entre eux. Le catalogue est généré depuis la documentation des bibliothèques que porte faustwasm 0.19.0 (Faust 2.90.0, bibliothèques 2.74.2) ; son en-tête donne ces versions et ce compte.
  • Ne rien couper net. Un module contourné ou retiré continue de tourner sur du silence, et ce qui résonnait finit de résonner. Mesuré sur une réverbération, selon le README : ba.bypass1 de Faust fait passer ses 97 champs de mémoire à 0 ; FaustScript en garde 81.
  • Refuser une ligne fausse sans arrêter le son : le graphe n’est touché que si le programme compile.

Où il en est

Le langage est fixé : les huit éléments de Faust ont été revus, et chaque affirmation de la spécification vérifiée en compilant. Le traducteur marche : les trois pièces de examples/ passent sans geste refusé, et les 310 tests du traducteur passent le 28 octobre 2026. Recompiler un module prend environ 35 ms, contre environ 614 ms pour un programme de cinquante modules (médianes mesurées le 28 octobre 2026 avec libfaust en WebAssembly, faustwasm 0.19.0) ; node tools/measure-compilation.mjs refait la mesure. Les nouveautés sont dans le journal des modifications du dépôt.

Ce qui vient : l’hôte qui fait sonner FaustScript dans le navigateur, par faustwasm. Le projet figure sur la page « Powered By Faust » du site de Faust et dans la liste d’outils de livecoding.fr ; je les y ai proposés, les deux ajouts ont été acceptés en août 2026. Au 28 octobre 2026, les deux pages le présentent encore sous le nom FaustX et pointent vers l’ancienne adresse du dépôt, que GitHub redirige.

Dépôt · Site · Faust · Powered By Faust · livecoding.fr

FaustScript est un projet indépendant, sans lien avec GRAME-CNCM, qui développe Faust. Merci à Stéphane Letz (GRAME), qui m’a conseillé de refaire les mesures par faustwasm, et à Raphaël Forment pour l’ajout à livecoding.fr.

Fabrication. Claude Code (Claude Opus 5.5), à partir du dépôt, de son README et de ses notes de version. Méthode