← Back to publications
Net art by Lysandre Vervialle-Bince · 28 May 2026

Bionum

Bienvenue dans l'univers de Bionum, une étude générative et interactive qui vous plonge au cœur d'un organisme vivant, constitué de cellules lumineuses, produisant de la musique en temps réel. Au cœur de ce premier projet, chaque cellule se transforme en une source sonore autonome, dotée de sa propre position, vitesse, taille, couleur, énergie et identité sonore. À travers des mouvements de rapprochement, de fusion, de division ou de mort, ces cellules modifient progressivement la musique, fonctionnant ainsi comme une partition vivante. Ici, le son n'est pas préétabli, mais émerge du comportement dynamique de cet organisme fascinant. L'objectif n'est pas de produire des sons aléatoires, mais de composer une musique "esthétique", immersive et captivante, inspirée des genres tels que l’ambient, le drone, la musique générative, ainsi que des textures granulaires et du glitch doux. Les cellules ont la capacité de générer des sons longs, des pulsations, des grains sonores, des harmoniques ou même de petits accidents électroacoustiques. Le système intègre également des gammes musicales et des règles harmoniques pour éviter le désordre sonore. Le visuel joue un rôle clé dans cette expérience immersive : l’écran représente un milieu biologique abstrait, évoquant une boîte de Pétri numérique ou un univers microscopique. Les cellules brillent, laissent des traînées lumineuses et changent de couleur selon leur énergie et leur son, donnant au spectateur l'impression d'observer un organisme vivant, en pleine respiration, croissance et transformation, qui produit sa propre musique. L'utilisateur devient alors un jardinier sonore, interagissant avec cet organisme : il peut ajouter des cellules, perturber leur mouvement avec la souris, provoquer des mutations, ou encore choisir des modes calmes, stables ou chaotiques. Malgré ces interactions, le système demeure autonome, continuant d'évoluer et de composer indépendamment. Enfin, le projet intègre un chef d’orchestre invisible, nommé Conductor, qui surveille la densité sonore, le nombre de cellules, les collisions, l'énergie globale et le niveau de dissonance. Ce chef d'orchestre ajuste automatiquement le volume, les effets, les divisions et les disparitions des cellules pour garantir que la musique reste cohérente, belle et agréable à écouter. Bionum est un projet qui fusionne art numérique, programmation, biologie imaginaire et musique électroacoustique. Il transforme un système de cellules en un instrument vivant, capable de générer une musique organique, évolutive et poétique. L'ambition est de créer une expérience sonore et visuelle originale où l'on n'écoute pas seulement une musique, mais où l'on observe un être vivant qui la compose.

Bionum

Installation SONORE ET VISUELLE générative

Présentons plus en détail cette réalisation.

p5.js Web Audio API Musique générative Seed reproductible Organisme sonore

Architecture du site

Le site repose sur trois couches principales : la structure, l’apparence et le moteur génératif.

HTML

Le fichier <span class="inline-code">index.html</span> crée les panneaux visibles : modes, seed, boutons audio, export, métriques du Conductor, interface du Rituel et statut des cellules.

CSS

Le fichier <span class="inline-code">styles.css</span> construit l’ambiance visuelle : fond sombre, panneaux translucides, typographie, responsive, générique de fin et mode interface cachée avec la touche <span class="inline-code">H</span>.

JavaScript

Le fichier <span class="inline-code">app.js</span> contient tout le moteur : cellules, organisme, moteur sonore, chef d’orchestre, interactions, enregistrement et mode Rituel.

Techniquement, le projet utilise p5.js pour dessiner le canvas, la Web Audio API pour générer le son, MediaRecorder pour capturer la vidéo ou l’audio, et une seed reproductible pour recréer le même organisme.

La boucle principale

Au chargement de la page, le site récupère l’interface, crée le moteur audio, crée l’organisme puis connecte les interactions.

<pre class="code-embed"><code>const ui = collectUi();

const audio = new AudioEngine();
organism = new Organism(p, audio, ui);

interactions = new InteractionManager(organism, audio, ui);&lt;/code&gt;&lt;/pre&gt;

Ensuite, la boucle p5 exécute deux opérations à 30 images par seconde.

<pre class="code-embed"><code>organism.update();
organism.draw(p);</code></pre>

À chaque image, les cellules vieillissent, se déplacent, interagissent, déclenchent des événements, le Conductor analyse

l’état global, l’audio est mis à jour et le canvas est redessiné. Le site est volontairement limité à

&lt;span class="inline-code"&gt;30 FPS&lt;/span&gt; pour réduire la latence et éviter de surcharger l’ordinateur.

Les cellules

La classe centrale du projet est <span class="inline-code">Cell</span>. Une cellule n’est pas seulement un point graphique : c’est une entité complète avec un comportement biologique et une identité sonore.

Paramètres physiques

  • x, y : position
  • vx, vy : vitesse
  • size : taille
  • mass : masse
  • age : âge

Paramètres biologiques

  • energy : énergie
  • state : calme, active, instable, mourante
  • family : drone, granular, pulsing, spectral, unstable
  • gene : ADN comportemental et sonore

Paramètres sonores

  • frequency : fréquence actuelle
  • targetFrequency : fréquence cible
  • modulation : vibrato et instabilité
  • hue, saturation, lightness : couleur liée au timbre

Le gène d’une cellule est créé dans createGene(). Il définit son attraction, sa répulsion, son errance, son seuil de division, sa durée de vie, son vibrato, son instabilité, son rapport de formant et sa couleur d’événement.

Hasard contrôlé et seed

Le projet ne repose pas sur un hasard pur. Il utilise un pseudo-hasard contrôlé par une seed. La fonction

&lt;span class="inline-code"&gt;hashSeed(seed)&lt;/span&gt; transforme un texte, par exemple &lt;span class="inline-code"&gt;"marais-bleu-2049"&lt;/span&gt;,
en nombre. Ensuite, la classe &lt;span class="inline-code"&gt;SeededRandom&lt;/span&gt; génère une suite de valeurs toujours identique pour la même seed.

Ainsi, chaque seed fonctionne comme une partition vivante : elle donne un point de départ reproductible, tout en laissant l’organisme évoluer de manière organique.

Déplacement des cellules

Les cellules ne se déplacent pas au hasard total. Leur mouvement vient d’une addition de forces : champ de flux, répulsion, attraction harmonique, influence de la souris, rebond doux sur les bords et chaos contrôlé.

Champ de flux

La fonction flowAt(x, y, t) crée un champ vectoriel avec des sinus et des cosinus.

<pre class="code-embed"><code>a = sin(nx * 8.2 + t * 0.6) + cos(ny * 7.1 - t * 0.4)
b = cos(nx * 6.4 - t * 0.5) - sin(ny * 8.6 + t * 0.3)

return {

x: cos(a + b),
y: sin(a - b)

}&lt;/code&gt;&lt;/pre&gt;

Ce champ produit un mouvement fluide, comparable à un courant invisible.

Répulsion et attraction

Si deux cellules sont trop proches, elles se repoussent pour éviter la superposition. Une distance désirée est calculée.

desired = tailleA + tailleB + 18

Si la distance réelle est plus petite que cette distance désirée, une force opposée est appliquée. À moyenne distance, les cellules peuvent au contraire s’attirer selon leur compatibilité harmonique.

<pre class="code-embed"><code>compatibility = organism.harmonicCompatibility(this, other)
pull = compatibility * attraction * distanceFactor</code></pre>

Les cellules musicalement compatibles ont donc plus tendance à se rapprocher.

Mouvement final

Le mouvement final suit cette logique d’intégration physique :

<pre class="code-embed"><code>vx += ax * dt * 60

vy += ay * dt * 60
x += vx * dt * 60

y += vy * dt * 60&lt;/code&gt;&lt;/pre&gt;

La vitesse est ensuite limitée pour empêcher les cellules de devenir trop rapides.

Correspondance visuel-son

Chaque paramètre visuel influence directement un paramètre sonore.

Position X

Panoramique gauche/droite et registre.

Position Y

Hauteur dans la gamme, filtrage et profondeur.

Taille

Volume, présence et profondeur sonore.

Énergie

Brillance, volume, densité et instabilité.

Vitesse

Modulation, vibrato et tremblement.

Âge

Fragilité du timbre et disparition progressive.

Harmonie et fréquences

Le moteur contient plusieurs systèmes harmoniques internes : pentatonique mineure, lydien, dorien, mineur naturel et spectre harmonique naturel. Même si le choix manuel n’est plus affiché dans l’interface, la seed choisit toujours un mode harmonique interne.

La fréquence d’une cellule est calculée dans frequencyForCell(cell).

  • baseFrequency choisit une fondamentale autour de 41, 49, 55, 65 ou 73 Hz.
  • xRegister dépend de la position horizontale.
  • yIndex dépend de la position verticale.
  • energyOctave ajoute une octave si la cellule possède beaucoup d’énergie.

La formule principale est celle du tempérament égal :

frequency = baseFrequency * 2 ** ((degree + octave * 12) / 12)

Chaque octave double la fréquence. Les 12 demi-tons divisent l’octave, et
<span class="inline-code">2 ** (n / 12)</span> donne le rapport de fréquence pour <span class="inline-code">n</span> demi-tons.

Pour le mode spectral, le moteur utilise des ratios naturels :

1, 9/8, 5/4, 4/3, 3/2, 8/5, 5/3, 7/4, 2

Compatibilité harmonique

La fonction harmonicCompatibility(a, b) compare deux fréquences.

<pre class="code-embed"><code>ratio = max(freqA, freqB) / min(freqA, freqB)
semitone = round(12 * log2(ratio)) % 12</code></pre>

  • Unisson, quinte et quarte : très compatibles.
  • Tierces et sixtes : compatibles.
  • Secondes : moins compatibles.
  • Triton : instable, mais davantage accepté en mode chaos.

Les familles sonores

Drone

Son stable et profond. Il utilise une sinusoïde fondamentale et une onde triangle à l’octave. C’est la base respirante.

Granular

Son textural. Il utilise un bruit filtré en boucle, une sinusoïde discrète et un filtre bandpass. C’est la matière microscopique.

Pulsing

Son pulsé. Il utilise une onde triangle, une sinusoïde grave et une modulation de volume avec sin(phase * pulseRate).

Spectral

Son lumineux. Il utilise une fondamentale sinusoïdale, une octave et une modulation légère. C’est le halo harmonique.

Unstable

Son fragile et tendu. Il utilise une sinusoïde, une sawtooth très faible et un vibrato plus instable.

Création du son

Le moteur sonore est <span class="inline-code">AudioEngine</span>. Lorsque l’utilisateur clique sur

&lt;span class="inline-code"&gt;Start Audio&lt;/span&gt;, le navigateur autorise l’audio et le moteur crée un

&lt;span class="inline-code"&gt;AudioContext&lt;/span&gt;.

La chaîne audio globale est construite dans buildGraph().

<pre class="code-embed"><code>voix des cellules

→ bus général
→ dry / delay / reverb
→ highpass
→ lowpass
→ compresseur
→ saturation légère
→ master gain
→ limiteur final
→ gain de sécurité

→ sortie audio&lt;/code&gt;&lt;/pre&gt;

  • highpass coupe les très graves inutiles.
  • lowpass limite les aigus agressifs.
  • compressor stabilise le niveau.
  • saturator ajoute une légère couleur.
  • limiter évite les pics.
  • outputGain réduit encore la sortie pour la sécurité.

Voix actives et paramètres sonores

Toutes les cellules ne jouent pas forcément en même temps. Pour éviter la saturation,
<span class="inline-code">syncCells()</span> trie les cellules par importance.

importance = energy * size

Les cellules les plus grandes et les plus énergiques deviennent prioritaires. Selon l’écran, environ 5 à 7 voix sont actives simultanément.

Dans updateVoice(), chaque cellule modifie sa voix sonore en temps réel.

<pre class="code-embed"><code>osc.frequency.setTargetAtTime(...)
pan = mapRange(cell.x, 0, width, -0.96, 0.96)</code></pre>

La fréquence glisse vers la fréquence cible. Le filtre dépend de l’énergie, de la vitesse, de la position verticale et du gène sonore.
Le panoramique dépend de la position horizontale : une cellule à gauche sonne à gauche, une cellule à droite sonne à droite.

Événements sonores

Collision

Bruit filtré, bandpass, attaque courte, panoramique au point de collision et intensité liée à la force.

Division

Deux pings, une petite cloche et une fréquence dérivée de la cellule mère.

Fusion

Deux oscillateurs glissent vers la fréquence de la nouvelle cellule. Le son devient plus long et plus cérémoniel.

Mort

Souffle doux, filtre grave, ralentissement visuel et fade-out sonore.

Le Conductor

Le <span class="inline-code">Conductor</span> est le chef d’orchestre invisible. Il observe l’organisme et ajuste ses paramètres pour que la musique reste vivante, dense, mais écoutable.

Il mesure

  • la densité ;
  • l’énergie moyenne ;
  • la dissonance ;
  • les collisions récentes.

Il ajuste

  • la probabilité de division ;
  • la probabilité de mort ;
  • le chaos ;
  • la réverbération ;
  • le delay ;
  • le filtrage global ;
  • la consonance ;
  • l’énergie cible.

Si la densité devient trop haute, les divisions sont freinées, la mort augmente, la réverbération diminue et le volume global baisse. Si la dissonance augmente, le filtre est adouci et le système corrige la consonance.

Les modes

Calme

Peu de cellules, énergie basse, peu de collisions, réverbération large et ambiance douce.

Stable

Équilibre entre naissance et mort, densité moyenne et interactions régulières.

Chaos

Énergie plus haute, collisions nombreuses, divisions rapides et modulation plus forte, toujours limitée par le Conductor.

Rituel

Mode narratif qui redémarre depuis la seed, masque l’interface, affiche une introduction, développe l’organisme puis lance un générique.

Mode Rituel

Le mode Rituel dure environ cinq minutes au total : une minute d’introduction, environ trois minutes d’organisme visible et une minute de générique.

<pre class="code-embed"><code>RITUAL_DURATION = 240

RITUAL_INTRO_DURATION = 60

RITUAL_CREDITS_DURATION = 60&lt;/code&gt;&lt;/pre&gt;

Le temps de l’organisme est structuré en plusieurs étapes : éveil, prolifération, friction, débordement, chaos total et dissolution.

Pendant le Rituel, plusieurs ruptures suppriment toutes les cellules d’un coup. Une nouvelle souche apparaît ensuite, comme une nouvelle génération, ce qui donne au mode Rituel une forme de récit plutôt qu’un simple flux infini.

Naissance, division, fusion, collision et mort

Naissance

Une cellule peut naître au lancement, par auto-évolution, par clic, par division ou pendant le Rituel.

Division

Une cellule se divise si son énergie dépasse son seuil génétique et si la densité locale reste raisonnable.

3, 4, 7, 12, 19

Ces intervalles correspondent à la tierce mineure, tierce majeure, quinte, octave et octave + quinte.

Fusion

Deux cellules proches et harmoniquement compatibles peuvent fusionner. La nouvelle fréquence utilise une moyenne géométrique.

sqrt(freqA * freqB)

Collision

Une collision sépare physiquement les cellules, augmente légèrement leur énergie et déclenche un événement visuel TOUCH.

Mort

Une cellule peut mourir si elle est trop vieille, manque d’énergie, reçoit un clic droit ou entre dans la dissolution du Rituel.

Design visuel

Le visuel utilise un fond sombre, un canvas plein écran, des panneaux translucides, des cellules en HSL, des halos, des anneaux, des labels d’événement et des connexions entre cellules compatibles.

Drone

Ellipse stable.

Granular

Petits points autour de la cellule.

Pulsing

Cercles pulsants.

Spectral

Rayons lumineux.

Unstable

Forme anguleuse et instable.

Optimisation et responsive

Le projet est optimisé pour limiter la latence et rester fluide.

  • Rendu limité à 30 FPS.
  • Nombre maximal de cellules limité.
  • Nombre maximal de voix audio limité.
  • Moins de particules sur petits écrans.
  • Audio synchronisé toutes les quelques frames.
  • Canvas volontairement sobre.
  • Densité adaptée à la taille de l’écran.

Une grille spatiale divise l’écran en cases de <span class="inline-code">180px</span>. Au lieu de comparer chaque cellule avec toutes les autres, une cellule vérifie seulement les cellules proches. Cela réduit fortement les calculs.

Le responsive utilise <span class="inline-code">100dvw</span>, <span class="inline-code">100dvh</span>, des media queries et
<span class="inline-code">qualityProfile()</span> pour adapter la densité à l’écran.

Interactions et exports

Interactions

  • Clic vide : ajouter une cellule.
  • Clic sur cellule : solo temporaire.
  • Clic long : drone massif.
  • Double-clic : division forcée.
  • Clic droit : mort douce.
  • Molette : énergie globale.
  • C, S, X : calme, stable, chaos.
  • R : renaissance.
  • M : mutation.
  • A : auto-évolution.
  • H ou F : masquer l’interface.
  • Espace : pause.

Exports

  • Enregistrement WAV.
  • Export du dernier WAV.
  • Vidéo WebM.
  • Sauvegarde JSON.
  • Chargement JSON.
  • Image PNG.

Le JSON sauvegarde la seed, le mode, l’harmonie interne, la fréquence de base, les cellules, leurs positions, vitesses, tailles, énergies, âges, familles, couleurs et gènes.

Synthèse

Bionum est une partition vivante. Les cellules sont les voix, les interactions deviennent des événements musicaux, et le Conductor régule l’ensemble pour maintenir une forme organique, immersive et écoutable. Le projet réunit simulation biologique, mathématiques musicales, synthèse sonore en temps réel et design génératif.</div>