Une visualisation qui vit dans le lecteur
La plupart des lecteurs te donnent un analyseur de spectre et s'arrêtent là. rox a ces panneaux, un moteur Milkdrop pour vingt ans de préréglages, et en dessous une couche de modulation : des signaux nommés tirés de l'audio, acheminés vers des entrées de shaders que tu écris toi-même, enregistrés dans le fichier même où vit le reste de ton thème.
D'abord les panneaux ordinaires
Un panneau de spectre avec styles en barres ou en blocs, dégradés, crêtes ayant leur propre gravité, étiquettes de fréquence, et un zonage séparé qui analyse au-dessus et en dessous d'une fréquence choisie avec des tailles de fenêtre différentes, pour que chaque extrémité de la plage arbitre elle-même entre réactivité et résolution. Une bande de forme d'onde qui dessine la piste entière, par canal, et fait sauter la lecture là où tu cliques. Un VU-mètre. Une étagère de pochettes qui les fait tourner en vraie 3D. Rien de tout cela ne demande une ligne de code et c'est ce que la plupart des gens utiliseront.
Mettre en pause fige les barres là où elles étaient, au lieu de les laisser tomber au sol. Cela paraît anodin jusqu'au moment où tu essaies de regarder l'instant exact où tu as fait pause.
Milkdrop, dans un panneau et derrière tout le reste
Un panneau Milkdrop rend les préréglages via libprojectM sur son propre thread et dessine le résultat à travers la même chaîne de shaders que tout le reste : il s'ancre, se met en onglet et se détache comme n'importe quel autre panneau, et un shader de surface passe dessus de la même façon. Dépose un pack de préréglages dans le dossier indiqué sur la page Préréglages, Cream of the Crop ou le jeu MilkDrop d'origine, et lance une nouvelle analyse. Les textures livrées dans un pack sont trouvées toutes seules.
Choisir un préréglage ouvre un navigateur dans sa propre fenêtre : une arborescence de dossiers ou une grille de vignettes, un filtre, un interrupteur de favoris et la navigation au clavier. Cliquer sur un préréglage le charge tout de suite derrière la fenêtre, ce que tu vois est donc le vrai rendu et pas un aperçu. La rotation définit ce que Suivant, Précédent et le changement minuté parcourent, et le verrou garde un préréglage d'une piste à l'autre.
Le même moteur tourne en fond derrière chaque fenêtre, composé par-dessus la pochette floutée à l'intensité que tu règles. Un préréglage peut garder ses propres couleurs, s'inverser pour le thème clair, peindre dans la palette ou prendre la couleur de la pochette en cours en gardant son propre détail, et une teinte d'album décale les tons vers la pochette. Une file arrêtée le fait disparaître en fondu et le thread de rendu s'arrête, un visuel inactif ne coûte donc rien.
Des shaders, sur quatre surfaces
Un shader rox est un unique étage de fragment WGSL. Il peut s'exécuter sur le corps d'un seul panneau, comme panneau Shader à part entière, en surcouche sur toute la fenêtre, ou en fond peignant sous tous les panneaux, derrière la pochette. La surcouche et le fond ont chacun un interrupteur qui les étend à toutes les fenêtres ouvertes de rox. Même langage, même bloc d'uniformes, même acheminement partout.
Chaque shader reçoit l'horloge, la résolution, le pointeur, et huit flottants méta décrivant l'instant : le volume, où se trouve la tête de lecture dans la piste, si l'audio avance réellement, la durée de la piste, et à quel point la palette actuelle s'affiche sombre, pour qu'un même shader puisse s'habiller pour le clair comme pour le sombre au lieu d'être livré pour le seul thème sur lequel il a été écrit.
Un shader de panneau peut aussi lire ce que le panneau a réellement dessiné. Une liaison de masque lui remet le dessin du panneau rejoué sur de la transparence, et les panneaux publient la forme de leur contenu, une ombre ou une lueur suit donc une pochette encadrée de bandes noires plutôt que les bandes vides de part et d'autre.
Au-delà d'un étage, un commentaire // @pass découpe le texte en une chaîne pouvant aller jusqu'à huit, chacun capable de lire les passes précédentes par leur nom. C'est ce dont une pyramide de flou ou un bloom en deux étages a besoin. Une ligne // @asset nomme une image à échantillonner, et // @asset art: @cover lie la pochette de la piste en cours, et se relie à nouveau à chaque changement de piste. Neuf exemples sont livrés avec l'application, chacun démontrant une partie différente de ce contrat plutôt que neuf variations d'un plasma.
Pointe le panneau sur un fichier du disque et rox le surveille. Enregistre dans ton éditeur et la fenêtre l'a. Un enregistrement qui ne compile pas laisse la dernière version valide à l'écran avec l'erreur dans le panneau, parce que perdre l'image est une mauvaise façon d'apprendre qu'on a mal tapé un point-virgule.
Les signaux, c'est la partie qu'on ne trouve pas ailleurs
Un shader avec une horloge dedans est un économiseur d'écran. Ce qui en fait une visualisation, c'est ce dont tu le nourris, et dans rox c'est un ensemble de signaux nommés partagé par toute l'application. Tu les construis dans une fenêtre à part, sous Application, à côté de l'égaliseur, et elle embarque un spectre et des commandes de lecture pour la même raison que l'égaliseur : tu choisis une bande à l'œil et à l'oreille sur ce que tu écoutes vraiment.
Cinq types de source. Une bande, c'est l'énergie entre deux fréquences, le signal sur lequel une montée s'appuie. Le niveau, c'est le mixage entier. Une attaque pulse quand une bande dépasse sa propre moyenne récente, le signal sur lequel une frappe s'appuie. Un déclencheur pulse quand une bande franchit une ligne que tu as tracée, pour la matière où la moyenne glissante ne redescend jamais et où une attaque se tait après la première mesure. Un total additionne un autre signal dans le temps et revient à zéro une fois arrivé à un, un shader peut donc le lire comme une phase qui avance tant que la musique est forte et s'arrête quand elle ne l'est pas.
Chacun porte un lissage de réponse et une porte. La porte est le réglage qui mérite sa place : une bande qui suit le bruit de fond garde tous les réglages qui y sont rattachés éternellement un peu hors de leur position de repos, et un seuil avec une courbe au-dessus livre plutôt du silence entre les frappes. L'indicateur dessine la valeur d'avant la porte avec le seuil tracé en travers, puisqu'une barre disparue sous sa propre porte n'aiderait en rien à placer cette porte.
Une route rattache un signal à un paramètre avec une plage de sortie : ce signal, cette cible, d'ici à là. Seize emplacements atteignent chaque shader, et les emplacements vers lesquels rien n'est acheminé reçoivent un simple curseur dans les réglages, une apparence peut donc être à moitié jouée et à moitié réglée à la main.
Critters, en guise d'argument
L'un des espaces de travail livrés, c'est le lecteur entier rendu en impression 1 bit : un tramage ordonné sur chaque surface, des tons qui s'écrasent avec les infrabasses, et un mur de bruit derrière les panneaux qui bouge avec le morceau. Ce sont cinq signaux et quatre shaders dans un seul fichier, et rien de tout cela n'est un cas particulier dans l'application.

Charge-le depuis la fenêtre d'accueil, puis ouvre les réglages et démonte-le. Tous les autres.
Exécuter le shader d'un inconnu
Les shaders voyagent à l'intérieur des fichiers d'espace de travail, une apparence importée arrive donc en portant le code de quelqu'un d'autre.
Rien ne s'exécute avant que tu ne le dises. Le code de chaque shader reçoit une empreinte, et la liste d'approbation est locale à la machine et n'est jamais écrite que par une action directe : tu as choisi le fichier, tu as rechargé, tu as choisi un préréglage, tu as appuyé sur Approuver. Une apparence arrivée dans un paquet reste là, inerte, avec un bouton en dessous, en attendant. Les exemples livrés avec rox sont dignes de confiance par construction, parce qu'ils sont compilés dans le binaire.
En activer un ouvre une fenêtre de confirmation qui attend une réponse au lieu de compter à rebours, et cette fenêtre ne passe jamais elle-même sous un shader. Quoi que le shader fasse au reste de l'écran, le chemin de sortie reste lisible.
Ce qui n'est pas traité
- Les routes atteignent les emplacements de shaders et les réglages du panneau de particules. Les réglages de tous les autres panneaux restent des curseurs que tu places à la main.
- Des préréglages Milkdrop, pas AVS. Il n'y a pas d'importateur pour l'AVS de Winamp. Et un préréglage est un fichier sur ton disque, celui qui est chargé reste donc propre à la machine au lieu de voyager dans un espace de travail.
- Pas de surface de contrôle MIDI ni OSC. La passe de surcouche et les passes de panneaux sont ce qui existe, pilotées par l'audio et le pointeur.
- Une passe sur toute la fenêtre est une vraie passe GPU à chaque image. Sur un portable sur batterie, c'est un choix que tu fais.
Entre « je veux que tout le lecteur clignote sur la grosse caisse » et l'avoir à l'écran, il y a une bande, une porte et une route, et aucune des trois ne demande de recompiler.
Essaie-le sur ta propre bibliothèque
Rien ici n'appelle qui que ce soit : l'analyse porte sur l'audio qui traverse déjà le lecteur. Plus sur ce que porte un espace de travail.
Sous Arch ou NixOS ? Installe-le plutôt depuis l'AUR ou le flake Nix.